#include "csmtp.h"\r
#include "registry.h"\r
#include "unicodeutils.h"\r
+#include "hwsmtp.h"\r
+#include "Windns.h"\r
\r
CPatch::CPatch()\r
{\r
if(this->Parser(pathfile) )\r
return -1;\r
\r
+ int at=TO.Find(_T('@'));\r
+ int start =0;\r
+ TO = TO.Tokenize(_T(";"),start);\r
\r
+ CString server=TO.Mid(at+1);\r
+\r
+ PDNS_RECORD pDnsRecord; \r
+\r
+ DnsQuery(server, DNS_TYPE_MX,DNS_QUERY_BYPASS_CACHE,\r
+ NULL, //Contains DNS server IP address.\r
+ &pDnsRecord, //Resource record that contains the response.\r
+ NULL); \r
+\r
+ CString name,address;\r
+ GetNameAddress(this->m_Author,name,address);\r
+\r
+\r
+ SendEmail(FALSE,pDnsRecord->Data.MX.pNameExchange,\r
+ NULL,NULL,FALSE,address,TO,this->m_Author,TO,this->m_Subject,_T("Test"));\r
+ \r
+ DnsRecordListFree(pDnsRecord,DnsFreeRecordList);\r
+\r
+#if 0\r
CRegString server(REG_SMTP_SERVER);\r
CRegDWORD port(REG_SMTP_PORT,25);\r
CRegDWORD bAuth(REG_SMTP_ISAUTH);\r
}\r
\r
return !mail.Send();\r
+#endif\r
+\r
\r
}\r
\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
+ AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib Dnsapi.lib"\r
LinkIncremental="2"\r
AdditionalLibraryDirectories=""\r
IgnoreDefaultLibraryNames=""\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
+ AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib Dnsapi.lib"\r
LinkIncremental="2"\r
IgnoreDefaultLibraryNames=""\r
DelayLoadDLLs="gdiplus.dll"\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
+ AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib Dnsapi.lib"\r
LinkIncremental="1"\r
AdditionalLibraryDirectories="../../ext/wingit"\r
IgnoreDefaultLibraryNames=""\r
/>\r
<Tool\r
Name="VCLinkerTool"\r
- AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib"\r
+ AdditionalDependencies="Crypt32.lib gdiplus.lib shfolder.lib shell32.lib comctl32.lib ws2_32.lib rpcrt4.lib shlwapi.lib wininet.lib version.lib Dnsapi.lib"\r
LinkIncremental="1"\r
IgnoreDefaultLibraryNames=""\r
DelayLoadDLLs="gdiplus.dll"\r
>\r
</File>\r
<File\r
- RelativePath=".\copy.ico"\r
+ RelativePath="..\Resources\copy.ico"\r
>\r
</File>\r
<File\r
- RelativePath="..\Resources\copy.ico"\r
+ RelativePath=".\copy.ico"\r
>\r
</File>\r
<File\r
>\r
</File>\r
<File\r
- RelativePath="..\Resources\explorer.ico"\r
+ RelativePath=".\explorer.ico"\r
>\r
</File>\r
<File\r
- RelativePath=".\explorer.ico"\r
+ RelativePath="..\Resources\explorer.ico"\r
>\r
</File>\r
<File\r
>\r
</File>\r
<File\r
- RelativePath=".\newfolder.ico"\r
+ RelativePath="..\Resources\newfolder.ico"\r
>\r
</File>\r
<File\r
- RelativePath="..\Resources\newfolder.ico"\r
+ RelativePath=".\newfolder.ico"\r
>\r
</File>\r
<File\r
>\r
</File>\r
<File\r
- RelativePath=".\refresh.ico"\r
+ RelativePath="..\Resources\refresh.ico"\r
>\r
</File>\r
<File\r
- RelativePath="..\Resources\refresh.ico"\r
+ RelativePath=".\refresh.ico"\r
>\r
</File>\r
<File\r
>\r
</File>\r
<File\r
- RelativePath="..\Resources\save.ico"\r
+ RelativePath=".\save.ico"\r
>\r
</File>\r
<File\r
- RelativePath=".\save.ico"\r
+ RelativePath="..\Resources\save.ico"\r
>\r
</File>\r
<File\r
>\r
</File>\r
<File\r
- RelativePath=".\up.ico"\r
+ RelativePath="..\Resources\up.ico"\r
>\r
</File>\r
<File\r
- RelativePath="..\Resources\up.ico"\r
+ RelativePath=".\up.ico"\r
>\r
</File>\r
<File\r
--- /dev/null
+// Base64.cpp: implementation of the CBase64 class.\r
+//\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "CBase64.h"\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// CBase64\r
+//////////////////////////////////////////////////////////////////////\r
+// Static Member Initializers\r
+//\r
+\r
+// The 7-bit alphabet used to encode binary information\r
+const char m_sBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";\r
+\r
+const int f_nMask[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };\r
+\r
+CBase64::CBase64()\r
+{\r
+ m_lBitStorage = 0;\r
+ m_nBitsRemaining = 0;\r
+ m_nInputSize = 0;\r
+ m_szInput = NULL;\r
+}\r
+\r
+CBase64::~CBase64()\r
+{\r
+}\r
+\r
+CStringA CBase64::Encode( IN const char* szEncoding, IN int nSize )\r
+{\r
+ CStringA sOutput = "";\r
+ int nNumBits = 6;\r
+ UINT nDigit;\r
+ int lp = 0;\r
+\r
+ ASSERT( szEncoding != NULL );\r
+ if( szEncoding == NULL )\r
+ return sOutput;\r
+ m_szInput = szEncoding;\r
+ m_nInputSize = nSize;\r
+\r
+ m_nBitsRemaining = 0;\r
+ nDigit = read_bits( nNumBits, &nNumBits, lp );\r
+ while( nNumBits > 0 )\r
+ {\r
+ sOutput += m_sBase64Alphabet[ (int)nDigit ];\r
+ nDigit = read_bits( nNumBits, &nNumBits, lp );\r
+ }\r
+ // Pad with '=' as per RFC 1521\r
+ while( sOutput.GetLength() % 4 != 0 )\r
+ {\r
+ sOutput += '=';\r
+ }\r
+ return sOutput;\r
+}\r
+\r
+// The size of the output buffer must not be less than\r
+// 3/4 the size of the input buffer. For simplicity,\r
+// make them the same size.\r
+// return : ½âÂëºóÊý¾Ý³¤¶È\r
+int CBase64::Decode ( IN const char* szDecoding, char* szOutput )\r
+{\r
+ CString sInput;\r
+ int c, lp =0;\r
+ int nDigit;\r
+ int nDecode[ 256 ];\r
+\r
+ ASSERT( szDecoding != NULL );\r
+ ASSERT( szOutput != NULL );\r
+ if( szOutput == NULL )\r
+ return 0;\r
+ if( szDecoding == NULL )\r
+ return 0;\r
+ sInput = szDecoding;\r
+ if( sInput.GetLength() == 0 )\r
+ return 0;\r
+\r
+ // Build Decode Table\r
+ //\r
+ int i;\r
+ for( i = 0; i < 256; i++ ) \r
+ nDecode[i] = -2; // Illegal digit\r
+ for( i=0; i < 64; i++ )\r
+ {\r
+ nDecode[ m_sBase64Alphabet[ i ] ] = i;\r
+ nDecode[ m_sBase64Alphabet[ i ] | 0x80 ] = i; // Ignore 8th bit\r
+ nDecode[ '=' ] = -1; \r
+ nDecode[ '=' | 0x80 ] = -1; // Ignore MIME padding char\r
+ }\r
+\r
+ // Clear the output buffer\r
+ memset( szOutput, 0, sInput.GetLength() + 1 );\r
+\r
+ // Decode the Input\r
+ //\r
+ for( lp = 0, i = 0; lp < sInput.GetLength(); lp++ )\r
+ {\r
+ c = sInput[ lp ];\r
+ nDigit = nDecode[ c & 0x7F ];\r
+ if( nDigit < -1 ) \r
+ {\r
+ return 0;\r
+ } \r
+ else if( nDigit >= 0 ) \r
+ // i (index into output) is incremented by write_bits()\r
+ write_bits( nDigit & 0x3F, 6, szOutput, i );\r
+ } \r
+ return i;\r
+}\r
+\r
+UINT CBase64::read_bits(int nNumBits, int * pBitsRead, int& lp)\r
+{\r
+ ULONG lScratch;\r
+ while( ( m_nBitsRemaining < nNumBits ) && \r
+ ( lp < m_nInputSize ) ) \r
+ {\r
+ int c = m_szInput[ lp++ ];\r
+ m_lBitStorage <<= 8;\r
+ m_lBitStorage |= (c & 0xff);\r
+ m_nBitsRemaining += 8;\r
+ }\r
+ if( m_nBitsRemaining < nNumBits ) \r
+ {\r
+ lScratch = m_lBitStorage << ( nNumBits - m_nBitsRemaining );\r
+ *pBitsRead = m_nBitsRemaining;\r
+ m_nBitsRemaining = 0;\r
+ } \r
+ else \r
+ {\r
+ lScratch = m_lBitStorage >> ( m_nBitsRemaining - nNumBits );\r
+ *pBitsRead = nNumBits;\r
+ m_nBitsRemaining -= nNumBits;\r
+ }\r
+ return (UINT)lScratch & f_nMask[nNumBits];\r
+}\r
+\r
+\r
+void CBase64::write_bits(UINT nBits,\r
+ int nNumBits,\r
+ LPSTR szOutput,\r
+ int& i)\r
+{\r
+ UINT nScratch;\r
+\r
+ m_lBitStorage = (m_lBitStorage << nNumBits) | nBits;\r
+ m_nBitsRemaining += nNumBits;\r
+ while( m_nBitsRemaining > 7 ) \r
+ {\r
+ nScratch = m_lBitStorage >> (m_nBitsRemaining - 8);\r
+ szOutput[ i++ ] = nScratch & 0xFF;\r
+ m_nBitsRemaining -= 8;\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+// HwSMTP.cpp: implementation of the CHwSMTP class.\r
+//\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "afxstr.h"\r
+#include "HwSMTP.h"\r
+#include "CBase64.h"\r
+#include "SpeedPostEmail.h"\r
+\r
+#include <Afxmt.h>\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+CPtrArray g_PtrAry_Threads;\r
+::CCriticalSection m_CSFor__g_PtrAry_Threads;\r
+\r
+class CEMailObject\r
+{\r
+public:\r
+ CEMailObject (\r
+ LPCTSTR lpszSmtpSrvHost,\r
+ LPCTSTR lpszUserName,\r
+ LPCTSTR lpszPasswd,\r
+ BOOL bMustAuth,\r
+ LPCTSTR lpszAddrFrom,\r
+ LPCTSTR lpszAddrTo,\r
+ LPCTSTR lpszSenderName,\r
+ LPCTSTR lpszReceiverName,\r
+ LPCTSTR lpszSubject,\r
+ LPCTSTR lpszBody,\r
+ LPCTSTR lpszCharSet,\r
+ CStringArray *pStrAryAttach,\r
+ CStringArray *pStrAryCC,\r
+ UINT nSmtpSrvPort\r
+ )\r
+ {\r
+ m_csSmtpSrvHost = GET_SAFE_STRING(lpszSmtpSrvHost);\r
+ m_csUserName = GET_SAFE_STRING(lpszUserName);\r
+ m_csPasswd = GET_SAFE_STRING(lpszPasswd);\r
+ m_bMustAuth = bMustAuth;\r
+ m_csAddrFrom = GET_SAFE_STRING(lpszAddrFrom);\r
+ m_csAddrTo = GET_SAFE_STRING(lpszAddrTo);\r
+ m_csSenderName = GET_SAFE_STRING(lpszSenderName);\r
+ m_csReceiverName = GET_SAFE_STRING(lpszReceiverName);\r
+ m_csSubject = GET_SAFE_STRING(lpszSubject);\r
+ m_csBody = GET_SAFE_STRING(lpszBody);\r
+ m_csCharSet = GET_SAFE_STRING(lpszCharSet);\r
+ if ( pStrAryAttach )\r
+ m_StrAryAttach.Append ( *pStrAryAttach );\r
+ if ( pStrAryCC )\r
+ m_StrAryCC.Append ( *pStrAryCC );\r
+ m_nSmtpSrvPort = nSmtpSrvPort;\r
+ m_hThread = NULL;\r
+ }\r
+\r
+public:\r
+ CString m_csSmtpSrvHost;\r
+ CString m_csUserName;\r
+ CString m_csPasswd;\r
+ BOOL m_bMustAuth;\r
+ CString m_csAddrFrom;\r
+ CString m_csAddrTo;\r
+ CString m_csSenderName;\r
+ CString m_csReceiverName;\r
+ CString m_csSubject;\r
+ CString m_csBody;\r
+ CString m_csCharSet;\r
+ CStringArray m_StrAryAttach;\r
+ CStringArray m_StrAryCC;\r
+ UINT m_nSmtpSrvPort;\r
+\r
+ HANDLE m_hThread;\r
+};\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CHwSMTP::CHwSMTP () :\r
+ m_bConnected ( FALSE ),\r
+ m_nSmtpSrvPort ( 25 ),\r
+ m_bMustAuth ( TRUE )\r
+{\r
+ m_csMIMEContentType = _T( "multipart/mixed");\r
+ m_csPartBoundary = _T( "WC_MAIL_PaRt_BoUnDaRy_05151998" );\r
+ m_csNoMIMEText = _T( "This is a multi-part message in MIME format." );\r
+// m_csCharSet = _T("\r\n\tcharset=\"iso-8859-1\"\r\n");\r
+}\r
+\r
+CHwSMTP::~CHwSMTP()\r
+{\r
+}\r
+\r
+BOOL CHwSMTP::SendEmail (\r
+ LPCTSTR lpszSmtpSrvHost,\r
+ LPCTSTR lpszUserName,\r
+ LPCTSTR lpszPasswd,\r
+ BOOL bMustAuth,\r
+ LPCTSTR lpszAddrFrom,\r
+ LPCTSTR lpszAddrTo,\r
+ LPCTSTR lpszSenderName,\r
+ LPCTSTR lpszReceiverName,\r
+ LPCTSTR lpszSubject,\r
+ LPCTSTR lpszBody,\r
+ LPCTSTR lpszCharSet, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"\r
+ CStringArray *pStrAryAttach/*=NULL*/,\r
+ CStringArray *pStrAryCC/*=NULL*/,\r
+ UINT nSmtpSrvPort/*=25*/\r
+ )\r
+{\r
+ TRACE ( _T("·¢ËÍÓʼþ£º%s, %s, %s\n"), lpszAddrTo, lpszReceiverName, lpszBody );\r
+ m_StrAryAttach.RemoveAll();\r
+ m_StrAryCC.RemoveAll();\r
+ m_csSmtpSrvHost = GET_SAFE_STRING ( lpszSmtpSrvHost );\r
+ if ( m_csSmtpSrvHost.GetLength() <= 0 )\r
+ {\r
+ m_csLastError.Format ( _T("Parameter Error!") );\r
+ return FALSE;\r
+ }\r
+ m_csUserName = GET_SAFE_STRING ( lpszUserName );\r
+ m_csPasswd = GET_SAFE_STRING ( lpszPasswd );\r
+ m_bMustAuth = bMustAuth;\r
+ if ( m_bMustAuth && m_csUserName.GetLength() <= 0 )\r
+ {\r
+ m_csLastError.Format ( _T("Parameter Error!") );\r
+ return FALSE;\r
+ }\r
+\r
+ m_csAddrFrom = GET_SAFE_STRING ( lpszAddrFrom );\r
+ m_csAddrTo = GET_SAFE_STRING ( lpszAddrTo );\r
+ m_csSenderName = GET_SAFE_STRING ( lpszSenderName );\r
+ m_csReceiverName = GET_SAFE_STRING ( lpszReceiverName );\r
+ m_csSubject = GET_SAFE_STRING ( lpszSubject );\r
+ m_csBody = GET_SAFE_STRING ( lpszBody );\r
+ m_nSmtpSrvPort = nSmtpSrvPort;\r
+ if ( lpszCharSet && lstrlen(lpszCharSet) > 0 )\r
+ m_csCharSet.Format ( _T("\r\n\tcharset=\"%s\"\r\n"), lpszCharSet );\r
+\r
+ if (\r
+ m_csAddrFrom.GetLength() <= 0 || m_csAddrTo.GetLength() <= 0 ||\r
+ m_csSenderName.GetLength() <= 0 || m_csReceiverName.GetLength() <= 0 ||\r
+ m_csSubject.GetLength() <= 0 || m_csBody.GetLength() <= 0\r
+ )\r
+ {\r
+ m_csLastError.Format ( _T("Parameter Error!") );\r
+ return FALSE;\r
+ }\r
+\r
+ if ( pStrAryAttach )\r
+ {\r
+ m_StrAryAttach.Append ( *pStrAryAttach );\r
+ }\r
+ if ( m_StrAryAttach.GetSize() < 1 )\r
+ m_csMIMEContentType = _T( "text/plain");\r
+\r
+ if ( pStrAryCC )\r
+ {\r
+ m_StrAryCC.Append ( *pStrAryCC );\r
+ } \r
+\r
+ // ´´½¨Socket\r
+ if ( !m_SendSock.Create () )\r
+ {\r
+ m_csLastError.Format ( _T("Create socket failed!") );\r
+ return FALSE;\r
+ }\r
+\r
+ // Á¬½Óµ½·þÎñÆ÷\r
+ if ( !m_SendSock.Connect ( m_csSmtpSrvHost, m_nSmtpSrvPort ) )\r
+ {\r
+ m_csLastError.Format ( _T("Connect to [ %s ] failed"), m_csSmtpSrvHost );\r
+ TRACE ( _T("%d\n"), GetLastError() );\r
+ return FALSE;\r
+ }\r
+ if ( !GetResponse( _T("220") ) ) return FALSE;\r
+\r
+ m_bConnected = TRUE;\r
+ return SendEmail();\r
+\r
+}\r
+\r
+\r
+BOOL CHwSMTP::GetResponse ( LPCTSTR lpszVerifyCode, int *pnCode/*=NULL*/)\r
+{\r
+ if ( !lpszVerifyCode || lstrlen(lpszVerifyCode) < 1 )\r
+ return FALSE;\r
+\r
+ char szRecvBuf[1024] = {0};\r
+ int nRet = 0;\r
+ char szStatusCode[4] = {0};\r
+ nRet = m_SendSock.Receive ( szRecvBuf, sizeof(szRecvBuf) );\r
+ TRACE ( _T("Received : %s\r\n"), szRecvBuf );\r
+ if ( nRet <= 0 )\r
+ {\r
+ m_csLastError.Format ( _T("Receive TCP data failed") );\r
+ return FALSE;\r
+ }\r
+// TRACE ( _T("ÊÕµ½·þÎñÆ÷»ØÓ¦£º%s\n"), szRecvBuf );\r
+\r
+ memcpy ( szStatusCode, szRecvBuf, 3 );\r
+ if ( pnCode ) (*pnCode) = atoi ( szStatusCode );\r
+\r
+ if ( strcmp ( szStatusCode, CMultiByteString(lpszVerifyCode).GetBuffer() ) != 0 )\r
+ {\r
+ m_csLastError.Format ( _T("Received invalid response : %s"), GetCompatibleString(szRecvBuf,FALSE) );\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+// ÀûÓÃsocket·¢ËÍÊý¾Ý£¬Êý¾Ý³¤¶È²»Äܳ¬¹ý10M\r
+BOOL CHwSMTP::Send(LPCTSTR lpszData, ... )\r
+{\r
+ if ( !m_bConnected )\r
+ {\r
+ m_csLastError.Format ( _T("Didn't connect") );\r
+ return FALSE;\r
+ }\r
+\r
+ TCHAR *buf = NULL;\r
+ // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ\r
+ for ( int nBufCount = 1024; nBufCount<10*1024*1024; nBufCount += 1024 )\r
+ {\r
+ buf = new TCHAR[nBufCount];\r
+ if ( !buf )\r
+ {\r
+ ::AfxThrowMemoryException ();\r
+ return FALSE;\r
+ }\r
+ memset ( buf, 0, nBufCount*sizeof(TCHAR) );\r
+\r
+ va_list va;\r
+ va_start (va, lpszData);\r
+ int nLen = _vsnprintf_hw ((TCHAR*)buf, nBufCount-sizeof(TCHAR), lpszData, va);\r
+ va_end(va);\r
+ if ( nLen <= (int)(nBufCount-sizeof(TCHAR)) )\r
+ break;\r
+ delete[] buf; buf = NULL;\r
+ }\r
+ if ( !buf )\r
+ {\r
+ m_csLastError.Format ( _T("Memory too small or data too big.") );\r
+ return FALSE;\r
+ }\r
+\r
+ CMultiByteString cbsData ( buf );\r
+ delete[] buf; buf = NULL;\r
+ TRACE ( _T("Send : %s\r\n"), cbsData.GetBuffer() );\r
+ if ( m_SendSock.Send ( cbsData.GetBuffer(), cbsData.GetLength() ) != cbsData.GetLength() )\r
+ {\r
+ m_csLastError.Format ( _T("Socket send data failed") );\r
+ return FALSE;\r
+ }\r
+ \r
+ return TRUE;\r
+}\r
+\r
+BOOL CHwSMTP::SendEmail()\r
+{\r
+ BOOL bRet = TRUE;\r
+ char szLocalHostName[64] = {0};\r
+ gethostname ( (char*)szLocalHostName, sizeof(szLocalHostName) );\r
+\r
+ // hello£¬ÎÕÊÖ\r
+ if ( !Send ( _T("HELO %s\r\n"), GetCompatibleString(szLocalHostName,FALSE) ) )\r
+ {\r
+ return FALSE;\r
+ }\r
+ if ( !GetResponse ( _T("250") ) )\r
+ {\r
+ return FALSE;\r
+ }\r
+ // Éí·ÝÑéÖ¤\r
+ if ( m_bMustAuth && !auth() )\r
+ {\r
+ return FALSE;\r
+ }\r
+ // ·¢ËÍÓʼþÍ·\r
+ if ( !SendHead() )\r
+ {\r
+ return FALSE;\r
+ }\r
+ // ·¢ËÍÓʼþÖ÷Ìâ\r
+ if ( !SendSubject() )\r
+ {\r
+ return FALSE;\r
+ }\r
+ // ·¢ËÍÓʼþÕýÎÄ\r
+ if ( !SendBody() )\r
+ {\r
+ return FALSE;\r
+ }\r
+ // ·¢Ë͸½¼þ\r
+ if ( !SendAttach() )\r
+ {\r
+ return FALSE;\r
+ }\r
+ // ½áÊøÓʼþÕýÎÄ\r
+ if ( !Send ( _T(".\r\n") ) ) return FALSE;\r
+ if ( !GetResponse ( _T("250") ) )\r
+ return FALSE;\r
+\r
+ // Í˳ö·¢ËÍ\r
+ if ( HANDLE_IS_VALID(m_SendSock.m_hSocket) )\r
+ Send ( _T("QUIT\r\n") );\r
+ m_bConnected = FALSE;\r
+\r
+ return bRet;\r
+}\r
+\r
+BOOL CHwSMTP::auth()\r
+{\r
+ int nResponseCode = 0;\r
+ if ( !Send ( _T("auth login\r\n") ) ) return FALSE;\r
+ if ( !GetResponse ( _T("334"), &nResponseCode ) ) return FALSE;\r
+ if ( nResponseCode != 334 ) // ²»ÐèÒªÑéÖ¤Óû§ÃûºÍÃÜÂë\r
+ return TRUE;\r
+ \r
+ CBase64 Base64Encode;\r
+ CMultiByteString cbsUserName ( m_csUserName ), cbsPasswd ( m_csPasswd );\r
+ CString csBase64_UserName = GetCompatibleString ( Base64Encode.Encode ( cbsUserName.GetBuffer(), cbsUserName.GetLength() ).GetBuffer(0), FALSE );\r
+ CString csBase64_Passwd = GetCompatibleString ( Base64Encode.Encode ( cbsPasswd.GetBuffer(), cbsPasswd.GetLength() ).GetBuffer(0), FALSE );\r
+\r
+ if ( !Send ( _T("%s\r\n"), csBase64_UserName ) ) return FALSE;\r
+ if ( !GetResponse ( _T("334") ) )\r
+ {\r
+ m_csLastError.Format ( _T("Authentication UserName failed") );\r
+ return FALSE;\r
+ }\r
+\r
+ if ( !Send ( _T("%s\r\n"), csBase64_Passwd ) ) return FALSE;\r
+ if ( !GetResponse ( _T("235") ) )\r
+ {\r
+ m_csLastError.Format ( _T("Authentication Password failed") );\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+BOOL CHwSMTP::SendHead()\r
+{\r
+ if ( !Send ( _T("MAIL From: <%s>\r\n"), m_csAddrFrom ) ) return FALSE;\r
+ if ( !GetResponse ( _T("250") ) ) return FALSE;\r
+ if ( !Send ( _T("RCPT TO: <%s>\r\n"), m_csAddrTo ) ) return FALSE;\r
+ if ( !GetResponse ( _T("250") ) ) return FALSE;\r
+\r
+ for ( int i=0; i<m_StrAryCC.GetSize(); i++ )\r
+ {\r
+ if ( !Send ( _T("RCPT TO: <%s>\r\n"), m_StrAryCC.GetAt(i) ) ) return FALSE;\r
+ if ( !GetResponse ( _T("250") ) ) return FALSE;\r
+ }\r
+ if ( !Send ( _T("DATA\r\n") ) ) return FALSE;\r
+ if ( !GetResponse ( _T("354") ) ) return FALSE; \r
+\r
+ return TRUE;\r
+}\r
+\r
+BOOL CHwSMTP::SendSubject()\r
+{\r
+ CString csSubject;\r
+ csSubject += _T("Date: ");\r
+ COleDateTime tNow = COleDateTime::GetCurrentTime();\r
+ if ( tNow > 1 )\r
+ {\r
+ csSubject += GetCompatibleString(FormatDateTime (tNow, _T("%a, %d %b %y %H:%M:%S %Z")).GetBuffer(0),FALSE);\r
+ }\r
+ csSubject += _T("\r\n");\r
+ csSubject += FormatString ( _T("From: %s\r\nTo: %s\r\n"), m_csSenderName, m_csReceiverName );\r
+ csSubject += FormatString ( _T("Subject: %s\r\n"), m_csSubject );\r
+ csSubject += FormatString ( _T("X-Mailer: chrys\r\nMIME-Version: 1.0\r\nContent-Type: %s; %s boundary=%s\r\n\r\n") , \r
+ m_csMIMEContentType, m_csCharSet, m_csPartBoundary );\r
+\r
+ return Send ( csSubject );\r
+}\r
+\r
+BOOL CHwSMTP::SendBody()\r
+{\r
+ CString csBody, csTemp;\r
+\r
+ if ( m_StrAryAttach.GetSize() > 0 )\r
+ {\r
+ csTemp.Format ( _T("%s\r\n\r\n"), m_csNoMIMEText );\r
+ csBody += csTemp;\r
+ \r
+ csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );\r
+ csBody += csTemp;\r
+ \r
+ csTemp.Format ( _T("Content-Type: text/plain\r\n%sContent-Transfer-Encoding: 7Bit\r\n\r\n"),\r
+ m_csCharSet );\r
+ csBody += csTemp;\r
+ }\r
+\r
+ csTemp.Format ( _T("%s\r\n"), m_csBody );\r
+ csBody += csTemp;\r
+\r
+ if ( m_StrAryAttach.GetSize() > 0 )\r
+ {\r
+ csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );\r
+ csBody += csTemp;\r
+ }\r
+\r
+ return Send ( csBody );\r
+}\r
+\r
+BOOL CHwSMTP::SendAttach()\r
+{\r
+ int nCountAttach = (int)m_StrAryAttach.GetSize();\r
+ if ( nCountAttach < 1 ) return TRUE;\r
+\r
+ for ( int i=0; i<nCountAttach; i++ )\r
+ {\r
+ if ( !SendOnAttach ( m_StrAryAttach.GetAt(i) ) )\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+BOOL CHwSMTP::SendOnAttach(LPCTSTR lpszFileName)\r
+{\r
+ ASSERT ( lpszFileName );\r
+ CString csAttach, csTemp;\r
+\r
+ csTemp = lpszFileName;\r
+ CString csShortFileName = csTemp.GetBuffer(0) + csTemp.ReverseFind ( '\\' );\r
+ csShortFileName.TrimLeft ( _T("\\") );\r
+\r
+ csTemp.Format ( _T("Content-Type: application/octet-stream; file=%s\r\n"), csShortFileName );\r
+ csAttach += csTemp;\r
+\r
+ csTemp.Format ( _T("Content-Transfer-Encoding: base64\r\n") );\r
+ csAttach += csTemp;\r
+\r
+ csTemp.Format ( _T("Content-Disposition: attachment; filename=%s\r\n\r\n"), csShortFileName );\r
+ csAttach += csTemp;\r
+\r
+ DWORD dwFileSize = hwGetFileAttr(lpszFileName);\r
+ if ( dwFileSize > 5*1024*1024 )\r
+ {\r
+ m_csLastError.Format ( _T("File [%s] too big. File size is : %s"), lpszFileName, FormatBytes(dwFileSize) );\r
+ return FALSE;\r
+ }\r
+ char *pBuf = new char[dwFileSize+1];\r
+ if ( !pBuf ) \r
+ {\r
+ ::AfxThrowMemoryException ();\r
+ return FALSE;\r
+ }\r
+\r
+ CFile file;\r
+ try\r
+ {\r
+ if ( !file.Open ( lpszFileName, CFile::modeRead ) )\r
+ {\r
+ m_csLastError.Format ( _T("Open file [%s] failed"), lpszFileName );\r
+ return FALSE;\r
+ }\r
+ UINT nFileLen = file.Read ( pBuf, dwFileSize );\r
+ CBase64 Base64Encode;\r
+ csTemp = Base64Encode.Encode ( pBuf, nFileLen );\r
+ csAttach += csTemp;\r
+ csAttach += _T("\r\n\r\n");\r
+ }\r
+ catch ( CFileException e )\r
+ {\r
+ e.Delete();\r
+ m_csLastError.Format ( _T("Read file [%s] failed"), lpszFileName );\r
+ delete[] pBuf;\r
+ return FALSE;\r
+ }\r
+\r
+ csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );\r
+ csAttach += csTemp;\r
+\r
+ delete[] pBuf;\r
+ \r
+ return Send ( csAttach );\r
+}\r
+\r
+CString CHwSMTP::GetLastErrorText()\r
+{\r
+ return m_csLastError;\r
+}\r
+\r
+\r
+DWORD WINAPI ThreadProc_SendEmail( LPVOID lpParameter )\r
+{\r
+ CEMailObject *pEMailObject = (CEMailObject*)lpParameter;\r
+ ASSERT ( pEMailObject );\r
+\r
+ CHwSMTP HwSMTP;\r
+ BOOL bRet = HwSMTP.SendEmail (\r
+ pEMailObject->m_csSmtpSrvHost,\r
+ pEMailObject->m_csUserName,\r
+ pEMailObject->m_csPasswd,\r
+ pEMailObject->m_bMustAuth,\r
+ pEMailObject->m_csAddrFrom,\r
+ pEMailObject->m_csAddrTo,\r
+ pEMailObject->m_csSenderName,\r
+ pEMailObject->m_csReceiverName,\r
+ pEMailObject->m_csSubject,\r
+ pEMailObject->m_csBody,\r
+ pEMailObject->m_csCharSet,\r
+ &pEMailObject->m_StrAryAttach,\r
+ &pEMailObject->m_StrAryCC,\r
+ pEMailObject->m_nSmtpSrvPort\r
+ );\r
+ if ( !bRet)\r
+ {\r
+#ifdef _DEBUG\r
+ CString csError = HwSMTP.GetLastErrorText ();\r
+ csError = FormatString ( _T("Send a email to [%s] failed."), pEMailObject->m_csSmtpSrvHost );\r
+ AfxMessageBox ( csError );\r
+#endif\r
+ }\r
+\r
+ m_CSFor__g_PtrAry_Threads.Lock ();\r
+ int nFindPos = FindFromArray ( g_PtrAry_Threads, pEMailObject->m_hThread );\r
+ if ( nFindPos >= 0 )\r
+ g_PtrAry_Threads.RemoveAt ( nFindPos );\r
+ m_CSFor__g_PtrAry_Threads.Unlock ();\r
+\r
+ delete pEMailObject;\r
+ return bRet;\r
+}\r
+\r
+//\r
+// Óà SMTP ·þÎñ·¢Ë͵ç×ÓÓʼþ£¬Èç¹ûÉèÖòÎÊý bViaThreadSend=TRUE£¬ÄÇÔÚ³ÌÐò½áÊøʱӦ¸ÃÔÚ ExitInstance() Öе÷Óà EndOfSMTP() º¯Êý\r
+//\r
+BOOL SendEmail (\r
+ BOOL bViaThreadSend,\r
+ LPCTSTR lpszSmtpSrvHost,\r
+ LPCTSTR lpszUserName,\r
+ LPCTSTR lpszPasswd,\r
+ BOOL bMustAuth,\r
+ LPCTSTR lpszAddrFrom,\r
+ LPCTSTR lpszAddrTo,\r
+ LPCTSTR lpszSenderName,\r
+ LPCTSTR lpszReceiverName,\r
+ LPCTSTR lpszSubject,\r
+ LPCTSTR lpszBody,\r
+ LPCTSTR lpszCharSet/*=NULL*/,\r
+ CStringArray *pStrAryAttach/*=NULL*/,\r
+ CStringArray *pStrAryCC/*=NULL*/,\r
+ UINT nSmtpSrvPort/*=25*/\r
+ )\r
+{\r
+ if ( !lpszSmtpSrvHost || lstrlen(lpszSmtpSrvHost) < 1 ||\r
+ !lpszSubject || lstrlen(lpszSubject) < 1 ||\r
+ !lpszBody || lstrlen(lpszBody) < 1 )\r
+ {\r
+ AfxMessageBox ( _T("Parameter error !") );\r
+ return FALSE;\r
+ }\r
+\r
+ CEMailObject *pEMailObject = new CEMailObject (\r
+ lpszSmtpSrvHost,\r
+ lpszUserName,\r
+ lpszPasswd,\r
+ bMustAuth,\r
+ lpszAddrFrom,\r
+ lpszAddrTo,\r
+ lpszSenderName,\r
+ lpszReceiverName,\r
+ lpszSubject,\r
+ lpszBody,\r
+ lpszCharSet,\r
+ pStrAryAttach,\r
+ pStrAryCC,\r
+ nSmtpSrvPort\r
+ );\r
+ if ( !pEMailObject ) return FALSE;\r
+\r
+ BOOL bRet = FALSE;\r
+ if ( bViaThreadSend )\r
+ {\r
+ DWORD dwThreadId = 0;\r
+ pEMailObject->m_hThread = ::CreateThread ( NULL, 0, ::ThreadProc_SendEmail, pEMailObject, CREATE_SUSPENDED, &dwThreadId );\r
+ bRet = HANDLE_IS_VALID(pEMailObject->m_hThread);\r
+ m_CSFor__g_PtrAry_Threads.Lock();\r
+ g_PtrAry_Threads.Add ( pEMailObject->m_hThread );\r
+ m_CSFor__g_PtrAry_Threads.Unlock();\r
+ ResumeThread ( pEMailObject->m_hThread );\r
+ }\r
+ else\r
+ {\r
+ bRet = (BOOL)ThreadProc_SendEmail ( pEMailObject );\r
+ }\r
+\r
+ return bRet;\r
+}\r
+\r
+void EndOfSMTP ()\r
+{\r
+ // µÈ´ýËùÓÐÏß³ÌÖ´ÐÐÍê±Ï\r
+ for ( int i=0; i<g_PtrAry_Threads.GetSize(); i++ )\r
+ {\r
+ HANDLE hThread = (HANDLE)g_PtrAry_Threads.GetAt(i);\r
+ if ( HANDLE_IS_VALID(hThread) )\r
+ {\r
+ WaitForThreadEnd ( &hThread, 30*1000 );\r
+ }\r
+ }\r
+ g_PtrAry_Threads.RemoveAll ();\r
+}\r
+\r
+\r
+//\r
+// ½«×Ö·û´® lpszOrg ת»»Îª¶à×Ö½ÚµÄ×Ö·û´®£¬Èç¹û»¹ÒªÊ¹Óöà×Ö·û´®µÄ³¤¶È£¬¿ÉÒÔÓÃÒÔÏ·½Ê½À´Ê¹ÓÃÕâ¸öÀࣺ\r
+// CMultiByteString MultiByteString(_T("UNICODE×Ö·û´®"));\r
+// printf ( "ANSI ×Ö·û´®Îª£º %s£¬ ×Ö·û¸öÊýΪ£º %d £¬ ³¤¶ÈΪ£º %d×Ö½Ú\n", MultiByteString.GetBuffer(), MultiByteString.GetLength(), MultiByteString.GetSize() );\r
+//\r
+CMultiByteString::CMultiByteString( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT char *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )\r
+{\r
+ m_bNewBuffer = FALSE;\r
+ m_pszData = NULL;\r
+ m_nDataSize = 0;\r
+ m_nCharactersNumber = 0;\r
+ if ( !lpszOrg ) return;\r
+ \r
+ // ÅжÏÔʼ×Ö·û´®µÄ±àÂ뷽ʽ\r
+ BOOL bOrgIsUnicode = FALSE;\r
+ if ( nOrgStringEncodeType == STRING_IS_MULTICHARS ) bOrgIsUnicode = FALSE;\r
+ else if ( nOrgStringEncodeType == STRING_IS_UNICODE ) bOrgIsUnicode = TRUE;\r
+ else\r
+ {\r
+#ifdef UNICODE\r
+ bOrgIsUnicode = TRUE;\r
+#else\r
+ bOrgIsUnicode = FALSE;\r
+#endif\r
+ }\r
+ \r
+ // ¼ÆËã×Ö·û´®¸öÊýºÍÐèÒªµÄÄ¿±ê»º³å´óС\r
+ if ( bOrgIsUnicode )\r
+ {\r
+ m_nCharactersNumber = (int)wcslen((WCHAR*)lpszOrg);\r
+ m_nDataSize = (m_nCharactersNumber + 1) * sizeof(WCHAR);\r
+ }\r
+ else\r
+ {\r
+ m_nCharactersNumber = (int)strlen((char*)lpszOrg);\r
+ m_nDataSize = (m_nCharactersNumber + 1) * sizeof(char);\r
+ }\r
+ \r
+ // ʹÓõ÷ÓÃÕß´«ÈëµÄ»º³å\r
+ if ( pOutBuf && nOutBufSize > 0 )\r
+ {\r
+ m_pszData = pOutBuf;\r
+ m_nDataSize = nOutBufSize;\r
+ }\r
+ // ×Ô¼ºÉêÇëÄڴ滺³å\r
+ else\r
+ {\r
+ m_pszData = (char*)new BYTE[m_nDataSize];\r
+ if ( !m_pszData )\r
+ {\r
+ ::AfxThrowMemoryException ();\r
+ return;\r
+ }\r
+ m_bNewBuffer = TRUE;\r
+ }\r
+ memset ( m_pszData, 0, m_nDataSize );\r
+ \r
+ if ( bOrgIsUnicode )\r
+ {\r
+ m_nCharactersNumber = WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, m_nCharactersNumber, (LPSTR)m_pszData, m_nDataSize/sizeof(char)-1, NULL, NULL );\r
+ if ( m_nCharactersNumber < 1 ) m_nCharactersNumber = (int)strlen ( m_pszData );\r
+ }\r
+ else\r
+ {\r
+ m_nCharactersNumber = __min ( m_nCharactersNumber, (int)(m_nDataSize/sizeof(char)-1) );\r
+ strncpy ( m_pszData, (const char*)lpszOrg, m_nCharactersNumber );\r
+ m_nCharactersNumber = (int)strlen ( m_pszData );\r
+ }\r
+ m_nDataSize = ( m_nCharactersNumber + 1 ) * sizeof(char);\r
+}\r
+\r
+CMultiByteString::~CMultiByteString ()\r
+{\r
+ if ( m_bNewBuffer && m_pszData )\r
+ {\r
+ delete[] m_pszData;\r
+ }\r
+}\r
+\r
+//\r
+// ½« lpszOrg ת»»Îª¸Ã³ÌÐòʹÓõıàÂë×Ö·û´®£¬Èç¹û¸Ã³ÌÐòÊÇ UNICODE ¾ÍתΪ UNICODE£¬Èç¹ûÊÇ ANSI ¾ÍתΪ ANSI µÄ\r
+//\r
+CString GetCompatibleString ( LPVOID lpszOrg, BOOL bOrgIsUnicode, int nOrgLength/*=-1*/ )\r
+{\r
+ if ( !lpszOrg ) return _T("");\r
+ \r
+ TRY\r
+ {\r
+#ifdef UNICODE\r
+ if ( bOrgIsUnicode )\r
+ {\r
+ if ( nOrgLength > 0 )\r
+ {\r
+ WCHAR *szRet = new WCHAR[nOrgLength+1];\r
+ if ( !szRet ) return _T("");\r
+ memset ( szRet, 0, (nOrgLength+1)*sizeof(WCHAR) );\r
+ memcpy ( szRet, lpszOrg, nOrgLength*sizeof(WCHAR) );\r
+ CString csRet = szRet;\r
+ delete[] szRet;\r
+ return csRet;\r
+ }\r
+ else if ( nOrgLength == 0 )\r
+ return _T("");\r
+ else\r
+ return (LPCTSTR)lpszOrg;\r
+ }\r
+ \r
+ if ( nOrgLength < 0 )\r
+ nOrgLength = (int)strlen((const char*)lpszOrg);\r
+ int nWideCount = nOrgLength + 1;\r
+ WCHAR *wchar = new WCHAR[nWideCount];\r
+ if ( !wchar ) return _T("");\r
+ memset ( wchar, 0, nWideCount*sizeof(WCHAR) );\r
+ ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszOrg, nOrgLength, wchar, nWideCount);\r
+ CString csRet = wchar;\r
+ delete[] wchar;\r
+ return csRet;\r
+#else\r
+ if ( !bOrgIsUnicode )\r
+ {\r
+ if ( nOrgLength > 0 )\r
+ {\r
+ char *szRet = new char[nOrgLength+1];\r
+ if ( !szRet ) return _T("");\r
+ memset ( szRet, 0, (nOrgLength+1)*sizeof(char) );\r
+ memcpy ( szRet, lpszOrg, nOrgLength*sizeof(char) );\r
+ CString csRet = szRet;\r
+ delete[] szRet;\r
+ return csRet;\r
+ }\r
+ else if ( nOrgLength == 0 )\r
+ return _T("");\r
+ else\r
+ return (LPCTSTR)lpszOrg;\r
+ }\r
+ \r
+ if ( nOrgLength < 0 )\r
+ nOrgLength = (int)wcslen((WCHAR*)lpszOrg);\r
+ int nMultiByteCount = nOrgLength + 1;\r
+ char *szMultiByte = new char[nMultiByteCount];\r
+ if ( !szMultiByte ) return _T("");\r
+ memset ( szMultiByte, 0, nMultiByteCount*sizeof(char) );\r
+ ::WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, nOrgLength, (LPSTR)szMultiByte, nMultiByteCount, NULL, NULL );\r
+ CString csRet = szMultiByte;\r
+ delete[] szMultiByte;\r
+ return csRet;\r
+#endif\r
+ }\r
+ CATCH_ALL(e)\r
+ {\r
+ THROW_LAST ();\r
+ }\r
+ END_CATCH_ALL\r
+ \r
+ return _T("");\r
+}\r
+\r
+CString FormatDateTime ( COleDateTime &DateTime, LPCTSTR pFormat )\r
+{ \r
+ // If null, return empty string\r
+ if ( DateTime.GetStatus() == COleDateTime::null || DateTime.GetStatus() == COleDateTime::invalid )\r
+ return _T("");\r
+ \r
+ UDATE ud;\r
+ if (S_OK != VarUdateFromDate(DateTime.m_dt, 0, &ud))\r
+ {\r
+ return _T("");\r
+ }\r
+ \r
+ struct tm tmTemp;\r
+ tmTemp.tm_sec = ud.st.wSecond;\r
+ tmTemp.tm_min = ud.st.wMinute;\r
+ tmTemp.tm_hour = ud.st.wHour;\r
+ tmTemp.tm_mday = ud.st.wDay;\r
+ tmTemp.tm_mon = ud.st.wMonth - 1;\r
+ tmTemp.tm_year = ud.st.wYear - 1900;\r
+ tmTemp.tm_wday = ud.st.wDayOfWeek;\r
+ tmTemp.tm_yday = ud.wDayOfYear - 1;\r
+ tmTemp.tm_isdst = 0;\r
+ \r
+ CString strDate;\r
+ LPTSTR lpszTemp = strDate.GetBufferSetLength(256);\r
+ _tcsftime(lpszTemp, strDate.GetLength(), pFormat, &tmTemp);\r
+ strDate.ReleaseBuffer();\r
+ \r
+ return strDate;\r
+}\r
+\r
+CString FormatString ( LPCTSTR lpszStr, ... )\r
+{\r
+ TCHAR *buf = NULL;\r
+ // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ\r
+ for ( int nBufCount = 1024; nBufCount<5*1024*1024; nBufCount += 1024 )\r
+ {\r
+ buf = new TCHAR[nBufCount];\r
+ if ( !buf )\r
+ {\r
+ ::AfxThrowMemoryException ();\r
+ return _T("");\r
+ }\r
+ memset ( buf, 0, nBufCount*sizeof(TCHAR) );\r
+ \r
+ va_list va;\r
+ va_start (va, lpszStr);\r
+ int nLen = _vsnprintf_hw ((TCHAR*)buf, nBufCount-sizeof(TCHAR), lpszStr, va);\r
+ va_end(va);\r
+ if ( nLen <= (int)(nBufCount-sizeof(TCHAR)) )\r
+ break;\r
+ delete[] buf; buf = NULL;\r
+ }\r
+ if ( !buf )\r
+ {\r
+ return _T("");\r
+ }\r
+ \r
+ CString csMsg = buf;\r
+ delete[] buf; buf = NULL;\r
+ return csMsg;\r
+}\r
+\r
+/********************************************************************************\r
+* Function Type : Global\r
+* Parameter : lpFileName - Îļþ·¾¶\r
+* Return Value : -1 - ʧ°Ü\r
+* >=0 - Îļþ´óС\r
+* Description : »ñÈ¡ÎļþÊôÐÔ ( Îļþ´óС¡¢´´½¨Ê±¼ä )\r
+*********************************************************************************/\r
+int hwGetFileAttr ( LPCTSTR lpFileName, OUT CFileStatus *pFileStatus/*=NULL*/ )\r
+{\r
+ if ( !lpFileName || lstrlen(lpFileName) < 1 ) return -1;\r
+ \r
+ CFileStatus fileStatus;\r
+ fileStatus.m_attribute = 0;\r
+ fileStatus.m_size = 0;\r
+ memset ( fileStatus.m_szFullName, 0, sizeof(fileStatus.m_szFullName) );\r
+ BOOL bRet = FALSE;\r
+ TRY\r
+ {\r
+ if ( CFile::GetStatus(lpFileName,fileStatus) )\r
+ {\r
+ bRet = TRUE;\r
+ }\r
+ }\r
+ CATCH (CFileException, e)\r
+ {\r
+ ASSERT ( FALSE );\r
+ bRet = FALSE;\r
+ }\r
+ CATCH_ALL(e)\r
+ {\r
+ ASSERT ( FALSE );\r
+ bRet = FALSE;\r
+ }\r
+ END_CATCH_ALL;\r
+ \r
+ if ( pFileStatus )\r
+ {\r
+ pFileStatus->m_ctime = fileStatus.m_ctime;\r
+ pFileStatus->m_mtime = fileStatus.m_mtime;\r
+ pFileStatus->m_atime = fileStatus.m_atime;\r
+ pFileStatus->m_size = fileStatus.m_size;\r
+ pFileStatus->m_attribute = fileStatus.m_attribute;\r
+ pFileStatus->_m_padding = fileStatus._m_padding;\r
+ lstrcpy ( pFileStatus->m_szFullName, fileStatus.m_szFullName );\r
+ \r
+ }\r
+ \r
+ return (int)fileStatus.m_size;\r
+}\r
+\r
+//\r
+// ½«Ò»¸ö±íʾ×Ö½ÚµÄÊýÓÿɶÁÐԺõÄ×Ö·û´®À´±íʾ£¬ÀýÈ罫 12345678 ×Ö½Úת»»Îª£º\r
+// 11.77M\r
+// nFlag - 0 : ×Ô¶¯Æ¥Å䵥λ\r
+// 1 : ÒÔ Kb Ϊµ¥Î»\r
+// 2 : ÒÔ Mb Ϊµ¥Î»\r
+// 3 : ÒÔ Gb Ϊµ¥Î»\r
+// \r
+CString FormatBytes ( double fBytesNum, BOOL bShowUnit/*=TRUE*/, int nFlag/*=0*/ )\r
+{\r
+ CString csRes;\r
+ if ( nFlag == 0 )\r
+ {\r
+ if ( fBytesNum >= 1024.0 && fBytesNum < 1024.0*1024.0 )\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum / 1024.0, bShowUnit?_T(" K"):_T("") );\r
+ else if ( fBytesNum >= 1024.0*1024.0 && fBytesNum < 1024.0*1024.0*1024.0 )\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0), bShowUnit?_T(" M"):_T("") );\r
+ else if ( fBytesNum >= 1024.0*1024.0*1024.0 )\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0*1024.0), bShowUnit?_T(" G"):_T("") );\r
+ else\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum, bShowUnit?_T(" B"):_T("") );\r
+ }\r
+ else if ( nFlag == 1 )\r
+ {\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum / 1024.0, bShowUnit?_T(" K"):_T("") );\r
+ }\r
+ else if ( nFlag == 2 )\r
+ {\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0), bShowUnit?_T(" M"):_T("") );\r
+ }\r
+ else if ( nFlag == 3 )\r
+ {\r
+ csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0*1024.0), bShowUnit?_T(" G"):_T("") );\r
+ }\r
+ \r
+ return csRes;\r
+}\r
+\r
+//\r
+// µÈ´ýÏß³ÌÍ˳ö\r
+//\r
+BOOL WaitForThreadEnd ( HANDLE *phThread, DWORD dwWaitTime /*=10*1000*/ )\r
+{\r
+ BOOL bRet = TRUE;\r
+ ASSERT ( phThread );\r
+ if ( !(*phThread) ) return TRUE;\r
+ if ( ::WaitForSingleObject ( *phThread, dwWaitTime ) == WAIT_TIMEOUT )\r
+ {\r
+ bRet = FALSE;\r
+ ::TerminateThread ( *phThread, 0 );\r
+ }\r
+ ::CloseHandle ( *phThread );\r
+ (*phThread) = NULL;\r
+ return bRet;\r
+}\r
--- /dev/null
+// HwSMTP.h: interface for the CHwSMTP class.\r
+//\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+/*******************************************************************\r
+ ˵Ã÷\r
+ 1¡¢ÕâÊÇÎÒ×Ô¼ºÐ´µÄÒ»¸öÀûÓÃSMTP·þÎñÆ÷·¢ËÍÓʼþµÄÀ࣬¿ÉÒÔʵÏÖ¸½¼þµÄ\r
+·¢ËÍ¡£\r
+ 2¡¢ÔÚ InitInstance() º¯Êýµ÷Óà \r
+ if (!AfxSocketInit())\r
+ {\r
+ AfxMessageBox(IDP_SOCKETS_INIT_FAILED);\r
+ return FALSE;\r
+ }\r
+ ÔÚ ExitInstance () Öе÷Óà ::WSACleanup ();\r
+*******************************************************************/\r
+\r
+/****************************************************************************************************************\r
+Ͷ¸å˵Ã÷£º\r
+****************************************************************************************************************/\r
+#define NOTE_SpeedPostMail \\r
+_T("\\r
+ ¡¾Èí¼þÃû³Æ¡¿\r\n\\r
+ ÎÞÐëSMTP·þÎñÆ÷ÖÐתֱ½Ó½«E-Mailµç×ÓÓʼþ·¢Ë͵½¶Ô·½ÓÊÏä\r\n\\r
+ ¡¾°æ ±¾¡¿\r\n\\r
+ 1.0.0\r\n\\r
+ ¡¾²Ù×÷ϵͳ¡¿\r\n\\r
+ Windows ×ÀÃæϵÁÐ\r\n\\r
+ ¡¾×÷ Õß¡¿\r\n\\r
+ лºìΰ ¡¤ chrys ¡¤ chrys@163.com ¡¤ http://www.viction.net\r\n\\r
+ ¡¾Èí¼þ˵Ã÷¡¿\r\n\\r
+ ´ó¼ÒÒ»¶¨ÊìϤFoxmailÖеġ°ÌØ¿ìרµÝ¡±£¬ËüÄÜÖ±½Ó½«Óʼþ·¢Ë͵½¶Ô·½µÄÓʼþ·þÎñÆ÷ÖУ¬¶ø²»ÐèÒª¾¹ýSMTP·þÎñÆ÷ÖÐת£¬\\r
+±¾´úÂ뽫ÏòÄãÆÊÎö¡°ÌØ¿ìרµÝ¡±·¢Ë͵ç×ÓÓʼþµÄ·½·¨¡£´úÂëÖÐÌṩÁËÍø¿¨ÐÅÏ¢»ñÈ¡À࣬¿ÉÒÔ»ñÈ¡±¾»úIPµØÖ·¡¢×ÓÍøÑÚÂë¡¢DNS¡¢\\r
+Wins¡¢Íø¿¨MACµØÖ·µÈÏà¹ØÐÅÏ¢£»»¹ÌṩÁËSMTPÐÒé½âÎöÀ࣬¸ÃÀàʵÏÖÁËSMTP¿Í»§¶Ë¹¦ÄܵÄʵÏÖÀ࣬ʵÏÖµç×ÓÓʼþÊÕ·¢£»Base64±àÂëʵÏÖ\\r
+ÁË×Ö·û±àÂëµÄ·½·¨¡£\r\n\\r
+ Äã¿ÉÒÔÈÎÒâÐ޸ĸ´ÖƱ¾´úÂ룬µ«Çë±£ÁôÕâ¶ÎÎÄ×Ö²»ÒªÐ޸ġ£\r\n\\r
+ Ï£ÍûÎÒÄÜΪÖйúµÄÈí¼þÐÐÒµ¾¡Ò»·Ý±¡Á¦£¡\r\n\\r
+ ¡¾¿ª·¢ÈÕÆÚ¡¿\r\n\\r
+ 2008-11-23 3:54\r\n")\r
+\r
+#include <afxsock.h>\r
+\r
+#if !defined(AFX_HwSMTP_H__633A52B7_1CBE_41D7_BDA3_188D98D692AF__INCLUDED_)\r
+#define AFX_HwSMTP_H__633A52B7_1CBE_41D7_BDA3_188D98D692AF__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+class CHwSMTP \r
+{\r
+public:\r
+ CString GetLastErrorText();\r
+ BOOL SendEmail (\r
+ LPCTSTR lpszSmtpSrvHost,\r
+ LPCTSTR lpszUserName,\r
+ LPCTSTR lpszPasswd,\r
+ BOOL bMustAuth,\r
+ LPCTSTR lpszAddrFrom,\r
+ LPCTSTR lpszAddrTo,\r
+ LPCTSTR lpszSenderName,\r
+ LPCTSTR lpszReceiverName,\r
+ LPCTSTR lpszSubject,\r
+ LPCTSTR lpszBody,\r
+ LPCTSTR lpszCharSet, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"\r
+ CStringArray *pStrAryAttach=NULL,\r
+ CStringArray *pStrAryCC=NULL,\r
+ UINT nSmtpSrvPort=25\r
+ );\r
+ CHwSMTP();\r
+ virtual ~CHwSMTP();\r
+\r
+private:\r
+ BOOL SendSubject();\r
+ CStringArray m_StrAryCC;\r
+ BOOL SendHead();\r
+ BOOL auth();\r
+ BOOL SendEmail();\r
+ BOOL Send ( LPCTSTR lpszData, ... );\r
+ BOOL GetResponse( LPCTSTR lpszVerifyCode, int *pnCode=NULL );\r
+ BOOL m_bConnected;\r
+ CSocket m_SendSock;\r
+ CStringArray m_StrAryAttach;\r
+ CString m_csSmtpSrvHost;\r
+ CString m_csUserName;\r
+ CString m_csPasswd;\r
+ CString m_csAddrFrom;\r
+ CString m_csAddrTo;\r
+ CString m_csSenderName;\r
+ CString m_csReceiverName;\r
+ CString m_csSubject;\r
+ CString m_csBody;\r
+private:\r
+ BOOL m_bMustAuth;\r
+ UINT m_nSmtpSrvPort;\r
+ CString m_csCharSet;\r
+\r
+ CString m_csLastError;\r
+ BOOL SendOnAttach(LPCTSTR lpszFileName);\r
+ BOOL SendAttach();\r
+ BOOL SendBody();\r
+ CString m_csMIMEContentType;\r
+ CString m_csPartBoundary;\r
+ CString m_csNoMIMEText;\r
+\r
+};\r
+\r
+BOOL SendEmail (\r
+ BOOL bViaThreadSend, // FALSE - Ö±½Ó·¢ËÍ£¬ TRUE - ÔÚÏß³ÌÖз¢ËÍ£¬·µ»ØÏ߳̾ä±ú\r
+ LPCTSTR lpszSmtpSrvHost, // SMTP ·þÎñÆ÷£¬È磺smtp.21cn.com\r
+ LPCTSTR lpszUserName, // µÇ¼·þÎñÆ÷ÑéÖ¤Éí·ÝµÄÓû§Ãû\r
+ LPCTSTR lpszPasswd, // µÇ¼·þÎñÆ÷ÑéÖ¤Éí·ÝµÄÃÜÂë\r
+ BOOL bMustAuth, // SMTP ·þÎñÆ÷ÐèÒªÉí·ÝÑéÖ¤\r
+ LPCTSTR lpszAddrFrom, // ·¢ËÍÕß E-Mail µØÖ·\r
+ LPCTSTR lpszAddrTo, // ½ÓÊÕÕßµÄ E-Mail µØÖ·\r
+ LPCTSTR lpszSenderName, // ·¢ËÍÕßµÄÃû×Ö£¬ÀýÈ磺лºìΰ\r
+ LPCTSTR lpszReceiverName, // ½ÓÊÕÕßµÄÃû×Ö£¬ÀýÈ磺ÕÅ·É\r
+ LPCTSTR lpszSubject, // ÓʼþÖ÷Ìâ\r
+ LPCTSTR lpszBody, // ÓʼþÄÚÈÝ\r
+ LPCTSTR lpszCharSet=NULL, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"\r
+ CStringArray *pStrAryAttach=NULL, // ¸½¼þÎļþ·¾¶£¬¿ÉÒÔ¶à¸ö\r
+ CStringArray *pStrAryCC=NULL, // ³ËÍ E-Mail µØÖ·£¬¿ÉÒÔ¶à¸ö\r
+ UINT nSmtpSrvPort=25 // SMTP ·þÎñÆ÷µÄ TCP ¶Ë¿ÚºÅ\r
+ );\r
+void EndOfSMTP ();\r
+\r
+#endif // !defined(AFX_HwSMTP_H__633A52B7_1CBE_41D7_BDA3_188D98D692AF__INCLUDED_)\r
--- /dev/null
+// OneNetAdapterInfo.cpp: implementation of the COneNetAdapterInfo class.\r
+//\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#include "stdafx.h"\r
+#include "SpeedPostEmail.h"\r
+#include "NetAdapterInfo.h"\r
+#include "Iphlpapi.h"\r
+#include "IpTypes.h"\r
+\r
+#ifdef _DEBUG\r
+#undef THIS_FILE\r
+static char THIS_FILE[]=__FILE__;\r
+#define new DEBUG_NEW\r
+#endif\r
+\r
+#define MALLOC( bytes ) ::HeapAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, (bytes) )\r
+#define FREE( ptr ) if( ptr ) ::HeapFree( ::GetProcessHeap(), 0, ptr )\r
+#define REMALLOC( ptr, bytes ) ::HeapReAlloc( ::GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, bytes )\r
+\r
+#pragma comment ( lib, "iphlpapi.lib" )\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+COneNetAdapterInfo::COneNetAdapterInfo ( IP_ADAPTER_INFO *pAdptInfo )\r
+{\r
+ m_bInitOk = FALSE;\r
+ memset ( &m_PhysicalAddress, 0, sizeof(m_PhysicalAddress) );\r
+ m_nPhysicalAddressLength = 0;\r
+ ASSERT ( pAdptInfo );\r
+ memcpy ( &m_AdptInfo, pAdptInfo, sizeof(IP_ADAPTER_INFO) );\r
+ if ( !Init() )\r
+ {\r
+ TRACE ( _T("[%s - %s] initialize failed."), Get_Name(), Get_Desc() );\r
+ }\r
+}\r
+\r
+COneNetAdapterInfo::~COneNetAdapterInfo()\r
+{\r
+ \r
+}\r
+\r
+//\r
+// ¸ù¾Ý´«ÈëµÄ pAdptInfo ÐÅÏ¢À´»ñÈ¡Ö¸¶¨Íø¿¨µÄ»ù±¾ÐÅÏ¢\r
+//\r
+BOOL COneNetAdapterInfo::Init ()\r
+{\r
+ IP_ADDR_STRING* pNext = NULL;\r
+ IP_PER_ADAPTER_INFO* pPerAdapt = NULL;\r
+ ULONG ulLen = 0;\r
+ DWORD dwErr = ERROR_SUCCESS;\r
+ ASSERT ( m_AdptInfo.AddressLength > 0 );\r
+ t_IPINFO iphold;\r
+\r
+ // ½«±äÁ¿Çå¿Õ\r
+ m_bInitOk = FALSE;\r
+ m_csName.Empty ();\r
+ m_csDesc.Empty ();\r
+ m_CurIPInfo.csIP.Empty ();\r
+ m_CurIPInfo.csSubnet.Empty ();\r
+ m_Ary_IP.RemoveAll ();\r
+ m_Ary_DNS.RemoveAll ();\r
+ m_Ary_Gateway.RemoveAll ();\r
+ \r
+#ifndef _UNICODE\r
+ m_csName = m_AdptInfo.AdapterName;\r
+ m_csDesc = m_AdptInfo.Description;\r
+#else\r
+ USES_CONVERSION;\r
+ m_csName = A2W ( m_AdptInfo.AdapterName );\r
+ m_csDesc = A2W ( m_AdptInfo.Description );\r
+#endif\r
+ \r
+ // »ñÈ¡µ±Ç°ÕýÔÚʹÓõÄIPµØÖ·\r
+ if ( m_AdptInfo.CurrentIpAddress )\r
+ {\r
+ m_CurIPInfo.csIP = m_AdptInfo.CurrentIpAddress->IpAddress.String;\r
+ m_CurIPInfo.csSubnet = m_AdptInfo.CurrentIpAddress->IpMask.String;\r
+ }\r
+ else\r
+ {\r
+ m_CurIPInfo.csIP = _T("0.0.0.0");\r
+ m_CurIPInfo.csSubnet = _T("0.0.0.0");\r
+ }\r
+ \r
+ // »ñÈ¡±¾Íø¿¨ÖÐËùÓеÄIPµØÖ·\r
+ pNext = &( m_AdptInfo.IpAddressList );\r
+ while ( pNext )\r
+ {\r
+ iphold.csIP = pNext->IpAddress.String;\r
+ iphold.csSubnet = pNext->IpMask.String;\r
+ m_Ary_IP.Add ( iphold );\r
+ pNext = pNext->Next;\r
+ }\r
+ \r
+ // »ñÈ¡±¾Íø¿¨ÖÐËùÓеÄÍø¹ØÐÅÏ¢\r
+ pNext = &( m_AdptInfo.GatewayList );\r
+ while ( pNext )\r
+ {\r
+ m_Ary_Gateway.Add ( A2W( pNext->IpAddress.String ));\r
+ pNext = pNext->Next;\r
+ }\r
+ \r
+ // »ñÈ¡±¾Íø¿¨ÖÐËùÓÐµÄ DNS\r
+ dwErr = ::GetPerAdapterInfo ( m_AdptInfo.Index, pPerAdapt, &ulLen );\r
+ if( dwErr == ERROR_BUFFER_OVERFLOW )\r
+ {\r
+ pPerAdapt = ( IP_PER_ADAPTER_INFO* ) MALLOC( ulLen );\r
+ dwErr = ::GetPerAdapterInfo( m_AdptInfo.Index, pPerAdapt, &ulLen );\r
+ \r
+ // if we succeed than we need to drop into our loop\r
+ // and fill the dns array will all available IP\r
+ // addresses.\r
+ if( dwErr == ERROR_SUCCESS )\r
+ {\r
+ pNext = &( pPerAdapt->DnsServerList );\r
+ while( pNext )\r
+ {\r
+ m_Ary_DNS.Add( A2W( pNext->IpAddress.String ) );\r
+ pNext = pNext->Next;\r
+ } \r
+ m_bInitOk = TRUE;\r
+ }\r
+\r
+ // this is done outside the dwErr == ERROR_SUCCES just in case. the macro\r
+ // uses NULL pointer checking so it is ok if pPerAdapt was never allocated.\r
+ FREE( pPerAdapt );\r
+ }\r
+\r
+ return m_bInitOk;\r
+}\r
+\r
+//\r
+// ÊÍ·Å»òˢб¾Íø¿¨µÄIPµØÖ·\r
+//\r
+BOOL COneNetAdapterInfo::RenewReleaseIP( Func_OperateIP func )\r
+{ \r
+ IP_INTERFACE_INFO* pInfo = NULL;\r
+ BOOL bDidIt = FALSE;\r
+ ULONG ulLen = 0;\r
+ int nNumInterfaces = 0;\r
+ int nCnt = 0;\r
+ DWORD dwErr = ERROR_SUCCESS;\r
+\r
+ dwErr = ::GetInterfaceInfo ( pInfo, &ulLen );\r
+ if( dwErr == ERROR_INSUFFICIENT_BUFFER )\r
+ {\r
+ pInfo = ( IP_INTERFACE_INFO* ) MALLOC( ulLen );\r
+ dwErr = ::GetInterfaceInfo ( pInfo, &ulLen );\r
+ \r
+ if( dwErr != ERROR_SUCCESS )\r
+ {\r
+ return FALSE; \r
+ }\r
+ }\r
+ \r
+ // we can assume from here out that we have a valid array\r
+ // of IP_INTERFACE_INFO structures due to the error \r
+ // checking one above.\r
+ nNumInterfaces = ulLen / sizeof( IP_INTERFACE_INFO );\r
+ for( nCnt = 0; nCnt < nNumInterfaces; nCnt++ )\r
+ {\r
+ if( pInfo[ nCnt ].Adapter[ 0 ].Index == m_AdptInfo.Index )\r
+ {\r
+ dwErr = func( &pInfo[ nCnt ].Adapter[ 0 ] );\r
+ \r
+ // free all used memory since we don't need it any more.\r
+ FREE( pInfo ); \r
+ \r
+ bDidIt = ( dwErr == NO_ERROR ); \r
+ if( ! bDidIt ) { \r
+ return FALSE;\r
+ }\r
+ \r
+ break;\r
+ }\r
+ } \r
+ \r
+ return bDidIt;\r
+}\r
+\r
+////////////////////////////////////////////////////////////\r
+// Desc:\r
+// Releases the addresses held by this adapter.\r
+////////////////////////////////////////////////////////////\r
+BOOL COneNetAdapterInfo::ReleaseIP()\r
+{ \r
+ return RenewReleaseIP ( ::IpReleaseAddress );\r
+}\r
+\r
+////////////////////////////////////////////////////////////\r
+// Desc:\r
+// Renews the address being held by this adapter.\r
+////////////////////////////////////////////////////////////\r
+BOOL COneNetAdapterInfo::RenewIP()\r
+{\r
+ return RenewReleaseIP ( ::IpRenewAddress );\r
+}\r
+\r
+CString COneNetAdapterInfo::GetAdapterTypeString ()\r
+{\r
+ UINT nType = m_AdptInfo.Type;\r
+ CString csType = _T("");\r
+ switch( nType )\r
+ {\r
+ case MIB_IF_TYPE_OTHER: csType = _T("Other"); break;\r
+ case MIB_IF_TYPE_ETHERNET: csType = _T("Ethernet"); break; \r
+ case MIB_IF_TYPE_TOKENRING: csType = _T("Token Ring"); break; \r
+ case MIB_IF_TYPE_FDDI: csType = _T("FDDI"); break; \r
+ case MIB_IF_TYPE_PPP: csType = _T("PPP"); break; \r
+ case MIB_IF_TYPE_LOOPBACK: csType = _T("Loopback"); break; \r
+ case MIB_IF_TYPE_SLIP: csType = _T("SLIP"); break; \r
+ default: csType = _T("Invalid Adapter Type"); break;\r
+ };\r
+ \r
+ return csType;\r
+}\r
+\r
+time_t COneNetAdapterInfo::Get_LeaseObtained() const { return m_AdptInfo.LeaseObtained; }\r
+time_t COneNetAdapterInfo::Get_LeaseExpired() const { return m_AdptInfo.LeaseExpires; }\r
+int COneNetAdapterInfo::Get_IPCount() const { return (int)m_Ary_IP.GetSize(); }\r
+int COneNetAdapterInfo::Get_DNSCount() const { return (int)m_Ary_DNS.GetSize(); }\r
+CString COneNetAdapterInfo::Get_CurrentIP() const { return m_CurIPInfo.csIP; }\r
+BOOL COneNetAdapterInfo::Is_DHCP_Used() const { return m_AdptInfo.DhcpEnabled; }\r
+CString COneNetAdapterInfo::Get_DHCPAddr() const { return m_AdptInfo.DhcpServer.IpAddress.String; }\r
+BOOL COneNetAdapterInfo::Is_Wins_Used() const { return m_AdptInfo.HaveWins; }\r
+CString COneNetAdapterInfo::Get_PrimaryWinsServer() const { return m_AdptInfo.PrimaryWinsServer.IpAddress.String; }\r
+CString COneNetAdapterInfo::Get_SecondaryWinsServer() const { return m_AdptInfo.SecondaryWinsServer.IpAddress.String; }\r
+int COneNetAdapterInfo::Get_GatewayCount() const { return m_Ary_Gateway.GetSize(); }\r
+DWORD COneNetAdapterInfo::Get_AdapterIndex() const { return m_AdptInfo.Index; }\r
+UINT COneNetAdapterInfo::Get_AdapterType() const { return m_AdptInfo.Type; }\r
+\r
+CString COneNetAdapterInfo::Get_IPAddr ( int nIndex ) const\r
+{ \r
+ CString csAddr = _T("");\r
+ if ( nIndex >= 0 && nIndex < m_Ary_IP.GetSize() )\r
+ {\r
+ csAddr = m_Ary_IP.GetAt(nIndex).csIP;\r
+ }\r
+ \r
+ return csAddr;\r
+}\r
+\r
+CString COneNetAdapterInfo::Get_Subnet ( int nIndex ) const\r
+{ \r
+ CString csAddr = _T("");\r
+ if ( nIndex >= 0 && nIndex < m_Ary_IP.GetSize() )\r
+ {\r
+ csAddr = m_Ary_IP.GetAt(nIndex).csSubnet;\r
+ }\r
+ \r
+ return csAddr;\r
+}\r
+\r
+CString COneNetAdapterInfo::Get_DNSAddr ( int nIndex ) const\r
+{ \r
+ CString csAddr = _T("");\r
+ if ( nIndex >= 0 && nIndex < m_Ary_DNS.GetSize() )\r
+ {\r
+ csAddr = m_Ary_DNS.GetAt(nIndex);\r
+ }\r
+ \r
+ return csAddr;\r
+}\r
+\r
+CString COneNetAdapterInfo::Get_GatewayAddr ( int nIndex ) const\r
+{ \r
+ CString csAddr = _T("");\r
+ if ( nIndex >= 0 && nIndex < m_Ary_Gateway.GetSize() )\r
+ {\r
+ csAddr = m_Ary_Gateway.GetAt(nIndex);\r
+ }\r
+ \r
+ return csAddr;\r
+}\r
+\r
+void COneNetAdapterInfo::Set_PhysicalAddress ( int nPhysicalAddressLength, BYTE *pPhysicalAddress )\r
+{\r
+ if ( !pPhysicalAddress ) return;\r
+ m_nPhysicalAddressLength = __min(nPhysicalAddressLength,sizeof(m_PhysicalAddress));\r
+ memcpy ( m_PhysicalAddress, pPhysicalAddress, m_nPhysicalAddressLength );\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CNetAdapterInfo::CNetAdapterInfo ()\r
+{\r
+}\r
+\r
+CNetAdapterInfo::~CNetAdapterInfo()\r
+{\r
+ DeleteAllNetAdapterInfo ();\r
+}\r
+\r
+void CNetAdapterInfo::DeleteAllNetAdapterInfo()\r
+{\r
+ for ( int i=0; i<m_Ary_NetAdapterInfo.GetSize(); i++ )\r
+ {\r
+ COneNetAdapterInfo *pOneNetAdapterInfo = (COneNetAdapterInfo*)m_Ary_NetAdapterInfo.GetAt(i);\r
+ if ( pOneNetAdapterInfo ) delete pOneNetAdapterInfo;\r
+ }\r
+ m_Ary_NetAdapterInfo.RemoveAll ();\r
+}\r
+\r
+//\r
+// ö¾ÙÍøÂçÊÊÅäÆ÷\r
+// return : ------------------------------------------------------------\r
+// -1 - ʧ°Ü\r
+// >=0 - ÍøÂçÊÊÅäÆ÷ÊýÁ¿\r
+//\r
+int CNetAdapterInfo::EnumNetworkAdapters ()\r
+{\r
+ DeleteAllNetAdapterInfo ();\r
+\r
+ IP_ADAPTER_INFO* pAdptInfo = NULL;\r
+ IP_ADAPTER_INFO* pNextAd = NULL;\r
+ ULONG ulLen = 0;\r
+ int nCnt = 0;\r
+ \r
+ DWORD dwError = ::GetAdaptersInfo ( pAdptInfo, &ulLen );\r
+ if( dwError != ERROR_BUFFER_OVERFLOW ) return -1;\r
+ pAdptInfo = ( IP_ADAPTER_INFO* )MALLOC ( ulLen );\r
+ dwError = ::GetAdaptersInfo( pAdptInfo, &ulLen );\r
+ if ( dwError != ERROR_SUCCESS ) return -1;\r
+ \r
+ pNextAd = pAdptInfo;\r
+ while( pNextAd )\r
+ {\r
+ COneNetAdapterInfo *pOneNetAdapterInfo = new COneNetAdapterInfo ( pNextAd );\r
+ if ( pOneNetAdapterInfo )\r
+ {\r
+ m_Ary_NetAdapterInfo.Add ( pOneNetAdapterInfo );\r
+ }\r
+ nCnt ++;\r
+ pNextAd = pNextAd->Next;\r
+ }\r
+ \r
+ // free any memory we allocated from the heap before\r
+ // exit. we wouldn't wanna leave memory leaks now would we? ;p\r
+ FREE( pAdptInfo ); \r
+ \r
+ return nCnt;\r
+}\r
+\r
+COneNetAdapterInfo* CNetAdapterInfo::Get_OneNetAdapterInfo ( int nIndex )\r
+{\r
+ if ( nIndex < 0 || nIndex >= m_Ary_NetAdapterInfo.GetSize() )\r
+ {\r
+ ASSERT ( FALSE );\r
+ return NULL;\r
+ }\r
+\r
+ return (COneNetAdapterInfo*)m_Ary_NetAdapterInfo.GetAt(nIndex);\r
+}\r
+\r
+COneNetAdapterInfo* CNetAdapterInfo::Get_OneNetAdapterInfo ( DWORD dwIndex )\r
+{\r
+ for ( int i=0; i<m_Ary_NetAdapterInfo.GetSize(); i++ )\r
+ {\r
+ COneNetAdapterInfo *pOneNetAdapterInfo = (COneNetAdapterInfo*)m_Ary_NetAdapterInfo.GetAt(i);\r
+ if ( pOneNetAdapterInfo && pOneNetAdapterInfo->Get_AdapterIndex() == dwIndex )\r
+ return pOneNetAdapterInfo;\r
+ }\r
+\r
+ return NULL;\r
+}\r
+\r
+void CNetAdapterInfo::Refresh ()\r
+{\r
+ DeleteAllNetAdapterInfo ();\r
+ EnumNetworkAdapters ();\r
+ GetAdapterAddress ();\r
+}\r
+\r
+//\r
+// »ñÈ¡Íø¿¨µÄµØÖ·ÐÅÏ¢£¬Ö÷ÒªÊÇMACµØÖ·\r
+//\r
+BOOL CNetAdapterInfo::GetAdapterAddress ()\r
+{\r
+ DWORD dwSize = 0;\r
+ DWORD dwRetVal = 0;\r
+ BOOL bRet = FALSE;\r
+\r
+ int i = 0;\r
+\r
+ // Set the flags to pass to GetAdaptersAddresses\r
+ ULONG flags = GAA_FLAG_INCLUDE_PREFIX;\r
+\r
+ // default to unspecified address family (both)\r
+ // AF_INET for IPv4, AF_INET6 for IPv6\r
+ ULONG family = AF_UNSPEC;\r
+\r
+ LPVOID lpMsgBuf = NULL;\r
+\r
+ PIP_ADAPTER_ADDRESSES pAddresses = NULL;\r
+ ULONG outBufLen = 0;\r
+\r
+ PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;\r
+ PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;\r
+ PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;\r
+ PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;\r
+ IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;\r
+ IP_ADAPTER_PREFIX *pPrefix = NULL;\r
+\r
+ outBufLen = sizeof (IP_ADAPTER_ADDRESSES);\r
+ pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);\r
+ if (pAddresses == NULL) return FALSE;\r
+\r
+ // Make an initial call to GetAdaptersAddresses to get the \r
+ // size needed into the outBufLen variable\r
+ if ( ::GetAdaptersAddresses ( family, flags, NULL, pAddresses, &outBufLen ) == ERROR_BUFFER_OVERFLOW )\r
+ {\r
+ FREE(pAddresses);\r
+ pAddresses = (IP_ADAPTER_ADDRESSES *) MALLOC(outBufLen);\r
+ }\r
+ if (pAddresses == NULL) return FALSE;\r
+\r
+ // Make a second call to GetAdapters Addresses to get the\r
+ // actual data we want\r
+#ifdef _DEBUG\r
+ TRACE ( _T("Memory allocated for GetAdapterAddresses = %d bytes\n"), outBufLen);\r
+ TRACE ( _T("Calling GetAdaptersAddresses function with family = " ) );\r
+ if (family == AF_INET)\r
+ TRACE(_T("AF_INET\n"));\r
+ if (family == AF_INET6)\r
+ TRACE(_T("AF_INET6\n"));\r
+ if (family == AF_UNSPEC)\r
+ TRACE(_T("AF_UNSPEC\n\n"));\r
+#endif\r
+ dwRetVal = GetAdaptersAddresses ( family, flags, NULL, pAddresses, &outBufLen );\r
+\r
+ if ( dwRetVal == NO_ERROR )\r
+ {\r
+ // If successful, output some information from the data we received\r
+ pCurrAddresses = pAddresses;\r
+ while (pCurrAddresses)\r
+ {\r
+ TRACE(_T("\tLength of the IP_ADAPTER_ADDRESS struct: %ld\n"),\r
+ pCurrAddresses->Length);\r
+ TRACE(_T("\tIfIndex (IPv4 interface): %u\n"), pCurrAddresses->IfIndex);\r
+ TRACE(_T("\tAdapter name: %s\n"), pCurrAddresses->AdapterName);\r
+\r
+ pUnicast = pCurrAddresses->FirstUnicastAddress;\r
+ if (pUnicast != NULL)\r
+ {\r
+ for (i = 0; pUnicast != NULL; i++)\r
+ pUnicast = pUnicast->Next;\r
+ TRACE(_T("\tNumber of Unicast Addresses: %d\n"), i);\r
+ }\r
+ else\r
+ {\r
+ TRACE(_T("\tNo Unicast Addresses\n"));\r
+ }\r
+\r
+ pAnycast = pCurrAddresses->FirstAnycastAddress;\r
+ if (pAnycast)\r
+ {\r
+ for (i = 0; pAnycast != NULL; i++)\r
+ pAnycast = pAnycast->Next;\r
+ TRACE(_T("\tNumber of Anycast Addresses: %d\n"), i);\r
+ }\r
+ else\r
+ {\r
+ TRACE(_T("\tNo Anycast Addresses\n"));\r
+ }\r
+\r
+ pMulticast = pCurrAddresses->FirstMulticastAddress;\r
+ if (pMulticast)\r
+ {\r
+ for (i = 0; pMulticast != NULL; i++)\r
+ pMulticast = pMulticast->Next;\r
+ TRACE(_T("\tNumber of Multicast Addresses: %d\n"), i);\r
+ }\r
+ else\r
+ {\r
+ TRACE(_T("\tNo Multicast Addresses\n"));\r
+ }\r
+\r
+ pDnServer = pCurrAddresses->FirstDnsServerAddress;\r
+ if (pDnServer)\r
+ {\r
+ for (i = 0; pDnServer != NULL; i++)\r
+ pDnServer = pDnServer->Next;\r
+ TRACE(_T("\tNumber of DNS Server Addresses: %d\n"), i);\r
+ }\r
+ else\r
+ {\r
+ TRACE(_T("\tNo DNS Server Addresses\n"));\r
+ }\r
+\r
+ TRACE(_T("\tDNS Suffix: %wS\n"), pCurrAddresses->DnsSuffix);\r
+ TRACE(_T("\tDescription: %wS\n"), pCurrAddresses->Description);\r
+ TRACE(_T("\tFriendly name: %wS\n"), pCurrAddresses->FriendlyName);\r
+\r
+ if (pCurrAddresses->PhysicalAddressLength != 0)\r
+ {\r
+ TRACE(_T("\tPhysical address: "));\r
+ for (i = 0; i < (int) pCurrAddresses->PhysicalAddressLength; i++)\r
+ {\r
+ if ( i == (int)(pCurrAddresses->PhysicalAddressLength - 1))\r
+ TRACE(_T("%.2X\n"), (int) pCurrAddresses->PhysicalAddress[i]);\r
+ else\r
+ TRACE(_T("%.2X-"), (int) pCurrAddresses->PhysicalAddress[i]);\r
+ }\r
+\r
+ COneNetAdapterInfo* pNetAdapterInfo = Get_OneNetAdapterInfo ( pCurrAddresses->IfIndex );\r
+ if ( pNetAdapterInfo )\r
+ {\r
+ pNetAdapterInfo->Set_PhysicalAddress ( pCurrAddresses->PhysicalAddressLength, pCurrAddresses->PhysicalAddress );\r
+ }\r
+ }\r
+ TRACE(_T("\tFlags: %ld\n"), pCurrAddresses->Flags);\r
+ TRACE(_T("\tMtu: %lu\n"), pCurrAddresses->Mtu);\r
+ TRACE(_T("\tIfType: %ld\n"), pCurrAddresses->IfType);\r
+ TRACE(_T("\tOperStatus: %ld\n"), pCurrAddresses->OperStatus);\r
+ TRACE(_T("\tIpv6IfIndex (IPv6 interface): %u\n"),\r
+ pCurrAddresses->Ipv6IfIndex);\r
+ TRACE(_T("\tZoneIndices (hex): "));\r
+ for (i = 0; i < 16; i++)\r
+ TRACE(_T("%lx "), pCurrAddresses->ZoneIndices[i]);\r
+ TRACE(_T("\n"));\r
+\r
+ pPrefix = pCurrAddresses->FirstPrefix;\r
+ if (pPrefix)\r
+ {\r
+ for (i = 0; pPrefix != NULL; i++)\r
+ pPrefix = pPrefix->Next;\r
+ TRACE(_T("\tNumber of IP Adapter Prefix entries: %d\n"), i);\r
+ }\r
+ else\r
+ {\r
+ TRACE(_T("\tNumber of IP Adapter Prefix entries: 0\n"));\r
+ }\r
+\r
+ TRACE(_T("\n"));\r
+\r
+ pCurrAddresses = pCurrAddresses->Next;\r
+ bRet = TRUE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ TRACE(_T("Call to GetAdaptersAddresses failed with error: %d\n"), dwRetVal );\r
+ if (dwRetVal == ERROR_NO_DATA)\r
+ {\r
+ TRACE(_T("\tNo addresses were found for the requested parameters\n"));\r
+ }\r
+ else\r
+ {\r
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language\r
+ (LPTSTR) & lpMsgBuf, 0, NULL))\r
+ {\r
+ TRACE(_T("\tError: %s"), lpMsgBuf);\r
+ LocalFree(lpMsgBuf);\r
+ FREE(pAddresses);\r
+ }\r
+ }\r
+ bRet = FALSE;\r
+ }\r
+ FREE(pAddresses);\r
+\r
+ return bRet;\r
+}\r
+\r
+CString MacAddress2String ( int nPhysicalAddressLength, BYTE *pPhysicalAddress )\r
+{\r
+ ASSERT ( nPhysicalAddressLength >= 6 );\r
+ AfxIsValidAddress(pPhysicalAddress,nPhysicalAddressLength,TRUE);\r
+ CString csMacAddress, csOneCell;\r
+ for ( int i=0; i<nPhysicalAddressLength; i++ )\r
+ {\r
+ csOneCell.Format ( _T("%.2X"), (int)pPhysicalAddress[i] );\r
+ if ( !csMacAddress.IsEmpty() ) csMacAddress += _T("-");\r
+ csMacAddress += csOneCell;\r
+ }\r
+\r
+ return csMacAddress;\r
+}
\ No newline at end of file
--- /dev/null
+// OneNetAdapterInfo.h: interface for the COneNetAdapterInfo class.\r
+//\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#if !defined(AFX_OneNetAdapterInfo_H__A899410F_5CFF_4958_80C4_D1AC693F62E3__INCLUDED_)\r
+#define AFX_OneNetAdapterInfo_H__A899410F_5CFF_4958_80C4_D1AC693F62E3__INCLUDED_\r
+\r
+#if _MSC_VER > 1000\r
+#pragma once\r
+#endif // _MSC_VER > 1000\r
+\r
+/*\r
+ ˵Ã÷\r
+ »ñÈ¡Íø¿¨ÐÅÏ¢£¬°üÀ¨IPµØÖ·¡¢DNS¡¢Íø¹Ø¡¢ÊÇ·ñΪ¶¯Ì¬IP¡¢DHCPµÈ£¬¸ÃÀ಻ÓöÁȡע²á±í¼´¿É»ñÈ¡×îеÄÍø¿¨ÐÅÏ¢\r
+ÁíÍ⻹¿ÉÒÔÊÍ·ÅÍø¿¨µØÖ·²¢ÖØÐÂˢеØÖ·\r
+*/\r
+\r
+#include <winsock2.h>\r
+#include <iphlpapi.h>\r
+#include <Afxtempl.h>\r
+\r
+typedef struct _IPINFO\r
+{\r
+ CString csIP;\r
+ CString csSubnet;\r
+} t_IPINFO;\r
+typedef CArray<t_IPINFO,t_IPINFO&> t_Ary_IPINFO;\r
+\r
+typedef DWORD ( __stdcall *Func_OperateIP)( PIP_ADAPTER_INDEX_MAP AdapterInfo );\r
+CString MacAddress2String ( int nPhysicalAddressLength, BYTE *pPhysicalAddress );\r
+\r
+class COneNetAdapterInfo\r
+{\r
+public:\r
+ COneNetAdapterInfo ( IP_ADAPTER_INFO *pAdptInfo );\r
+ virtual ~COneNetAdapterInfo();\r
+ CString Get_Name() { return m_csName; }\r
+ CString Get_Desc() { return m_csDesc; }\r
+ BOOL ReleaseIP();\r
+ BOOL RenewIP();\r
+ CString GetAdapterTypeString ();\r
+\r
+ time_t Get_LeaseObtained() const;\r
+ time_t Get_LeaseExpired() const;\r
+ int Get_IPCount() const;\r
+ int Get_DNSCount() const;\r
+ CString Get_CurrentIP() const;\r
+ BOOL Is_DHCP_Used() const;\r
+ CString Get_DHCPAddr() const;\r
+ BOOL Is_Wins_Used() const;\r
+ CString Get_PrimaryWinsServer() const;\r
+ CString Get_SecondaryWinsServer() const;\r
+ int Get_GatewayCount() const;\r
+ DWORD Get_AdapterIndex() const;\r
+ UINT Get_AdapterType() const;\r
+ CString Get_IPAddr ( int nIndex ) const;\r
+ CString Get_Subnet ( int nIndex ) const;\r
+ CString Get_DNSAddr ( int nIndex ) const;\r
+ CString Get_GatewayAddr ( int nIndex ) const;\r
+ void Set_PhysicalAddress ( int nPhysicalAddressLength, BYTE *pPhysicalAddress );\r
+ CString Get_PhysicalAddressStr () { return MacAddress2String ( m_nPhysicalAddressLength, m_PhysicalAddress ); }\r
+\r
+private:\r
+ BOOL Init ();\r
+ BOOL RenewReleaseIP( Func_OperateIP func );\r
+\r
+public:\r
+ BOOL m_bInitOk;\r
+private:\r
+ IP_ADAPTER_INFO m_AdptInfo;\r
+ CString m_csName;\r
+ CString m_csDesc;\r
+ t_IPINFO m_CurIPInfo; // this is also in the ip address list but this is the address currently active. \r
+ t_Ary_IPINFO m_Ary_IP;\r
+ CStringArray m_Ary_DNS;\r
+ CStringArray m_Ary_Gateway;\r
+ BYTE m_PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];\r
+ int m_nPhysicalAddressLength;\r
+};\r
+\r
+class CNetAdapterInfo\r
+{\r
+public:\r
+ CNetAdapterInfo ();\r
+ ~CNetAdapterInfo();\r
+ int GetNetCardCount () { return m_Ary_NetAdapterInfo.GetSize(); }\r
+ COneNetAdapterInfo* Get_OneNetAdapterInfo ( int nIndex );\r
+ COneNetAdapterInfo* CNetAdapterInfo::Get_OneNetAdapterInfo ( DWORD dwIndex );\r
+ void Refresh ();\r
+\r
+private:\r
+ int EnumNetworkAdapters ();\r
+ void DeleteAllNetAdapterInfo();\r
+ BOOL GetAdapterAddress ();\r
+\r
+private:\r
+ CPtrArray m_Ary_NetAdapterInfo;\r
+};\r
+\r
+#endif // !defined(AFX_OneNetAdapterInfo_H__A899410F_5CFF_4958_80C4_D1AC693F62E3__INCLUDED_)\r
>\r
</File>\r
<File\r
+ RelativePath=".\CBase64.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\CmdLineParser.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\HwSMTP.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath=".\HwSMTP.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\LangDll.cpp"\r
>\r
</File>\r
/* \r
base64.cpp and base64.h\r
\r
- Copyright (C) 2004-2008 René Nyffenegger\r
+ Copyright (C) 2004-2008 Ren?Nyffenegger\r
\r
This source code is provided 'as-is', without any express or implied\r
warranty. In no event will the author be held liable for any damages\r
\r
3. This notice may not be removed or altered from any source distribution.\r
\r
- René Nyffenegger rene.nyffenegger@adp-gmbh.ch\r
+ Ren?Nyffenegger rene.nyffenegger@adp-gmbh.ch\r
\r
*/\r
\r
std::string base64_encode(unsigned char const* , unsigned int len);\r
std::string base64_decode(std::string const& s);\r
\r
-#endif
\ No newline at end of file
+#endif\r
--- /dev/null
+#include "stdafx.h"\r
+#include "dnsmx.h"\r
+\r
+#define ASCII_NULL '\0'\r
+#define MAXHOSTNAME 256\r
+#define BUFSIZE 2048\r
+\r
+// #pragma comment ( lib, "ws2_32.lib" )\r
+\r
+/* DNS Header Format\r
+*\r
+* All DNS Message Formats have basically the same structure\r
+* (note that an RR (DNS Resource Record) is described in\r
+* the other structures that follow this header description):\r
+*\r
+* +--------------------------------+\r
+* | DNS Header: <defined below> |\r
+* +--------------------------------+\r
+* | Question: type of query |\r
+* | QNAME: <see below> |\r
+* | QTYPE: 2-octet RR type |\r
+* | QCLASS: 2-octet RR class |\r
+* +--------------------------------+\r
+* | Answer: RR answer to query |\r
+* +--------------------------------+\r
+* | Authority: RR for name server |\r
+* +--------------------------------+\r
+* | Additional: RR(s) other info |\r
+* +--------------------------------+\r
+*\r
+* QNAME is a variable length field where each portion of the\r
+* "dotted-notation" domain name is replaced by the number of\r
+* octets to follow. So, for example, the domain name\r
+* "www.sockets.com" is represented by:\r
+*\r
+* 0 1\r
+* octet 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6\r
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+* |3|w|w|w|7|s|o|c|k|e|t|s|3|c|o|m|0|\r
+* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\r
+*\r
+* NOTE: The last section, "Additional," often contains records\r
+* for queries the server anticipates will be sent (to reduce\r
+* traffic). For example, a response to an MX query, would\r
+* usually have the A record in additional information.\r
+*/\r
+typedef struct dns_hdr\r
+{\r
+ USHORT dns_id; /* client query ID number */\r
+ USHORT dns_flags; /* qualify contents <see below> */\r
+ USHORT dns_q_count; /* number of questions */\r
+ USHORT dns_rr_count; /* number of answer RRs */\r
+ USHORT dns_auth_count; /* number of authority RRs */\r
+ USHORT dns_add_count; /* number of additional RRs */\r
+} DNS_HDR, *PDNS_HDR, FAR *LPDNS_HDR;\r
+\r
+#define DNS_HDR_LEN 12\r
+\r
+/* DNS Flags field values\r
+*\r
+* bits: 0 1-4 5 6 7 8 9-11 12-15\r
+* +----+--------+----+----+----+----+--------+-------+\r
+* | QR | opcode | AA | TC | RD | RA | <zero> | rcode |\r
+* +----+--------+----+----+----+----+--------+-------+\r
+*\r
+* QR: 0 for query, and 1 for response\r
+* opcode: type of query (0: standard, and 1: inverse query)\r
+* AA: set if answer from domain authority\r
+* TC: set if message had to be truncated\r
+* RD: set if recursive query desired\r
+* RA: set if recursion is available from server\r
+* <zero>: reserved field\r
+* rcode: resulting error non-zero value from authoritative\r
+* server (0: no error, 3: name does not exist)\r
+*/\r
+#define DNS_FLAG_QR 0x8SpeedPostEmail\r
+#define DNS_FLAG_AA 0x0400\r
+#define DNS_FLAG_TC 0x0200\r
+#define DNS_FLAG_RD 0x0100\r
+#define DNS_FLAG_RA 0x0080\r
+#define DNS_RCODE_MASK 0xSpeedPostEmailF\r
+#define DNS_OPCODE_MASK 0x7800\r
+\r
+/* DNS Opcode (type of query) */\r
+char *DNS_Opcode[] =\r
+{\r
+ "Standard Query", /* 0: QUERY */\r
+ "Inverse Query", /* 1: IQUERY */\r
+ "Server Status Request", /* 2: STATUS */\r
+};\r
+\r
+/* DNS Response Codes (error descriptions) */\r
+char *DNS_RCode[] =\r
+{\r
+ "No Error", /* 0: ok */\r
+ "Format Error", /* 1: bad query */\r
+ "Server Failure", /* 2: server is hosed */\r
+ "Name Error", /* 3: name doesn't exist (authoritative) */\r
+ "Not Implemented", /* 4: server doesn't support query */\r
+ "Refused" /* 5: server refused request */\r
+};\r
+\r
+/* DNS Generic Resource Record format (from RFC 1034 and 1035)\r
+*\r
+* NOTE: The first field in the DNS RR Record header is always\r
+* the domain name in QNAME format (see earlier description)\r
+*/\r
+typedef struct dns_rr_hdr\r
+{\r
+ USHORT rr_type; /* RR type code (e.g. A, MX, NS, etc.) */\r
+ USHORT rr_class; /* RR class code (IN for Internet) */\r
+ ULONG rr_ttl; /* Time-to-live for resource */\r
+ USHORT rr_rdlength; /* length of RDATA field (in octets) */\r
+ USHORT rr_rdata; /* (fieldname used as a ptr) */\r
+} DNS_RR_HDR, *PDNS_RR_HDR, FAR *LPDNS_RR_HDR;\r
+\r
+#define DNS_RR_HDR_LEN 12\r
+\r
+/* DNS Resource Record RDATA Field Descriptions\r
+*\r
+* The RDATA field contains resource record data associated\r
+* with the specified domain name\r
+*\r
+* Type Value Description\r
+* -------------------------------------------------------------\r
+* A 1 IP Address (32-bit IP version 4)\r
+* NS 2 Name server QNAME (for referrals & recursive queries)\r
+* CNAME 5 Canonical name of an alias (in QNAME format)\r
+* SOA 6 Start of Zone Transfer (see definition below)\r
+* WKS 11 Well-known services (see definition below)\r
+* PTR 12 QNAME pointing to other nodes (e.g. in inverse lookups)\r
+* HINFO 13 Host Information (CPU string, then OS string)\r
+* MX 15 Mail server preference and QNAME (see below)\r
+*/\r
+char *DNS_RR_Type [] =\r
+{\r
+ "<invalid>",\r
+ "A", // 1: Host Address\r
+ "NS", // 2: Authoritative Name Server\r
+ "MD", // 3: <obsolete>\r
+ "MF", // 4: <obsolete>\r
+ "CNAME", // 5: The true, canonical name for an alias\r
+ "SOA", // 6: Start-of-Zone of authority record\r
+ "MB", // 7: Mailbox <experimental>\r
+ "MG", // 8: Mailgroup <experimental>\r
+ "MR", // 9: Mail Rename Domain Name <experimental>\r
+ "NULL", // 10: NULL Resource Record <experimental>\r
+ "WKS", // 11: Well-known service description\r
+ "PTR", // 12: Domain Name Pointer\r
+ "HINFO", // 13: Host Information\r
+ "MINFO", // 14: Mailbox or Mail List information\r
+ "MX", // 15: Mail Exchange (from RFC 974)\r
+ "TXT" // 16: Text String\r
+};\r
+\r
+#define DNS_RRTYPE_A 1\r
+#define DNS_RRTYPE_NS 2\r
+#define DNS_RRTYPE_CNAME 5\r
+#define DNS_RRTYPE_SOA 6\r
+#define DNS_RRTYPE_WKS 11\r
+#define DNS_RRTYPE_PTR 12\r
+#define DNS_RRTYPE_HINFO 13\r
+#define DNS_RRTYPE_MX 15\r
+\r
+/* DNS Resource Record Classes:\r
+*\r
+* One almost always uses Internet RR Class (also note: the\r
+* class value 255 denotes a wildcard, all classes)\r
+*/\r
+char *DNS_RR_Class [] =\r
+{\r
+ "<invalid>",\r
+ "IN", // 1: Internet - used for most queries!\r
+ "CS", // 2: CSNET <obsolete>\r
+ "CH", // 3: CHAOS Net\r
+ "HS" // 4: Hesiod\r
+};\r
+\r
+#define DNS_RRCLASS_IN 1\r
+#define DNS_RRCLASS_CS 2\r
+#define DNS_RRCLASS_CH 3\r
+#define DNS_RRCLASS_HS 4\r
+\r
+/* DNS SOA Resource Data Field\r
+*\r
+* NOTE: First two fields not shown here. They are:\r
+* MNAME: QNAME of primary server for this zone\r
+* RNAME: QNAME of mailbox of admin for this zone\r
+*/\r
+typedef struct dns_rdata_soa\r
+{\r
+ ULONG soa_serial; /* data version for this zone */\r
+ ULONG soa_refresh; /* time-to-live for data (in seconds) */\r
+ ULONG soa_retry; /* time between retrieds (in seconds) */\r
+ ULONG soa_expire; /* time until zone not auth (in seconds) */\r
+ ULONG soa_minimum; /* default TTL for RRs (in seconds) */\r
+} DNS_RDATA_SOA, PDNS_RDATA_SOA, FAR *LPDNS_RDATA_SOA;\r
+\r
+#define DNS_SOA_LEN 20\r
+\r
+/* DNS WKS Resource Data Field (RFC 1035)\r
+*\r
+* NOTE: The bitmap field is variable length, with as many\r
+* octets necessary to indicate the bit field for the port\r
+* number.\r
+*/\r
+typedef struct dns_rdata_wks\r
+{\r
+ ULONG wks_addr; /* IPv4 address */\r
+ UCHAR wks_protocol; /* Protocol (e.g. 6=TCP, 17=UDP) */\r
+ UCHAR wks_bitmap; /* e.g. bit 26 = SMTP (port 25) */\r
+} DNS_RDATA_WKS, *PDNS_RDATA_WKS, FAR *LPDNS_RDATA_WKS;\r
+\r
+#define DNS_WKX_LEN 6\r
+\r
+/* DNS MX Resource Data Field\r
+*/\r
+typedef struct dns_rdata_mx\r
+{\r
+ USHORT mx_pref; /* Preference value */\r
+ USHORT mx_xchange; /* QNAME (field used as ptr) */\r
+} DNS_RDATA_MX, *PDNS_RDATA_MX, FAR *LPDNS_RDATA_MX;\r
+\r
+#define DNS_MX_LEN 4\r
+\r
+/* Variables used for DNS Header construction & parsing */\r
+PDNS_HDR pDNShdr;\r
+PDNS_RR_HDR pDNS_RR;\r
+PDNS_RDATA_SOA pDNS_SOA;\r
+PDNS_RDATA_WKS pDNS_WKS;\r
+PDNS_RDATA_MX pDNS_MX;\r
+\r
+/* For Parsing Names in a Reply */\r
+#define INDIR_MASK 0xc0\r
+\r
+/* Number of bytes of fixed size data in query structure */\r
+#define QFIXEDSZ 4\r
+/* number of bytes of fixed size data in resource record */\r
+#define RRFIXEDSZ 10\r
+\r
+/* Processor Types */\r
+char *aszProcessor[] =\r
+{\r
+ "",\r
+ "",\r
+ "",\r
+ "Intel 386",\r
+ "Intel 486",\r
+ "Intel Pentium"\r
+};\r
+\r
+\r
+void GetQName( char FAR *pszHostName, char FAR *pQName );\r
+void PrintQName( char FAR *pQName );\r
+int PutQName( char FAR *pszHostName, char FAR *pQName );\r
+\r
+USHORT _getshort(char *msgp)\r
+{\r
+ register UCHAR *p = (UCHAR *) msgp;\r
+ register USHORT u;\r
+ \r
+ u = *p++ << 8;\r
+ return ((USHORT)(u | *p));\r
+}\r
+\r
+ULONG _getlong(char *msgp)\r
+{\r
+ register UCHAR *p = (UCHAR *) msgp;\r
+ register ULONG u;\r
+ \r
+ u = *p++; u <<= 8;\r
+ u |= *p++; u <<= 8;\r
+ u |= *p++; u <<= 8;\r
+ return (u | *p);\r
+}\r
+\r
+\r
+/*\r
+* Expand compressed domain name 'comp_dn' to full domain name.\r
+* 'msg' is a pointer to the begining of the message,\r
+* 'eomorig' points to the first location after the message,\r
+* 'exp_dn' is a pointer to a buffer of size 'length' for the result.\r
+* Return size of compressed name or -1 if there was an error.\r
+*/\r
+int dn_expand(char *msg,char *eomorig,char *comp_dn,char *exp_dn,int length)\r
+{\r
+ register char *cp, *dn;\r
+ register int n, c;\r
+ char *eom;\r
+ int len = -1, checked = 0;\r
+ \r
+ dn = exp_dn;\r
+ cp = comp_dn;\r
+ eom = exp_dn + length - 1;\r
+ /*\r
+ * fetch next label in domain name\r
+ */\r
+ while (n = *cp++) {\r
+ /*\r
+ * Check for indirection\r
+ */\r
+ switch (n & INDIR_MASK) {\r
+ case 0:\r
+ if (dn != exp_dn) {\r
+ if (dn >= eom)\r
+ return (-1);\r
+ *dn++ = '.';\r
+ }\r
+ if (dn+n >= eom)\r
+ return (-1);\r
+ checked += n + 1;\r
+ while (--n >= 0) {\r
+ if ((c = *cp++) == '.') {\r
+ if (dn+n+1 >= eom)\r
+ return (-1);\r
+ *dn++ = '\\';\r
+ }\r
+ *dn++ = c;\r
+ if (cp >= eomorig) /* out of range */\r
+ return(-1);\r
+ }\r
+ break;\r
+ \r
+ case INDIR_MASK:\r
+ if (len < 0)\r
+ len = cp - comp_dn + 1;\r
+ cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff));\r
+ if (cp < msg || cp >= eomorig) /* out of range */\r
+ return(-1);\r
+ checked += 2;\r
+ /*\r
+ * Check for loops in the compressed name;\r
+ * if we've looked at the whole message,\r
+ * there must be a loop.\r
+ */\r
+ if (checked >= eomorig - msg)\r
+ return (-1);\r
+ break;\r
+ \r
+ default:\r
+ return (-1); /* flag error */\r
+ }\r
+ }\r
+ *dn = '\0';\r
+ if (len < 0)\r
+ len = cp - comp_dn;\r
+ return (len);\r
+}\r
+\r
+/*\r
+* Skip over a compressed domain name. Return the size or -1.\r
+*/\r
+int dn_skipname(UCHAR *comp_dn, UCHAR *eom)\r
+{\r
+ register UCHAR *cp;\r
+ register int n;\r
+ \r
+ cp = comp_dn;\r
+ while (cp < eom && (n = *cp++)) {\r
+ /*\r
+ * check for indirection\r
+ */\r
+ switch (n & INDIR_MASK) {\r
+ case 0: /* normal case, n == len */\r
+ cp += n;\r
+ continue;\r
+ default: /* illegal type */\r
+ return (-1);\r
+ case INDIR_MASK: /* indirection */\r
+ cp++;\r
+ }\r
+ break;\r
+ }\r
+ return (cp - comp_dn);\r
+}\r
+\r
+//\r
+// ÉèÖÃ×èÈûģʽ\r
+//\r
+BOOL SetBlockingMode ( SOCKET hSocket, BOOL bNonblockingEnable )\r
+{\r
+ if ( hSocket == INVALID_SOCKET || hSocket == 0 )\r
+ {\r
+ return FALSE;\r
+ }\r
+ \r
+ long cmd = FIONBIO;\r
+ long zero = 0;\r
+ u_long* argp = NULL;\r
+ if ( bNonblockingEnable )\r
+ argp = (u_long*)&cmd;\r
+ else\r
+ argp = (u_long*)&zero;\r
+ int err = ioctlsocket ( hSocket, cmd, argp );\r
+ if ( err != 0 )\r
+ {\r
+ return FALSE;\r
+ }\r
+ \r
+ return TRUE;\r
+}\r
+\r
+\r
+BOOL GetMX (\r
+ char *pszQuery,\r
+ char *pszServer,\r
+ OUT t_Ary_MXHostInfos &Ary_MXHostInfos\r
+ )\r
+{\r
+ SOCKET hSocket;\r
+ SOCKADDR_IN stSockAddr; // socket address structures\r
+ int nAddrLen = sizeof( SOCKADDR_IN );\r
+ \r
+ HOSTENT *pHostEnt;\r
+ \r
+ char achBufOut[ BUFSIZE ] = { 0 };\r
+ char achBufIn[ BUFSIZE ] = { 0 };\r
+ int nQueryLen = 0;\r
+ int nRC;\r
+ \r
+ char *p, *np, name[128], *eom;\r
+ int count, j, i, n;\r
+ \r
+ memset( &stSockAddr, ASCII_NULL, sizeof( stSockAddr ) );\r
+ \r
+ stSockAddr.sin_family = AF_INET;\r
+ stSockAddr.sin_port = htons( 53);\r
+ stSockAddr.sin_addr.s_addr = inet_addr( pszServer );\r
+ if ( stSockAddr.sin_addr.s_addr == INADDR_NONE )\r
+ {\r
+ pHostEnt = gethostbyname( pszServer );\r
+ if ( pHostEnt )\r
+ {\r
+ stSockAddr.sin_addr.s_addr = *((ULONG *)pHostEnt->h_addr_list[0]);\r
+ }\r
+ else\r
+ {\r
+ return FALSE;\r
+ } // end if\r
+ } // end if\r
+ \r
+ \r
+ /*------------------------------------------------------------\r
+ * Get a DGRAM socket\r
+ */\r
+ \r
+ hSocket = socket( AF_INET, SOCK_DGRAM, 0 );\r
+ \r
+ if ( hSocket == INVALID_SOCKET )\r
+ {\r
+ return FALSE;\r
+ } // end if\r
+\r
+ /*-----------------------------------------------------------\r
+ * Format DNS Query\r
+ */\r
+ \r
+ pDNShdr = (PDNS_HDR)&( achBufOut[ 0 ] );\r
+ pDNShdr->dns_id = htons( 0xDEAD );\r
+ pDNShdr->dns_flags = htons( DNS_FLAG_RD ); // do recurse\r
+ pDNShdr->dns_q_count = htons( 1 ); // one query\r
+ pDNShdr->dns_rr_count = 0; // none in query\r
+ pDNShdr->dns_auth_count = 0; // none in query\r
+ pDNShdr->dns_add_count = 0; // none in query\r
+ \r
+ nQueryLen = PutQName( pszQuery, &(achBufOut[ DNS_HDR_LEN ] ) );\r
+ nQueryLen += DNS_HDR_LEN;\r
+ \r
+ achBufOut[ nQueryLen++ ] = 0;\r
+ achBufOut[ nQueryLen++ ] = 0; \r
+ achBufOut[ nQueryLen ] = DNS_RRTYPE_MX;\r
+ achBufOut[ nQueryLen + 1 ] = 0;\r
+ achBufOut[ nQueryLen + 2 ] = DNS_RRCLASS_IN;\r
+ achBufOut[ nQueryLen + 3 ] = 0;\r
+ \r
+ nQueryLen += 4;\r
+ \r
+ /*-----------------------------------------------------------\r
+ * Send DNS Query to server\r
+ */\r
+ \r
+ nRC = sendto( hSocket,\r
+ achBufOut,\r
+ nQueryLen,\r
+ 0,\r
+ (LPSOCKADDR)&stSockAddr,\r
+ sizeof( SOCKADDR_IN ) );\r
+ \r
+ if ( nRC == SOCKET_ERROR )\r
+ {\r
+ \r
+ closesocket( hSocket );\r
+ return FALSE;\r
+ }\r
+ else\r
+ {\r
+ \r
+ }\r
+ \r
+// VERIFY ( SetBlockingMode ( hSocket, TRUE ) );\r
+\r
+ // Óà select Ä£ÐÍʵÏÖÁ¬½Ó³¬Ê±\r
+ struct timeval timeout;\r
+ fd_set r;\r
+ FD_ZERO(&r);\r
+ FD_SET(hSocket, &r);\r
+ timeout.tv_sec = 5; //Á¬½Ó³¬Ê±Ãë\r
+ timeout.tv_usec =0;\r
+ int ret = select(0, &r, 0, 0, &timeout);\r
+ if ( ret == SOCKET_ERROR )\r
+ {\r
+ ::closesocket(hSocket);\r
+ hSocket = SOCKET_ERROR;\r
+ return FALSE;\r
+ }\r
+\r
+ // µÃµ½¿É¶ÁµÄÊý¾Ý³¤¶È\r
+ long cmd = FIONREAD;\r
+ u_long argp = 0;\r
+ BOOL err = ioctlsocket ( hSocket, cmd, (u_long*)&argp );\r
+ if ( err || argp < 1 )\r
+ {\r
+ ::closesocket(hSocket);\r
+ hSocket = SOCKET_ERROR;\r
+ return FALSE;\r
+ }\r
+\r
+ nRC = recvfrom( hSocket,\r
+ achBufIn,\r
+ BUFSIZE,\r
+ 0,\r
+ (LPSOCKADDR)&stSockAddr,\r
+ &nAddrLen );\r
+ \r
+ if ( nRC == SOCKET_ERROR )\r
+ {\r
+ int nWSAErr = WSAGetLastError();\r
+ \r
+ if ( nWSAErr != WSAETIMEDOUT )\r
+ {\r
+ \r
+ closesocket( hSocket );\r
+ return FALSE;\r
+ }\r
+ else\r
+ {\r
+ \r
+ closesocket( hSocket );\r
+ return FALSE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ pDNShdr = (PDNS_HDR)&( achBufIn[ 0 ] );\r
+ p = (char *)&pDNShdr[0];\r
+ p+=12;\r
+ count = (int)*p;\r
+ \r
+ // Parse the Question...\r
+ for (i = 0; i< ntohs(pDNShdr->dns_q_count); i++)\r
+ {\r
+ np = name;\r
+ eom = (char *)pDNShdr+nRC;\r
+ \r
+ if ( (n = dn_expand((char *)pDNShdr, eom, p, name, 127)) < 0 )\r
+ {\r
+ return FALSE;\r
+ \r
+ }\r
+ p += n + QFIXEDSZ;\r
+ } \r
+ \r
+ for (i = 0; i< ntohs(pDNShdr->dns_rr_count); i++)\r
+ {\r
+ \r
+ // The Question Name appears Again...\r
+ if ((n = dn_expand((char *)pDNShdr, eom, p, name, 127)) < 0)\r
+ {\r
+ return FALSE;\r
+ }\r
+ p+=n;\r
+ \r
+ \r
+ j = _getshort(p);; //TYPE\r
+ p+=2;\r
+ //printf("%s\tType:%d", name, j);\r
+ \r
+ j = _getshort(p); //CLASS\r
+ p+=2;\r
+ // printf("\tClass:%d", j);\r
+ \r
+ j = _getlong(p); //TTL\r
+ p+=4;\r
+ // printf("\tTTL:%d", j);\r
+ \r
+ j = _getshort(p); //RDLENGTH\r
+ p+=2;\r
+ // printf("\tRDLENGTH:%d", j);\r
+ \r
+ j = _getshort(p); //N??\r
+ p+=2;\r
+ \r
+ // This should be an MX Name...\r
+ if ( (n = dn_expand((char *)pDNShdr, eom, p, name, 127)) < 0 )\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ t_MXHostInfo tMXHostInfo = {0};\r
+ strncpy ( (char*)tMXHostInfo.szMXHost, name, sizeof(tMXHostInfo.szMXHost)/sizeof(tMXHostInfo.szMXHost[0]) );\r
+ tMXHostInfo.N = j;\r
+ Ary_MXHostInfos.Add ( tMXHostInfo );\r
+ TRACE ( _T("%s\t%d\r\n"), name, j );\r
+ p += n;\r
+ }\r
+ return TRUE;\r
+ \r
+ \r
+ }\r
+ \r
+ \r
+ closesocket( hSocket );\r
+ return FALSE;\r
+}\r
+\r
+\r
+void GetQName( char FAR *pszHostName, char FAR *pQName )\r
+{\r
+ \r
+ int i, j, k;\r
+ \r
+ for ( i = 0; i < BUFSIZE; i++ )\r
+ {\r
+ j = *pQName;\r
+ \r
+ if ( j == 0 )\r
+ break;\r
+ \r
+ for ( k = 1; k <= j; k++ )\r
+ {\r
+ *pszHostName++ = *( pQName + i + k );\r
+ } // end for loop\r
+ } // end for loop\r
+ \r
+ *pszHostName++ = ASCII_NULL;\r
+} /* end GetQName() */\r
+\r
+\r
+void PrintQName( char FAR *pQName )\r
+{\r
+ int i, j, k;\r
+ \r
+ for ( i = 0; i < BUFSIZE; i++ )\r
+ {\r
+ j = *pQName;\r
+ \r
+ if ( j == 0 )\r
+ break;\r
+ \r
+ for ( k = 1; k <= j; k++ )\r
+ {\r
+ //printf( "%c", *( pQName + i + k ) );\r
+ } // end for loop\r
+ } // end for loop\r
+} /* end PrintQName() */\r
+\r
+\r
+int PutQName( char FAR *pszHostName, char FAR *pQName )\r
+{\r
+ int i;\r
+ int j = 0;\r
+ int k = 0;\r
+ \r
+ \r
+ for ( i = 0; *( pszHostName + i ); i++ )\r
+ {\r
+ char c = *( pszHostName + i ); /* get next character */\r
+ \r
+ \r
+ if ( c == '.' )\r
+ {\r
+ /* dot encountered, fill in previous length */\r
+ *( pQName + j ) = k;\r
+ \r
+ k = 0; /* reset segment length */\r
+ j = i + 1; /* set index to next counter */\r
+ }\r
+ else\r
+ {\r
+ *( pQName + i + 1 ) = c; /* assign to QName */\r
+ k++; /* inc count of seg chars */\r
+ } // end if\r
+ } // end for loop\r
+ \r
+ *(pQName + j ) = k; /* count for final segment */\r
+ *(pQName + i + 1 ) = 0; /* count for trailing NULL segment is 0 */\r
+ \r
+ return ( i + 1 ); /* return total length of QName */\r
+}\r
+\r
+//\r
+// ³¢ÊÔËùÓеÄDNSÀ´²éѯÓʾַþÎñÆ÷µØÖ·\r
+//\r
+BOOL GetMX (\r
+ char *pszQuery, // Òª²éѯµÄÓòÃû\r
+ OUT t_Ary_MXHostInfos &Ary_MXHostInfos // Êä³ö Mail Exchange Ö÷»úÃû\r
+ )\r
+{\r
+ CNetAdapterInfo m_NetAdapterInfo;\r
+ m_NetAdapterInfo.Refresh ();\r
+ int nNetAdapterCount = m_NetAdapterInfo.GetNetCardCount();\r
+ for ( int i=0; i<nNetAdapterCount; i++ )\r
+ {\r
+ COneNetAdapterInfo *pOneNetAdapterInfo = m_NetAdapterInfo.Get_OneNetAdapterInfo ( i );\r
+ if ( pOneNetAdapterInfo )\r
+ {\r
+ int nDNSCount = pOneNetAdapterInfo->Get_DNSCount ();\r
+ for ( int j=0; j<nDNSCount; j++ )\r
+ {\r
+ CString csDNS = pOneNetAdapterInfo->Get_DNSAddr ( j );\r
+ if ( GetMX ( pszQuery, csDNS.GetBuffer(0), Ary_MXHostInfos ) )\r
+ {\r
+ return TRUE;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}
\ No newline at end of file
--- /dev/null
+//DNS Query\r
+\r
+/* ˵Ã÷\r
+ 1¡¢ÔÚ InitInstance() º¯ÊýÖмÓÉÏÒÔÏ´úÂ룺\r
+WSADATA wsaData;\r
+int err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );\r
+if ( err )\r
+{\r
+ return FALSE;\r
+}\r
+\r
+ 2¡¢ÔÚ ExitInstance() º¯ÊýÖмÓÉÏÒÔÏ´úÂ룺\r
+ WSACleanup();\r
+\r
+*/\r
+\r
+#include <Afxtempl.h>\r
+#include "NetAdapterInfo.h"\r
+\r
+typedef struct _MXHostInfo\r
+{\r
+ char szMXHost[1024];\r
+ int N;\r
+} t_MXHostInfo;\r
+typedef CArray<t_MXHostInfo,t_MXHostInfo&> t_Ary_MXHostInfos;\r
+\r
+BOOL GetMX (\r
+ char *pszQuery, // Òª²éѯµÄÓòÃû\r
+ OUT t_Ary_MXHostInfos &Ary_MXHostInfos // Êä³ö Mail Exchange Ö÷»úÃû\r
+ );\r
+\r
#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0.\r
#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE.\r
#endif\r
+\r
+#ifndef NTDDI_VERSION\r
+#define NTDDI_VERSION NTDDI_WIN2KSP1\r
+#endif
\ No newline at end of file