1 // HwSMTP.cpp: implementation of the CHwSMTP class.
3 //////////////////////////////////////////////////////////////////////
9 #include "SpeedPostEmail.h"
15 static char THIS_FILE
[]=__FILE__
;
19 CPtrArray g_PtrAry_Threads
;
20 ::CCriticalSection m_CSFor__g_PtrAry_Threads
;
26 LPCTSTR lpszSmtpSrvHost
,
33 LPCTSTR lpszReceiverName
,
37 CStringArray
*pStrAryAttach
,
44 m_csSmtpSrvHost
= GET_SAFE_STRING(lpszSmtpSrvHost
);
45 m_csUserName
= GET_SAFE_STRING(lpszUserName
);
46 m_csPasswd
= GET_SAFE_STRING(lpszPasswd
);
47 m_bMustAuth
= bMustAuth
;
48 m_csAddrFrom
= GET_SAFE_STRING(lpszAddrFrom
);
49 m_csAddrTo
= GET_SAFE_STRING(lpszAddrTo
);
50 m_csFromName
= GET_SAFE_STRING(lpszFromName
);
51 m_csReceiverName
= GET_SAFE_STRING(lpszReceiverName
);
52 m_csSubject
= GET_SAFE_STRING(lpszSubject
);
53 m_csBody
= GET_SAFE_STRING(lpszBody
);
54 m_csCharSet
= GET_SAFE_STRING(lpszCharSet
);
55 m_StrCC
= GET_SAFE_STRING(pStrAryCC
);
56 m_csSender
= GET_SAFE_STRING(pSender
);
57 m_csToList
= GET_SAFE_STRING(pToList
);
60 m_StrAryAttach
.Append ( *pStrAryAttach
);
62 m_nSmtpSrvPort
= nSmtpSrvPort
;
67 CString m_csSmtpSrvHost
;
74 CString m_csReceiverName
;
78 CStringArray m_StrAryAttach
;
87 //////////////////////////////////////////////////////////////////////
88 // Construction/Destruction
89 //////////////////////////////////////////////////////////////////////
92 m_bConnected ( FALSE
),
93 m_nSmtpSrvPort ( 25 ),
96 m_csPartBoundary
= _T( "WC_MAIL_PaRt_BoUnDaRy_05151998" );
97 m_csMIMEContentType
= FormatString ( _T( "multipart/mixed; boundary=%s" ), m_csPartBoundary
);
98 m_csNoMIMEText
= _T( "This is a multi-part message in MIME format." );
99 //m_csCharSet = _T("\r\n\tcharset=\"iso-8859-1\"\r\n");
108 void CHwSMTP::GetNameAddress(CString
&in
, CString
&name
,CString
&address
)
111 start
=in
.Find(_T('<'));
112 end
=in
.Find(_T('>'));
114 if(start
>=0 && end
>=0)
117 address
=in
.Mid(start
+1,end
-start
-1);
123 CString
CHwSMTP::GetServerAddress(CString
&email
)
128 start
= email
.Find(_T("<"));
129 end
= email
.Find(_T(">"));
131 if(start
>=0 && end
>=0)
133 str
=email
.Mid(start
+1,end
-start
-1);
140 start
= str
.Find(_T('@'));
141 return str
.Mid(start
+1);
145 BOOL
CHwSMTP::SendSpeedEmail
147 LPCTSTR lpszAddrFrom
,
151 LPCTSTR lpszCharSet
, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"
152 CStringArray
*pStrAryAttach
,
161 To
+= GET_SAFE_STRING(lpszAddrTo
);
163 To
+= GET_SAFE_STRING(pStrAryCC
);
165 std::map
<CString
,std::vector
<CString
>> Address
;
170 CString one
= To
.Tokenize(_T(";"),start
);
176 addr
= GetServerAddress(one
);
181 Address
[addr
].push_back(one
);
185 std::map
<CString
,std::vector
<CString
>>::iterator itr1
= Address
.begin();
186 for( ; itr1
!= Address
.end(); ++itr1
)
188 PDNS_RECORD pDnsRecord
;
191 DnsQuery(itr1
->first
,
192 DNS_TYPE_MX
,DNS_QUERY_STANDARD
,
193 NULL
, //Contains DNS server IP address.
194 &pDnsRecord
, //Resource record that contains the response.
200 for(int i
=0;i
<itr1
->second
.size();i
++)
211 if(pNext
->wType
== DNS_TYPE_MX
)
212 if(SendEmail(pNext
->Data
.MX
.pNameExchange
,NULL
,NULL
,false,
213 lpszAddrFrom
,to
,lpszSubject
,lpszBody
,lpszCharSet
,pStrAryAttach
,pStrAryCC
,
214 25,pSend
,lpszAddrTo
))
221 //SendEmail(itr1.first,NULL,NULL,false,lpszAddrFrom,,lpszFromname);
222 DnsRecordListFree(pDnsRecord
,DnsFreeRecordList
);
227 BOOL
CHwSMTP::SendEmail (
228 LPCTSTR lpszSmtpSrvHost
,
229 LPCTSTR lpszUserName
,
232 LPCTSTR lpszAddrFrom
,
236 LPCTSTR lpszCharSet
, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"
237 CStringArray
*pStrAryAttach
/*=NULL*/,
238 LPCTSTR pStrAryCC
/*=NULL*/,
239 UINT nSmtpSrvPort
,/*=25*/
244 TRACE ( _T("·¢ËÍÓʼþ£º%s, %s\n"), lpszAddrTo
, lpszBody
);
245 m_StrAryAttach
.RemoveAll();
247 m_StrCC
+= GET_SAFE_STRING(pStrAryCC
);
249 m_csSmtpSrvHost
= GET_SAFE_STRING ( lpszSmtpSrvHost
);
250 if ( m_csSmtpSrvHost
.GetLength() <= 0 )
252 m_csLastError
.Format ( _T("Parameter Error!") );
255 m_csUserName
= GET_SAFE_STRING ( lpszUserName
);
256 m_csPasswd
= GET_SAFE_STRING ( lpszPasswd
);
257 m_bMustAuth
= bMustAuth
;
258 if ( m_bMustAuth
&& m_csUserName
.GetLength() <= 0 )
260 m_csLastError
.Format ( _T("Parameter Error!") );
264 m_csAddrFrom
= GET_SAFE_STRING ( lpszAddrFrom
);
265 m_csAddrTo
= GET_SAFE_STRING ( lpszAddrTo
);
266 // m_csFromName = GET_SAFE_STRING ( lpszFromName );
267 // m_csReceiverName = GET_SAFE_STRING ( lpszReceiverName );
268 m_csSubject
= GET_SAFE_STRING ( lpszSubject
);
269 m_csBody
= GET_SAFE_STRING ( lpszBody
);
271 this->m_csSender
= GET_SAFE_STRING(pSender
);
272 this->m_csToList
= GET_SAFE_STRING(pToList
);
274 m_nSmtpSrvPort
= nSmtpSrvPort
;
276 if ( lpszCharSet
&& lstrlen(lpszCharSet
) > 0 )
277 m_csCharSet
.Format ( _T("\r\n\tcharset=\"%s\"\r\n"), lpszCharSet
);
280 m_csAddrFrom
.GetLength() <= 0 || m_csAddrTo
.GetLength() <= 0
283 m_csLastError
.Format ( _T("Parameter Error!") );
289 m_StrAryAttach
.Append ( *pStrAryAttach
);
291 if ( m_StrAryAttach
.GetSize() < 1 )
292 m_csMIMEContentType
= FormatString ( _T( "text/plain; %s" ), m_csCharSet
);
296 if ( !m_SendSock
.Create () )
298 int nResult
= GetLastError();
299 m_csLastError
.Format ( _T("Create socket failed!") );
304 if ( !m_SendSock
.Connect ( m_csSmtpSrvHost
, m_nSmtpSrvPort
) )
306 m_csLastError
.Format ( _T("Connect to [ %s ] failed"), m_csSmtpSrvHost
);
307 TRACE ( _T("%d\n"), GetLastError() );
310 if ( !GetResponse( _T("220") ) ) return FALSE
;
313 BOOL ret
= SendEmail();
321 BOOL
CHwSMTP::GetResponse ( LPCTSTR lpszVerifyCode
, int *pnCode
/*=NULL*/)
323 if ( !lpszVerifyCode
|| lstrlen(lpszVerifyCode
) < 1 )
326 char szRecvBuf
[1024] = {0};
328 char szStatusCode
[4] = {0};
329 nRet
= m_SendSock
.Receive ( szRecvBuf
, sizeof(szRecvBuf
) );
330 TRACE ( _T("Received : %s\r\n"), szRecvBuf
);
333 m_csLastError
.Format ( _T("Receive TCP data failed") );
336 // TRACE ( _T("ÊÕµ½·þÎñÆ÷»ØÓ¦£º%s\n"), szRecvBuf );
338 memcpy ( szStatusCode
, szRecvBuf
, 3 );
339 if ( pnCode
) (*pnCode
) = atoi ( szStatusCode
);
341 if ( strcmp ( szStatusCode
, CMultiByteString(lpszVerifyCode
).GetBuffer() ) != 0 )
343 m_csLastError
.Format ( _T("Received invalid response : %s"), GetCompatibleString(szRecvBuf
,FALSE
) );
349 BOOL
CHwSMTP::SendBuffer(char *buff
,int size
)
355 m_csLastError
.Format ( _T("Didn't connect") );
359 if ( m_SendSock
.Send ( buff
, size
) != size
)
361 m_csLastError
.Format ( _T("Socket send data failed") );
367 // ÀûÓÃsocket·¢ËÍÊý¾Ý£¬Êý¾Ý³¤¶È²»Äܳ¬¹ý10M
368 BOOL
CHwSMTP::Send(CString
&str
)
372 m_csLastError
.Format ( _T("Didn't connect") );
376 CMultiByteString
cbsData ( str
);
378 TRACE ( _T("Send : %s\r\n"), cbsData
.GetBuffer() );
379 if ( m_SendSock
.Send ( cbsData
.GetBuffer(), cbsData
.GetLength() ) != cbsData
.GetLength() )
381 m_csLastError
.Format ( _T("Socket send data failed") );
388 BOOL
CHwSMTP::SendEmail()
391 char szLocalHostName
[64] = {0};
392 gethostname ( (char*)szLocalHostName
, sizeof(szLocalHostName
) );
396 str
.Format(_T("HELO %s\r\n"), GetCompatibleString(szLocalHostName
,FALSE
));
401 if ( !GetResponse ( _T("250") ) )
406 if ( m_bMustAuth
&& !auth() )
416 if ( !SendSubject() )
431 if ( !Send ( CString(_T(".\r\n") ) ) ) return FALSE
;
432 if ( !GetResponse ( _T("250") ) )
436 if ( HANDLE_IS_VALID(m_SendSock
.m_hSocket
) )
437 Send ( CString(_T("QUIT\r\n")) );
438 m_bConnected
= FALSE
;
445 int nResponseCode
= 0;
446 if ( !Send ( CString(_T("auth login\r\n")) ) ) return FALSE
;
447 if ( !GetResponse ( _T("334"), &nResponseCode
) ) return FALSE
;
448 if ( nResponseCode
!= 334 ) // ²»ÐèÒªÑéÖ¤Óû§ÃûºÍÃÜÂë
451 CBase64 Base64Encode
;
452 CMultiByteString
cbsUserName ( m_csUserName
), cbsPasswd ( m_csPasswd
);
453 CString csBase64_UserName
= GetCompatibleString ( Base64Encode
.Encode ( cbsUserName
.GetBuffer(), cbsUserName
.GetLength() ).GetBuffer(0), FALSE
);
454 CString csBase64_Passwd
= GetCompatibleString ( Base64Encode
.Encode ( cbsPasswd
.GetBuffer(), cbsPasswd
.GetLength() ).GetBuffer(0), FALSE
);
457 str
.Format( _T("%s\r\n"), csBase64_UserName
);
461 if ( !GetResponse ( _T("334") ) )
463 m_csLastError
.Format ( _T("Authentication UserName failed") );
467 str
.Format(_T("%s\r\n"), csBase64_Passwd
);
471 if ( !GetResponse ( _T("235") ) )
473 m_csLastError
.Format ( _T("Authentication Password failed") );
480 BOOL
CHwSMTP::SendHead()
484 GetNameAddress(m_csAddrFrom
,name
,addr
);
486 str
.Format( _T("MAIL From: <%s>\r\n"), addr
);
487 if ( !Send ( str
) ) return FALSE
;
489 if ( !GetResponse ( _T("250") ) ) return FALSE
;
494 CString one
=m_csAddrTo
.Tokenize(_T(";"),start
);
500 GetNameAddress(one
,name
,addr
);
502 str
.Format(_T("RCPT TO: <%s>\r\n"), addr
);
503 if ( !Send ( str
) ) return FALSE
;
504 if ( !GetResponse ( _T("250") ) ) return FALSE
;
508 for ( int i
=0; i
<m_StrAryCC
.GetSize(); i
++ )
510 str
.Format(_T("RCPT TO: <%s>\r\n"), m_StrAryCC
.GetAt(i
) );
511 if ( !Send ( str
) ) return FALSE
;
512 if ( !GetResponse ( _T("250") ) ) return FALSE
;
516 if ( !Send ( CString(_T("DATA\r\n") ) ) ) return FALSE
;
517 if ( !GetResponse ( CString(_T("354") )) ) return FALSE
;
522 BOOL
CHwSMTP::SendSubject()
525 csSubject
+= _T("Date: ");
526 COleDateTime tNow
= COleDateTime::GetCurrentTime();
529 csSubject
+= FormatDateTime (tNow
, _T("%a, %d %b %y %H:%M:%S %Z"));
531 csSubject
+= _T("\r\n");
532 csSubject
+= FormatString ( _T("From: %s\r\n"), this->m_csAddrFrom
);
534 csSubject
+= FormatString ( _T("CC: %s\r\n"), this->m_StrCC
);
536 if(m_csSender
.IsEmpty())
537 m_csSender
= this->m_csAddrFrom
;
539 csSubject
+= FormatString ( _T("Sender: %s\r\n"), this->m_csSender
);
541 if(this->m_csToList
.IsEmpty())
542 m_csToList
= m_csReceiverName
;
544 csSubject
+= FormatString ( _T("To: %s\r\n"), this->m_csToList
);
548 csSubject
+= FormatString ( _T("Subject: %s\r\n"), m_csSubject
);
551 csSubject
+= FormatString ( _T("X-Mailer: TortoiseGit\r\nMIME-Version: 1.0\r\nContent-Type: %s\r\n\r\n"),
552 m_csMIMEContentType
);
554 return Send ( csSubject
);
557 BOOL
CHwSMTP::SendBody()
559 CString csBody
, csTemp
;
561 if ( m_StrAryAttach
.GetSize() > 0 )
563 csTemp
.Format ( _T("%s\r\n\r\n"), m_csNoMIMEText
);
566 csTemp
.Format ( _T("--%s\r\n"), m_csPartBoundary
);
569 csTemp
.Format ( _T("Content-Type: text/plain\r\n%sContent-Transfer-Encoding: 7Bit\r\n\r\n"),
574 //csTemp.Format ( _T("%s\r\n"), m_csBody );
576 csBody
+= _T("\r\n");
578 return Send ( csBody
);
581 BOOL
CHwSMTP::SendAttach()
583 int nCountAttach
= (int)m_StrAryAttach
.GetSize();
584 if ( nCountAttach
< 1 ) return TRUE
;
586 for ( int i
=0; i
<nCountAttach
; i
++ )
588 if ( !SendOnAttach ( m_StrAryAttach
.GetAt(i
) ) )
595 BOOL
CHwSMTP::SendOnAttach(LPCTSTR lpszFileName
)
597 ASSERT ( lpszFileName
);
598 CString csAttach
, csTemp
;
600 csTemp
= lpszFileName
;
601 CString csShortFileName
= csTemp
.GetBuffer(0) + csTemp
.ReverseFind ( '\\' );
602 csShortFileName
.TrimLeft ( _T("\\") );
604 csTemp
.Format ( _T("--%s\r\n"), m_csPartBoundary
);
607 csTemp
.Format ( _T("Content-Type: application/octet-stream; file=%s\r\n"), csShortFileName
);
610 csTemp
.Format ( _T("Content-Transfer-Encoding: base64\r\n") );
613 csTemp
.Format ( _T("Content-Disposition: attachment; filename=%s\r\n\r\n"), csShortFileName
);
616 DWORD dwFileSize
= hwGetFileAttr(lpszFileName
);
617 if ( dwFileSize
> 5*1024*1024 )
619 m_csLastError
.Format ( _T("File [%s] too big. File size is : %s"), lpszFileName
, FormatBytes(dwFileSize
) );
622 char *pBuf
= new char[dwFileSize
+1];
625 ::AfxThrowMemoryException ();
629 if(!Send ( csAttach
))
636 if ( !file
.Open ( lpszFileName
, CFile::modeRead
) )
638 m_csLastError
.Format ( _T("Open file [%s] failed"), lpszFileName
);
641 UINT nFileLen
= file
.Read ( pBuf
, dwFileSize
);
642 CBase64 Base64Encode
;
643 filedata
= Base64Encode
.Encode ( pBuf
, nFileLen
);
644 filedata
+= _T("\r\n\r\n");
646 catch ( CFileException e
)
649 m_csLastError
.Format ( _T("Read file [%s] failed"), lpszFileName
);
654 if(!SendBuffer( filedata
.GetBuffer() ))
661 //return Send ( csAttach );
664 CString
CHwSMTP::GetLastErrorText()
666 return m_csLastError
;
670 DWORD WINAPI
ThreadProc_SendEmail( LPVOID lpParameter
)
672 CEMailObject
*pEMailObject
= (CEMailObject
*)lpParameter
;
673 ASSERT ( pEMailObject
);
676 BOOL bRet
= HwSMTP
.SendEmail (
677 pEMailObject
->m_csSmtpSrvHost
,
678 pEMailObject
->m_csUserName
,
679 pEMailObject
->m_csPasswd
,
680 pEMailObject
->m_bMustAuth
,
681 pEMailObject
->m_csAddrFrom
,
682 pEMailObject
->m_csAddrTo
,
683 pEMailObject
->m_csSubject
,
684 pEMailObject
->m_csBody
,
685 pEMailObject
->m_csCharSet
,
686 &pEMailObject
->m_StrAryAttach
,
687 pEMailObject
->m_StrCC
,
688 pEMailObject
->m_nSmtpSrvPort
,
689 pEMailObject
->m_csSender
694 CString csError
= HwSMTP
.GetLastErrorText ();
695 csError
= FormatString ( _T("Send a email to [%s] failed."), pEMailObject
->m_csSmtpSrvHost
);
696 AfxMessageBox ( csError
);
700 m_CSFor__g_PtrAry_Threads
.Lock ();
701 int nFindPos
= FindFromArray ( g_PtrAry_Threads
, pEMailObject
->m_hThread
);
703 g_PtrAry_Threads
.RemoveAt ( nFindPos
);
704 m_CSFor__g_PtrAry_Threads
.Unlock ();
711 // Óà SMTP ·þÎñ·¢Ë͵ç×ÓÓʼþ£¬Èç¹ûÉèÖòÎÊý bViaThreadSend=TRUE£¬ÄÇÔÚ³ÌÐò½áÊøʱӦ¸ÃÔÚ ExitInstance() Öе÷Óà EndOfSMTP() º¯Êý
715 LPCTSTR lpszSmtpSrvHost
,
716 LPCTSTR lpszUserName
,
719 LPCTSTR lpszAddrFrom
,
721 LPCTSTR lpszFromName
,
722 LPCTSTR lpszReceiverName
,
725 LPCTSTR lpszCharSet
/*=NULL*/,
726 CStringArray
*pStrAryAttach
/*=NULL*/,
727 LPCTSTR pStrAryCC
/*=NULL*/,
728 UINT nSmtpSrvPort
/*=25*/,
733 if ( !lpszSmtpSrvHost
|| lstrlen(lpszSmtpSrvHost
) < 1 ||
734 !lpszSubject
|| lstrlen(lpszSubject
) < 1 ||
735 !lpszBody
|| lstrlen(lpszBody
) < 1 )
737 AfxMessageBox ( _T("Parameter error !") );
741 CEMailObject
*pEMailObject
= new CEMailObject (
759 if ( !pEMailObject
) return FALSE
;
762 if ( bViaThreadSend
)
764 DWORD dwThreadId
= 0;
765 pEMailObject
->m_hThread
= ::CreateThread ( NULL
, 0, ::ThreadProc_SendEmail
, pEMailObject
, CREATE_SUSPENDED
, &dwThreadId
);
766 bRet
= HANDLE_IS_VALID(pEMailObject
->m_hThread
);
767 m_CSFor__g_PtrAry_Threads
.Lock();
768 g_PtrAry_Threads
.Add ( pEMailObject
->m_hThread
);
769 m_CSFor__g_PtrAry_Threads
.Unlock();
770 ResumeThread ( pEMailObject
->m_hThread
);
774 bRet
= (BOOL
)ThreadProc_SendEmail ( pEMailObject
);
782 // µÈ´ýËùÓÐÏß³ÌÖ´ÐÐÍê±Ï
783 for ( int i
=0; i
<g_PtrAry_Threads
.GetSize(); i
++ )
785 HANDLE hThread
= (HANDLE
)g_PtrAry_Threads
.GetAt(i
);
786 if ( HANDLE_IS_VALID(hThread
) )
788 WaitForThreadEnd ( &hThread
, 30*1000 );
791 g_PtrAry_Threads
.RemoveAll ();
796 // ½«×Ö·û´® lpszOrg ת»»Îª¶à×Ö½ÚµÄ×Ö·û´®£¬Èç¹û»¹ÒªÊ¹Óöà×Ö·û´®µÄ³¤¶È£¬¿ÉÒÔÓÃÒÔÏ·½Ê½À´Ê¹ÓÃÕâ¸öÀࣺ
797 // CMultiByteString MultiByteString(_T("UNICODE×Ö·û´®"));
798 // printf ( "ANSI ×Ö·û´®Îª£º %s£¬ ×Ö·û¸öÊýΪ£º %d £¬ ³¤¶ÈΪ£º %d×Ö½Ú\n", MultiByteString.GetBuffer(), MultiByteString.GetLength(), MultiByteString.GetSize() );
800 CMultiByteString::CMultiByteString( LPCTSTR lpszOrg
, int nOrgStringEncodeType
/*=STRING_IS_SOFTCODE*/, OUT
char *pOutBuf
/*=NULL*/, int nOutBufSize
/*=0*/ )
802 m_bNewBuffer
= FALSE
;
805 m_nCharactersNumber
= 0;
806 if ( !lpszOrg
) return;
808 // ÅжÏÔʼ×Ö·û´®µÄ±àÂ뷽ʽ
809 BOOL bOrgIsUnicode
= FALSE
;
810 if ( nOrgStringEncodeType
== STRING_IS_MULTICHARS
) bOrgIsUnicode
= FALSE
;
811 else if ( nOrgStringEncodeType
== STRING_IS_UNICODE
) bOrgIsUnicode
= TRUE
;
815 bOrgIsUnicode
= TRUE
;
817 bOrgIsUnicode
= FALSE
;
821 // ¼ÆËã×Ö·û´®¸öÊýºÍÐèÒªµÄÄ¿±ê»º³å´óС
824 m_nCharactersNumber
= (int)wcslen((WCHAR
*)lpszOrg
);
825 m_nDataSize
= (m_nCharactersNumber
+ 1) * sizeof(WCHAR
);
829 m_nCharactersNumber
= (int)strlen((char*)lpszOrg
);
830 m_nDataSize
= (m_nCharactersNumber
+ 1) * sizeof(char);
833 // ʹÓõ÷ÓÃÕß´«ÈëµÄ»º³å
834 if ( pOutBuf
&& nOutBufSize
> 0 )
837 m_nDataSize
= nOutBufSize
;
842 m_pszData
= (char*)new BYTE
[m_nDataSize
];
845 ::AfxThrowMemoryException ();
850 memset ( m_pszData
, 0, m_nDataSize
);
854 m_nCharactersNumber
= WideCharToMultiByte ( CP_ACP
, 0, (LPCWSTR
)lpszOrg
, m_nCharactersNumber
, (LPSTR
)m_pszData
, m_nDataSize
/sizeof(char)-1, NULL
, NULL
);
855 if ( m_nCharactersNumber
< 1 ) m_nCharactersNumber
= (int)strlen ( m_pszData
);
859 m_nCharactersNumber
= __min ( m_nCharactersNumber
, (int)(m_nDataSize
/sizeof(char)-1) );
860 strncpy ( m_pszData
, (const char*)lpszOrg
, m_nCharactersNumber
);
861 m_nCharactersNumber
= (int)strlen ( m_pszData
);
863 m_nDataSize
= ( m_nCharactersNumber
+ 1 ) * sizeof(char);
866 CMultiByteString::~CMultiByteString ()
868 if ( m_bNewBuffer
&& m_pszData
)
875 // ½« lpszOrg ת»»Îª¸Ã³ÌÐòʹÓõıàÂë×Ö·û´®£¬Èç¹û¸Ã³ÌÐòÊÇ UNICODE ¾ÍתΪ UNICODE£¬Èç¹ûÊÇ ANSI ¾ÍתΪ ANSI µÄ
877 CString
GetCompatibleString ( LPVOID lpszOrg
, BOOL bOrgIsUnicode
, int nOrgLength
/*=-1*/ )
879 if ( !lpszOrg
) return _T("");
886 if ( nOrgLength
> 0 )
888 WCHAR
*szRet
= new WCHAR
[nOrgLength
+1];
889 if ( !szRet
) return _T("");
890 memset ( szRet
, 0, (nOrgLength
+1)*sizeof(WCHAR
) );
891 memcpy ( szRet
, lpszOrg
, nOrgLength
*sizeof(WCHAR
) );
892 CString csRet
= szRet
;
896 else if ( nOrgLength
== 0 )
899 return (LPCTSTR
)lpszOrg
;
902 if ( nOrgLength
< 0 )
903 nOrgLength
= (int)strlen((const char*)lpszOrg
);
904 int nWideCount
= nOrgLength
+ 1;
905 WCHAR
*wchar
= new WCHAR
[nWideCount
];
906 if ( !wchar
) return _T("");
907 memset ( wchar
, 0, nWideCount
*sizeof(WCHAR
) );
908 ::MultiByteToWideChar(CP_ACP
, 0, (LPCSTR
)lpszOrg
, nOrgLength
, wchar
, nWideCount
);
909 CString csRet
= wchar
;
913 if ( !bOrgIsUnicode
)
915 if ( nOrgLength
> 0 )
917 char *szRet
= new char[nOrgLength
+1];
918 if ( !szRet
) return _T("");
919 memset ( szRet
, 0, (nOrgLength
+1)*sizeof(char) );
920 memcpy ( szRet
, lpszOrg
, nOrgLength
*sizeof(char) );
921 CString csRet
= szRet
;
925 else if ( nOrgLength
== 0 )
928 return (LPCTSTR
)lpszOrg
;
931 if ( nOrgLength
< 0 )
932 nOrgLength
= (int)wcslen((WCHAR
*)lpszOrg
);
933 int nMultiByteCount
= nOrgLength
+ 1;
934 char *szMultiByte
= new char[nMultiByteCount
];
935 if ( !szMultiByte
) return _T("");
936 memset ( szMultiByte
, 0, nMultiByteCount
*sizeof(char) );
937 ::WideCharToMultiByte ( CP_ACP
, 0, (LPCWSTR
)lpszOrg
, nOrgLength
, (LPSTR
)szMultiByte
, nMultiByteCount
, NULL
, NULL
);
938 CString csRet
= szMultiByte
;
939 delete[] szMultiByte
;
952 CString
FormatDateTime ( COleDateTime
&DateTime
, LPCTSTR pFormat
)
954 // If null, return empty string
955 if ( DateTime
.GetStatus() == COleDateTime::null
|| DateTime
.GetStatus() == COleDateTime::invalid
)
959 if (S_OK
!= VarUdateFromDate(DateTime
.m_dt
, 0, &ud
))
964 TCHAR
*weeks
[]={_T("Sun"),_T("Mon"),_T("Tue"),_T("Wen"),_T("Thu"),_T("Fri"),_T("Sat")};
965 TCHAR
*month
[]={_T("JAN"),_T("FEB"),_T("MAR"),_T("APR"),
966 _T("MAY"),_T("JUN"),_T("JUL"),_T("AUG"),
967 _T("SEP"),_T("OCT"),_T("NOV"),_T("DEC")};
969 TIME_ZONE_INFORMATION stTimeZone
;
970 GetTimeZoneInformation(&stTimeZone
);
973 strDate
.Format(_T("%s, %d %s %02d %d:%d:%d %c%04d")
974 ,weeks
[ud
.st
.wDayOfWeek
],
975 ud
.st
.wDay
,month
[ud
.st
.wMonth
-1],ud
.st
.wYear
%100,ud
.st
.wHour
,
976 ud
.st
.wMinute
,ud
.st
.wSecond
,
977 stTimeZone
.Bias
>0?_T('-'):_T('+'),
978 abs(stTimeZone
.Bias
*10/6)
983 CString
FormatString ( LPCTSTR lpszStr
, ... )
986 // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ
987 for ( int nBufCount
= 1024; nBufCount
<5*1024*1024; nBufCount
+= 1024 )
989 buf
= new TCHAR
[nBufCount
];
992 ::AfxThrowMemoryException ();
995 memset ( buf
, 0, nBufCount
*sizeof(TCHAR
) );
998 va_start (va
, lpszStr
);
999 int nLen
= _vsnprintf_hw ((TCHAR
*)buf
, nBufCount
-sizeof(TCHAR
), lpszStr
, va
);
1001 if ( nLen
<= (int)(nBufCount
-sizeof(TCHAR
)) )
1003 delete[] buf
; buf
= NULL
;
1010 CString csMsg
= buf
;
1011 delete[] buf
; buf
= NULL
;
1015 /********************************************************************************
1016 * Function Type : Global
1017 * Parameter : lpFileName - Îļþ·¾¶
1018 * Return Value : -1 - ʧ°Ü
1020 * Description : »ñÈ¡ÎļþÊôÐÔ ( Îļþ´óС¡¢´´½¨Ê±¼ä )
1021 *********************************************************************************/
1022 int hwGetFileAttr ( LPCTSTR lpFileName
, OUT CFileStatus
*pFileStatus
/*=NULL*/ )
1024 if ( !lpFileName
|| lstrlen(lpFileName
) < 1 ) return -1;
1026 CFileStatus fileStatus
;
1027 fileStatus
.m_attribute
= 0;
1028 fileStatus
.m_size
= 0;
1029 memset ( fileStatus
.m_szFullName
, 0, sizeof(fileStatus
.m_szFullName
) );
1033 if ( CFile::GetStatus(lpFileName
,fileStatus
) )
1038 CATCH (CFileException
, e
)
1052 pFileStatus
->m_ctime
= fileStatus
.m_ctime
;
1053 pFileStatus
->m_mtime
= fileStatus
.m_mtime
;
1054 pFileStatus
->m_atime
= fileStatus
.m_atime
;
1055 pFileStatus
->m_size
= fileStatus
.m_size
;
1056 pFileStatus
->m_attribute
= fileStatus
.m_attribute
;
1057 pFileStatus
->_m_padding
= fileStatus
._m_padding
;
1058 lstrcpy ( pFileStatus
->m_szFullName
, fileStatus
.m_szFullName
);
1062 return (int)fileStatus
.m_size
;
1066 // ½«Ò»¸ö±íʾ×Ö½ÚµÄÊýÓÿɶÁÐԺõÄ×Ö·û´®À´±íʾ£¬ÀýÈ罫 12345678 ×Ö½Úת»»Îª£º
1068 // nFlag - 0 : ×Ô¶¯Æ¥Å䵥λ
1073 CString
FormatBytes ( double fBytesNum
, BOOL bShowUnit
/*=TRUE*/, int nFlag
/*=0*/ )
1078 if ( fBytesNum
>= 1024.0 && fBytesNum
< 1024.0*1024.0 )
1079 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ 1024.0, bShowUnit
?_T(" K"):_T("") );
1080 else if ( fBytesNum
>= 1024.0*1024.0 && fBytesNum
< 1024.0*1024.0*1024.0 )
1081 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0), bShowUnit
?_T(" M"):_T("") );
1082 else if ( fBytesNum
>= 1024.0*1024.0*1024.0 )
1083 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0*1024.0), bShowUnit
?_T(" G"):_T("") );
1085 csRes
.Format ( _T("%.2f%s"), fBytesNum
, bShowUnit
?_T(" B"):_T("") );
1087 else if ( nFlag
== 1 )
1089 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ 1024.0, bShowUnit
?_T(" K"):_T("") );
1091 else if ( nFlag
== 2 )
1093 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0), bShowUnit
?_T(" M"):_T("") );
1095 else if ( nFlag
== 3 )
1097 csRes
.Format ( _T("%.2f%s"), fBytesNum
/ (1024.0*1024.0*1024.0), bShowUnit
?_T(" G"):_T("") );
1106 BOOL
WaitForThreadEnd ( HANDLE
*phThread
, DWORD dwWaitTime
/*=10*1000*/ )
1109 ASSERT ( phThread
);
1110 if ( !(*phThread
) ) return TRUE
;
1111 if ( ::WaitForSingleObject ( *phThread
, dwWaitTime
) == WAIT_TIMEOUT
)
1114 ::TerminateThread ( *phThread
, 0 );
1116 ::CloseHandle ( *phThread
);