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 static char user[] = "USER ";
420 POP3Transport *This = (POP3Transport *)iface;
424 TRACE("(%s)\n", username);
426 len = sizeof(user) + strlen(username) + 2; /* "\r\n" */
427 command = HeapAlloc(GetProcessHeap(), 0, len);
429 strcpy(command, user);
430 strcat(command, username);
431 strcat(command, "\r\n");
433 This->command = POP3_USER;
434 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvUSERResp);
436 HeapFree(GetProcessHeap(), 0, command);
440 static HRESULT WINAPI POP3Transport_CommandPASS(IPOP3Transport *iface, LPSTR password)
442 static char pass[] = "PASS ";
443 POP3Transport *This = (POP3Transport *)iface;
447 TRACE("(%p)\n", password);
449 len = sizeof(pass) + strlen(password) + 2; /* "\r\n" */
450 command = HeapAlloc(GetProcessHeap(), 0, len);
452 strcpy(command, pass);
453 strcat(command, password);
454 strcat(command, "\r\n");
456 This->command = POP3_PASS;
457 InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvPASSResp);
459 HeapFree(GetProcessHeap(), 0, command);
463 static HRESULT WINAPI POP3Transport_CommandLIST(
464 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
466 static char list[] = "LIST\r\n";
467 POP3Transport *This = (POP3Transport *)iface;
469 TRACE("(%u, %u)\n", cmdtype, dwPopId);
471 This->command = POP3_LIST;
472 InternetTransport_DoCommand(&This->InetTransport, list, POP3Transport_CallbackRecvLISTResp);
476 static HRESULT WINAPI POP3Transport_CommandTOP(
477 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId, DWORD cPreviewLines)
479 FIXME("(%u, %u, %u)\n", cmdtype, dwPopId, cPreviewLines);
483 static HRESULT WINAPI POP3Transport_CommandQUIT(IPOP3Transport *iface)
485 static char command[] = "QUIT\r\n";
486 POP3Transport *This = (POP3Transport *)iface;
490 This->command = POP3_QUIT;
491 return InternetTransport_DoCommand(&This->InetTransport, command, POP3Transport_CallbackRecvQUITResp);
494 static HRESULT WINAPI POP3Transport_CommandSTAT(IPOP3Transport *iface)
496 static char stat[] = "STAT\r\n";
497 POP3Transport *This = (POP3Transport *)iface;
501 This->command = POP3_STAT;
502 InternetTransport_DoCommand(&This->InetTransport, stat, POP3Transport_CallbackRecvSTATResp);
506 static HRESULT WINAPI POP3Transport_CommandNOOP(IPOP3Transport *iface)
512 static HRESULT WINAPI POP3Transport_CommandRSET(IPOP3Transport *iface)
518 static HRESULT WINAPI POP3Transport_CommandUIDL(
519 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
521 static char uidl[] = "UIDL\r\n";
522 POP3Transport *This = (POP3Transport *)iface;
524 TRACE("(%u, %u)\n", cmdtype, dwPopId);
526 This->command = POP3_UIDL;
527 InternetTransport_DoCommand(&This->InetTransport, uidl, POP3Transport_CallbackRecvUIDLResp);
531 static HRESULT WINAPI POP3Transport_CommandDELE(
532 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
534 FIXME("(%u, %u)\n", cmdtype, dwPopId);
538 static HRESULT WINAPI POP3Transport_CommandRETR(
539 IPOP3Transport *iface, POP3CMDTYPE cmdtype, DWORD dwPopId)
541 FIXME("(%u, %u)\n", cmdtype, dwPopId);
545 static const IPOP3TransportVtbl POP3TransportVtbl =
547 POP3Transport_QueryInterface,
548 POP3Transport_AddRef,
549 POP3Transport_Release,
550 POP3Transport_GetServerInfo,
551 POP3Transport_GetIXPType,
552 POP3Transport_IsState,
553 POP3Transport_InetServerFromAccount,
554 POP3Transport_Connect,
555 POP3Transport_HandsOffCallback,
556 POP3Transport_Disconnect,
557 POP3Transport_DropConnection,
558 POP3Transport_GetStatus,
559 POP3Transport_InitNew,
560 POP3Transport_MarkItem,
561 POP3Transport_CommandAUTH,
562 POP3Transport_CommandUSER,
563 POP3Transport_CommandPASS,
564 POP3Transport_CommandLIST,
565 POP3Transport_CommandTOP,
566 POP3Transport_CommandQUIT,
567 POP3Transport_CommandSTAT,
568 POP3Transport_CommandNOOP,
569 POP3Transport_CommandRSET,
570 POP3Transport_CommandUIDL,
571 POP3Transport_CommandDELE,
572 POP3Transport_CommandRETR
575 HRESULT WINAPI CreatePOP3Transport(IPOP3Transport **ppTransport)
578 POP3Transport *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
580 return E_OUTOFMEMORY;
582 This->InetTransport.u.vtblPOP3 = &POP3TransportVtbl;
584 hr = InternetTransport_Init(&This->InetTransport);
587 HeapFree(GetProcessHeap(), 0, This);
591 *ppTransport = (IPOP3Transport *)&This->InetTransport.u.vtblPOP3;
592 IPOP3Transport_AddRef(*ppTransport);
597 static HRESULT WINAPI POP3TransportCF_QueryInterface(LPCLASSFACTORY iface,
598 REFIID riid, LPVOID *ppv)
601 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
604 IUnknown_AddRef(iface);
607 return E_NOINTERFACE;
610 static ULONG WINAPI POP3TransportCF_AddRef(LPCLASSFACTORY iface)
612 return 2; /* non-heap based object */
615 static ULONG WINAPI POP3TransportCF_Release(LPCLASSFACTORY iface)
617 return 1; /* non-heap based object */
620 static HRESULT WINAPI POP3TransportCF_CreateInstance(LPCLASSFACTORY iface,
621 LPUNKNOWN pUnk, REFIID riid, LPVOID *ppv)
624 IPOP3Transport *pPop3Transport;
626 TRACE("(%p, %s, %p)\n", pUnk, debugstr_guid(riid), ppv);
631 return CLASS_E_NOAGGREGATION;
633 hr = CreatePOP3Transport(&pPop3Transport);
637 hr = IPOP3Transport_QueryInterface(pPop3Transport, riid, ppv);
638 IPOP3Transport_Release(pPop3Transport);
643 static HRESULT WINAPI POP3TransportCF_LockServer(LPCLASSFACTORY iface, BOOL fLock)
645 FIXME("(%d)\n",fLock);
649 static const IClassFactoryVtbl POP3TransportCFVtbl =
651 POP3TransportCF_QueryInterface,
652 POP3TransportCF_AddRef,
653 POP3TransportCF_Release,
654 POP3TransportCF_CreateInstance,
655 POP3TransportCF_LockServer
657 static const IClassFactoryVtbl *POP3TransportCF = &POP3TransportCFVtbl;
659 HRESULT POP3TransportCF_Create(REFIID riid, LPVOID *ppv)
661 return IClassFactory_QueryInterface((IClassFactory *)&POP3TransportCF, riid, ppv);