4 * Copyright 2008 Hans Leidekker for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/debug.h"
34 #include "inetcomm_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(inetcomm);
40 InternetTransport InetTransport;
46 static HRESULT POP3Transport_ParseResponse(POP3Transport *This, char *pszResponse, POP3RESPONSE *pResponse)
48 TRACE("response: %s\n", debugstr_a(pszResponse));
50 pResponse->command = This->command;
51 pResponse->fDone = TRUE; /* FIXME */
53 if (!memcmp(pszResponse, "+OK", 3))
54 pResponse->rIxpResult.hrResult = S_OK;
56 pResponse->rIxpResult.hrResult = S_FALSE;
58 pResponse->rIxpResult.pszResponse = pszResponse;
59 pResponse->rIxpResult.uiServerError = 0;
60 pResponse->rIxpResult.hrServerError = pResponse->rIxpResult.hrResult;
61 pResponse->rIxpResult.dwSocketError = 0;
62 pResponse->pTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3;
63 pResponse->fValidInfo = FALSE; /* FIXME */
65 if (This->InetTransport.pCallback && This->InetTransport.fCommandLogging)
67 ITransportCallback_OnCommand(This->InetTransport.pCallback, CMD_RESP,
68 pResponse->rIxpResult.pszResponse, pResponse->rIxpResult.hrServerError,
69 (IInternetTransport *)&This->InetTransport.u.vtbl);
74 static void POP3Transport_CallbackProcessLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
76 POP3Transport *This = (POP3Transport *)iface;
77 POP3RESPONSE response;
82 hr = POP3Transport_ParseResponse(This, pBuffer, &response);
85 /* FIXME: handle error */
89 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
92 static void POP3Transport_CallbackRecvLISTResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
94 POP3Transport *This = (POP3Transport *)iface;
97 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessLISTResp);
100 static void POP3Transport_CallbackProcessUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
102 POP3Transport *This = (POP3Transport *)iface;
103 POP3RESPONSE response;
108 hr = POP3Transport_ParseResponse(This, pBuffer, &response);
111 /* FIXME: handle error */
115 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
118 static void POP3Transport_CallbackRecvUIDLResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
120 POP3Transport *This = (POP3Transport *)iface;
123 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUIDLResp);
126 static void POP3Transport_CallbackProcessSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
128 POP3Transport *This = (POP3Transport *)iface;
129 POP3RESPONSE response;
134 hr = POP3Transport_ParseResponse(This, pBuffer, &response);
137 /* FIXME: handle error */
141 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
144 static void POP3Transport_CallbackRecvSTATResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
146 POP3Transport *This = (POP3Transport *)iface;
149 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessSTATResp);
152 static void POP3Transport_CallbackProcessPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
154 POP3Transport *This = (POP3Transport *)iface;
155 POP3RESPONSE response;
160 hr = POP3Transport_ParseResponse(This, pBuffer, &response);
163 /* FIXME: handle error */
167 InternetTransport_ChangeStatus(&This->InetTransport, IXP_AUTHORIZED);
168 InternetTransport_ChangeStatus(&This->InetTransport, IXP_CONNECTED);
170 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
173 static void POP3Transport_CallbackRecvPASSResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
175 POP3Transport *This = (POP3Transport *)iface;
178 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessPASSResp);
181 static void POP3Transport_CallbackProcessUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
183 static char pass[] = "PASS ";
184 POP3Transport *This = (POP3Transport *)iface;
185 POP3RESPONSE response;
192 hr = POP3Transport_ParseResponse(This, pBuffer, &response);
195 /* FIXME: handle error */
199 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
201 len = sizeof(pass) + strlen(This->server.szPassword) + 2; /* "\r\n" */
202 command = HeapAlloc(GetProcessHeap(), 0, len);
204 strcpy(command, pass);
205 strcat(command, This->server.szPassword);
206 strcat(command, "\r\n");
208 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp);
209 HeapFree(GetProcessHeap(), 0, command);
212 static void POP3Transport_CallbackRecvUSERResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
214 POP3Transport *This = (POP3Transport *)iface;
217 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessUSERResp);
220 static void POP3Transport_CallbackSendUSERCmd(IInternetTransport *iface, char *pBuffer, int cbBuffer)
222 static char user[] = "USER ";
223 POP3Transport *This = (POP3Transport *)iface;
229 len = sizeof(user) + strlen(This->server.szUserName) + 2; /* "\r\n" */
230 command = HeapAlloc(GetProcessHeap(), 0, len);
232 strcpy(command, user);
233 strcat(command, This->server.szUserName);
234 strcat(command, "\r\n");
235 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp);
237 HeapFree(GetProcessHeap(), 0, command);
240 static void POP3Transport_CallbackProcessQUITResponse(IInternetTransport *iface, char *pBuffer, int cbBuffer)
242 POP3Transport *This = (POP3Transport *)iface;
243 POP3RESPONSE response;
246 TRACE("%s\n", debugstr_an(pBuffer, cbBuffer));
248 hr = POP3Transport_ParseResponse(This, pBuffer, &response);
251 /* FIXME: handle error */
255 IPOP3Callback_OnResponse((IPOP3Callback *)This->InetTransport.pCallback, &response);
256 InternetTransport_DropConnection(&This->InetTransport);
259 static void POP3Transport_CallbackRecvQUITResp(IInternetTransport *iface, char *pBuffer, int cbBuffer)
261 POP3Transport *This = (POP3Transport *)iface;
264 InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackProcessQUITResponse);
267 static HRESULT WINAPI POP3Transport_QueryInterface(IPOP3Transport *iface, REFIID riid, void **ppv)
269 TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
271 if (IsEqualIID(riid, &IID_IUnknown) ||
272 IsEqualIID(riid, &IID_IInternetTransport) ||
273 IsEqualIID(riid, &IID_IPOP3Transport))
276 IUnknown_AddRef(iface);
280 FIXME("no interface for %s\n", debugstr_guid(riid));
281 return E_NOINTERFACE;
284 static ULONG WINAPI POP3Transport_AddRef(IPOP3Transport *iface)
286 POP3Transport *This = (POP3Transport *)iface;
287 return InterlockedIncrement((LONG *)&This->refs);
290 static ULONG WINAPI POP3Transport_Release(IPOP3Transport *iface)
292 POP3Transport *This = (POP3Transport *)iface;
293 ULONG refs = InterlockedDecrement((LONG *)&This->refs);
296 TRACE("destroying %p\n", This);
297 if (This->InetTransport.Status != IXP_DISCONNECTED)
298 InternetTransport_DropConnection(&This->InetTransport);
299 if (This->InetTransport.pCallback) ITransportCallback_Release(This->InetTransport.pCallback);
300 HeapFree(GetProcessHeap(), 0, This);
305 static HRESULT WINAPI POP3Transport_GetServerInfo(IPOP3Transport *iface,
306 LPINETSERVER pInetServer)
308 POP3Transport *This = (POP3Transport *)iface;
310 TRACE("(%p)\n", pInetServer);
311 return InternetTransport_GetServerInfo(&This->InetTransport, pInetServer);
314 static IXPTYPE WINAPI POP3Transport_GetIXPType(IPOP3Transport *iface)
320 static HRESULT WINAPI POP3Transport_IsState(IPOP3Transport *iface, IXPISSTATE isstate)
322 FIXME("(%u)\n", isstate);
326 static HRESULT WINAPI POP3Transport_InetServerFromAccount(
327 IPOP3Transport *iface, IImnAccount *pAccount, LPINETSERVER pInetServer)
329 POP3Transport *This = (POP3Transport *)iface;
331 TRACE("(%p, %p)\n", pAccount, pInetServer);
332 return InternetTransport_InetServerFromAccount(&This->InetTransport, pAccount, pInetServer);
335 static HRESULT WINAPI POP3Transport_Connect(IPOP3Transport *iface,
336 LPINETSERVER pInetServer, boolean fAuthenticate, boolean fCommandLogging)
338 POP3Transport *This = (POP3Transport *)iface;
341 TRACE("(%p, %s, %s)\n", pInetServer, fAuthenticate ? "TRUE" : "FALSE", fCommandLogging ? "TRUE" : "FALSE");
343 hr = InternetTransport_Connect(&This->InetTransport, pInetServer, fAuthenticate, fCommandLogging);
347 This->command = POP3_USER;
348 This->server = *pInetServer;
349 return InternetTransport_ReadLine(&This->InetTransport, POP3Transport_CallbackSendUSERCmd);
352 static HRESULT WINAPI POP3Transport_HandsOffCallback(IPOP3Transport *iface)
354 POP3Transport *This = (POP3Transport *)iface;
357 return InternetTransport_HandsOffCallback(&This->InetTransport);
360 static HRESULT WINAPI POP3Transport_Disconnect(IPOP3Transport *iface)
363 return IPOP3Transport_CommandQUIT(iface);
366 static HRESULT WINAPI POP3Transport_DropConnection(IPOP3Transport *iface)
368 POP3Transport *This = (POP3Transport *)iface;
371 return InternetTransport_DropConnection(&This->InetTransport);
374 static HRESULT WINAPI POP3Transport_GetStatus(IPOP3Transport *iface,
375 IXPSTATUS *pCurrentStatus)
377 POP3Transport *This = (POP3Transport *)iface;
380 return InternetTransport_GetStatus(&This->InetTransport, pCurrentStatus);
383 static HRESULT WINAPI POP3Transport_InitNew(IPOP3Transport *iface,
384 LPSTR pszLogFilePath, IPOP3Callback *pCallback)
386 POP3Transport *This = (POP3Transport *)iface;
388 TRACE("(%s, %p)\n", debugstr_a(pszLogFilePath), pCallback);
394 FIXME("not using log file of %s, use Wine debug logging instead\n",
395 debugstr_a(pszLogFilePath));
397 IPOP3Callback_AddRef(pCallback);
398 This->InetTransport.pCallback = (ITransportCallback *)pCallback;
399 This->InetTransport.fInitialised = TRUE;
404 static HRESULT WINAPI POP3Transport_MarkItem(IPOP3Transport *iface, POP3MARKTYPE marktype,
405 DWORD dwPopId, boolean fMarked)
407 FIXME("(%u, %u, %d)\n", marktype, dwPopId, fMarked);
411 static HRESULT WINAPI POP3Transport_CommandAUTH(IPOP3Transport *iface, LPSTR pszAuthType)
413 FIXME("(%s)\n", pszAuthType);
417 static HRESULT WINAPI POP3Transport_CommandUSER(IPOP3Transport *iface, LPSTR username)
419 FIXME("(%s)\n", username);
423 static HRESULT WINAPI POP3Transport_CommandPASS(IPOP3Transport *iface, LPSTR password)
425 FIXME("(%s)\n", password);
429 static HRESULT WINAPI POP3Transport_CommandLIST(
430 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
432 static char list[] = "LIST\r\n";
433 POP3Transport *This = (POP3Transport *)iface;
435 TRACE("(%u, %u)\n", cmdtype, dwPopId);
437 This->command = POP3_LIST;
438 InternetTransport_DoCommand(&This->InetTransport, list, POP3Transport_CallbackRecvLISTResp);
442 static HRESULT WINAPI POP3Transport_CommandTOP(
443 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId, DWORD cPreviewLines)
445 FIXME("(%u, %u, %u)\n", cmdtype, dwPopId, cPreviewLines);
449 static HRESULT WINAPI POP3Transport_CommandQUIT(IPOP3Transport *iface)
451 static char command[] = "QUIT\r\n";
452 POP3Transport *This = (POP3Transport *)iface;
456 This->command = POP3_QUIT;
457 return InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvQUITResp);
460 static HRESULT WINAPI POP3Transport_CommandSTAT(IPOP3Transport *iface)
462 static char stat[] = "STAT\r\n";
463 POP3Transport *This = (POP3Transport *)iface;
467 This->command = POP3_STAT;
468 InternetTransport_DoCommand(&This->InetTransport, stat, POP3Transport_CallbackRecvSTATResp);
472 static HRESULT WINAPI POP3Transport_CommandNOOP(IPOP3Transport *iface)
478 static HRESULT WINAPI POP3Transport_CommandRSET(IPOP3Transport *iface)
484 static HRESULT WINAPI POP3Transport_CommandUIDL(
485 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
487 static char uidl[] = "UIDL\r\n";
488 POP3Transport *This = (POP3Transport *)iface;
490 TRACE("(%u, %u)\n", cmdtype, dwPopId);
492 This->command = POP3_UIDL;
493 InternetTransport_DoCommand(&This->InetTransport, uidl, POP3Transport_CallbackRecvUIDLResp);
497 static HRESULT WINAPI POP3Transport_CommandDELE(
498 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
500 FIXME("(%u, %u)\n", cmdtype, dwPopId);
504 static HRESULT WINAPI POP3Transport_CommandRETR(
505 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
507 FIXME("(%u, %u)\n", cmdtype, dwPopId);
511 static const IPOP3TransportVtbl POP3TransportVtbl =
513 POP3Transport_QueryInterface,
514 POP3Transport_AddRef,
515 POP3Transport_Release,
516 POP3Transport_GetServerInfo,
517 POP3Transport_GetIXPType,
518 POP3Transport_IsState,
519 POP3Transport_InetServerFromAccount,
520 POP3Transport_Connect,
521 POP3Transport_HandsOffCallback,
522 POP3Transport_Disconnect,
523 POP3Transport_DropConnection,
524 POP3Transport_GetStatus,
525 POP3Transport_InitNew,
526 POP3Transport_MarkItem,
527 POP3Transport_CommandAUTH,
528 POP3Transport_CommandUSER,
529 POP3Transport_CommandPASS,
530 POP3Transport_CommandLIST,
531 POP3Transport_CommandTOP,
532 POP3Transport_CommandQUIT,
533 POP3Transport_CommandSTAT,
534 POP3Transport_CommandNOOP,
535 POP3Transport_CommandRSET,
536 POP3Transport_CommandUIDL,
537 POP3Transport_CommandDELE,
538 POP3Transport_CommandRETR
541 HRESULT WINAPI CreatePOP3Transport(IPOP3Transport **ppTransport)
544 POP3Transport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
546 return E_OUTOFMEMORY;
548 This->InetTransport.u.vtblPOP3 = &POP3TransportVtbl;
550 hr = InternetTransport_Init(&This->InetTransport);
553 HeapFree(GetProcessHeap(), 0, This);
557 *ppTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3;
558 IPOP3Transport_AddRef(*ppTransport);
563 static HRESULT WINAPI POP3TransportCF_QueryInterface(LPCLASSFACTORY iface,
564 REFIID riid, LPVOID *ppv)
567 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
570 IUnknown_AddRef(iface);
573 return E_NOINTERFACE;
576 static ULONG WINAPI POP3TransportCF_AddRef(LPCLASSFACTORY iface)
578 return 2; /* non-heap based object */
581 static ULONG WINAPI POP3TransportCF_Release(LPCLASSFACTORY iface)
583 return 1; /* non-heap based object */
586 static HRESULT WINAPI POP3TransportCF_CreateInstance(LPCLASSFACTORY iface,
587 LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
590 IPOP3Transport *pPop3Transport;
592 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
597 return CLASS_E_NOAGGREGATION;
599 hr = CreatePOP3Transport(&pPop3Transport);
603 hr = IPOP3Transport_QueryInterface(pPop3Transport, riid, ppv);
604 IPOP3Transport_Release(pPop3Transport);
609 static HRESULT WINAPI POP3TransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
611 FIXME("(%d)\n",fLock);
615 static const IClassFactoryVtbl POP3TransportCFVtbl =
617 POP3TransportCF_QueryInterface,
618 POP3TransportCF_AddRef,
619 POP3TransportCF_Release,
620 POP3TransportCF_CreateInstance,
621 POP3TransportCF_LockServer
623 static const IClassFactoryVtbl *POP3TransportCF = &POP3TransportCFVtbl;
625 HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv)
627 return IClassFactory_QueryInterface((IClassFactory *)&POP3TransportCF, riid, ppv);