From 34b8a16cc7d5116c6b844316f1252769f39d8315 Mon Sep 17 00:00:00 2001 From: Dmitry Chapyshev Date: Sat, 8 Nov 2008 07:14:34 +0000 Subject: [PATCH] - Sync inetcomm with Wine Head - Sync imnxport.idl and mimeole.idl svn path=/trunk/; revision=37250 --- reactos/dll/win32/inetcomm/imaptransport.c | 511 ++++++++ reactos/dll/win32/inetcomm/inetcomm.rbuild | 5 + reactos/dll/win32/inetcomm/inetcomm.spec | 12 +- reactos/dll/win32/inetcomm/inetcomm_main.c | 28 +- reactos/dll/win32/inetcomm/inetcomm_private.h | 14 +- .../dll/win32/inetcomm/internettransport.c | 21 + reactos/dll/win32/inetcomm/mimeintl.c | 596 ++++++++++ reactos/dll/win32/inetcomm/mimeole.c | 110 +- reactos/dll/win32/inetcomm/pop3transport.c | 662 +++++++++++ reactos/dll/win32/inetcomm/regsvr.c | 14 +- reactos/dll/win32/inetcomm/smtptransport.c | 1047 +++++++++++++++++ reactos/include/psdk/imnxport.idl | 427 ++++++- reactos/include/psdk/mimeole.idl | 87 +- 13 files changed, 3485 insertions(+), 49 deletions(-) create mode 100644 reactos/dll/win32/inetcomm/imaptransport.c create mode 100644 reactos/dll/win32/inetcomm/mimeintl.c create mode 100644 reactos/dll/win32/inetcomm/pop3transport.c create mode 100644 reactos/dll/win32/inetcomm/smtptransport.c diff --git a/reactos/dll/win32/inetcomm/imaptransport.c b/reactos/dll/win32/inetcomm/imaptransport.c new file mode 100644 index 00000000000..4cef0838d23 --- /dev/null +++ b/reactos/dll/win32/inetcomm/imaptransport.c @@ -0,0 +1,511 @@ +/* + * IMAP Transport + * + * Copyright 2008 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winuser.h" +#include "objbase.h" +#include "mimeole.h" +#include "wine/debug.h" + +#include "inetcomm_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(inetcomm); + +typedef struct +{ + InternetTransport InetTransport; + ULONG refs; +} IMAPTransport; + +static HRESULT WINAPI IMAPTransport_QueryInterface(IIMAPTransport *iface, REFIID riid, void **ppv) +{ + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IInternetTransport) || + IsEqualIID(riid, &IID_IIMAPTransport)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + *ppv = NULL; + FIXME("no interface for %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI IMAPTransport_AddRef(IIMAPTransport *iface) +{ + IMAPTransport *This = (IMAPTransport *)iface; + return InterlockedIncrement((LONG *)&This->refs); +} + +static ULONG WINAPI IMAPTransport_Release(IIMAPTransport *iface) +{ + IMAPTransport *This = (IMAPTransport *)iface; + ULONG refs = InterlockedDecrement((LONG *)&This->refs); + if (!refs) + { + TRACE("destroying %p\n", This); + if (This->InetTransport.Status != IXP_DISCONNECTED) + InternetTransport_DropConnection(&This->InetTransport); + if (This->InetTransport.pCallback) ITransportCallback_Release(This->InetTransport.pCallback); + HeapFree(GetProcessHeap(), 0, This); + } + return refs; +} + +static HRESULT WINAPI IMAPTransport_GetServerInfo(IIMAPTransport *iface, + LPINETSERVER pInetServer) +{ + IMAPTransport *This = (IMAPTransport *)iface; + + TRACE("(%p)\n", pInetServer); + return InternetTransport_GetServerInfo(&This->InetTransport, pInetServer); +} + +static IXPTYPE WINAPI IMAPTransport_GetIXPType(IIMAPTransport *iface) +{ + TRACE("()\n"); + return IXP_IMAP; +} + +static HRESULT WINAPI IMAPTransport_IsState(IIMAPTransport *iface, + IXPISSTATE isstate) +{ + FIXME("(%d): stub\n", isstate); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_InetServerFromAccount( + IIMAPTransport *iface, IImnAccount *pAccount, LPINETSERVER pInetServer) +{ + IMAPTransport *This = (IMAPTransport *)iface; + + TRACE("(%p, %p)\n", pAccount, pInetServer); + return InternetTransport_InetServerFromAccount(&This->InetTransport, pAccount, pInetServer); +} + +static HRESULT WINAPI IMAPTransport_Connect(IIMAPTransport *iface, + LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging) +{ + IMAPTransport *This = (IMAPTransport *)iface; + HRESULT hr; + + TRACE("(%p, %s, %s)\n", pInetServer, fAuthenticate ? "TRUE" : "FALSE", fCommandLogging ? "TRUE" : "FALSE"); + + hr = InternetTransport_Connect(&This->InetTransport, pInetServer, fAuthenticate, fCommandLogging); + return hr; +} + +static HRESULT WINAPI IMAPTransport_HandsOffCallback(IIMAPTransport *iface) +{ + IMAPTransport *This = (IMAPTransport *)iface; + + TRACE("()\n"); + return InternetTransport_HandsOffCallback(&This->InetTransport); +} + +static HRESULT WINAPI IMAPTransport_Disconnect(IIMAPTransport *iface) +{ + FIXME("(): stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_DropConnection(IIMAPTransport *iface) +{ + IMAPTransport *This = (IMAPTransport *)iface; + + TRACE("()\n"); + return InternetTransport_DropConnection(&This->InetTransport); +} + +static HRESULT WINAPI IMAPTransport_GetStatus(IIMAPTransport *iface, + IXPSTATUS *pCurrentStatus) +{ + IMAPTransport *This = (IMAPTransport *)iface; + + TRACE("()\n"); + return InternetTransport_GetStatus(&This->InetTransport, pCurrentStatus); +} + +static HRESULT WINAPI IMAPTransport_InitNew(IIMAPTransport *iface, + LPSTR pszLogFilePath, IIMAPCallback *pCallback) +{ + IMAPTransport *This = (IMAPTransport *)iface; + + TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath), pCallback); + + if (!pCallback) + return E_INVALIDARG; + + if (pszLogFilePath) + FIXME("not using log file of %s, use Wine debug logging instead\n", + debugstr_a(pszLogFilePath)); + + IIMAPCallback_AddRef(pCallback); + This->InetTransport.pCallback = (ITransportCallback *)pCallback; + This->InetTransport.fInitialised = TRUE; + + return S_OK; +} + +static HRESULT WINAPI IMAPTransport_NewIRangeList(IIMAPTransport *iface, + IRangeList **pprlNewRangeList) +{ + FIXME("(%p): stub\n", pprlNewRangeList); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Capability(IIMAPTransport *iface, + DWORD *pdwCapabilityFlags) +{ + FIXME("(%p): stub\n", pdwCapabilityFlags); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Select(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %s): stub\n", wParam, lParam, pCBHandler, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Examine(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %s): stub\n", wParam, lParam, pCBHandler, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Create(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %s): stub\n", wParam, lParam, pCBHandler, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Delete(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %s): stub\n", wParam, lParam, pCBHandler, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Rename(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, LPSTR lpszMailboxName, LPSTR lpszNewMailboxName) +{ + FIXME("(%ld, %ld, %p, %s, %s): stub\n", wParam, lParam, pCBHandler, + debugstr_a(lpszMailboxName), debugstr_a(lpszNewMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Subscribe(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %s): stub\n", wParam, lParam, pCBHandler, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Unsubscribe(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %s): stub\n", wParam, lParam, pCBHandler, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_List(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, LPSTR lpszMailboxNameReference, LPSTR lpszMailboxNamePattern) +{ + FIXME("(%ld, %ld, %p, %s, %s): stub\n", wParam, lParam, pCBHandler, + debugstr_a(lpszMailboxNameReference), debugstr_a(lpszMailboxNamePattern)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Lsub(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, LPSTR lpszMailboxNameReference, LPSTR lpszMailboxNamePattern) +{ + FIXME("(%ld, %ld, %p, %s, %s): stub\n", wParam, lParam, pCBHandler, + debugstr_a(lpszMailboxNameReference), debugstr_a(lpszMailboxNamePattern)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Append(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszMailboxName, + LPSTR lpszMessageFlags, FILETIME ftMessageDateTime, LPSTREAM lpstmMessageToSave) +{ + FIXME("(%ld, %ld, %p, %s, %s, %p): stub\n", wParam, lParam, pCBHandler, + debugstr_a(lpszMailboxName), debugstr_a(lpszMessageFlags), lpstmMessageToSave); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Close(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler) +{ + FIXME("(%ld, %ld, %p): stub\n", wParam, lParam, pCBHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Expunge(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler) +{ + FIXME("(%ld, %ld, %p): stub\n", wParam, lParam, pCBHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Search(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler, LPSTR lpszSearchCriteria, + boolean bReturnUIDs, IRangeList *pMsgRange, boolean bUIDRangeList) +{ + FIXME("(%ld, %ld, %p, %s, %d, %p, %d): stub\n", wParam, lParam, pCBHandler, + debugstr_a(lpszSearchCriteria), bReturnUIDs, pMsgRange, bUIDRangeList); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Fetch(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, IRangeList *pMsgRange, boolean bUIDMsgRange, LPSTR lpszFetchArgs) +{ + FIXME("(%ld, %ld, %p, %p, %d, %s): stub\n", wParam, lParam, pCBHandler, pMsgRange, + bUIDMsgRange, debugstr_a(lpszFetchArgs)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Store(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, IRangeList *pMsgRange, boolean bUIDRangeList, LPSTR lpszStoreArgs) +{ + FIXME("(%ld, %ld, %p, %p, %d, %s): stub\n", wParam, lParam, pCBHandler, pMsgRange, + bUIDRangeList, debugstr_a(lpszStoreArgs)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Copy(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, IRangeList *pMsgRange, boolean bUIDRangeList, LPSTR lpszMailboxName) +{ + FIXME("(%ld, %ld, %p, %p, %d, %s): stub\n", wParam, lParam, pCBHandler, pMsgRange, + bUIDRangeList, debugstr_a(lpszMailboxName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Noop(IIMAPTransport *iface, + WPARAM wParam, LPARAM lParam, IIMAPCallback *pCBHandler) +{ + FIXME("(%ld, %ld, %p): stub\n", wParam, lParam, pCBHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_ResizeMsgSeqNumTable(IIMAPTransport *iface, DWORD dwSizeOfMbox) +{ + FIXME("(%u): stub\n", dwSizeOfMbox); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_UpdateSeqNumToUID(IIMAPTransport *iface, + DWORD dwMsgSeqNum, DWORD dwUID) +{ + FIXME("(%u, %u): stub\n", dwMsgSeqNum, dwUID); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_RemoveSequenceNum(IIMAPTransport *iface, DWORD dwDeletedMsgSeqNum) +{ + FIXME("(%u): stub\n", dwDeletedMsgSeqNum); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_MsgSeqNumToUID(IIMAPTransport *iface, DWORD dwMsgSeqNum, + DWORD *pdwUID) +{ + FIXME("(%u, %p): stub\n", dwMsgSeqNum, pdwUID); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_GetMsgSeqNumToUIDArray(IIMAPTransport *iface, + DWORD **ppdwMsgSeqNumToUIDArray, DWORD *pdwNumberOfElements) +{ + FIXME("(%p, %p): stub\n", ppdwMsgSeqNumToUIDArray, pdwNumberOfElements); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_GetHighestMsgSeqNum(IIMAPTransport *iface, DWORD *pdwHighestMSN) +{ + FIXME("(%p): stub\n", pdwHighestMSN); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_ResetMsgSeqNumToUID(IIMAPTransport *iface) +{ + FIXME("(): stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_SetDefaultCBHandler(IIMAPTransport *iface, IIMAPCallback *pCBHandler) +{ + FIXME("(%p): stub\n", pCBHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI IMAPTransport_Status(IIMAPTransport *iface, WPARAM wParam, LPARAM lParam, + IIMAPCallback *pCBHandler, LPSTR pszMailboxName, LPSTR pszStatusCmdArgs) +{ + FIXME("(%ld, %ld, %p, %s, %s): stub\n", wParam, lParam, pCBHandler, + debugstr_a(pszMailboxName), debugstr_a(pszStatusCmdArgs)); + return E_NOTIMPL; +} + +static const IIMAPTransportVtbl IMAPTransportVtbl = +{ + IMAPTransport_QueryInterface, + IMAPTransport_AddRef, + IMAPTransport_Release, + IMAPTransport_GetServerInfo, + IMAPTransport_GetIXPType, + IMAPTransport_IsState, + IMAPTransport_InetServerFromAccount, + IMAPTransport_Connect, + IMAPTransport_HandsOffCallback, + IMAPTransport_Disconnect, + IMAPTransport_DropConnection, + IMAPTransport_GetStatus, + IMAPTransport_InitNew, + IMAPTransport_NewIRangeList, + IMAPTransport_Capability, + IMAPTransport_Select, + IMAPTransport_Examine, + IMAPTransport_Create, + IMAPTransport_Delete, + IMAPTransport_Rename, + IMAPTransport_Subscribe, + IMAPTransport_Unsubscribe, + IMAPTransport_List, + IMAPTransport_Lsub, + IMAPTransport_Append, + IMAPTransport_Close, + IMAPTransport_Expunge, + IMAPTransport_Search, + IMAPTransport_Fetch, + IMAPTransport_Store, + IMAPTransport_Copy, + IMAPTransport_Noop, + IMAPTransport_ResizeMsgSeqNumTable, + IMAPTransport_UpdateSeqNumToUID, + IMAPTransport_RemoveSequenceNum, + IMAPTransport_MsgSeqNumToUID, + IMAPTransport_GetMsgSeqNumToUIDArray, + IMAPTransport_GetHighestMsgSeqNum, + IMAPTransport_ResetMsgSeqNumToUID, + IMAPTransport_SetDefaultCBHandler, + IMAPTransport_Status +}; + +HRESULT WINAPI CreateIMAPTransport(IIMAPTransport **ppTransport) +{ + HRESULT hr; + IMAPTransport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->InetTransport.u.vtblIMAP = &IMAPTransportVtbl; + This->refs = 0; + hr = InternetTransport_Init(&This->InetTransport); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, This); + return hr; + } + + *ppTransport = (IIMAPTransport *)&This->InetTransport.u.vtblIMAP; + IIMAPTransport_AddRef(*ppTransport); + + return S_OK; +} + +static HRESULT WINAPI IMAPTransportCF_QueryInterface(LPCLASSFACTORY iface, + REFIID riid, LPVOID *ppv) +{ + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI IMAPTransportCF_AddRef(LPCLASSFACTORY iface) +{ + return 2; /* non-heap based object */ +} + +static ULONG WINAPI IMAPTransportCF_Release(LPCLASSFACTORY iface) +{ + return 1; /* non-heap based object */ +} + +static HRESULT WINAPI IMAPTransportCF_CreateInstance(LPCLASSFACTORY iface, + LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) +{ + HRESULT hr; + IIMAPTransport *pImapTransport; + + TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv); + + *ppv = NULL; + + if (pUnk) + return CLASS_E_NOAGGREGATION; + + hr = CreateIMAPTransport(&pImapTransport); + if (FAILED(hr)) + return hr; + + hr = IIMAPTransport_QueryInterface(pImapTransport, riid, ppv); + IIMAPTransport_Release(pImapTransport); + + return hr; +} + +static HRESULT WINAPI IMAPTransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) +{ + FIXME("(%d), stub!\n",fLock); + return S_OK; +} + +static const IClassFactoryVtbl IMAPTransportCFVtbl = +{ + IMAPTransportCF_QueryInterface, + IMAPTransportCF_AddRef, + IMAPTransportCF_Release, + IMAPTransportCF_CreateInstance, + IMAPTransportCF_LockServer +}; +static const IClassFactoryVtbl *IMAPTransportCF = &IMAPTransportCFVtbl; + +HRESULT IMAPTransportCF_Create(REFIID riid, LPVOID *ppv) +{ + return IClassFactory_QueryInterface((IClassFactory *)&IMAPTransportCF, riid, ppv); +} diff --git a/reactos/dll/win32/inetcomm/inetcomm.rbuild b/reactos/dll/win32/inetcomm/inetcomm.rbuild index 88ab3d28e90..3178a195d46 100644 --- a/reactos/dll/win32/inetcomm/inetcomm.rbuild +++ b/reactos/dll/win32/inetcomm/inetcomm.rbuild @@ -8,14 +8,19 @@ include/reactos/wine 0x600 + imaptransport.c inetcomm_main.c internettransport.c + mimeintl.c mimeole.c + pop3transport.c regsvr.c + smtptransport.c inetcomm.spec wine uuid ole32 + oleaut32 ws2_32 user32 advapi32 diff --git a/reactos/dll/win32/inetcomm/inetcomm.spec b/reactos/dll/win32/inetcomm/inetcomm.spec index 36a5d8bd52f..0c90b4db28e 100644 --- a/reactos/dll/win32/inetcomm/inetcomm.spec +++ b/reactos/dll/win32/inetcomm/inetcomm.spec @@ -1,10 +1,10 @@ @ stub CreateIMAPTransport2 -@ stub CreateIMAPTransport +@ stdcall CreateIMAPTransport(ptr) @ stub CreateNNTPTransport -@ stub CreatePOP3Transport +@ stdcall CreatePOP3Transport(ptr) @ stub CreateRASTransport @ stub CreateRangeList -@ stub CreateSMTPTransport +@ stdcall CreateSMTPTransport(ptr) @ stdcall -private DllCanUnloadNow() @ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @@ -59,7 +59,7 @@ @ stub MimeOleDecodeHeader @ stub MimeOleEncodeHeader @ stub MimeOleFileTimeToInetDate -@ stub MimeOleFindCharset +@ stdcall MimeOleFindCharset(str ptr) @ stub MimeOleGenerateCID @ stub MimeOleGenerateFileName @ stub MimeOleGenerateMID @@ -71,12 +71,12 @@ @ stub MimeOleGetCodePageCharset @ stub MimeOleGetCodePageInfo @ stub MimeOleGetContentTypeExt -@ stub MimeOleGetDefaultCharset +@ stdcall MimeOleGetDefaultCharset(ptr) @ stub MimeOleGetExtContentType @ stub MimeOleGetFileExtension @ stub MimeOleGetFileInfo @ stub MimeOleGetFileInfoW -@ stub MimeOleGetInternat +@ stdcall MimeOleGetInternat(ptr) @ stub MimeOleGetPropA @ stub MimeOleGetPropW @ stub MimeOleGetPropertySchema diff --git a/reactos/dll/win32/inetcomm/inetcomm_main.c b/reactos/dll/win32/inetcomm/inetcomm_main.c index 15350df89e2..1d71877782d 100644 --- a/reactos/dll/win32/inetcomm/inetcomm_main.c +++ b/reactos/dll/win32/inetcomm/inetcomm_main.c @@ -37,6 +37,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(inetcomm); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { + static IMimeInternational *international; + TRACE("(%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved); switch (fdwReason) @@ -47,8 +49,10 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) DisableThreadLibraryCalls(hinstDLL); if (!InternetTransport_RegisterClass(hinstDLL)) return FALSE; + MimeInternational_Construct(&international); break; case DLL_PROCESS_DETACH: + IMimeInternational_Release(international); InternetTransport_UnregisterClass(hinstDLL); break; default: @@ -133,6 +137,8 @@ static const struct IClassFactoryVtbl cf_vtbl = static cf mime_body_cf = { &cf_vtbl, MimeBody_create }; static cf mime_allocator_cf = { &cf_vtbl, MimeAllocator_create }; +static cf mime_message_cf = { &cf_vtbl, MimeMessage_create }; +static cf mime_security_cf = { &cf_vtbl, MimeSecurity_create }; /*********************************************************************** * DllGetClassObject (INETCOMM.@) @@ -143,7 +149,27 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv ); - if( IsEqualCLSID( rclsid, &CLSID_IMimeBody )) + if (IsEqualCLSID(rclsid, &CLSID_ISMTPTransport)) + return SMTPTransportCF_Create(iid, ppv); + + if (IsEqualCLSID(rclsid, &CLSID_ISMTPTransport2)) + return SMTPTransportCF_Create(iid, ppv); + + if (IsEqualCLSID(rclsid, &CLSID_IIMAPTransport)) + return IMAPTransportCF_Create(iid, ppv); + + if (IsEqualCLSID(rclsid, &CLSID_IPOP3Transport)) + return POP3TransportCF_Create(iid, ppv); + + if ( IsEqualCLSID( rclsid, &CLSID_IMimeSecurity )) + { + cf = (IClassFactory*) &mime_security_cf.lpVtbl; + } + else if( IsEqualCLSID( rclsid, &CLSID_IMimeMessage )) + { + cf = (IClassFactory*) &mime_message_cf.lpVtbl; + } + else if( IsEqualCLSID( rclsid, &CLSID_IMimeBody )) { cf = (IClassFactory*) &mime_body_cf.lpVtbl; } diff --git a/reactos/dll/win32/inetcomm/inetcomm_private.h b/reactos/dll/win32/inetcomm/inetcomm_private.h index bf6e5ce31dd..589f92c3950 100644 --- a/reactos/dll/win32/inetcomm/inetcomm_private.h +++ b/reactos/dll/win32/inetcomm/inetcomm_private.h @@ -32,7 +32,9 @@ struct InternetTransport union { const IInternetTransportVtbl *vtbl; - const ISMTPTransportVtbl *vtblSMTP; + const ISMTPTransport2Vtbl *vtblSMTP2; + const IIMAPTransportVtbl *vtblIMAP; + const IPOP3TransportVtbl *vtblPOP3; } u; ITransportCallback *pCallback; @@ -65,9 +67,19 @@ HRESULT InternetTransport_ReadLine(InternetTransport *This, INETXPORT_COMPLETION_FUNCTION fnCompletion); HRESULT InternetTransport_Write(InternetTransport *This, const char *pvData, int cbSize, INETXPORT_COMPLETION_FUNCTION fnCompletion); +HRESULT InternetTransport_DoCommand(InternetTransport *This, + LPCSTR pszCommand, INETXPORT_COMPLETION_FUNCTION fnCompletion); BOOL InternetTransport_RegisterClass(HINSTANCE hInstance); void InternetTransport_UnregisterClass(HINSTANCE hInstance); HRESULT MimeBody_create(IUnknown *outer, void **obj); HRESULT MimeAllocator_create(IUnknown *outer, void **obj); +HRESULT MimeMessage_create(IUnknown *outer, void **obj); +HRESULT MimeSecurity_create(IUnknown *outer, void **obj); + +HRESULT MimeInternational_Construct(IMimeInternational **internat); + +HRESULT SMTPTransportCF_Create(REFIID riid, LPVOID *ppv); +HRESULT IMAPTransportCF_Create(REFIID riid, LPVOID *ppv); +HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv); diff --git a/reactos/dll/win32/inetcomm/internettransport.c b/reactos/dll/win32/inetcomm/internettransport.c index bba6aaba110..7cef414434a 100644 --- a/reactos/dll/win32/inetcomm/internettransport.c +++ b/reactos/dll/win32/inetcomm/internettransport.c @@ -26,8 +26,12 @@ #include "windef.h" #include "winbase.h" #include "winnt.h" +#include "winuser.h" #include "winsock2.h" #include "ws2tcpip.h" +#include "objbase.h" +#include "ole2.h" +#include "mimeole.h" #include "wine/debug.h" @@ -270,6 +274,23 @@ HRESULT InternetTransport_Write(InternetTransport *This, const char *pvData, return S_OK; } +HRESULT InternetTransport_DoCommand(InternetTransport *This, + LPCSTR pszCommand, INETXPORT_COMPLETION_FUNCTION fnCompletion) +{ + if (This->Status == IXP_DISCONNECTED) + return IXP_E_NOT_CONNECTED; + + if (This->fnCompletion) + return IXP_E_BUSY; + + if (This->pCallback && This->fCommandLogging) + { + ITransportCallback_OnCommand(This->pCallback, CMD_SEND, (LPSTR)pszCommand, 0, + (IInternetTransport *)&This->u.vtbl); + } + return InternetTransport_Write(This, pszCommand, strlen(pszCommand), fnCompletion); +} + static LRESULT CALLBACK InternetTransport_WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == IX_READ) diff --git a/reactos/dll/win32/inetcomm/mimeintl.c b/reactos/dll/win32/inetcomm/mimeintl.c new file mode 100644 index 00000000000..6d37147e2bf --- /dev/null +++ b/reactos/dll/win32/inetcomm/mimeintl.c @@ -0,0 +1,596 @@ +/* + * MIME OLE International interface + * + * Copyright 2008 Huw Davies for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#define NONAMELESSUNION + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" +#include "objbase.h" +#include "ole2.h" +#include "mimeole.h" +#include "mlang.h" + +#include "wine/list.h" +#include "wine/unicode.h" +#include "wine/debug.h" + +#include "inetcomm_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(inetcomm); + +typedef struct +{ + struct list entry; + INETCSETINFO cs_info; +} charset_entry; + +typedef struct +{ + const IMimeInternationalVtbl *lpVtbl; + LONG refs; + CRITICAL_SECTION cs; + + struct list charsets; + LONG next_charset_handle; + HCHARSET default_charset; +} internat; + +static inline internat *impl_from_IMimeInternational( IMimeInternational *iface ) +{ + return (internat *)((char*)iface - FIELD_OFFSET(internat, lpVtbl)); +} + +static inline HRESULT get_mlang(IMultiLanguage **ml) +{ + return CoCreateInstance(&CLSID_CMultiLanguage, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, + &IID_IMultiLanguage, (void **)ml); +} + +static HRESULT WINAPI MimeInternat_QueryInterface( IMimeInternational *iface, REFIID riid, LPVOID *ppobj ) +{ + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IMimeInternational)) + { + IMimeInternational_AddRef( iface ); + *ppobj = iface; + return S_OK; + } + + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI MimeInternat_AddRef( IMimeInternational *iface ) +{ + internat *This = impl_from_IMimeInternational( iface ); + return InterlockedIncrement(&This->refs); +} + +static ULONG WINAPI MimeInternat_Release( IMimeInternational *iface ) +{ + internat *This = impl_from_IMimeInternational( iface ); + ULONG refs; + + refs = InterlockedDecrement(&This->refs); + if (!refs) + { + charset_entry *charset, *cursor2; + + LIST_FOR_EACH_ENTRY_SAFE(charset, cursor2, &This->charsets, charset_entry, entry) + { + list_remove(&charset->entry); + HeapFree(GetProcessHeap(), 0, charset); + } + HeapFree(GetProcessHeap(), 0, This); + } + + return refs; +} + +static HRESULT WINAPI MimeInternat_SetDefaultCharset(IMimeInternational *iface, HCHARSET hCharset) +{ + internat *This = impl_from_IMimeInternational( iface ); + + TRACE("(%p)->(%p)\n", iface, hCharset); + + if(hCharset == NULL) return E_INVALIDARG; + /* FIXME check hCharset is valid */ + + InterlockedExchangePointer(&This->default_charset, hCharset); + + return S_OK; +} + +static HRESULT WINAPI MimeInternat_GetDefaultCharset(IMimeInternational *iface, LPHCHARSET phCharset) +{ + internat *This = impl_from_IMimeInternational( iface ); + HRESULT hr = S_OK; + + TRACE("(%p)->(%p)\n", iface, phCharset); + + if(This->default_charset == NULL) + { + HCHARSET hcs; + hr = IMimeInternational_GetCodePageCharset(iface, GetACP(), CHARSET_BODY, &hcs); + if(SUCCEEDED(hr)) + InterlockedCompareExchangePointer(&This->default_charset, hcs, NULL); + } + *phCharset = This->default_charset; + + return hr; +} + +static HRESULT mlang_getcodepageinfo(UINT cp, MIMECPINFO *mlang_cp_info) +{ + HRESULT hr; + IMultiLanguage *ml; + + hr = get_mlang(&ml); + + if(SUCCEEDED(hr)) + { + hr = IMultiLanguage_GetCodePageInfo(ml, cp, mlang_cp_info); + IMultiLanguage_Release(ml); + } + return hr; +} + +static HRESULT WINAPI MimeInternat_GetCodePageCharset(IMimeInternational *iface, CODEPAGEID cpiCodePage, + CHARSETTYPE ctCsetType, + LPHCHARSET phCharset) +{ + HRESULT hr; + MIMECPINFO mlang_cp_info; + + TRACE("(%p)->(%d, %d, %p)\n", iface, cpiCodePage, ctCsetType, phCharset); + + *phCharset = NULL; + + hr = mlang_getcodepageinfo(cpiCodePage, &mlang_cp_info); + if(SUCCEEDED(hr)) + { + const WCHAR *charset_nameW = NULL; + char *charset_name; + DWORD len; + + switch(ctCsetType) + { + case CHARSET_BODY: + charset_nameW = mlang_cp_info.wszBodyCharset; + break; + case CHARSET_HEADER: + charset_nameW = mlang_cp_info.wszHeaderCharset; + break; + case CHARSET_WEB: + charset_nameW = mlang_cp_info.wszWebCharset; + break; + default: + return MIME_E_INVALID_CHARSET_TYPE; + } + len = WideCharToMultiByte(CP_ACP, 0, charset_nameW, -1, NULL, 0, NULL, NULL); + charset_name = HeapAlloc(GetProcessHeap(), 0, len); + WideCharToMultiByte(CP_ACP, 0, charset_nameW, -1, charset_name, len, NULL, NULL); + hr = IMimeInternational_FindCharset(iface, charset_name, phCharset); + HeapFree(GetProcessHeap(), 0, charset_name); + } + return hr; +} + +static HRESULT mlang_getcsetinfo(const char *charset, MIMECSETINFO *mlang_info) +{ + DWORD len = MultiByteToWideChar(CP_ACP, 0, charset, -1, NULL, 0); + BSTR bstr = SysAllocStringLen(NULL, len - 1); + HRESULT hr; + IMultiLanguage *ml; + + MultiByteToWideChar(CP_ACP, 0, charset, -1, bstr, len); + + hr = get_mlang(&ml); + + if(SUCCEEDED(hr)) + { + hr = IMultiLanguage_GetCharsetInfo(ml, bstr, mlang_info); + IMultiLanguage_Release(ml); + } + SysFreeString(bstr); + if(FAILED(hr)) hr = MIME_E_NOT_FOUND; + return hr; +} + +static HCHARSET add_charset(struct list *list, MIMECSETINFO *mlang_info, HCHARSET handle) +{ + charset_entry *charset = HeapAlloc(GetProcessHeap(), 0, sizeof(*charset)); + + WideCharToMultiByte(CP_ACP, 0, mlang_info->wszCharset, -1, + charset->cs_info.szName, sizeof(charset->cs_info.szName), NULL, NULL); + charset->cs_info.cpiWindows = mlang_info->uiCodePage; + charset->cs_info.cpiInternet = mlang_info->uiInternetEncoding; + charset->cs_info.hCharset = handle; + charset->cs_info.dwReserved1 = 0; + list_add_head(list, &charset->entry); + + return charset->cs_info.hCharset; +} + +static HRESULT WINAPI MimeInternat_FindCharset(IMimeInternational *iface, LPCSTR pszCharset, + LPHCHARSET phCharset) +{ + internat *This = impl_from_IMimeInternational( iface ); + HRESULT hr = MIME_E_NOT_FOUND; + charset_entry *charset; + + TRACE("(%p)->(%s, %p)\n", iface, debugstr_a(pszCharset), phCharset); + + *phCharset = NULL; + + EnterCriticalSection(&This->cs); + + LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry) + { + if(!lstrcmpiA(charset->cs_info.szName, pszCharset)) + { + *phCharset = charset->cs_info.hCharset; + hr = S_OK; + break; + } + } + + if(hr == MIME_E_NOT_FOUND) + { + MIMECSETINFO mlang_info; + + LeaveCriticalSection(&This->cs); + hr = mlang_getcsetinfo(pszCharset, &mlang_info); + EnterCriticalSection(&This->cs); + + if(SUCCEEDED(hr)) + *phCharset = add_charset(&This->charsets, &mlang_info, + (HCHARSET)InterlockedIncrement(&This->next_charset_handle)); + } + + LeaveCriticalSection(&This->cs); + return hr; +} + +static HRESULT WINAPI MimeInternat_GetCharsetInfo(IMimeInternational *iface, HCHARSET hCharset, + LPINETCSETINFO pCsetInfo) +{ + internat *This = impl_from_IMimeInternational( iface ); + HRESULT hr = MIME_E_INVALID_HANDLE; + charset_entry *charset; + + TRACE("(%p)->(%p, %p)\n", iface, hCharset, pCsetInfo); + + EnterCriticalSection(&This->cs); + + LIST_FOR_EACH_ENTRY(charset, &This->charsets, charset_entry, entry) + { + if(charset->cs_info.hCharset == hCharset) + { + *pCsetInfo = charset->cs_info; + hr = S_OK; + break; + } + } + + LeaveCriticalSection(&This->cs); + + return hr; +} + +static HRESULT WINAPI MimeInternat_GetCodePageInfo(IMimeInternational *iface, CODEPAGEID cpiCodePage, + LPCODEPAGEINFO pCodePageInfo) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI MimeInternat_CanConvertCodePages(IMimeInternational *iface, CODEPAGEID cpiSource, + CODEPAGEID cpiDest) +{ + HRESULT hr; + IMultiLanguage *ml; + + TRACE("(%p)->(%d, %d)\n", iface, cpiSource, cpiDest); + + /* Could call mlang.IsConvertINetStringAvailable() to avoid the COM overhead if need be. */ + + hr = get_mlang(&ml); + if(SUCCEEDED(hr)) + { + hr = IMultiLanguage_IsConvertible(ml, cpiSource, cpiDest); + IMultiLanguage_Release(ml); + } + + return hr; +} + +static HRESULT WINAPI MimeInternat_DecodeHeader(IMimeInternational *iface, HCHARSET hCharset, + LPCSTR pszData, + LPPROPVARIANT pDecoded, + LPRFC1522INFO pRfc1522Info) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI MimeInternat_EncodeHeader(IMimeInternational *iface, HCHARSET hCharset, + LPPROPVARIANT pData, + LPSTR *ppszEncoded, + LPRFC1522INFO pRfc1522Info) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI MimeInternat_ConvertBuffer(IMimeInternational *iface, CODEPAGEID cpiSource, + CODEPAGEID cpiDest, LPBLOB pIn, LPBLOB pOut, + ULONG *pcbRead) +{ + HRESULT hr; + IMultiLanguage *ml; + + TRACE("(%p)->(%d, %d, %p, %p, %p)\n", iface, cpiSource, cpiDest, pIn, pOut, pcbRead); + + *pcbRead = 0; + pOut->cbSize = 0; + + /* Could call mlang.ConvertINetString() to avoid the COM overhead if need be. */ + + hr = get_mlang(&ml); + if(SUCCEEDED(hr)) + { + DWORD mode = 0; + UINT in_size = pIn->cbSize, out_size; + + hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, pIn->pBlobData, &in_size, + NULL, &out_size); + if(hr == S_OK) /* S_FALSE means the conversion could not be performed */ + { + pOut->pBlobData = CoTaskMemAlloc(out_size); + if(!pOut->pBlobData) + hr = E_OUTOFMEMORY; + else + { + mode = 0; + in_size = pIn->cbSize; + hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, pIn->pBlobData, &in_size, + pOut->pBlobData, &out_size); + + if(hr == S_OK) + { + *pcbRead = in_size; + pOut->cbSize = out_size; + } + else + CoTaskMemFree(pOut->pBlobData); + } + } + IMultiLanguage_Release(ml); + } + + return hr; +} + +static HRESULT WINAPI MimeInternat_ConvertString(IMimeInternational *iface, CODEPAGEID cpiSource, + CODEPAGEID cpiDest, LPPROPVARIANT pIn, + LPPROPVARIANT pOut) +{ + HRESULT hr; + int src_len; + IMultiLanguage *ml; + + TRACE("(%p)->(%d, %d, %p %p)\n", iface, cpiSource, cpiDest, pIn, pOut); + + switch(pIn->vt) + { + case VT_LPSTR: + if(cpiSource == CP_UNICODE) cpiSource = GetACP(); + src_len = strlen(pIn->u.pszVal); + break; + case VT_LPWSTR: + cpiSource = CP_UNICODE; + src_len = strlenW(pIn->u.pwszVal) * sizeof(WCHAR); + break; + default: + return E_INVALIDARG; + } + + hr = get_mlang(&ml); + if(SUCCEEDED(hr)) + { + DWORD mode = 0; + UINT in_size = src_len, out_size; + + hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, (BYTE*)pIn->u.pszVal, &in_size, + NULL, &out_size); + if(hr == S_OK) /* S_FALSE means the conversion could not be performed */ + { + out_size += (cpiDest == CP_UNICODE) ? sizeof(WCHAR) : sizeof(char); + + pOut->u.pszVal = CoTaskMemAlloc(out_size); + if(!pOut->u.pszVal) + hr = E_OUTOFMEMORY; + else + { + mode = 0; + in_size = src_len; + hr = IMultiLanguage_ConvertString(ml, &mode, cpiSource, cpiDest, (BYTE*)pIn->u.pszVal, &in_size, + (BYTE*)pOut->u.pszVal, &out_size); + + if(hr == S_OK) + { + if(cpiDest == CP_UNICODE) + { + pOut->u.pwszVal[out_size / sizeof(WCHAR)] = 0; + pOut->vt = VT_LPWSTR; + } + else + { + pOut->u.pszVal[out_size] = '\0'; + pOut->vt = VT_LPSTR; + } + } + else + CoTaskMemFree(pOut->u.pszVal); + } + } + IMultiLanguage_Release(ml); + } + return hr; +} + +static HRESULT WINAPI MimeInternat_MLANG_ConvertInetReset(IMimeInternational *iface) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI MimeInternat_MLANG_ConvertInetString(IMimeInternational *iface, CODEPAGEID cpiSource, + CODEPAGEID cpiDest, + LPCSTR pSource, + int *pnSizeOfSource, + LPSTR pDestination, + int *pnDstSize) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI MimeInternat_Rfc1522Decode(IMimeInternational *iface, LPCSTR pszValue, + LPSTR pszCharset, + ULONG cchmax, + LPSTR *ppszDecoded) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI MimeInternat_Rfc1522Encode(IMimeInternational *iface, LPCSTR pszValue, + HCHARSET hCharset, + LPSTR *ppszEncoded) +{ + FIXME("stub\n"); + return E_NOTIMPL; +} + +static IMimeInternationalVtbl mime_internat_vtbl = +{ + MimeInternat_QueryInterface, + MimeInternat_AddRef, + MimeInternat_Release, + MimeInternat_SetDefaultCharset, + MimeInternat_GetDefaultCharset, + MimeInternat_GetCodePageCharset, + MimeInternat_FindCharset, + MimeInternat_GetCharsetInfo, + MimeInternat_GetCodePageInfo, + MimeInternat_CanConvertCodePages, + MimeInternat_DecodeHeader, + MimeInternat_EncodeHeader, + MimeInternat_ConvertBuffer, + MimeInternat_ConvertString, + MimeInternat_MLANG_ConvertInetReset, + MimeInternat_MLANG_ConvertInetString, + MimeInternat_Rfc1522Decode, + MimeInternat_Rfc1522Encode +}; + +static internat *global_internat; + +HRESULT MimeInternational_Construct(IMimeInternational **internat) +{ + global_internat = HeapAlloc(GetProcessHeap(), 0, sizeof(*global_internat)); + global_internat->lpVtbl = &mime_internat_vtbl; + global_internat->refs = 0; + InitializeCriticalSection(&global_internat->cs); + + list_init(&global_internat->charsets); + global_internat->next_charset_handle = 0; + global_internat->default_charset = NULL; + + *internat = (IMimeInternational*)&global_internat->lpVtbl; + + IMimeInternational_AddRef(*internat); + return S_OK; +} + +HRESULT WINAPI MimeOleGetInternat(IMimeInternational **internat) +{ + TRACE("(%p)\n", internat); + + *internat = (IMimeInternational *)&global_internat->lpVtbl; + IMimeInternational_AddRef(*internat); + return S_OK; +} + +HRESULT WINAPI MimeOleFindCharset(LPCSTR name, LPHCHARSET charset) +{ + IMimeInternational *internat; + HRESULT hr; + + TRACE("(%s, %p)\n", debugstr_a(name), charset); + + hr = MimeOleGetInternat(&internat); + if(SUCCEEDED(hr)) + { + hr = IMimeInternational_FindCharset(internat, name, charset); + IMimeInternational_Release(internat); + } + return hr; +} + +HRESULT WINAPI MimeOleGetCharsetInfo(HCHARSET hCharset, LPINETCSETINFO pCsetInfo) +{ + IMimeInternational *internat; + HRESULT hr; + + TRACE("(%p, %p)\n", hCharset, pCsetInfo); + + hr = MimeOleGetInternat(&internat); + if(SUCCEEDED(hr)) + { + hr = IMimeInternational_GetCharsetInfo(internat, hCharset, pCsetInfo); + IMimeInternational_Release(internat); + } + return hr; +} + +HRESULT WINAPI MimeOleGetDefaultCharset(LPHCHARSET charset) +{ + IMimeInternational *internat; + HRESULT hr; + + TRACE("(%p)\n", charset); + + hr = MimeOleGetInternat(&internat); + if(SUCCEEDED(hr)) + { + hr = IMimeInternational_GetDefaultCharset(internat, charset); + IMimeInternational_Release(internat); + } + return hr; +} diff --git a/reactos/dll/win32/inetcomm/mimeole.c b/reactos/dll/win32/inetcomm/mimeole.c index 7e9d709f5ce..07aa6bd0de7 100644 --- a/reactos/dll/win32/inetcomm/mimeole.c +++ b/reactos/dll/win32/inetcomm/mimeole.c @@ -69,7 +69,7 @@ static const property_t default_props[] = {"Content-Type", PID_HDR_CNTTYPE, MPF_MIME | MPF_HASPARAMS, VT_LPSTR}, {"Content-Transfer-Encoding", PID_HDR_CNTXFER, MPF_MIME, VT_LPSTR}, {"Content-ID", PID_HDR_CNTID, MPF_MIME, VT_LPSTR}, - {"Content-Disposition", PID_HDR_CNTDISP, MPF_MIME, VT_LPSTR}, + {"Content-Disposition", PID_HDR_CNTDISP, MPF_MIME | MPF_HASPARAMS, VT_LPSTR}, {"To", PID_HDR_TO, MPF_ADDRESS, VT_LPSTR}, {"Cc", PID_HDR_CC, MPF_ADDRESS, VT_LPSTR}, {"Sender", PID_HDR_SENDER, MPF_ADDRESS, VT_LPSTR}, @@ -820,8 +820,26 @@ static HRESULT WINAPI MimeBody_SetOption( const TYPEDID oid, LPCPROPVARIANT pValue) { - FIXME("(%p)->(%08x, %p): stub\n", iface, oid, pValue); - return E_NOTIMPL; + HRESULT hr = E_NOTIMPL; + TRACE("(%p)->(%08x, %p)\n", iface, oid, pValue); + + if(pValue->vt != TYPEDID_TYPE(oid)) + { + WARN("Called with vartype %04x and oid %08x\n", pValue->vt, oid); + return E_INVALIDARG; + } + + switch(oid) + { + case OID_SECURITY_HWND_OWNER: + FIXME("OID_SECURITY_HWND_OWNER (value %08x): ignoring\n", pValue->u.ulVal); + hr = S_OK; + break; + default: + FIXME("Unhandled oid %08x\n", oid); + } + + return hr; } static HRESULT WINAPI MimeBody_GetOption( @@ -846,8 +864,17 @@ static HRESULT WINAPI MimeBody_IsType( IMimeBody* iface, IMSGBODYTYPE bodytype) { - FIXME("(%p)->(%d): stub\n", iface, bodytype); - return E_NOTIMPL; + MimeBody *This = impl_from_IMimeBody(iface); + + TRACE("(%p)->(%d)\n", iface, bodytype); + switch(bodytype) + { + case IBT_EMPTY: + return This->data ? S_FALSE : S_OK; + default: + FIXME("Unimplemented bodytype %d - returning S_OK\n", bodytype); + } + return S_OK; } static HRESULT WINAPI MimeBody_SetDisplayName( @@ -2172,8 +2199,30 @@ static HRESULT WINAPI MimeMessage_SetOption( const TYPEDID oid, LPCPROPVARIANT pValue) { - FIXME("(%p)->(%08x, %p)\n", iface, oid, pValue); - return E_NOTIMPL; + HRESULT hr = E_NOTIMPL; + TRACE("(%p)->(%08x, %p)\n", iface, oid, pValue); + + if(pValue->vt != TYPEDID_TYPE(oid)) + { + WARN("Called with vartype %04x and oid %08x\n", pValue->vt, oid); + return E_INVALIDARG; + } + + switch(oid) + { + case OID_HIDE_TNEF_ATTACHMENTS: + FIXME("OID_HIDE_TNEF_ATTACHMENTS (value %d): ignoring\n", pValue->u.boolVal); + hr = S_OK; + break; + case OID_SHOW_MACBINARY: + FIXME("OID_SHOW_MACBINARY (value %d): ignoring\n", pValue->u.boolVal); + hr = S_OK; + break; + default: + FIXME("Unhandled oid %08x\n", oid); + } + + return hr; } static HRESULT WINAPI MimeMessage_GetOption( @@ -2491,22 +2540,19 @@ static const IMimeMessageVtbl MimeMessageVtbl = MimeMessage_GetRootMoniker, }; -/*********************************************************************** - * MimeOleCreateMessage (INETCOMM.@) - */ -HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage) +HRESULT MimeMessage_create(IUnknown *outer, void **obj) { MimeMessage *This; - TRACE("(%p, %p)\n", pUnkOuter, ppMessage); + TRACE("(%p, %p)\n", outer, obj); - if (pUnkOuter) + if (outer) { FIXME("outer unknown not supported yet\n"); return E_NOTIMPL; } - *ppMessage = NULL; + *obj = NULL; This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) return E_OUTOFMEMORY; @@ -2517,10 +2563,19 @@ HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessag list_init(&This->body_tree); This->next_hbody = (HBODY)1; - *ppMessage = (IMimeMessage *)&This->lpVtbl; + *obj = (IMimeMessage *)&This->lpVtbl; return S_OK; } +/*********************************************************************** + * MimeOleCreateMessage (INETCOMM.@) + */ +HRESULT WINAPI MimeOleCreateMessage(IUnknown *pUnkOuter, IMimeMessage **ppMessage) +{ + TRACE("(%p, %p)\n", pUnkOuter, ppMessage); + return MimeMessage_create(NULL, (void **)ppMessage); +} + /*********************************************************************** * MimeOleSetCompatMode (INETCOMM.@) */ @@ -2705,16 +2760,13 @@ static const IMimeSecurityVtbl MimeSecurityVtbl = MimeSecurity_GetCertData }; -/*********************************************************************** - * MimeOleCreateSecurity (INETCOMM.@) - */ -HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity) +HRESULT MimeSecurity_create(IUnknown *outer, void **obj) { MimeSecurity *This; - TRACE("(%p)\n", ppSecurity); + *obj = NULL; - *ppSecurity = NULL; + if (outer) return CLASS_E_NOAGGREGATION; This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); if (!This) return E_OUTOFMEMORY; @@ -2722,10 +2774,17 @@ HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity) This->lpVtbl = &MimeSecurityVtbl; This->refs = 1; - *ppSecurity = (IMimeSecurity *)&This->lpVtbl; + *obj = (IMimeSecurity *)&This->lpVtbl; return S_OK; } +/*********************************************************************** + * MimeOleCreateSecurity (INETCOMM.@) + */ +HRESULT WINAPI MimeOleCreateSecurity(IMimeSecurity **ppSecurity) +{ + return MimeSecurity_create(NULL, (void **)ppSecurity); +} typedef struct { @@ -2930,10 +2989,3 @@ HRESULT WINAPI MimeOleGetAllocator(IMimeAllocator **alloc) { return MimeAllocator_create(NULL, (void**)alloc); } - -HRESULT WINAPI MimeOleGetCharsetInfo(HCHARSET hCharset, LPINETCSETINFO pCsetInfo) -{ - FIXME("(%p, %p)\n", hCharset, pCsetInfo); - if(!hCharset) return E_INVALIDARG; - return E_FAIL; -} diff --git a/reactos/dll/win32/inetcomm/pop3transport.c b/reactos/dll/win32/inetcomm/pop3transport.c new file mode 100644 index 00000000000..afb4094b209 --- /dev/null +++ b/reactos/dll/win32/inetcomm/pop3transport.c @@ -0,0 +1,662 @@ +/* + * POP3 Transport + * + * Copyright 2008 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winuser.h" +#include "objbase.h" +#include "mimeole.h" +#include "wine/debug.h" + +#include "inetcomm_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(inetcomm); + +typedef struct +{ + InternetTransport InetTransport; + ULONG refs; + INETSERVER server; + POP3COMMAND command; +} POP3Transport; + +static HRESULT POP3Transport_ParseResponse(POP3Transport *This, char *pszResponse, POP3RESPONSE *pResponse) +{ + TRACE("response: %s\n", debugstr_a(pszResponse)); + + pResponse->command = This->command; + pResponse->fDone = TRUE; /* FIXME */ + + if (!memcmp(pszResponse, "+OK", 3)) + pResponse->rIxpResult.hrResult = S_OK; + else + pResponse->rIxpResult.hrResult = S_FALSE; + + pResponse->rIxpResult.pszResponse = pszResponse; + pResponse->rIxpResult.uiServerError = 0; + pResponse->rIxpResult.hrServerError = pResponse->rIxpResult.hrResult; + pResponse->rIxpResult.dwSocketError = 0; + pResponse->pTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3; + pResponse->fValidInfo = FALSE; /* FIXME */ + + if (This->InetTransport.pCallback && This->InetTransport.fCommandLogging) + { + ITransportCallback_OnCommand(This->InetTransport.pCallback, CMD_RESP, + pResponse->rIxpResult.pszResponse, pResponse->rIxpResult.hrServerError, + (IInternetTransport *)&This->InetTransport.u.vtbl); + } + return S_OK; +} + +static void POP3Transport_CallbackProcessLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + POP3RESPONSE response; + HRESULT hr; + + TRACE("\n"); + + hr = POP3Transport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); +} + +static void POP3Transport_CallbackRecvLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessLISTResp); +} + +static void POP3Transport_CallbackProcessUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + POP3RESPONSE response; + HRESULT hr; + + TRACE("\n"); + + hr = POP3Transport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); +} + +static void POP3Transport_CallbackRecvUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUIDLResp); +} + +static void POP3Transport_CallbackProcessSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + POP3RESPONSE response; + HRESULT hr; + + TRACE("\n"); + + hr = POP3Transport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); +} + +static void POP3Transport_CallbackRecvSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessSTATResp); +} + +static void POP3Transport_CallbackProcessPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + POP3RESPONSE response; + HRESULT hr; + + TRACE("\n"); + + hr = POP3Transport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED); + InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED); + + IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); +} + +static void POP3Transport_CallbackRecvPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessPASSResp); +} + +static void POP3Transport_CallbackProcessUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + static char pass[] = "PASS "; + POP3Transport *This = (POP3Transport *)iface; + POP3RESPONSE response; + char *command; + int len; + HRESULT hr; + + TRACE("\n"); + + hr = POP3Transport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); + + len = sizeof(pass) + strlen(This->server.szPassword) + 2; /* "\r\n" */ + command = HeapAlloc(GetProcessHeap(), 0, len); + + strcpy(command, pass); + strcat(command, This->server.szPassword); + strcat(command, "\r\n"); + + InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp); + HeapFree(GetProcessHeap(), 0, command); +} + +static void POP3Transport_CallbackRecvUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUSERResp); +} + +static void POP3Transport_CallbackSendUSERCmd(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + static char user[] = "USER "; + POP3Transport *This = (POP3Transport *)iface; + char *command; + int len; + + TRACE("\n"); + + len = sizeof(user) + strlen(This->server.szUserName) + 2; /* "\r\n" */ + command = HeapAlloc(GetProcessHeap(), 0, len); + + strcpy(command, user); + strcat(command, This->server.szUserName); + strcat(command, "\r\n"); + InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp); + + HeapFree(GetProcessHeap(), 0, command); +} + +static void POP3Transport_CallbackProcessQUITResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + POP3RESPONSE response; + HRESULT hr; + + TRACE("%s\n", debugstr_an(pBuffer, cbBuffer)); + + hr = POP3Transport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response); + InternetTransport_DropConnection(&This->InetTransport); +} + +static void POP3Transport_CallbackRecvQUITResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessQUITResponse); +} + +static HRESULT WINAPI POP3Transport_QueryInterface(IPOP3Transport *iface, REFIID riid, void **ppv) +{ + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IInternetTransport) || + IsEqualIID(riid, &IID_IPOP3Transport)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + *ppv = NULL; + FIXME("no interface for %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI POP3Transport_AddRef(IPOP3Transport *iface) +{ + POP3Transport *This = (POP3Transport *)iface; + return InterlockedIncrement((LONG *)&This->refs); +} + +static ULONG WINAPI POP3Transport_Release(IPOP3Transport *iface) +{ + POP3Transport *This = (POP3Transport *)iface; + ULONG refs = InterlockedDecrement((LONG *)&This->refs); + if (!refs) + { + TRACE("destroying %p\n", This); + if (This->InetTransport.Status != IXP_DISCONNECTED) + InternetTransport_DropConnection(&This->InetTransport); + if (This->InetTransport.pCallback) ITransportCallback_Release(This->InetTransport.pCallback); + HeapFree(GetProcessHeap(), 0, This); + } + return refs; +} + +static HRESULT WINAPI POP3Transport_GetServerInfo(IPOP3Transport *iface, + LPINETSERVER pInetServer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("(%p)\n", pInetServer); + return InternetTransport_GetServerInfo(&This->InetTransport, pInetServer); +} + +static IXPTYPE WINAPI POP3Transport_GetIXPType(IPOP3Transport *iface) +{ + TRACE("()\n"); + return IXP_POP3; +} + +static HRESULT WINAPI POP3Transport_IsState(IPOP3Transport *iface, IXPISSTATE isstate) +{ + FIXME("(%u)\n", isstate); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_InetServerFromAccount( + IPOP3Transport *iface, IImnAccount *pAccount, LPINETSERVER pInetServer) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("(%p, %p)\n", pAccount, pInetServer); + return InternetTransport_InetServerFromAccount(&This->InetTransport, pAccount, pInetServer); +} + +static HRESULT WINAPI POP3Transport_Connect(IPOP3Transport *iface, + LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging) +{ + POP3Transport *This = (POP3Transport *)iface; + HRESULT hr; + + TRACE("(%p, %s, %s)\n", pInetServer, fAuthenticate ? "TRUE" : "FALSE", fCommandLogging ? "TRUE" : "FALSE"); + + hr = InternetTransport_Connect(&This->InetTransport, pInetServer, fAuthenticate, fCommandLogging); + if (FAILED(hr)) + return hr; + + This->command = POP3_USER; + This->server = *pInetServer; + return InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackSendUSERCmd); +} + +static HRESULT WINAPI POP3Transport_HandsOffCallback(IPOP3Transport *iface) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("()\n"); + return InternetTransport_HandsOffCallback(&This->InetTransport); +} + +static HRESULT WINAPI POP3Transport_Disconnect(IPOP3Transport *iface) +{ + TRACE("()\n"); + return IPOP3Transport_CommandQUIT(iface); +} + +static HRESULT WINAPI POP3Transport_DropConnection(IPOP3Transport *iface) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("()\n"); + return InternetTransport_DropConnection(&This->InetTransport); +} + +static HRESULT WINAPI POP3Transport_GetStatus(IPOP3Transport *iface, + IXPSTATUS *pCurrentStatus) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("()\n"); + return InternetTransport_GetStatus(&This->InetTransport, pCurrentStatus); +} + +static HRESULT WINAPI POP3Transport_InitNew(IPOP3Transport *iface, + LPSTR pszLogFilePath, IPOP3Callback *pCallback) +{ + POP3Transport *This = (POP3Transport *)iface; + + TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath), pCallback); + + if (!pCallback) + return E_INVALIDARG; + + if (pszLogFilePath) + FIXME("not using log file of %s, use Wine debug logging instead\n", + debugstr_a(pszLogFilePath)); + + IPOP3Callback_AddRef(pCallback); + This->InetTransport.pCallback = (ITransportCallback *)pCallback; + This->InetTransport.fInitialised = TRUE; + + return S_OK; +} + +static HRESULT WINAPI POP3Transport_MarkItem(IPOP3Transport *iface, POP3MARKTYPE marktype, + DWORD dwPopId, boolean fMarked) +{ + FIXME("(%u, %u, %d)\n", marktype, dwPopId, fMarked); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_CommandAUTH(IPOP3Transport *iface, LPSTR pszAuthType) +{ + FIXME("(%s)\n", pszAuthType); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_CommandUSER(IPOP3Transport *iface, LPSTR username) +{ + static char user[] = "USER "; + POP3Transport *This = (POP3Transport *)iface; + char *command; + int len; + + TRACE("(%s)\n", username); + + len = sizeof(user) + strlen(username) + 2; /* "\r\n" */ + command = HeapAlloc(GetProcessHeap(), 0, len); + + strcpy(command, user); + strcat(command, username); + strcat(command, "\r\n"); + + This->command = POP3_USER; + InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp); + + HeapFree(GetProcessHeap(), 0, command); + return S_OK; +} + +static HRESULT WINAPI POP3Transport_CommandPASS(IPOP3Transport *iface, LPSTR password) +{ + static char pass[] = "PASS "; + POP3Transport *This = (POP3Transport *)iface; + char *command; + int len; + + TRACE("(%p)\n", password); + + len = sizeof(pass) + strlen(password) + 2; /* "\r\n" */ + command = HeapAlloc(GetProcessHeap(), 0, len); + + strcpy(command, pass); + strcat(command, password); + strcat(command, "\r\n"); + + This->command = POP3_PASS; + InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp); + + HeapFree(GetProcessHeap(), 0, command); + return S_OK; +} + +static HRESULT WINAPI POP3Transport_CommandLIST( + IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) +{ + static char list[] = "LIST\r\n"; + POP3Transport *This = (POP3Transport *)iface; + + TRACE("(%u, %u)\n", cmdtype, dwPopId); + + This->command = POP3_LIST; + InternetTransport_DoCommand(&This->InetTransport, list, POP3Transport_CallbackRecvLISTResp); + return S_OK; +} + +static HRESULT WINAPI POP3Transport_CommandTOP( + IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId, DWORD cPreviewLines) +{ + FIXME("(%u, %u, %u)\n", cmdtype, dwPopId, cPreviewLines); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_CommandQUIT(IPOP3Transport *iface) +{ + static char command[] = "QUIT\r\n"; + POP3Transport *This = (POP3Transport *)iface; + + TRACE("()\n"); + + This->command = POP3_QUIT; + return InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvQUITResp); +} + +static HRESULT WINAPI POP3Transport_CommandSTAT(IPOP3Transport *iface) +{ + static char stat[] = "STAT\r\n"; + POP3Transport *This = (POP3Transport *)iface; + + TRACE("\n"); + + This->command = POP3_STAT; + InternetTransport_DoCommand(&This->InetTransport, stat, POP3Transport_CallbackRecvSTATResp); + return S_OK; +} + +static HRESULT WINAPI POP3Transport_CommandNOOP(IPOP3Transport *iface) +{ + FIXME("()\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_CommandRSET(IPOP3Transport *iface) +{ + FIXME("()\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_CommandUIDL( + IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) +{ + static char uidl[] = "UIDL\r\n"; + POP3Transport *This = (POP3Transport *)iface; + + TRACE("(%u, %u)\n", cmdtype, dwPopId); + + This->command = POP3_UIDL; + InternetTransport_DoCommand(&This->InetTransport, uidl, POP3Transport_CallbackRecvUIDLResp); + return S_OK; +} + +static HRESULT WINAPI POP3Transport_CommandDELE( + IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) +{ + FIXME("(%u, %u)\n", cmdtype, dwPopId); + return E_NOTIMPL; +} + +static HRESULT WINAPI POP3Transport_CommandRETR( + IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId) +{ + FIXME("(%u, %u)\n", cmdtype, dwPopId); + return E_NOTIMPL; +} + +static const IPOP3TransportVtbl POP3TransportVtbl = +{ + POP3Transport_QueryInterface, + POP3Transport_AddRef, + POP3Transport_Release, + POP3Transport_GetServerInfo, + POP3Transport_GetIXPType, + POP3Transport_IsState, + POP3Transport_InetServerFromAccount, + POP3Transport_Connect, + POP3Transport_HandsOffCallback, + POP3Transport_Disconnect, + POP3Transport_DropConnection, + POP3Transport_GetStatus, + POP3Transport_InitNew, + POP3Transport_MarkItem, + POP3Transport_CommandAUTH, + POP3Transport_CommandUSER, + POP3Transport_CommandPASS, + POP3Transport_CommandLIST, + POP3Transport_CommandTOP, + POP3Transport_CommandQUIT, + POP3Transport_CommandSTAT, + POP3Transport_CommandNOOP, + POP3Transport_CommandRSET, + POP3Transport_CommandUIDL, + POP3Transport_CommandDELE, + POP3Transport_CommandRETR +}; + +HRESULT WINAPI CreatePOP3Transport(IPOP3Transport **ppTransport) +{ + HRESULT hr; + POP3Transport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->InetTransport.u.vtblPOP3 = &POP3TransportVtbl; + This->refs = 0; + hr = InternetTransport_Init(&This->InetTransport); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, This); + return hr; + } + + *ppTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3; + IPOP3Transport_AddRef(*ppTransport); + + return S_OK; +} + +static HRESULT WINAPI POP3TransportCF_QueryInterface(LPCLASSFACTORY iface, + REFIID riid, LPVOID *ppv) +{ + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI POP3TransportCF_AddRef(LPCLASSFACTORY iface) +{ + return 2; /* non-heap based object */ +} + +static ULONG WINAPI POP3TransportCF_Release(LPCLASSFACTORY iface) +{ + return 1; /* non-heap based object */ +} + +static HRESULT WINAPI POP3TransportCF_CreateInstance(LPCLASSFACTORY iface, + LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) +{ + HRESULT hr; + IPOP3Transport *pPop3Transport; + + TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv); + + *ppv = NULL; + + if (pUnk) + return CLASS_E_NOAGGREGATION; + + hr = CreatePOP3Transport(&pPop3Transport); + if (FAILED(hr)) + return hr; + + hr = IPOP3Transport_QueryInterface(pPop3Transport, riid, ppv); + IPOP3Transport_Release(pPop3Transport); + + return hr; +} + +static HRESULT WINAPI POP3TransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) +{ + FIXME("(%d)\n",fLock); + return S_OK; +} + +static const IClassFactoryVtbl POP3TransportCFVtbl = +{ + POP3TransportCF_QueryInterface, + POP3TransportCF_AddRef, + POP3TransportCF_Release, + POP3TransportCF_CreateInstance, + POP3TransportCF_LockServer +}; +static const IClassFactoryVtbl *POP3TransportCF = &POP3TransportCFVtbl; + +HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv) +{ + return IClassFactory_QueryInterface((IClassFactory *)&POP3TransportCF, riid, ppv); +} diff --git a/reactos/dll/win32/inetcomm/regsvr.c b/reactos/dll/win32/inetcomm/regsvr.c index 620cfa78ef4..4c7310cc172 100644 --- a/reactos/dll/win32/inetcomm/regsvr.c +++ b/reactos/dll/win32/inetcomm/regsvr.c @@ -31,8 +31,8 @@ #include "ocidl.h" #include "initguid.h" -#include "inetcomm_private.h" #include "mimeole.h" +#include "inetcomm_private.h" #include "wine/debug.h" @@ -404,6 +404,12 @@ static struct regsvr_coclass const coclass_list[] = { "inetcomm.dll", "Both" }, + { &CLSID_ISMTPTransport2, + "CLSID_ISMTPTransport2", + NULL, + "inetcomm.dll", + "Both" + }, { &CLSID_IPOP3Transport, "CLSID_IPOP3Transport", NULL, @@ -452,6 +458,12 @@ static struct regsvr_coclass const coclass_list[] = { "inetcomm.dll", "Both" }, + { &CLSID_IMimeSecurity, + "CLSID_IMimeSecurity", + NULL, + "inetcomm.dll", + "Both" + }, { NULL } /* list terminator */ }; diff --git a/reactos/dll/win32/inetcomm/smtptransport.c b/reactos/dll/win32/inetcomm/smtptransport.c new file mode 100644 index 00000000000..d704525e1ed --- /dev/null +++ b/reactos/dll/win32/inetcomm/smtptransport.c @@ -0,0 +1,1047 @@ +/* + * SMTP Transport + * + * Copyright 2006 Robert Shearman for CodeWeavers + * Copyright 2008 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#define COBJMACROS + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winuser.h" +#include "objbase.h" +#include "mimeole.h" +#include "wine/debug.h" + +#include "inetcomm_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(inetcomm); + +typedef struct +{ + InternetTransport InetTransport; + ULONG refs; + BOOL fESMTP; + SMTPMESSAGE pending_message; + INETADDR *addrlist; + ULONG ulCurrentAddressIndex; +} SMTPTransport; + +static HRESULT SMTPTransport_ParseResponse(SMTPTransport *This, char *pszResponse, SMTPRESPONSE *pResponse) +{ + HRESULT hrServerError; + + TRACE("response: %s\n", debugstr_a(pszResponse)); + + if (!isdigit(*pszResponse)) + return IXP_E_SMTP_RESPONSE_ERROR; + pResponse->pTransport = (ISMTPTransport *)&This->InetTransport.u.vtblSMTP2; + pResponse->rIxpResult.pszResponse = pszResponse; + pResponse->rIxpResult.dwSocketError = 0; + pResponse->rIxpResult.uiServerError = strtol(pszResponse, &pszResponse, 10); + if (*pszResponse == '-') + { + pResponse->fDone = FALSE; + pszResponse++; + } + else + pResponse->fDone = TRUE; + + switch (pResponse->rIxpResult.uiServerError) + { + case 211: hrServerError = IXP_E_SMTP_211_SYSTEM_STATUS; break; + case 214: hrServerError = IXP_E_SMTP_214_HELP_MESSAGE; break; + case 220: hrServerError = IXP_E_SMTP_220_READY; break; + case 221: hrServerError = IXP_E_SMTP_221_CLOSING; break; + case 245: hrServerError = IXP_E_SMTP_245_AUTH_SUCCESS; break; + case 250: hrServerError = IXP_E_SMTP_250_MAIL_ACTION_OKAY; break; + case 251: hrServerError = IXP_E_SMTP_251_FORWARDING_MAIL; break; + case 334: hrServerError = IXP_E_SMTP_334_AUTH_READY_RESPONSE; break; + case 354: hrServerError = IXP_E_SMTP_354_START_MAIL_INPUT; break; + case 421: hrServerError = IXP_E_SMTP_421_NOT_AVAILABLE; break; + case 450: hrServerError = IXP_E_SMTP_450_MAILBOX_BUSY; break; + case 451: hrServerError = IXP_E_SMTP_451_ERROR_PROCESSING; break; + case 452: hrServerError = IXP_E_SMTP_452_NO_SYSTEM_STORAGE; break; + case 454: hrServerError = IXP_E_SMTP_454_STARTTLS_FAILED; break; + case 500: hrServerError = IXP_E_SMTP_500_SYNTAX_ERROR; break; + case 501: hrServerError = IXP_E_SMTP_501_PARAM_SYNTAX; break; + case 502: hrServerError = IXP_E_SMTP_502_COMMAND_NOTIMPL; break; + case 503: hrServerError = IXP_E_SMTP_503_COMMAND_SEQ; break; + case 504: hrServerError = IXP_E_SMTP_504_COMMAND_PARAM_NOTIMPL; break; + case 530: hrServerError = IXP_E_SMTP_530_STARTTLS_REQUIRED; break; + case 550: hrServerError = IXP_E_SMTP_550_MAILBOX_NOT_FOUND; break; + case 551: hrServerError = IXP_E_SMTP_551_USER_NOT_LOCAL; break; + case 552: hrServerError = IXP_E_SMTP_552_STORAGE_OVERFLOW; break; + case 553: hrServerError = IXP_E_SMTP_553_MAILBOX_NAME_SYNTAX; break; + case 554: hrServerError = IXP_E_SMTP_554_TRANSACT_FAILED; break; + default: + hrServerError = IXP_E_SMTP_RESPONSE_ERROR; + break; + } + pResponse->rIxpResult.hrResult = hrServerError; + pResponse->rIxpResult.hrServerError = hrServerError; + + if (This->InetTransport.pCallback && This->InetTransport.fCommandLogging) + { + ITransportCallback_OnCommand(This->InetTransport.pCallback, CMD_RESP, + pResponse->rIxpResult.pszResponse, hrServerError, + (IInternetTransport *)&This->InetTransport.u.vtbl); + } + return S_OK; +} + +static void SMTPTransport_CallbackDoNothing(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + TRACE("\n"); +} + +static void SMTPTransport_CallbackReadResponseDoNothing(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackDoNothing); +} + +static void SMTPTransport_CallbackProcessDATAResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response = { 0 }; + HRESULT hr; + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + response.command = SMTP_DATA; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } +} + +static void SMTPTransport_CallbackReadDATAResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackProcessDATAResponse); +} + +static void SMTPTransport_CallbackProcessMAILResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response = { 0 }; + HRESULT hr; + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + response.command = SMTP_MAIL; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } +} + +static void SMTPTransport_CallbackReadMAILResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackProcessMAILResponse); +} + +static void SMTPTransport_CallbackProcessRCPTResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response = { 0 }; + HRESULT hr; + + TRACE("\n"); + + HeapFree(GetProcessHeap(), 0, This->addrlist); + This->addrlist = NULL; + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + response.command = SMTP_RCPT; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } +} + +static void SMTPTransport_CallbackReadRCPTResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackProcessRCPTResponse); +} + +static void SMTPTransport_CallbackProcessHelloResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response = { 0 }; + HRESULT hr; + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + response.command = This->fESMTP ? SMTP_EHLO : SMTP_HELO; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } + + if (!response.fDone) + { + InternetTransport_ReadLine(&This->InetTransport, + SMTPTransport_CallbackProcessHelloResp); + return; + } + + /* FIXME: try to authorize */ + + /* always changed to this status, even if authorization not support on server */ + InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED); + InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED); + + memset(&response, 0, sizeof(response)); + response.command = SMTP_CONNECTED; + response.fDone = TRUE; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); +} + +static void SMTPTransport_CallbackRecvHelloResp(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackProcessHelloResp); +} + +static void SMTPTransport_CallbackSendHello(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response = { 0 }; + HRESULT hr; + const char *pszHello; + char *pszCommand; + const char szHostName[] = "localhost"; /* FIXME */ + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + response.command = SMTP_BANNER; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } + + TRACE("(%s)\n", pBuffer); + + This->fESMTP = strstr(response.rIxpResult.pszResponse, "ESMTP") && + This->InetTransport.ServerInfo.dwFlags & (ISF_SSLONSAMEPORT|ISF_QUERYDSNSUPPORT|ISF_QUERYAUTHSUPPORT); + + if (This->fESMTP) + pszHello = "EHLO "; + else + pszHello = "HELO "; + + pszCommand = HeapAlloc(GetProcessHeap(), 0, strlen(pszHello) + strlen(szHostName) + 2); + strcpy(pszCommand, pszHello); + strcat(pszCommand, szHostName); + pszCommand[strlen(pszCommand)+1] = '\0'; + pszCommand[strlen(pszCommand)] = '\n'; + + InternetTransport_DoCommand(&This->InetTransport, pszCommand, + SMTPTransport_CallbackRecvHelloResp); + + HeapFree(GetProcessHeap(), 0, pszCommand); +} + +static void SMTPTransport_CallbackDisconnect(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response; + HRESULT hr; + + TRACE("\n"); + + if (pBuffer) + { + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } + } + InternetTransport_DropConnection(&This->InetTransport); +} + +static void SMTPTransport_CallbackMessageProcessResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response = { 0 }; + HRESULT hr; + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } + + response.command = SMTP_SEND_MESSAGE; + response.rIxpResult.hrResult = S_OK; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); +} + +static void SMTPTransport_CallbackMessageReadResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackMessageProcessResponse); +} + +static void SMTPTransport_CallbackMessageSendDOT(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + IStream_Release(This->pending_message.pstmMsg); + InternetTransport_DoCommand(&This->InetTransport, "\n.\n", + SMTPTransport_CallbackMessageReadResponse); +} + +static void SMTPTransport_CallbackMessageSendDataStream(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response; + HRESULT hr; + char *pszBuffer; + ULONG cbSize; + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } + + pszBuffer = HeapAlloc(GetProcessHeap(), 0, This->pending_message.cbSize); + hr = IStream_Read(This->pending_message.pstmMsg, pszBuffer, This->pending_message.cbSize, NULL); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + cbSize = This->pending_message.cbSize; + + /* FIXME: map "\n.\n" to "\n..\n", reallocate memory, update cbSize */ + + /* FIXME: properly stream the message rather than writing it all at once */ + + hr = InternetTransport_Write(&This->InetTransport, pszBuffer, cbSize, + SMTPTransport_CallbackMessageSendDOT); + + HeapFree(GetProcessHeap(), 0, pszBuffer); +} + +static void SMTPTransport_CallbackMessageReadDataResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackMessageSendDataStream); +} + +static void SMTPTransport_CallbackMessageSendTo(IInternetTransport *iface, char *pBuffer, int cbBuffer); + +static void SMTPTransport_CallbackMessageReadToResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackMessageSendTo); +} + +static void SMTPTransport_CallbackMessageSendTo(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + SMTPRESPONSE response; + HRESULT hr; + + TRACE("\n"); + + hr = SMTPTransport_ParseResponse(This, pBuffer, &response); + if (FAILED(hr)) + { + /* FIXME: handle error */ + return; + } + + if (FAILED(response.rIxpResult.hrServerError)) + { + ERR("server error: %s\n", debugstr_a(pBuffer)); + /* FIXME: handle error */ + return; + } + + for (; This->ulCurrentAddressIndex < This->pending_message.rAddressList.cAddress; This->ulCurrentAddressIndex++) + { + TRACE("address[%d]: %s\n", This->ulCurrentAddressIndex, + This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].szEmail); + + if ((This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].addrtype & ADDR_TOFROM_MASK) == ADDR_TO) + { + const char szCommandFormat[] = "RCPT TO: <%s>\n"; + char *szCommand; + int len = sizeof(szCommandFormat) - 2 /* "%s" */ + + strlen(This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].szEmail); + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return; + + sprintf(szCommand, szCommandFormat, + This->pending_message.rAddressList.prgAddress[This->ulCurrentAddressIndex].szEmail); + + This->ulCurrentAddressIndex++; + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackMessageReadToResponse); + + HeapFree(GetProcessHeap(), 0, szCommand); + return; + } + } + + hr = InternetTransport_DoCommand(&This->InetTransport, "DATA\n", + SMTPTransport_CallbackMessageReadDataResponse); +} + +static void SMTPTransport_CallbackMessageReadFromResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("\n"); + InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackMessageSendTo); +} + +static HRESULT WINAPI SMTPTransport_QueryInterface(ISMTPTransport2 *iface, REFIID riid, void **ppv) +{ + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IInternetTransport) || + IsEqualIID(riid, &IID_ISMTPTransport) || + IsEqualIID(riid, &IID_ISMTPTransport2)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + *ppv = NULL; + FIXME("no interface for %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI SMTPTransport_AddRef(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + return InterlockedIncrement((LONG *)&This->refs); +} + +static ULONG WINAPI SMTPTransport_Release(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + ULONG refs = InterlockedDecrement((LONG *)&This->refs); + if (!refs) + { + TRACE("destroying %p\n", This); + if (This->InetTransport.Status != IXP_DISCONNECTED) + InternetTransport_DropConnection(&This->InetTransport); + + if (This->InetTransport.pCallback) ITransportCallback_Release(This->InetTransport.pCallback); + HeapFree(GetProcessHeap(), 0, This->addrlist); + HeapFree(GetProcessHeap(), 0, This); + } + return refs; +} + +static HRESULT WINAPI SMTPTransport_GetServerInfo(ISMTPTransport2 *iface, + LPINETSERVER pInetServer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("(%p)\n", pInetServer); + return InternetTransport_GetServerInfo(&This->InetTransport, pInetServer); +} + +static IXPTYPE WINAPI SMTPTransport_GetIXPType(ISMTPTransport2 *iface) +{ + TRACE("()\n"); + return IXP_SMTP; +} + +static HRESULT WINAPI SMTPTransport_IsState(ISMTPTransport2 *iface, + IXPISSTATE isstate) +{ + FIXME("(%d): stub\n", isstate); + return E_NOTIMPL; +} + +static HRESULT WINAPI SMTPTransport_InetServerFromAccount( + ISMTPTransport2 *iface, IImnAccount *pAccount, LPINETSERVER pInetServer) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("(%p, %p)\n", pAccount, pInetServer); + return InternetTransport_InetServerFromAccount(&This->InetTransport, pAccount, pInetServer); +} + +static HRESULT WINAPI SMTPTransport_Connect(ISMTPTransport2 *iface, + LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging) +{ + SMTPTransport *This = (SMTPTransport *)iface; + HRESULT hr; + + TRACE("(%p, %s, %s)\n", pInetServer, fAuthenticate ? "TRUE" : "FALSE", fCommandLogging ? "TRUE" : "FALSE"); + + hr = InternetTransport_Connect(&This->InetTransport, pInetServer, fAuthenticate, fCommandLogging); + if (FAILED(hr)) + return hr; + + /* this starts the state machine, which continues in SMTPTransport_CallbackSendHELO */ + return InternetTransport_ReadLine(&This->InetTransport, SMTPTransport_CallbackSendHello); +} + +static HRESULT WINAPI SMTPTransport_HandsOffCallback(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("()\n"); + return InternetTransport_HandsOffCallback(&This->InetTransport); +} + +static HRESULT WINAPI SMTPTransport_Disconnect(ISMTPTransport2 *iface) +{ + TRACE("()\n"); + return ISMTPTransport2_CommandQUIT(iface); +} + +static HRESULT WINAPI SMTPTransport_DropConnection(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("()\n"); + return InternetTransport_DropConnection(&This->InetTransport); +} + +static HRESULT WINAPI SMTPTransport_GetStatus(ISMTPTransport2 *iface, + IXPSTATUS *pCurrentStatus) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("()\n"); + return InternetTransport_GetStatus(&This->InetTransport, pCurrentStatus); +} + +static HRESULT WINAPI SMTPTransport_InitNew(ISMTPTransport2 *iface, + LPSTR pszLogFilePath, ISMTPCallback *pCallback) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath), pCallback); + + if (!pCallback) + return E_INVALIDARG; + + if (pszLogFilePath) + FIXME("not using log file of %s, use Wine debug logging instead\n", + debugstr_a(pszLogFilePath)); + + ISMTPCallback_AddRef(pCallback); + This->InetTransport.pCallback = (ITransportCallback *)pCallback; + This->InetTransport.fInitialised = TRUE; + + return S_OK; +} + +static HRESULT WINAPI SMTPTransport_SendMessage(ISMTPTransport2 *iface, + LPSMTPMESSAGE pMessage) +{ + SMTPTransport *This = (SMTPTransport *)iface; + ULONG i, size; + LPSTR pszFromAddress = NULL; + const char szCommandFormat[] = "MAIL FROM: <%s>\n"; + char *szCommand; + int len; + HRESULT hr; + + TRACE("(%p)\n", pMessage); + + This->pending_message = *pMessage; + IStream_AddRef(pMessage->pstmMsg); + + size = pMessage->rAddressList.cAddress * sizeof(INETADDR); + This->addrlist = HeapAlloc(GetProcessHeap(), 0, size); + if (!This->addrlist) + return E_OUTOFMEMORY; + + memcpy(This->addrlist, pMessage->rAddressList.prgAddress, size); + This->pending_message.rAddressList.prgAddress = This->addrlist; + This->ulCurrentAddressIndex = 0; + + for (i = 0; i < pMessage->rAddressList.cAddress; i++) + { + if ((pMessage->rAddressList.prgAddress[i].addrtype & ADDR_TOFROM_MASK) == ADDR_FROM) + { + TRACE("address[%d]: ADDR_FROM, %s\n", i, + pMessage->rAddressList.prgAddress[i].szEmail); + pszFromAddress = pMessage->rAddressList.prgAddress[i].szEmail; + } + else if ((pMessage->rAddressList.prgAddress[i].addrtype & ADDR_TOFROM_MASK) == ADDR_TO) + { + TRACE("address[%d]: ADDR_TO, %s\n", i, + pMessage->rAddressList.prgAddress[i].szEmail); + } + } + + if (!pszFromAddress) + { + SMTPRESPONSE response; + memset(&response, 0, sizeof(response)); + response.command = SMTP_SEND_MESSAGE; + response.fDone = TRUE; + response.pTransport = (ISMTPTransport *)&This->InetTransport.u.vtblSMTP2; + response.rIxpResult.hrResult = IXP_E_SMTP_NO_SENDER; + ISMTPCallback_OnResponse((ISMTPCallback *)This->InetTransport.pCallback, &response); + return S_OK; + } + len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszFromAddress); + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return E_OUTOFMEMORY; + + sprintf(szCommand, szCommandFormat, pszFromAddress); + + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackMessageReadFromResponse); + + return hr; +} + +static HRESULT WINAPI SMTPTransport_CommandMAIL(ISMTPTransport2 *iface, LPSTR pszEmailFrom) +{ + SMTPTransport *This = (SMTPTransport *)iface; + const char szCommandFormat[] = "MAIL FROM: <%s>\n"; + char *szCommand; + int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailFrom); + HRESULT hr; + + TRACE("(%s)\n", pszEmailFrom); + + if (!pszEmailFrom) + return E_INVALIDARG; + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return E_OUTOFMEMORY; + + sprintf(szCommand, szCommandFormat, pszEmailFrom); + + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackReadMAILResponse); + + HeapFree(GetProcessHeap(), 0, szCommand); + return hr; +} + +static HRESULT WINAPI SMTPTransport_CommandRCPT(ISMTPTransport2 *iface, LPSTR pszEmailTo) +{ + SMTPTransport *This = (SMTPTransport *)iface; + const char szCommandFormat[] = "RCPT TO: <%s>\n"; + char *szCommand; + int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszEmailTo); + HRESULT hr; + + TRACE("(%s)\n", pszEmailTo); + + if (!pszEmailTo) + return E_INVALIDARG; + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return E_OUTOFMEMORY; + + sprintf(szCommand, szCommandFormat, pszEmailTo); + + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackReadRCPTResponse); + + HeapFree(GetProcessHeap(), 0, szCommand); + return hr; +} + +static HRESULT WINAPI SMTPTransport_CommandEHLO(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + const char szCommandFormat[] = "EHLO %s\n"; + const char szHostname[] = "localhost"; /* FIXME */ + char *szCommand; + int len = sizeof(szCommandFormat) - 2 /* "%s" */ + sizeof(szHostname); + HRESULT hr; + + TRACE("\n"); + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return E_OUTOFMEMORY; + + sprintf(szCommand, szCommandFormat, szHostname); + + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackReadResponseDoNothing); + + HeapFree(GetProcessHeap(), 0, szCommand); + return hr; +} + +static HRESULT WINAPI SMTPTransport_CommandHELO(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + const char szCommandFormat[] = "HELO %s\n"; + const char szHostname[] = "localhost"; /* FIXME */ + char *szCommand; + int len = sizeof(szCommandFormat) - 2 /* "%s" */ + sizeof(szHostname); + HRESULT hr; + + TRACE("()\n"); + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return E_OUTOFMEMORY; + + sprintf(szCommand, szCommandFormat, szHostname); + + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackReadResponseDoNothing); + + HeapFree(GetProcessHeap(), 0, szCommand); + return hr; +} + +static HRESULT WINAPI SMTPTransport_CommandAUTH(ISMTPTransport2 *iface, + LPSTR pszAuthType) +{ + SMTPTransport *This = (SMTPTransport *)iface; + const char szCommandFormat[] = "AUTH %s\n"; + char *szCommand; + int len = sizeof(szCommandFormat) - 2 /* "%s" */ + strlen(pszAuthType); + HRESULT hr; + + TRACE("(%s)\n", pszAuthType); + + if (!pszAuthType) + return E_INVALIDARG; + + szCommand = HeapAlloc(GetProcessHeap(), 0, len); + if (!szCommand) + return E_OUTOFMEMORY; + + sprintf(szCommand, szCommandFormat, pszAuthType); + + hr = InternetTransport_DoCommand(&This->InetTransport, szCommand, + SMTPTransport_CallbackReadResponseDoNothing); + + HeapFree(GetProcessHeap(), 0, szCommand); + return hr; +} + +static HRESULT WINAPI SMTPTransport_CommandQUIT(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("()\n"); + + InternetTransport_ChangeStatus(&This->InetTransport, IXP_DISCONNECTING); + return InternetTransport_DoCommand(&This->InetTransport, "QUIT\n", + SMTPTransport_CallbackDisconnect); +} + +static HRESULT WINAPI SMTPTransport_CommandRSET(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("()\n"); + + return InternetTransport_DoCommand(&This->InetTransport, "RSET\n", + SMTPTransport_CallbackReadResponseDoNothing); +} + +static HRESULT WINAPI SMTPTransport_CommandDATA(ISMTPTransport2 *iface) +{ + SMTPTransport *This = (SMTPTransport *)iface; + + TRACE("()\n"); + + return InternetTransport_DoCommand(&This->InetTransport, "DATA\n", + SMTPTransport_CallbackReadDATAResponse); +} + +static HRESULT WINAPI SMTPTransport_CommandDOT(ISMTPTransport2 *iface) +{ + FIXME("()\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SMTPTransport_SendDataStream(ISMTPTransport2 *iface, + IStream *pStream, ULONG cbSize) +{ + FIXME("(%p, %d)\n", pStream, cbSize); + return E_NOTIMPL; +} + +static HRESULT WINAPI SMTPTransport_SetWindow(ISMTPTransport2 *iface) +{ + FIXME("()\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SMTPTransport_ResetWindow(ISMTPTransport2 *iface) +{ + FIXME("()\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI SMTPTransport_SendMessage2(ISMTPTransport2 *iface, LPSMTPMESSAGE2 pMessage) +{ + FIXME("(%p)\n", pMessage); + return E_NOTIMPL; +} + +static HRESULT WINAPI SMTPTransport_CommandRCPT2(ISMTPTransport2 *iface, LPSTR pszEmailTo, + INETADDRTYPE atDSN) +{ + FIXME("(%s, %u)\n", pszEmailTo, atDSN); + return E_NOTIMPL; +} + +static const ISMTPTransport2Vtbl SMTPTransport2Vtbl = +{ + SMTPTransport_QueryInterface, + SMTPTransport_AddRef, + SMTPTransport_Release, + SMTPTransport_GetServerInfo, + SMTPTransport_GetIXPType, + SMTPTransport_IsState, + SMTPTransport_InetServerFromAccount, + SMTPTransport_Connect, + SMTPTransport_HandsOffCallback, + SMTPTransport_Disconnect, + SMTPTransport_DropConnection, + SMTPTransport_GetStatus, + SMTPTransport_InitNew, + SMTPTransport_SendMessage, + SMTPTransport_CommandMAIL, + SMTPTransport_CommandRCPT, + SMTPTransport_CommandEHLO, + SMTPTransport_CommandHELO, + SMTPTransport_CommandAUTH, + SMTPTransport_CommandQUIT, + SMTPTransport_CommandRSET, + SMTPTransport_CommandDATA, + SMTPTransport_CommandDOT, + SMTPTransport_SendDataStream, + SMTPTransport_SetWindow, + SMTPTransport_ResetWindow, + SMTPTransport_SendMessage2, + SMTPTransport_CommandRCPT2 +}; + +HRESULT WINAPI CreateSMTPTransport(ISMTPTransport **ppTransport) +{ + HRESULT hr; + SMTPTransport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->InetTransport.u.vtblSMTP2 = &SMTPTransport2Vtbl; + This->refs = 0; + This->fESMTP = FALSE; + hr = InternetTransport_Init(&This->InetTransport); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, This); + return hr; + } + + *ppTransport = (ISMTPTransport *)&This->InetTransport.u.vtblSMTP2; + ISMTPTransport_AddRef(*ppTransport); + + return S_OK; +} + + +static HRESULT WINAPI SMTPTransportCF_QueryInterface(LPCLASSFACTORY iface, + REFIID riid, LPVOID *ppv) +{ + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) + { + *ppv = iface; + IUnknown_AddRef(iface); + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG WINAPI SMTPTransportCF_AddRef(LPCLASSFACTORY iface) +{ + return 2; /* non-heap based object */ +} + +static ULONG WINAPI SMTPTransportCF_Release(LPCLASSFACTORY iface) +{ + return 1; /* non-heap based object */ +} + +static HRESULT WINAPI SMTPTransportCF_CreateInstance(LPCLASSFACTORY iface, + LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv) +{ + HRESULT hr; + ISMTPTransport *pSmtpTransport; + + TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv); + + *ppv = NULL; + + if (pUnk) + return CLASS_E_NOAGGREGATION; + + hr = CreateSMTPTransport(&pSmtpTransport); + if (FAILED(hr)) + return hr; + + hr = ISMTPTransport_QueryInterface(pSmtpTransport, riid, ppv); + ISMTPTransport_Release(pSmtpTransport); + + return hr; +} + +static HRESULT WINAPI SMTPTransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) +{ + FIXME("(%d)\n",fLock); + return S_OK; +} + +static const IClassFactoryVtbl SMTPTransportCFVtbl = +{ + SMTPTransportCF_QueryInterface, + SMTPTransportCF_AddRef, + SMTPTransportCF_Release, + SMTPTransportCF_CreateInstance, + SMTPTransportCF_LockServer +}; +static const IClassFactoryVtbl *SMTPTransportCF = &SMTPTransportCFVtbl; + +HRESULT SMTPTransportCF_Create(REFIID riid, LPVOID *ppv) +{ + return IClassFactory_QueryInterface((IClassFactory *)&SMTPTransportCF, riid, ppv); +} diff --git a/reactos/include/psdk/imnxport.idl b/reactos/include/psdk/imnxport.idl index 50f3e4e08ce..ef4f8ac4019 100644 --- a/reactos/include/psdk/imnxport.idl +++ b/reactos/include/psdk/imnxport.idl @@ -21,11 +21,13 @@ import "imnact.idl"; interface IInternetTransport; interface ISMTPTransport; interface IPOP3Transport; +interface IIMAPTransport; /* CLSIDs */ cpp_quote("DEFINE_GUID(CLSID_IInternetMessageUrl, 0xca30cc91, 0xb1b3, 0x11d0, 0x85, 0xd0, 0x00, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_ISMTPTransport, 0xfd853ce6, 0x7f86, 0x11d0, 0x82, 0x52, 0x00, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") +cpp_quote("DEFINE_GUID(CLSID_ISMTPTransport2, 0xdf2c7eC, 0x3435, 0x11d0, 0x81, 0xd0, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_IPOP3Transport, 0xfd853ce7, 0x7f86, 0x11d0, 0x82, 0x52, 0x00, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_INNTPTransport, 0xfd853ce8, 0x7f86, 0x11d0, 0x82, 0x52, 0x00, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_IRASTransport, 0xfd853ce9, 0x7f86, 0x11d0, 0x82, 0x52, 0x00, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") @@ -433,7 +435,7 @@ interface ISMTPCallback : ITransportCallback { [case(SMTP_SEND_STREAM)] SMTPSTREAM rStreamInfo; [default]; - }; + } DUMMYUNIONNAME; } SMTPRESPONSE, *LPSMTPRESPONSE; HRESULT OnResponse( @@ -604,7 +606,7 @@ interface IPOP3Callback : ITransportCallback [case(POP3_RETR)] POP3RETR rRetrInfo; [case(POP3_TOP)] POP3TOP rTopInfo; [default]; - }; + } DUMMYUNIONNAME; } POP3RESPONSE, *LPPOP3RESPONSE; HRESULT OnResponse( @@ -684,16 +686,429 @@ interface IPOP3Transport : IInternetTransport /* FIXME: INNTPCallback, INNTPTransport */ -/* FIXME: IRangeList */ +[ + object, + uuid(8C438160-4EF6-11d0-874F-00AA00530EE9), + local, +] +interface IRangeList : IUnknown +{ + const ULONG RL_RANGE_ERROR = ((ULONG)-1); + const ULONG RL_LAST_MESSAGE = ((ULONG)-1); -/* FIXME: IIMAPCallback, IIMAPTransport */ + HRESULT Clear(); + + HRESULT IsInRange( + [in] const ULONG value); + + HRESULT Min( + [out] ULONG *pulMin); + + HRESULT Max( + [out] ULONG *pulMax); + + HRESULT Save( + [out] byte **ppbDestination, + [out] ULONG *pulSizeOfDestination); + + HRESULT Load( + [in, size_is(ulSizeOfSource)] byte *pbSource, + [in] const ULONG ulSizeOfSource); + + HRESULT AddRange( + [in] const ULONG low, + [in] const ULONG high); + + HRESULT AddSingleValue( + [in] const ULONG value); + + HRESULT AddRangeList( + [in] const IRangeList *prl); + + HRESULT DeleteRange( + [in] const ULONG low, + [in] const ULONG high); + + HRESULT DeleteSingleValue( + [in] const ULONG value); + + HRESULT DeleteRangeList( + [in] const IRangeList *prl); + + HRESULT MinOfRange( + [in] const ULONG value, + [out] ULONG *pulMinOfRange); + + HRESULT MaxOfRange( + [in] const ULONG value, + [out] ULONG *pulMaxOfRange); + + HRESULT RangeToIMAPString( + [out] LPSTR *ppszDestination, + [out] LPDWORD pdwLengthOfDestination); + + HRESULT Next( + [in] const ULONG current, + [out] ULONG *pulNext); + + HRESULT Prev( + [in] const ULONG current, + [out] ULONG *pulPrev); + + HRESULT Cardinality( + [out] ULONG *pulCardinality); + + HRESULT CardinalityFrom( + [in] const ULONG ulStartPoint, + [out] ULONG *pulCardinalityFrom); +} + +[ + object, + uuid(E9E9D8A3-4EDD-11d0-874F-00AA00530EE9), + local +] +interface IIMAPCallback : ITransportCallback +{ + typedef DWORD IMAP_MBOXFLAGS; + const IMAP_MBOXFLAGS IMAP_MBOX_NOFLAGS = 0x0; + const IMAP_MBOXFLAGS IMAP_MBOX_MARKED = 0x1; + const IMAP_MBOXFLAGS IMAP_MBOX_NOINFERIORS = 0x2; + const IMAP_MBOXFLAGS IMAP_MBOX_NOSELECT = 0x4; + const IMAP_MBOXFLAGS IMAP_MBOX_UNMARKED = 0x8; + const IMAP_MBOXFLAGS IMAP_MBOX_ALLFLAGS = 0xf; + + typedef enum tagIMAP_RESPONSE_TYPE + { + irtERROR_NOTIFICATION, + irtCOMMAND_COMPLETION, + irtSERVER_ALERT, + irtPARSE_ERROR, + irtMAILBOX_UPDATE, + irtDELETED_MSG, + irtFETCH_BODY, + irtUPDATE_MSG, + irtAPPLICABLE_FLAGS, + irtPERMANENT_FLAGS, + irtUIDVALIDITY, + irtREADWRITE_STATUS, + irtTRYCREATE, + irtSEARCH, + irtMAILBOX_LISTING, + irtMAILBOX_STATUS, + irtAPPEND_PROGRESS, + irtUPDATE_MSG_EX + } IMAP_RESPONSE_TYPE; + + typedef struct tagFETCH_BODY_PART + { + DWORD dwMsgSeqNum; + LPSTR pszBodyTag; + DWORD dwTotalBytes; + DWORD dwSizeOfData; + DWORD dwOffset; + BOOL fDone; + LPSTR pszData; + LPARAM lpFetchCookie1; + LPARAM lpFetchCookie2; + } FETCH_BODY_PART; + + typedef struct tagFETCH_CMD_RESULTS + { + DWORD dwMsgSeqNum; + BOOL bMsgFlags; + IMAP_MSGFLAGS mfMsgFlags; + BOOL bRFC822Size; + DWORD dwRFC822Size; + BOOL bUID; + DWORD dwUID; + BOOL bInternalDate; + FILETIME ftInternalDate; + LPARAM lpFetchCookie1; + LPARAM lpFetchCookie2; + } FETCH_CMD_RESULTS; + + typedef struct tagIMAPADDR + { + LPSTR pszName; + LPSTR pszADL; + LPSTR pszMailbox; + LPSTR pszHost; + struct tagIMAPADDR *pNext; + } IMAPADDR; + + typedef struct tagFETCH_CMD_RESULTS_EX + { + DWORD dwMsgSeqNum; + BOOL bMsgFlags; + IMAP_MSGFLAGS mfMsgFlags; + BOOL bRFC822Size; + DWORD dwRFC822Size; + BOOL bUID; + DWORD dwUID; + BOOL bInternalDate; + FILETIME ftInternalDate; + LPARAM lpFetchCookie1; + LPARAM lpFetchCookie2; + BOOL bEnvelope; + FILETIME ftENVDate; + LPSTR pszENVSubject; + IMAPADDR *piaENVFrom; + IMAPADDR *piaENVSender; + IMAPADDR *piaENVReplyTo; + IMAPADDR *piaENVTo; + IMAPADDR *piaENVCc; + IMAPADDR *piaENVBcc; + LPSTR pszENVInReplyTo; + LPSTR pszENVMessageID; + DWORD dwReserved1; + DWORD dwReserved2; + DWORD dwReserved3; + } FETCH_CMD_RESULTS_EX; + + typedef struct tagMBOX_MSGCOUNT + { + BOOL bGotExistsResponse; + DWORD dwExists; + BOOL bGotRecentResponse; + DWORD dwRecent; + BOOL bGotUnseenResponse; + DWORD dwUnseen; + } MBOX_MSGCOUNT; + + typedef struct tagIMAP_LISTLSUB_RESPONSE + { + LPSTR pszMailboxName; + IMAP_MBOXFLAGS imfMboxFlags; + char cHierarchyChar; + } IMAP_LISTLSUB_RESPONSE; + + typedef struct tagIMAP_STATUS_RESPONSE + { + LPSTR pszMailboxName; + BOOL fMessages; + DWORD dwMessages; + BOOL fRecent; + DWORD dwRecent; + BOOL fUIDNext; + DWORD dwUIDNext; + BOOL fUIDValidity; + DWORD dwUIDValidity; + BOOL fUnseen; + DWORD dwUnseen; + } IMAP_STATUS_RESPONSE; + + typedef struct tagAPPEND_PROGRESS + { + DWORD dwUploaded; + DWORD dwTotal; + } APPEND_PROGRESS; + + typedef [switch_type(IMAP_RESPONSE_TYPE)] union tagIMAP_RESPONSE_DATA + { + [case (irtMAILBOX_UPDATE)] MBOX_MSGCOUNT *pmcMsgCount; + [case (irtDELETED_MSG)] DWORD dwDeletedMsgSeqNum; + [case (irtFETCH_BODY)] FETCH_BODY_PART *pFetchBodyPart; + [case (irtUPDATE_MSG)] FETCH_CMD_RESULTS *pFetchResults; + [case (irtAPPLICABLE_FLAGS, irtPERMANENT_FLAGS)] IMAP_MSGFLAGS imfImapMessageFlags; + [case (irtUIDVALIDITY)] DWORD dwUIDValidity; + [case (irtREADWRITE_STATUS)] BOOL bReadWrite; + [case (irtSEARCH)] IRangeList *prlSearchResults; + [case (irtMAILBOX_LISTING)] IMAP_LISTLSUB_RESPONSE illrdMailboxListing; + [case (irtMAILBOX_STATUS)] IMAP_STATUS_RESPONSE *pisrStatusResponse; + [case (irtAPPEND_PROGRESS)] APPEND_PROGRESS *papAppendProgress; + [case (irtUPDATE_MSG_EX)] FETCH_CMD_RESULTS_EX *pFetchResultsEx; + } IMAP_RESPONSE_DATA; + + typedef struct tagIMAP_RESPONSE + { + WPARAM wParam; + LPARAM lParam; + HRESULT hrResult; + LPSTR lpszResponseText; + IMAP_RESPONSE_TYPE irtResponseType; + [switch_is(irtResponseType)] IMAP_RESPONSE_DATA irdResponseData; + } IMAP_RESPONSE; + + HRESULT OnResponse([in] const IMAP_RESPONSE *pirIMAPResponse); +} + +[ +object, +uuid(E9E9D8A8-4EDD-11d0-874F-00AA00530EE9), +local, +] +interface IIMAPTransport : IInternetTransport +{ + const DWORD IMAP_CAPABILITY_IMAP4 = 0x1; + const DWORD IMAP_CAPABILITY_IMAP4rev1 = 0x2; + const DWORD IMAP_CAPABILITY_IDLE = 0x4; + const DWORD IMAP_CAPABILITY_ALLFLAGS = 0x7; + + HRESULT InitNew( + [in] LPSTR pszLogFilePath, + [in] IIMAPCallback *pCBHandler); + + HRESULT NewIRangeList( + [out] IRangeList **pprlNewRangeList); + + HRESULT Capability( + [out] DWORD *pdwCapabilityFlags); + + HRESULT Select( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName); + + HRESULT Examine( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName); + + HRESULT Create( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName); + + HRESULT Delete( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName); + + HRESULT Rename( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName, + [in] LPSTR lpszNewMailboxName); + + HRESULT Subscribe( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName); + + HRESULT Unsubscribe( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName); + + HRESULT List( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxNameReference, + [in] LPSTR lpszMailboxNamePattern); + + HRESULT Lsub( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxNameReference, + [in] LPSTR lpszMailboxNamePattern); + + HRESULT Append( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszMailboxName, + [in] LPSTR lpszMessageFlags, + [in] FILETIME ftMessageDateTime, + [in] LPSTREAM lpstmMessageToSave); + + HRESULT Close( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler); + + HRESULT Expunge( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler); + + HRESULT Search( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR lpszSearchCriteria, + [in] boolean bReturnUIDs, + [in] IRangeList *pMsgRange, + [in] boolean bUIDRangeList); + + HRESULT Fetch( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] IRangeList *pMsgRange, + [in] boolean bUIDMsgRange, + [in] LPSTR lpszFetchArgs); + + HRESULT Store( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] IRangeList *pMsgRange, + [in] boolean bUIDRangeList, + [in] LPSTR lpszStoreArgs); + + HRESULT Copy( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] IRangeList *pMsgRange, + [in] boolean bUIDRangeList, + [in] LPSTR lpszMailboxName); + + HRESULT Noop( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler); + + HRESULT ResizeMsgSeqNumTable( + [in] DWORD dwSizeOfMbox); + + HRESULT UpdateSeqNumToUID( + [in] DWORD dwMsgSeqNum, + [in] DWORD dwUID); + + HRESULT RemoveSequenceNum( + [in] DWORD dwDeletedMsgSeqNum); + + HRESULT MsgSeqNumToUID( + [in] DWORD dwMsgSeqNum, + [out] DWORD *pdwUID); + + HRESULT GetMsgSeqNumToUIDArray( + [out] DWORD **ppdwMsgSeqNumToUIDArray, + [out] DWORD *pdwNumberOfElements); + + HRESULT GetHighestMsgSeqNum( + [out] DWORD *pdwHighestMSN); + + HRESULT ResetMsgSeqNumToUID(); + + HRESULT SetDefaultCBHandler( + [in] IIMAPCallback *pCBHandler); + + HRESULT Status( + [in] WPARAM wParam, + [in] LPARAM lParam, + [in] IIMAPCallback *pCBHandler, + [in] LPSTR pszMailboxName, + [in] LPSTR pszStatusCmdArgs); +} #if 0 cpp_quote("HRESULT WINAPI CreateRASTransport(IRASTransport **ppTransport);") cpp_quote("HRESULT WINAPI CreateNNTPTransport(INNTPTransport **ppTransport);") -cpp_quote("HRESULT WINAPI CreateIMAPTransport(IIMAPTransport **ppTransport);") cpp_quote("HRESULT WINAPI CreateIMAPTransport2(IIMAPTransport2 **ppTransport);") -cpp_quote("HRESULT WINAPI CreateRangeList(IRangeList **ppRangeList);") #endif +cpp_quote("HRESULT WINAPI CreateRangeList(IRangeList **ppRangeList);") cpp_quote("HRESULT WINAPI CreateSMTPTransport(ISMTPTransport **ppTransport);") cpp_quote("HRESULT WINAPI CreatePOP3Transport(IPOP3Transport **ppTransport);") +cpp_quote("HRESULT WINAPI CreateIMAPTransport(IIMAPTransport **ppTransport);") diff --git a/reactos/include/psdk/mimeole.idl b/reactos/include/psdk/mimeole.idl index 9d4f45bc0cd..d74cdb591fa 100644 --- a/reactos/include/psdk/mimeole.idl +++ b/reactos/include/psdk/mimeole.idl @@ -32,6 +32,8 @@ interface IMimeEnumProperties; cpp_quote("DEFINE_GUID(CLSID_IMimeBody, 0xfd853cdb, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_IMimeAllocator, 0xfd853cdd, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_IMimeMessage, 0xfd853ce3, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") +cpp_quote("DEFINE_GUID(CLSID_IMimeSecurity, 0xfd853cde, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") +cpp_quote("DEFINE_GUID(CLSID_IVirtualStream, 0xfd853cdf, 0x7f86, 0x11d0, 0x82, 0x52, 0x0, 0xc0, 0x4f, 0xd8, 0x5a, 0xb4);") cpp_quote("#define MIME_E_REG_CREATE_KEY 0x800cce01") cpp_quote("#define MIME_E_REG_QUERY_INFO 0x800cce02") @@ -40,9 +42,19 @@ cpp_quote("#define MIME_E_BOUNDARY_MISMATCH 0x800cce04") cpp_quote("#define MIME_E_NOT_FOUND 0x800cce05") cpp_quote("#define MIME_E_NO_DATA 0x800cce05") cpp_quote("#define MIME_E_BUFFER_TOO_SMALL 0x800cce06") +cpp_quote("#define MIME_E_INVALID_ITEM_FLAGS 0x800cce07") +cpp_quote("#define MIME_E_ONE_LINE_ITEME 0x800cce08") +cpp_quote("#define MIME_E_INVALID_HANDLE 0x800cce09") +cpp_quote("#define MIME_E_CHARSET_TRANSLATE 0x800cce0a") +cpp_quote("#define MIME_E_NOT_INITIALIZED 0x800cce0b") + +cpp_quote("#define MIME_E_INVALID_CHARSET_TYPE 0x800cce31") cpp_quote("#define MIME_E_INVALID_TEXT_TYPE 0x800cce38") +cpp_quote("#define MIME_E_SECURITY_NOOP 0x800cceb1") +cpp_quote("#define MIME_S_SECURITY_NOOP 0x000cceb1") + cpp_quote("typedef enum tagMIMEPROPID {") cpp_quote(" PID_HDR_NEWSGROUP = 2,") cpp_quote(" PID_HDR_NEWSGROUPS = 3,") @@ -78,7 +90,14 @@ cpp_quote(" PID_HDR_SENDER = 61,") cpp_quote(" PID_HDR_INREPLYTO = 77,") cpp_quote("} MIMEPROPID;") +cpp_quote("#define TYPEDID_MASK ((ULONG)0xffff)") +cpp_quote("#define TYPEDID_TYPE(t) ((VARTYPE)((t) & TYPEDID_MASK))") + +cpp_quote("#define OID_HIDE_TNEF_ATTACHMENTS (0x000e0000 | VT_BOOL)") +cpp_quote("#define OID_SECURITY_TYPE (0x00180000 | VT_UI4)") +cpp_quote("#define OID_SECURITY_HWND_OWNER (0x00320000 | VT_UI4)") cpp_quote("#define OID_HEADER_RELOAD_TYPE (0x00370000 | VT_UI4)") +cpp_quote("#define OID_SHOW_MACBINARY (0x00390000 | VT_BOOL)") [ @@ -235,6 +254,9 @@ library MIMEOLE HRESULT GetCodePageInfo( [in] CODEPAGEID cpiCodePage, [in, out] LPCODEPAGEINFO pCodePageInfo); + HRESULT CanConvertCodePages( + [in] CODEPAGEID cpiSource, + [in] CODEPAGEID cpiDest); HRESULT DecodeHeader( [in] HCHARSET hCharset, [in] LPCSTR pszData, @@ -256,22 +278,22 @@ library MIMEOLE [in] CODEPAGEID cpiDest, [in] LPPROPVARIANT pIn, [in, out] LPPROPVARIANT pOut); - HRESULT MLANG_ConvertInetReset(); + HRESULT MLANG_ConvertInetReset(void); HRESULT MLANG_ConvertInetString( [in] CODEPAGEID cpiSource, [in] CODEPAGEID cpiDest, [in] LPCSTR pSource, [in] int *pnSizeOfSource, - [out] LPSTR pDestination, + [in,out,unique] LPSTR pDestination, [in] int *pnDstSize); HRESULT Rfc1522Decode( [in] LPCSTR pszValue, - [in] LPCSTR pszCharset, + [in,ref] LPSTR pszCharset, [in] ULONG cchmax, [out] LPSTR *ppszDecoded); HRESULT Rfc1522Encode( [in] LPCSTR pszValue, - [in] HCHARSET hCharset, + [in] HCHARSET hCharset, [out] LPSTR *ppszEncoded); } @@ -293,6 +315,19 @@ library MIMEOLE typedef BLOB THUMBBLOB; typedef void *HCAPICERTSTORE; + cpp_quote("#define MST_NONE 0x00000000") + cpp_quote("#define MST_THIS_SIGN 0x00000001") + cpp_quote("#define MST_THIS_ENCRYPT 0x00000002") + cpp_quote("#define MST_BLOB_FLAG 0x00000004") + cpp_quote("#define MST_THIS_BLOBSIGN (MST_BLOB_FLAG | MST_THIS_SIGN)") + cpp_quote("#define MST_CHILD_SIGN 0x00000100") + cpp_quote("#define MST_CHILD_ENCRYPT 0x00000200") + cpp_quote("#define MST_SUBMSG_SIGN 0x00001000") + cpp_quote("#define MST_SUBMSG_ENCRYPT 0x00002000") + cpp_quote("#define MST_RECEIPT_REQUEST 0x00010000") + cpp_quote("#define MST_CLASS_SMIME_V1 0x00000000") + cpp_quote("#define MST_CLASS_PGP 0x01000000") + typedef enum tagCERTSTATE { CERTIFICATE_OK, @@ -1041,6 +1076,8 @@ cpp_quote("#endif") ] interface IMimeEnumProperties : IUnknown { + typedef [unique] IMimeEnumProperties *LPMIMEENUMPROPERTIES; + typedef struct tagENUMPROPERTY { LPSTR pszName; @@ -1048,7 +1085,22 @@ cpp_quote("#endif") DWORD dwPropId; } ENUMPROPERTY, *LPENUMPROPERTY; - /* FIXME: fill this in */ + HRESULT Next( + [in] ULONG cFetch, + [in, out] LPENUMPROPERTY prgProp, + [out] ULONG *pcFetched); + + HRESULT Skip( + [in] ULONG cItems); + + HRESULT Reset(void); + + HRESULT Clone( + [out] IMimeEnumProperties **ppEnum); + + HRESULT Count( + [out] ULONG *pcItems); + } [ @@ -1164,6 +1216,31 @@ cpp_quote("#endif") { /* FIXME: fill this in */ } + + [ + uuid(ba715ae0-a740-11d2-8b22-0080c76b34c6), + local + ] + interface IMimeSecurityCallback : IUnknown + { + /* FIXME: fill this in */ + + cpp_quote("#define CMS_RECIPIENT_INFO_TYPE_UNKNOWN 0") + cpp_quote("#define CMS_RECIPIENT_INFO_TYPE_KEYTRANS 1") + cpp_quote("#define CMS_RECIPIENT_INFO_TYPE_KEYAGREE 2") + cpp_quote("#define CMS_RECIPIENT_INFO_TYPE_MAIL_LIST 3") + + cpp_quote("#define CMS_RECIPIENT_INFO_PUBKEY_CERTIFICATE 0") + cpp_quote("#define CMS_RECIPIENT_INFO_PUBKEY_KEYTRANS 1") + cpp_quote("#define CMS_RECIPIENT_INFO_PUBKEY_PROVIDER 2") + cpp_quote("#define CMS_RECIPIENT_INFO_PUBKEY_EPHEMERAL_KEYAGREE 3") + cpp_quote("#define CMS_RECIPIENT_INFO_PUBKEY_STATIC_KEYAGREE 4") + + cpp_quote("#define CMS_RECIPIENT_INFO_KEYID_CERTIFICATE 0") + cpp_quote("#define CMS_RECIPIENT_INFO_KEYID_ISSUERSERIAL 1") + cpp_quote("#define CMS_RECIPIENT_INFO_KEYID_KEY_ID 2") + + } } cpp_quote("#ifdef __cplusplus")