Support unrar64.dll
[xy_vsfilter.git] / include / atl / atlsmtputil.h
blob6ce443861d87a9474a71b3db02f55c2f95a56bd8
1 // This is a part of the Active Template Library.
2 // Copyright (C) Microsoft Corporation
3 // All rights reserved.
4 //
5 // This source code is only intended as a supplement to the
6 // Active Template Library Reference and related
7 // electronic documentation provided with the library.
8 // See these sources for detailed information regarding the
9 // Active Template Library product.
11 #ifndef __ATLSMTPUTIL_H__
12 #define __ATLSMTPUTIL_H__
14 #pragma once
16 #if (defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_))
17 #error <atlsmtputil.h> requires <winsock2.h> -- include <winsock2.h> before you include <windows.h> or <winsock.h>
18 #endif
19 #include <winsock2.h>
20 #include <windows.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <tchar.h>
24 #include <atlstr.h>
25 #include <winnls.h>
26 #include <atlspriv.h>
28 //=======================================================================
29 //defines for SMTPMail module
30 //=======================================================================
32 //If overlapped I/O is desired, need 2.0 or greater
33 #define ATLSMTP_WSA_VERSION ATL_WINSOCK_VER
35 //The maximum number of characters on a SMTP line
36 #define ATLSMTP_MAX_LINE_LENGTH 1000
38 #define ATLSMTP_MAX_SERVER_NAME_LENGTH 256
40 //Encoding schemes
41 #define ATLSMTP_BASE64_ENCODE 0
42 #define ATLSMTP_UUENCODE 1
43 #define ATLSMTP_QP_ENCODE 2
45 //I/O Defines
46 #define ATLSMTP_READBUFFER_SIZE 4096
47 #define ATLSMTP_GET_LINES 100
50 //Miscellaneous defines
51 #define ATLSMTP_SEND_FILE 1
52 #define ATLSMTP_FORMAT_SMTP 8
54 #define ATLSMTP_RETCODE_LEN 3
57 #pragma pack(push,_ATL_PACKING)
58 namespace ATL
61 //=======================================================================
62 // Miscellaneous Utility Functions
63 //=======================================================================
64 //A list of recipients in a string must by separated by one
65 //of the following characters
66 inline BOOL AtlSmtpIsRecipientDelimiter(char ch) throw()
68 return (ch == ',' || ch == ';' || ch == ' ' || ch == '\0');
71 //Send data to hFile and wait for it to finish sending
72 inline BOOL AtlSmtpSendAndWait(HANDLE hFile, LPCSTR lpData, int nDataLength, LPOVERLAPPED pOverlapped) throw()
74 ATLASSERT(lpData != NULL);
75 ATLENSURE_RETURN_VAL(pOverlapped != NULL, FALSE);
77 DWORD dwWritten = 0, dwErr = 0;
78 int nRet = 0, nBufPos = 0;
80 //write all the data
81 do
83 //Write a chunk of data, offsetting the buffer and amount to write by what's already
84 //been written
85 nRet = WriteFile(hFile, (void*)(lpData+nBufPos), nDataLength-nBufPos, &dwWritten, pOverlapped);
86 if (!nRet && (dwErr = GetLastError()) != ERROR_IO_INCOMPLETE && dwErr != ERROR_IO_PENDING)
87 return FALSE;
89 //Get the result of the write operation (wait for it)
90 nRet = GetOverlappedResult(hFile, pOverlapped, &dwWritten, TRUE);
91 if (!nRet)
92 return FALSE;
94 //Need to update offsets when writing to a file
95 pOverlapped->Offset += dwWritten;
96 nBufPos += dwWritten;
98 } while (nBufPos < nDataLength);
99 return TRUE;
103 //Read up to nDestLen bytes from hFile, keep reading while there's more data and there's
104 //room in the buffer
105 inline BOOL AtlSmtpReadData(__in HANDLE hFile, __out_ecount_part_z(*pnDestLen, *pnDestLen) LPSTR lpData, __inout int* pnDestLen, __in LPOVERLAPPED pOverlapped)
107 ATLASSERT(lpData != NULL);
108 ATLASSERT(pnDestLen != NULL);
109 ATLENSURE(pOverlapped != NULL);
111 DWORD dwRead = 0, dwErr = 0;
112 int nBufPos = 0;
115 //REad a chunk of data, offsetting the buffer and amount to read by what's already been read
116 int nRet = ReadFile(hFile, (void*)(lpData+nBufPos), (*pnDestLen)-nBufPos, &dwRead, pOverlapped);
117 if (!nRet && (dwErr = GetLastError()) != ERROR_MORE_DATA && dwErr != ERROR_IO_PENDING && dwErr != ERROR_IO_INCOMPLETE)
118 return FALSE;
120 //Get the result of the read operation (wait for it)
121 nRet = GetOverlappedResult(hFile, pOverlapped, &dwRead, TRUE);
122 if (!nRet)
123 return FALSE;
125 //Handle offsets when reading from a file
126 pOverlapped->Offset += dwRead;
127 nBufPos += dwRead;
128 } while (nBufPos < *pnDestLen && dwErr == ERROR_MORE_DATA);
129 *pnDestLen = nBufPos;
130 return TRUE;
134 //Used in sending encoded data
135 //lpData is the data to be sent now
136 //lpPrev is a pointer to the buffer that the previous call was made on
137 //This allows the new buffer (lpData) to be filled while lpPrev is being sent
138 //If all the data in lpPrev had not finished sending, we complete the send and wait
139 inline BOOL AtlSmtpSendOverlapped(HANDLE hFile, LPCSTR lpData, int nDataLength, LPCSTR lpPrev, DWORD dwPrevLength, LPOVERLAPPED pOverlapped)
141 ATLASSERT(lpData != NULL);
142 ATLENSURE(pOverlapped != NULL);
144 DWORD dwWritten = 0, dwErr = 0, dwBufPos = 0;
145 int nRet = 0;
147 //Get the results of the previous call (if any)
148 if (lpPrev && (!GetOverlappedResult(hFile, pOverlapped, &dwWritten, FALSE) || dwWritten < dwPrevLength))
150 //If any error but IO_INCOMPLETE, return failure
151 if ((dwErr = GetLastError()) != ERROR_SUCCESS && dwErr != ERROR_IO_INCOMPLETE && dwErr != ERROR_IO_PENDING)
153 return FALSE;
155 //Finish writing lpPrev if we need to
156 while (dwBufPos < dwPrevLength)
158 //Get the result of the previous write (wait for it)
159 nRet = GetOverlappedResult(hFile, pOverlapped, &dwWritten, TRUE);
160 if (!nRet || (dwBufPos += dwWritten) == dwPrevLength)
162 if ((dwErr = GetLastError()) != ERROR_IO_INCOMPLETE && dwErr != ERROR_IO_PENDING)
163 break;
166 //If we are writing to a file, we need to update the offsets
167 pOverlapped->Offset += dwWritten;
168 if(dwBufPos>dwPrevLength)
170 /* shouldn't happen */
171 ATLASSERT(false);
172 break;
174 nRet = WriteFile(hFile, (void*)(lpPrev+dwBufPos), dwPrevLength-dwBufPos, &dwWritten, pOverlapped);
176 //If any error but IO_PENDING and IO_INCOMPLETE, break
177 if (!nRet && (dwErr = GetLastError()) != ERROR_IO_PENDING && dwErr != ERROR_IO_INCOMPLETE)
178 break;
180 if (dwBufPos < dwPrevLength)
181 return FALSE;
184 //Now that all the previous data has been sent, start sending the current data
185 nRet = WriteFile(hFile, (void*)lpData, nDataLength, &dwWritten, pOverlapped);
186 GetOverlappedResult(hFile, pOverlapped, &dwWritten, FALSE);
188 pOverlapped->Offset += dwWritten;
190 //If any error but IO_PENDING
191 if (!nRet && (dwErr = GetLastError()) != ERROR_IO_PENDING && dwErr != ERROR_IO_INCOMPLETE)
192 return FALSE;
193 return TRUE;
197 //Send a SMTP command and read the response
198 //return TRUE if it matches szResponse, FALSE otherwise
199 inline BOOL AtlSmtpSendAndCheck(__in HANDLE hFile, __in LPCSTR lpData, __in int nDataLength, __out_ecount_part(nMaxResponseLength, *pnResponseLength) LPSTR lpResponse, __out int* pnResponseLength, __in int nMaxResponseLength,
200 __in_z LPCSTR szResponse, __in LPOVERLAPPED pOverlapped) throw()
202 ATLASSERT(lpData != NULL);
203 ATLASSERT(lpResponse != NULL);
204 ATLASSERT(pnResponseLength != NULL);
206 BOOL bRet = AtlSmtpSendAndWait(hFile, lpData, nDataLength, pOverlapped);
207 if (bRet)
209 *pnResponseLength = nMaxResponseLength;
210 bRet = AtlSmtpReadData(hFile, lpResponse, pnResponseLength, pOverlapped);
212 if (!bRet || strncmp((char*)lpResponse, szResponse, ATLSMTP_RETCODE_LEN))
213 return FALSE;
214 return TRUE;
217 } // namespace ATL
218 #pragma pack(pop)
220 #endif // __ATLSMTPUTIL_H__