1 // HwSMTP.cpp: implementation of the CHwSMTP class.
\r
3 //////////////////////////////////////////////////////////////////////
\r
9 #include "SpeedPostEmail.h"
\r
15 static char THIS_FILE[]=__FILE__;
\r
16 #define new DEBUG_NEW
\r
19 CPtrArray g_PtrAry_Threads;
\r
20 ::CCriticalSection m_CSFor__g_PtrAry_Threads;
\r
26 LPCTSTR lpszSmtpSrvHost,
\r
27 LPCTSTR lpszUserName,
\r
30 LPCTSTR lpszAddrFrom,
\r
32 LPCTSTR lpszFromName,
\r
33 LPCTSTR lpszReceiverName,
\r
34 LPCTSTR lpszSubject,
\r
36 LPCTSTR lpszCharSet,
\r
37 CStringArray *pStrAryAttach,
\r
44 m_csSmtpSrvHost = GET_SAFE_STRING(lpszSmtpSrvHost);
\r
45 m_csUserName = GET_SAFE_STRING(lpszUserName);
\r
46 m_csPasswd = GET_SAFE_STRING(lpszPasswd);
\r
47 m_bMustAuth = bMustAuth;
\r
48 m_csAddrFrom = GET_SAFE_STRING(lpszAddrFrom);
\r
49 m_csAddrTo = GET_SAFE_STRING(lpszAddrTo);
\r
50 m_csFromName = GET_SAFE_STRING(lpszFromName);
\r
51 m_csReceiverName = GET_SAFE_STRING(lpszReceiverName);
\r
52 m_csSubject = GET_SAFE_STRING(lpszSubject);
\r
53 m_csBody = GET_SAFE_STRING(lpszBody);
\r
54 m_csCharSet = GET_SAFE_STRING(lpszCharSet);
\r
55 m_StrCC = GET_SAFE_STRING(pStrAryCC);
\r
56 m_csSender = GET_SAFE_STRING(pSender);
\r
57 m_csToList = GET_SAFE_STRING(pToList);
\r
59 if ( pStrAryAttach )
\r
60 m_StrAryAttach.Append ( *pStrAryAttach );
\r
62 m_nSmtpSrvPort = nSmtpSrvPort;
\r
67 CString m_csSmtpSrvHost;
\r
68 CString m_csUserName;
\r
71 CString m_csAddrFrom;
\r
73 CString m_csFromName;
\r
74 CString m_csReceiverName;
\r
75 CString m_csSubject;
\r
77 CString m_csCharSet;
\r
78 CStringArray m_StrAryAttach;
\r
80 UINT m_nSmtpSrvPort;
\r
87 //////////////////////////////////////////////////////////////////////
\r
88 // Construction/Destruction
\r
89 //////////////////////////////////////////////////////////////////////
\r
91 CHwSMTP::CHwSMTP () :
\r
92 m_bConnected ( FALSE ),
\r
93 m_nSmtpSrvPort ( 25 ),
\r
94 m_bMustAuth ( TRUE )
\r
96 m_csMIMEContentType = _T( "multipart/mixed");
\r
97 m_csPartBoundary = _T( "WC_MAIL_PaRt_BoUnDaRy_05151998" );
\r
98 m_csNoMIMEText = _T( "This is a multi-part message in MIME format." );
\r
99 //m_csCharSet = _T("\r\n\tcharset=\"iso-8859-1\"\r\n");
\r
104 CHwSMTP::~CHwSMTP()
\r
108 void CHwSMTP::GetNameAddress(CString &in, CString &name,CString &address)
\r
111 start=in.Find(_T('<'));
\r
112 end=in.Find(_T('>'));
\r
114 if(start >=0 && end >=0)
\r
116 name=in.Left(start);
\r
117 address=in.Mid(start+1,end-start-1);
\r
123 CString CHwSMTP::GetServerAddress(CString &email)
\r
128 start = email.Find(_T("<"));
\r
129 end = email.Find(_T(">"));
\r
131 if(start>=0 && end >=0)
\r
133 str=email.Mid(start+1,end-start-1);
\r
140 start = str.Find(_T('@'));
\r
141 return str.Mid(start+1);
\r
145 BOOL CHwSMTP::SendSpeedEmail
\r
147 LPCTSTR lpszAddrFrom,
\r
148 LPCTSTR lpszAddrTo,
\r
149 LPCTSTR lpszSubject,
\r
151 LPCTSTR lpszCharSet, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"
\r
152 CStringArray *pStrAryAttach,
\r
161 To += GET_SAFE_STRING(lpszAddrTo);
\r
163 To += GET_SAFE_STRING(pStrAryCC);
\r
165 std::map<CString,std::vector<CString>> Address;
\r
168 while( start >= 0 )
\r
170 CString one= To.Tokenize(_T(";"),start);
\r
176 addr = GetServerAddress(one);
\r
181 Address[addr].push_back(one);
\r
185 std::map<CString,std::vector<CString>>::iterator itr1 = Address.begin();
\r
186 for( ; itr1 != Address.end(); ++itr1 )
\r
188 PDNS_RECORD pDnsRecord;
\r
191 DnsQuery(itr1->first ,
\r
192 DNS_TYPE_MX,DNS_QUERY_STANDARD,
\r
193 NULL, //Contains DNS server IP address.
\r
194 &pDnsRecord, //Resource record that contains the response.
\r
200 for(int i=0;i<itr1->second.size();i++)
\r
202 to+=itr1->second[i];
\r
212 if(SendEmail(pNext->Data.MX.pNameExchange,NULL,NULL,false,
\r
213 lpszAddrFrom,to,lpszSubject,lpszBody,lpszCharSet,pStrAryAttach,pStrAryCC,
\r
214 25,pSend,lpszAddrTo))
\r
216 pNext=pNext->pNext;
\r
221 //SendEmail(itr1.first,NULL,NULL,false,lpszAddrFrom,,lpszFromname);
\r
222 DnsRecordListFree(pDnsRecord,DnsFreeRecordList);
\r
227 BOOL CHwSMTP::SendEmail (
\r
228 LPCTSTR lpszSmtpSrvHost,
\r
229 LPCTSTR lpszUserName,
\r
230 LPCTSTR lpszPasswd,
\r
232 LPCTSTR lpszAddrFrom,
\r
233 LPCTSTR lpszAddrTo,
\r
234 LPCTSTR lpszSubject,
\r
236 LPCTSTR lpszCharSet, // ×Ö·û¼¯ÀàÐÍ£¬ÀýÈ磺·±ÌåÖÐÎÄÕâÀïÓ¦ÊäÈë"big5"£¬¼òÌåÖÐÎÄʱÊäÈë"gb2312"
\r
237 CStringArray *pStrAryAttach/*=NULL*/,
\r
238 LPCTSTR pStrAryCC/*=NULL*/,
\r
239 UINT nSmtpSrvPort,/*=25*/
\r
244 TRACE ( _T("·¢ËÍÓʼþ£º%s, %s\n"), lpszAddrTo, lpszBody );
\r
245 m_StrAryAttach.RemoveAll();
\r
247 m_StrCC += GET_SAFE_STRING(pStrAryCC);
\r
249 m_csSmtpSrvHost = GET_SAFE_STRING ( lpszSmtpSrvHost );
\r
250 if ( m_csSmtpSrvHost.GetLength() <= 0 )
\r
252 m_csLastError.Format ( _T("Parameter Error!") );
\r
255 m_csUserName = GET_SAFE_STRING ( lpszUserName );
\r
256 m_csPasswd = GET_SAFE_STRING ( lpszPasswd );
\r
257 m_bMustAuth = bMustAuth;
\r
258 if ( m_bMustAuth && m_csUserName.GetLength() <= 0 )
\r
260 m_csLastError.Format ( _T("Parameter Error!") );
\r
264 m_csAddrFrom = GET_SAFE_STRING ( lpszAddrFrom );
\r
265 m_csAddrTo = GET_SAFE_STRING ( lpszAddrTo );
\r
266 // m_csFromName = GET_SAFE_STRING ( lpszFromName );
\r
267 // m_csReceiverName = GET_SAFE_STRING ( lpszReceiverName );
\r
268 m_csSubject = GET_SAFE_STRING ( lpszSubject );
\r
269 m_csBody = GET_SAFE_STRING ( lpszBody );
\r
271 this->m_csSender = GET_SAFE_STRING(pSender);
\r
272 this->m_csToList = GET_SAFE_STRING(pToList);
\r
274 m_nSmtpSrvPort = nSmtpSrvPort;
\r
276 if ( lpszCharSet && lstrlen(lpszCharSet) > 0 )
\r
277 m_csCharSet.Format ( _T("\r\n\tcharset=\"%s\"\r\n"), lpszCharSet );
\r
280 m_csAddrFrom.GetLength() <= 0 || m_csAddrTo.GetLength() <= 0
\r
283 m_csLastError.Format ( _T("Parameter Error!") );
\r
287 if ( pStrAryAttach )
\r
289 m_StrAryAttach.Append ( *pStrAryAttach );
\r
291 if ( m_StrAryAttach.GetSize() < 1 )
\r
292 m_csMIMEContentType = _T( "text/plain");
\r
295 m_SendSock.Close();
\r
296 if ( !m_SendSock.Create () )
\r
298 int nResult = GetLastError();
\r
299 m_csLastError.Format ( _T("Create socket failed!") );
\r
304 if ( !m_SendSock.Connect ( m_csSmtpSrvHost, m_nSmtpSrvPort ) )
\r
306 m_csLastError.Format ( _T("Connect to [ %s ] failed"), m_csSmtpSrvHost );
\r
307 TRACE ( _T("%d\n"), GetLastError() );
\r
310 if ( !GetResponse( _T("220") ) ) return FALSE;
\r
312 m_bConnected = TRUE;
\r
313 BOOL ret= SendEmail();
\r
315 m_SendSock.Close();
\r
321 BOOL CHwSMTP::GetResponse ( LPCTSTR lpszVerifyCode, int *pnCode/*=NULL*/)
\r
323 if ( !lpszVerifyCode || lstrlen(lpszVerifyCode) < 1 )
\r
326 char szRecvBuf[1024] = {0};
\r
328 char szStatusCode[4] = {0};
\r
329 nRet = m_SendSock.Receive ( szRecvBuf, sizeof(szRecvBuf) );
\r
330 TRACE ( _T("Received : %s\r\n"), szRecvBuf );
\r
333 m_csLastError.Format ( _T("Receive TCP data failed") );
\r
336 // TRACE ( _T("ÊÕµ½·þÎñÆ÷»ØÓ¦£º%s\n"), szRecvBuf );
\r
338 memcpy ( szStatusCode, szRecvBuf, 3 );
\r
339 if ( pnCode ) (*pnCode) = atoi ( szStatusCode );
\r
341 if ( strcmp ( szStatusCode, CMultiByteString(lpszVerifyCode).GetBuffer() ) != 0 )
\r
343 m_csLastError.Format ( _T("Received invalid response : %s"), GetCompatibleString(szRecvBuf,FALSE) );
\r
349 BOOL CHwSMTP::SendBuffer(char *buff,int size)
\r
353 if ( !m_bConnected )
\r
355 m_csLastError.Format ( _T("Didn't connect") );
\r
359 if ( m_SendSock.Send ( buff, size ) != size )
\r
361 m_csLastError.Format ( _T("Socket send data failed") );
\r
367 // ÀûÓÃsocket·¢ËÍÊý¾Ý£¬Êý¾Ý³¤¶È²»Äܳ¬¹ý10M
\r
368 BOOL CHwSMTP::Send(CString &str )
\r
370 if ( !m_bConnected )
\r
372 m_csLastError.Format ( _T("Didn't connect") );
\r
376 CMultiByteString cbsData ( str );
\r
378 TRACE ( _T("Send : %s\r\n"), cbsData.GetBuffer() );
\r
379 if ( m_SendSock.Send ( cbsData.GetBuffer(), cbsData.GetLength() ) != cbsData.GetLength() )
\r
381 m_csLastError.Format ( _T("Socket send data failed") );
\r
388 BOOL CHwSMTP::SendEmail()
\r
391 char szLocalHostName[64] = {0};
\r
392 gethostname ( (char*)szLocalHostName, sizeof(szLocalHostName) );
\r
396 str.Format(_T("HELO %s\r\n"), GetCompatibleString(szLocalHostName,FALSE));
\r
397 if ( !Send ( str ))
\r
401 if ( !GetResponse ( _T("250") ) )
\r
406 if ( m_bMustAuth && !auth() )
\r
416 if ( !SendSubject() )
\r
426 if ( !SendAttach() )
\r
431 if ( !Send ( CString(_T(".\r\n") ) ) ) return FALSE;
\r
432 if ( !GetResponse ( _T("250") ) )
\r
436 if ( HANDLE_IS_VALID(m_SendSock.m_hSocket) )
\r
437 Send ( CString(_T("QUIT\r\n")) );
\r
438 m_bConnected = FALSE;
\r
443 BOOL CHwSMTP::auth()
\r
445 int nResponseCode = 0;
\r
446 if ( !Send ( CString(_T("auth login\r\n")) ) ) return FALSE;
\r
447 if ( !GetResponse ( _T("334"), &nResponseCode ) ) return FALSE;
\r
448 if ( nResponseCode != 334 ) // ²»ÐèÒªÑéÖ¤Óû§ÃûºÍÃÜÂë
\r
451 CBase64 Base64Encode;
\r
452 CMultiByteString cbsUserName ( m_csUserName ), cbsPasswd ( m_csPasswd );
\r
453 CString csBase64_UserName = GetCompatibleString ( Base64Encode.Encode ( cbsUserName.GetBuffer(), cbsUserName.GetLength() ).GetBuffer(0), FALSE );
\r
454 CString csBase64_Passwd = GetCompatibleString ( Base64Encode.Encode ( cbsPasswd.GetBuffer(), cbsPasswd.GetLength() ).GetBuffer(0), FALSE );
\r
457 str.Format( _T("%s\r\n"), csBase64_UserName );
\r
458 if ( !Send ( str ) )
\r
461 if ( !GetResponse ( _T("334") ) )
\r
463 m_csLastError.Format ( _T("Authentication UserName failed") );
\r
467 str.Format(_T("%s\r\n"), csBase64_Passwd );
\r
468 if ( !Send ( str ) )
\r
471 if ( !GetResponse ( _T("235") ) )
\r
473 m_csLastError.Format ( _T("Authentication Password failed") );
\r
480 BOOL CHwSMTP::SendHead()
\r
484 GetNameAddress(m_csAddrFrom,name,addr);
\r
486 str.Format( _T("MAIL From: <%s>\r\n"), addr );
\r
487 if ( !Send ( str ) ) return FALSE;
\r
489 if ( !GetResponse ( _T("250") ) ) return FALSE;
\r
494 CString one=m_csAddrTo.Tokenize(_T(";"),start);
\r
500 GetNameAddress(one,name,addr);
\r
502 str.Format(_T("RCPT TO: <%s>\r\n"), addr );
\r
503 if ( !Send ( str ) ) return FALSE;
\r
504 if ( !GetResponse ( _T("250") ) ) return FALSE;
\r
508 for ( int i=0; i<m_StrAryCC.GetSize(); i++ )
\r
510 str.Format(_T("RCPT TO: <%s>\r\n"), m_StrAryCC.GetAt(i) );
\r
511 if ( !Send ( str ) ) return FALSE;
\r
512 if ( !GetResponse ( _T("250") ) ) return FALSE;
\r
516 if ( !Send ( CString(_T("DATA\r\n") ) ) ) return FALSE;
\r
517 if ( !GetResponse ( CString(_T("354") )) ) return FALSE;
\r
522 BOOL CHwSMTP::SendSubject()
\r
525 csSubject += _T("Date: ");
\r
526 COleDateTime tNow = COleDateTime::GetCurrentTime();
\r
529 csSubject += GetCompatibleString(FormatDateTime (tNow, _T("%a, %d %b %y %H:%M:%S %Z")).GetBuffer(0),FALSE);
\r
531 csSubject += _T("\r\n");
\r
532 csSubject += FormatString ( _T("From: %s\r\n"), this->m_csAddrFrom);
\r
534 csSubject += FormatString ( _T("CC: %s\r\n"), this->m_StrCC);
\r
536 if(m_csSender.IsEmpty())
\r
537 m_csSender = this->m_csAddrFrom;
\r
539 csSubject += FormatString ( _T("Sender: %s\r\n"), this->m_csSender);
\r
541 if(this->m_csToList.IsEmpty())
\r
542 m_csToList = m_csReceiverName;
\r
544 csSubject += FormatString ( _T("To: %s\r\n"), this->m_csToList);
\r
546 CString m_csToList;
\r
548 csSubject += FormatString ( _T("Subject: %s\r\n"), m_csSubject );
\r
549 csSubject += FormatString ( _T("X-Mailer: TortoiseGit\r\nMIME-Version: 1.0\r\nContent-Type: %s; %s boundary=%s\r\n\r\n") ,
\r
550 m_csMIMEContentType, m_csCharSet, m_csPartBoundary );
\r
552 return Send ( csSubject );
\r
555 BOOL CHwSMTP::SendBody()
\r
557 CString csBody, csTemp;
\r
559 if ( m_StrAryAttach.GetSize() > 0 )
\r
561 csTemp.Format ( _T("%s\r\n\r\n"), m_csNoMIMEText );
\r
564 csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
\r
567 csTemp.Format ( _T("Content-Type: text/plain\r\n%sContent-Transfer-Encoding: 7Bit\r\n\r\n"),
\r
572 //csTemp.Format ( _T("%s\r\n"), m_csBody );
\r
573 csBody += m_csBody;
\r
574 csBody += _T("\r\n");
\r
576 return Send ( csBody );
\r
579 BOOL CHwSMTP::SendAttach()
\r
581 int nCountAttach = (int)m_StrAryAttach.GetSize();
\r
582 if ( nCountAttach < 1 ) return TRUE;
\r
584 for ( int i=0; i<nCountAttach; i++ )
\r
586 if ( !SendOnAttach ( m_StrAryAttach.GetAt(i) ) )
\r
593 BOOL CHwSMTP::SendOnAttach(LPCTSTR lpszFileName)
\r
595 ASSERT ( lpszFileName );
\r
596 CString csAttach, csTemp;
\r
598 csTemp = lpszFileName;
\r
599 CString csShortFileName = csTemp.GetBuffer(0) + csTemp.ReverseFind ( '\\' );
\r
600 csShortFileName.TrimLeft ( _T("\\") );
\r
602 csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
\r
603 csAttach += csTemp;
\r
605 csTemp.Format ( _T("Content-Type: application/octet-stream; file=%s\r\n"), csShortFileName );
\r
606 csAttach += csTemp;
\r
608 csTemp.Format ( _T("Content-Transfer-Encoding: base64\r\n") );
\r
609 csAttach += csTemp;
\r
611 csTemp.Format ( _T("Content-Disposition: attachment; filename=%s\r\n\r\n"), csShortFileName );
\r
612 csAttach += csTemp;
\r
614 DWORD dwFileSize = hwGetFileAttr(lpszFileName);
\r
615 if ( dwFileSize > 5*1024*1024 )
\r
617 m_csLastError.Format ( _T("File [%s] too big. File size is : %s"), lpszFileName, FormatBytes(dwFileSize) );
\r
620 char *pBuf = new char[dwFileSize+1];
\r
623 ::AfxThrowMemoryException ();
\r
627 if(!Send ( csAttach ))
\r
634 if ( !file.Open ( lpszFileName, CFile::modeRead ) )
\r
636 m_csLastError.Format ( _T("Open file [%s] failed"), lpszFileName );
\r
639 UINT nFileLen = file.Read ( pBuf, dwFileSize );
\r
640 CBase64 Base64Encode;
\r
641 filedata = Base64Encode.Encode ( pBuf, nFileLen );
\r
642 filedata += _T("\r\n\r\n");
\r
644 catch ( CFileException e )
\r
647 m_csLastError.Format ( _T("Read file [%s] failed"), lpszFileName );
\r
652 if(!SendBuffer( filedata.GetBuffer() ))
\r
659 //return Send ( csAttach );
\r
662 CString CHwSMTP::GetLastErrorText()
\r
664 return m_csLastError;
\r
668 DWORD WINAPI ThreadProc_SendEmail( LPVOID lpParameter )
\r
670 CEMailObject *pEMailObject = (CEMailObject*)lpParameter;
\r
671 ASSERT ( pEMailObject );
\r
674 BOOL bRet = HwSMTP.SendEmail (
\r
675 pEMailObject->m_csSmtpSrvHost,
\r
676 pEMailObject->m_csUserName,
\r
677 pEMailObject->m_csPasswd,
\r
678 pEMailObject->m_bMustAuth,
\r
679 pEMailObject->m_csAddrFrom,
\r
680 pEMailObject->m_csAddrTo,
\r
681 pEMailObject->m_csSubject,
\r
682 pEMailObject->m_csBody,
\r
683 pEMailObject->m_csCharSet,
\r
684 &pEMailObject->m_StrAryAttach,
\r
685 pEMailObject->m_StrCC,
\r
686 pEMailObject->m_nSmtpSrvPort,
\r
687 pEMailObject->m_csSender
\r
692 CString csError = HwSMTP.GetLastErrorText ();
\r
693 csError = FormatString ( _T("Send a email to [%s] failed."), pEMailObject->m_csSmtpSrvHost );
\r
694 AfxMessageBox ( csError );
\r
698 m_CSFor__g_PtrAry_Threads.Lock ();
\r
699 int nFindPos = FindFromArray ( g_PtrAry_Threads, pEMailObject->m_hThread );
\r
700 if ( nFindPos >= 0 )
\r
701 g_PtrAry_Threads.RemoveAt ( nFindPos );
\r
702 m_CSFor__g_PtrAry_Threads.Unlock ();
\r
704 delete pEMailObject;
\r
709 // Óà SMTP ·þÎñ·¢Ë͵ç×ÓÓʼþ£¬Èç¹ûÉèÖòÎÊý bViaThreadSend=TRUE£¬ÄÇÔÚ³ÌÐò½áÊøʱӦ¸ÃÔÚ ExitInstance() Öе÷Óà EndOfSMTP() º¯Êý
\r
712 BOOL bViaThreadSend,
\r
713 LPCTSTR lpszSmtpSrvHost,
\r
714 LPCTSTR lpszUserName,
\r
715 LPCTSTR lpszPasswd,
\r
717 LPCTSTR lpszAddrFrom,
\r
718 LPCTSTR lpszAddrTo,
\r
719 LPCTSTR lpszFromName,
\r
720 LPCTSTR lpszReceiverName,
\r
721 LPCTSTR lpszSubject,
\r
723 LPCTSTR lpszCharSet/*=NULL*/,
\r
724 CStringArray *pStrAryAttach/*=NULL*/,
\r
725 LPCTSTR pStrAryCC/*=NULL*/,
\r
726 UINT nSmtpSrvPort/*=25*/,
\r
727 LPCTSTR lpszSender,
\r
731 if ( !lpszSmtpSrvHost || lstrlen(lpszSmtpSrvHost) < 1 ||
\r
732 !lpszSubject || lstrlen(lpszSubject) < 1 ||
\r
733 !lpszBody || lstrlen(lpszBody) < 1 )
\r
735 AfxMessageBox ( _T("Parameter error !") );
\r
739 CEMailObject *pEMailObject = new CEMailObject (
\r
757 if ( !pEMailObject ) return FALSE;
\r
760 if ( bViaThreadSend )
\r
762 DWORD dwThreadId = 0;
\r
763 pEMailObject->m_hThread = ::CreateThread ( NULL, 0, ::ThreadProc_SendEmail, pEMailObject, CREATE_SUSPENDED, &dwThreadId );
\r
764 bRet = HANDLE_IS_VALID(pEMailObject->m_hThread);
\r
765 m_CSFor__g_PtrAry_Threads.Lock();
\r
766 g_PtrAry_Threads.Add ( pEMailObject->m_hThread );
\r
767 m_CSFor__g_PtrAry_Threads.Unlock();
\r
768 ResumeThread ( pEMailObject->m_hThread );
\r
772 bRet = (BOOL)ThreadProc_SendEmail ( pEMailObject );
\r
780 // µÈ´ýËùÓÐÏß³ÌÖ´ÐÐÍê±Ï
\r
781 for ( int i=0; i<g_PtrAry_Threads.GetSize(); i++ )
\r
783 HANDLE hThread = (HANDLE)g_PtrAry_Threads.GetAt(i);
\r
784 if ( HANDLE_IS_VALID(hThread) )
\r
786 WaitForThreadEnd ( &hThread, 30*1000 );
\r
789 g_PtrAry_Threads.RemoveAll ();
\r
794 // ½«×Ö·û´® lpszOrg ת»»Îª¶à×Ö½ÚµÄ×Ö·û´®£¬Èç¹û»¹ÒªÊ¹Óöà×Ö·û´®µÄ³¤¶È£¬¿ÉÒÔÓÃÒÔÏ·½Ê½À´Ê¹ÓÃÕâ¸öÀࣺ
\r
795 // CMultiByteString MultiByteString(_T("UNICODE×Ö·û´®"));
\r
796 // printf ( "ANSI ×Ö·û´®Îª£º %s£¬ ×Ö·û¸öÊýΪ£º %d £¬ ³¤¶ÈΪ£º %d×Ö½Ú\n", MultiByteString.GetBuffer(), MultiByteString.GetLength(), MultiByteString.GetSize() );
\r
798 CMultiByteString::CMultiByteString( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT char *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )
\r
800 m_bNewBuffer = FALSE;
\r
803 m_nCharactersNumber = 0;
\r
804 if ( !lpszOrg ) return;
\r
806 // ÅжÏÔʼ×Ö·û´®µÄ±àÂ뷽ʽ
\r
807 BOOL bOrgIsUnicode = FALSE;
\r
808 if ( nOrgStringEncodeType == STRING_IS_MULTICHARS ) bOrgIsUnicode = FALSE;
\r
809 else if ( nOrgStringEncodeType == STRING_IS_UNICODE ) bOrgIsUnicode = TRUE;
\r
813 bOrgIsUnicode = TRUE;
\r
815 bOrgIsUnicode = FALSE;
\r
819 // ¼ÆËã×Ö·û´®¸öÊýºÍÐèÒªµÄÄ¿±ê»º³å´óС
\r
820 if ( bOrgIsUnicode )
\r
822 m_nCharactersNumber = (int)wcslen((WCHAR*)lpszOrg);
\r
823 m_nDataSize = (m_nCharactersNumber + 1) * sizeof(WCHAR);
\r
827 m_nCharactersNumber = (int)strlen((char*)lpszOrg);
\r
828 m_nDataSize = (m_nCharactersNumber + 1) * sizeof(char);
\r
831 // ʹÓõ÷ÓÃÕß´«ÈëµÄ»º³å
\r
832 if ( pOutBuf && nOutBufSize > 0 )
\r
834 m_pszData = pOutBuf;
\r
835 m_nDataSize = nOutBufSize;
\r
837 // ×Ô¼ºÉêÇëÄڴ滺³å
\r
840 m_pszData = (char*)new BYTE[m_nDataSize];
\r
843 ::AfxThrowMemoryException ();
\r
846 m_bNewBuffer = TRUE;
\r
848 memset ( m_pszData, 0, m_nDataSize );
\r
850 if ( bOrgIsUnicode )
\r
852 m_nCharactersNumber = WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, m_nCharactersNumber, (LPSTR)m_pszData, m_nDataSize/sizeof(char)-1, NULL, NULL );
\r
853 if ( m_nCharactersNumber < 1 ) m_nCharactersNumber = (int)strlen ( m_pszData );
\r
857 m_nCharactersNumber = __min ( m_nCharactersNumber, (int)(m_nDataSize/sizeof(char)-1) );
\r
858 strncpy ( m_pszData, (const char*)lpszOrg, m_nCharactersNumber );
\r
859 m_nCharactersNumber = (int)strlen ( m_pszData );
\r
861 m_nDataSize = ( m_nCharactersNumber + 1 ) * sizeof(char);
\r
864 CMultiByteString::~CMultiByteString ()
\r
866 if ( m_bNewBuffer && m_pszData )
\r
868 delete[] m_pszData;
\r
873 // ½« lpszOrg ת»»Îª¸Ã³ÌÐòʹÓõıàÂë×Ö·û´®£¬Èç¹û¸Ã³ÌÐòÊÇ UNICODE ¾ÍתΪ UNICODE£¬Èç¹ûÊÇ ANSI ¾ÍתΪ ANSI µÄ
\r
875 CString GetCompatibleString ( LPVOID lpszOrg, BOOL bOrgIsUnicode, int nOrgLength/*=-1*/ )
\r
877 if ( !lpszOrg ) return _T("");
\r
882 if ( bOrgIsUnicode )
\r
884 if ( nOrgLength > 0 )
\r
886 WCHAR *szRet = new WCHAR[nOrgLength+1];
\r
887 if ( !szRet ) return _T("");
\r
888 memset ( szRet, 0, (nOrgLength+1)*sizeof(WCHAR) );
\r
889 memcpy ( szRet, lpszOrg, nOrgLength*sizeof(WCHAR) );
\r
890 CString csRet = szRet;
\r
894 else if ( nOrgLength == 0 )
\r
897 return (LPCTSTR)lpszOrg;
\r
900 if ( nOrgLength < 0 )
\r
901 nOrgLength = (int)strlen((const char*)lpszOrg);
\r
902 int nWideCount = nOrgLength + 1;
\r
903 WCHAR *wchar = new WCHAR[nWideCount];
\r
904 if ( !wchar ) return _T("");
\r
905 memset ( wchar, 0, nWideCount*sizeof(WCHAR) );
\r
906 ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszOrg, nOrgLength, wchar, nWideCount);
\r
907 CString csRet = wchar;
\r
911 if ( !bOrgIsUnicode )
\r
913 if ( nOrgLength > 0 )
\r
915 char *szRet = new char[nOrgLength+1];
\r
916 if ( !szRet ) return _T("");
\r
917 memset ( szRet, 0, (nOrgLength+1)*sizeof(char) );
\r
918 memcpy ( szRet, lpszOrg, nOrgLength*sizeof(char) );
\r
919 CString csRet = szRet;
\r
923 else if ( nOrgLength == 0 )
\r
926 return (LPCTSTR)lpszOrg;
\r
929 if ( nOrgLength < 0 )
\r
930 nOrgLength = (int)wcslen((WCHAR*)lpszOrg);
\r
931 int nMultiByteCount = nOrgLength + 1;
\r
932 char *szMultiByte = new char[nMultiByteCount];
\r
933 if ( !szMultiByte ) return _T("");
\r
934 memset ( szMultiByte, 0, nMultiByteCount*sizeof(char) );
\r
935 ::WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, nOrgLength, (LPSTR)szMultiByte, nMultiByteCount, NULL, NULL );
\r
936 CString csRet = szMultiByte;
\r
937 delete[] szMultiByte;
\r
950 CString FormatDateTime ( COleDateTime &DateTime, LPCTSTR pFormat )
\r
952 // If null, return empty string
\r
953 if ( DateTime.GetStatus() == COleDateTime::null || DateTime.GetStatus() == COleDateTime::invalid )
\r
957 if (S_OK != VarUdateFromDate(DateTime.m_dt, 0, &ud))
\r
963 tmTemp.tm_sec = ud.st.wSecond;
\r
964 tmTemp.tm_min = ud.st.wMinute;
\r
965 tmTemp.tm_hour = ud.st.wHour;
\r
966 tmTemp.tm_mday = ud.st.wDay;
\r
967 tmTemp.tm_mon = ud.st.wMonth - 1;
\r
968 tmTemp.tm_year = ud.st.wYear - 1900;
\r
969 tmTemp.tm_wday = ud.st.wDayOfWeek;
\r
970 tmTemp.tm_yday = ud.wDayOfYear - 1;
\r
971 tmTemp.tm_isdst = 0;
\r
974 LPTSTR lpszTemp = strDate.GetBufferSetLength(256);
\r
975 _tcsftime(lpszTemp, strDate.GetLength(), pFormat, &tmTemp);
\r
976 strDate.ReleaseBuffer();
\r
981 CString FormatString ( LPCTSTR lpszStr, ... )
\r
984 // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ
\r
985 for ( int nBufCount = 1024; nBufCount<5*1024*1024; nBufCount += 1024 )
\r
987 buf = new TCHAR[nBufCount];
\r
990 ::AfxThrowMemoryException ();
\r
993 memset ( buf, 0, nBufCount*sizeof(TCHAR) );
\r
996 va_start (va, lpszStr);
\r
997 int nLen = _vsnprintf_hw ((TCHAR*)buf, nBufCount-sizeof(TCHAR), lpszStr, va);
\r
999 if ( nLen <= (int)(nBufCount-sizeof(TCHAR)) )
\r
1001 delete[] buf; buf = NULL;
\r
1008 CString csMsg = buf;
\r
1009 delete[] buf; buf = NULL;
\r
1013 /********************************************************************************
\r
1014 * Function Type : Global
\r
1015 * Parameter : lpFileName - Îļþ·¾¶
\r
1016 * Return Value : -1 - ʧ°Ü
\r
1018 * Description : »ñÈ¡ÎļþÊôÐÔ ( Îļþ´óС¡¢´´½¨Ê±¼ä )
\r
1019 *********************************************************************************/
\r
1020 int hwGetFileAttr ( LPCTSTR lpFileName, OUT CFileStatus *pFileStatus/*=NULL*/ )
\r
1022 if ( !lpFileName || lstrlen(lpFileName) < 1 ) return -1;
\r
1024 CFileStatus fileStatus;
\r
1025 fileStatus.m_attribute = 0;
\r
1026 fileStatus.m_size = 0;
\r
1027 memset ( fileStatus.m_szFullName, 0, sizeof(fileStatus.m_szFullName) );
\r
1028 BOOL bRet = FALSE;
\r
1031 if ( CFile::GetStatus(lpFileName,fileStatus) )
\r
1036 CATCH (CFileException, e)
\r
1048 if ( pFileStatus )
\r
1050 pFileStatus->m_ctime = fileStatus.m_ctime;
\r
1051 pFileStatus->m_mtime = fileStatus.m_mtime;
\r
1052 pFileStatus->m_atime = fileStatus.m_atime;
\r
1053 pFileStatus->m_size = fileStatus.m_size;
\r
1054 pFileStatus->m_attribute = fileStatus.m_attribute;
\r
1055 pFileStatus->_m_padding = fileStatus._m_padding;
\r
1056 lstrcpy ( pFileStatus->m_szFullName, fileStatus.m_szFullName );
\r
1060 return (int)fileStatus.m_size;
\r
1064 // ½«Ò»¸ö±íʾ×Ö½ÚµÄÊýÓÿɶÁÐԺõÄ×Ö·û´®À´±íʾ£¬ÀýÈ罫 12345678 ×Ö½Úת»»Îª£º
\r
1066 // nFlag - 0 : ×Ô¶¯Æ¥Å䵥λ
\r
1067 // 1 : ÒÔ Kb Ϊµ¥Î»
\r
1068 // 2 : ÒÔ Mb Ϊµ¥Î»
\r
1069 // 3 : ÒÔ Gb Ϊµ¥Î»
\r
1071 CString FormatBytes ( double fBytesNum, BOOL bShowUnit/*=TRUE*/, int nFlag/*=0*/ )
\r
1076 if ( fBytesNum >= 1024.0 && fBytesNum < 1024.0*1024.0 )
\r
1077 csRes.Format ( _T("%.2f%s"), fBytesNum / 1024.0, bShowUnit?_T(" K"):_T("") );
\r
1078 else if ( fBytesNum >= 1024.0*1024.0 && fBytesNum < 1024.0*1024.0*1024.0 )
\r
1079 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0), bShowUnit?_T(" M"):_T("") );
\r
1080 else if ( fBytesNum >= 1024.0*1024.0*1024.0 )
\r
1081 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0*1024.0), bShowUnit?_T(" G"):_T("") );
\r
1083 csRes.Format ( _T("%.2f%s"), fBytesNum, bShowUnit?_T(" B"):_T("") );
\r
1085 else if ( nFlag == 1 )
\r
1087 csRes.Format ( _T("%.2f%s"), fBytesNum / 1024.0, bShowUnit?_T(" K"):_T("") );
\r
1089 else if ( nFlag == 2 )
\r
1091 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0), bShowUnit?_T(" M"):_T("") );
\r
1093 else if ( nFlag == 3 )
\r
1095 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0*1024.0), bShowUnit?_T(" G"):_T("") );
\r
1104 BOOL WaitForThreadEnd ( HANDLE *phThread, DWORD dwWaitTime /*=10*1000*/ )
\r
1107 ASSERT ( phThread );
\r
1108 if ( !(*phThread) ) return TRUE;
\r
1109 if ( ::WaitForSingleObject ( *phThread, dwWaitTime ) == WAIT_TIMEOUT )
\r
1112 ::TerminateThread ( *phThread, 0 );
\r
1114 ::CloseHandle ( *phThread );
\r
1115 (*phThread) = NULL;
\r