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_csPartBoundary = _T( "WC_MAIL_PaRt_BoUnDaRy_05151998" );
\r
97 m_csMIMEContentType = FormatString ( _T( "multipart/mixed; boundary=%s" ), m_csPartBoundary);
\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 = FormatString ( _T( "text/plain; %s" ), m_csCharSet);
\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 += FormatDateTime (tNow, _T("%a, %d %b %y %H:%M:%S %Z"));
\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
551 csSubject += FormatString ( _T("X-Mailer: TortoiseGit\r\nMIME-Version: 1.0\r\nContent-Type: %s\r\n\r\n"),
\r
552 m_csMIMEContentType );
\r
554 return Send ( csSubject );
\r
557 BOOL CHwSMTP::SendBody()
\r
559 CString csBody, csTemp;
\r
561 if ( m_StrAryAttach.GetSize() > 0 )
\r
563 csTemp.Format ( _T("%s\r\n\r\n"), m_csNoMIMEText );
\r
566 csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
\r
569 csTemp.Format ( _T("Content-Type: text/plain\r\n%sContent-Transfer-Encoding: 7Bit\r\n\r\n"),
\r
574 //csTemp.Format ( _T("%s\r\n"), m_csBody );
\r
575 csBody += m_csBody;
\r
576 csBody += _T("\r\n");
\r
578 return Send ( csBody );
\r
581 BOOL CHwSMTP::SendAttach()
\r
583 int nCountAttach = (int)m_StrAryAttach.GetSize();
\r
584 if ( nCountAttach < 1 ) return TRUE;
\r
586 for ( int i=0; i<nCountAttach; i++ )
\r
588 if ( !SendOnAttach ( m_StrAryAttach.GetAt(i) ) )
\r
595 BOOL CHwSMTP::SendOnAttach(LPCTSTR lpszFileName)
\r
597 ASSERT ( lpszFileName );
\r
598 CString csAttach, csTemp;
\r
600 csTemp = lpszFileName;
\r
601 CString csShortFileName = csTemp.GetBuffer(0) + csTemp.ReverseFind ( '\\' );
\r
602 csShortFileName.TrimLeft ( _T("\\") );
\r
604 csTemp.Format ( _T("--%s\r\n"), m_csPartBoundary );
\r
605 csAttach += csTemp;
\r
607 csTemp.Format ( _T("Content-Type: application/octet-stream; file=%s\r\n"), csShortFileName );
\r
608 csAttach += csTemp;
\r
610 csTemp.Format ( _T("Content-Transfer-Encoding: base64\r\n") );
\r
611 csAttach += csTemp;
\r
613 csTemp.Format ( _T("Content-Disposition: attachment; filename=%s\r\n\r\n"), csShortFileName );
\r
614 csAttach += csTemp;
\r
616 DWORD dwFileSize = hwGetFileAttr(lpszFileName);
\r
617 if ( dwFileSize > 5*1024*1024 )
\r
619 m_csLastError.Format ( _T("File [%s] too big. File size is : %s"), lpszFileName, FormatBytes(dwFileSize) );
\r
622 char *pBuf = new char[dwFileSize+1];
\r
625 ::AfxThrowMemoryException ();
\r
629 if(!Send ( csAttach ))
\r
636 if ( !file.Open ( lpszFileName, CFile::modeRead ) )
\r
638 m_csLastError.Format ( _T("Open file [%s] failed"), lpszFileName );
\r
641 UINT nFileLen = file.Read ( pBuf, dwFileSize );
\r
642 CBase64 Base64Encode;
\r
643 filedata = Base64Encode.Encode ( pBuf, nFileLen );
\r
644 filedata += _T("\r\n\r\n");
\r
646 catch ( CFileException e )
\r
649 m_csLastError.Format ( _T("Read file [%s] failed"), lpszFileName );
\r
654 if(!SendBuffer( filedata.GetBuffer() ))
\r
661 //return Send ( csAttach );
\r
664 CString CHwSMTP::GetLastErrorText()
\r
666 return m_csLastError;
\r
670 DWORD WINAPI ThreadProc_SendEmail( LPVOID lpParameter )
\r
672 CEMailObject *pEMailObject = (CEMailObject*)lpParameter;
\r
673 ASSERT ( pEMailObject );
\r
676 BOOL bRet = HwSMTP.SendEmail (
\r
677 pEMailObject->m_csSmtpSrvHost,
\r
678 pEMailObject->m_csUserName,
\r
679 pEMailObject->m_csPasswd,
\r
680 pEMailObject->m_bMustAuth,
\r
681 pEMailObject->m_csAddrFrom,
\r
682 pEMailObject->m_csAddrTo,
\r
683 pEMailObject->m_csSubject,
\r
684 pEMailObject->m_csBody,
\r
685 pEMailObject->m_csCharSet,
\r
686 &pEMailObject->m_StrAryAttach,
\r
687 pEMailObject->m_StrCC,
\r
688 pEMailObject->m_nSmtpSrvPort,
\r
689 pEMailObject->m_csSender
\r
694 CString csError = HwSMTP.GetLastErrorText ();
\r
695 csError = FormatString ( _T("Send a email to [%s] failed."), pEMailObject->m_csSmtpSrvHost );
\r
696 AfxMessageBox ( csError );
\r
700 m_CSFor__g_PtrAry_Threads.Lock ();
\r
701 int nFindPos = FindFromArray ( g_PtrAry_Threads, pEMailObject->m_hThread );
\r
702 if ( nFindPos >= 0 )
\r
703 g_PtrAry_Threads.RemoveAt ( nFindPos );
\r
704 m_CSFor__g_PtrAry_Threads.Unlock ();
\r
706 delete pEMailObject;
\r
711 // Óà SMTP ·þÎñ·¢Ë͵ç×ÓÓʼþ£¬Èç¹ûÉèÖòÎÊý bViaThreadSend=TRUE£¬ÄÇÔÚ³ÌÐò½áÊøʱӦ¸ÃÔÚ ExitInstance() Öе÷Óà EndOfSMTP() º¯Êý
\r
714 BOOL bViaThreadSend,
\r
715 LPCTSTR lpszSmtpSrvHost,
\r
716 LPCTSTR lpszUserName,
\r
717 LPCTSTR lpszPasswd,
\r
719 LPCTSTR lpszAddrFrom,
\r
720 LPCTSTR lpszAddrTo,
\r
721 LPCTSTR lpszFromName,
\r
722 LPCTSTR lpszReceiverName,
\r
723 LPCTSTR lpszSubject,
\r
725 LPCTSTR lpszCharSet/*=NULL*/,
\r
726 CStringArray *pStrAryAttach/*=NULL*/,
\r
727 LPCTSTR pStrAryCC/*=NULL*/,
\r
728 UINT nSmtpSrvPort/*=25*/,
\r
729 LPCTSTR lpszSender,
\r
733 if ( !lpszSmtpSrvHost || lstrlen(lpszSmtpSrvHost) < 1 ||
\r
734 !lpszSubject || lstrlen(lpszSubject) < 1 ||
\r
735 !lpszBody || lstrlen(lpszBody) < 1 )
\r
737 AfxMessageBox ( _T("Parameter error !") );
\r
741 CEMailObject *pEMailObject = new CEMailObject (
\r
759 if ( !pEMailObject ) return FALSE;
\r
762 if ( bViaThreadSend )
\r
764 DWORD dwThreadId = 0;
\r
765 pEMailObject->m_hThread = ::CreateThread ( NULL, 0, ::ThreadProc_SendEmail, pEMailObject, CREATE_SUSPENDED, &dwThreadId );
\r
766 bRet = HANDLE_IS_VALID(pEMailObject->m_hThread);
\r
767 m_CSFor__g_PtrAry_Threads.Lock();
\r
768 g_PtrAry_Threads.Add ( pEMailObject->m_hThread );
\r
769 m_CSFor__g_PtrAry_Threads.Unlock();
\r
770 ResumeThread ( pEMailObject->m_hThread );
\r
774 bRet = (BOOL)ThreadProc_SendEmail ( pEMailObject );
\r
782 // µÈ´ýËùÓÐÏß³ÌÖ´ÐÐÍê±Ï
\r
783 for ( int i=0; i<g_PtrAry_Threads.GetSize(); i++ )
\r
785 HANDLE hThread = (HANDLE)g_PtrAry_Threads.GetAt(i);
\r
786 if ( HANDLE_IS_VALID(hThread) )
\r
788 WaitForThreadEnd ( &hThread, 30*1000 );
\r
791 g_PtrAry_Threads.RemoveAll ();
\r
796 // ½«×Ö·û´® lpszOrg ת»»Îª¶à×Ö½ÚµÄ×Ö·û´®£¬Èç¹û»¹ÒªÊ¹Óöà×Ö·û´®µÄ³¤¶È£¬¿ÉÒÔÓÃÒÔÏ·½Ê½À´Ê¹ÓÃÕâ¸öÀࣺ
\r
797 // CMultiByteString MultiByteString(_T("UNICODE×Ö·û´®"));
\r
798 // printf ( "ANSI ×Ö·û´®Îª£º %s£¬ ×Ö·û¸öÊýΪ£º %d £¬ ³¤¶ÈΪ£º %d×Ö½Ú\n", MultiByteString.GetBuffer(), MultiByteString.GetLength(), MultiByteString.GetSize() );
\r
800 CMultiByteString::CMultiByteString( LPCTSTR lpszOrg, int nOrgStringEncodeType/*=STRING_IS_SOFTCODE*/, OUT char *pOutBuf/*=NULL*/, int nOutBufSize/*=0*/ )
\r
802 m_bNewBuffer = FALSE;
\r
805 m_nCharactersNumber = 0;
\r
806 if ( !lpszOrg ) return;
\r
808 // ÅжÏÔʼ×Ö·û´®µÄ±àÂ뷽ʽ
\r
809 BOOL bOrgIsUnicode = FALSE;
\r
810 if ( nOrgStringEncodeType == STRING_IS_MULTICHARS ) bOrgIsUnicode = FALSE;
\r
811 else if ( nOrgStringEncodeType == STRING_IS_UNICODE ) bOrgIsUnicode = TRUE;
\r
815 bOrgIsUnicode = TRUE;
\r
817 bOrgIsUnicode = FALSE;
\r
821 // ¼ÆËã×Ö·û´®¸öÊýºÍÐèÒªµÄÄ¿±ê»º³å´óС
\r
822 if ( bOrgIsUnicode )
\r
824 m_nCharactersNumber = (int)wcslen((WCHAR*)lpszOrg);
\r
825 m_nDataSize = (m_nCharactersNumber + 1) * sizeof(WCHAR);
\r
829 m_nCharactersNumber = (int)strlen((char*)lpszOrg);
\r
830 m_nDataSize = (m_nCharactersNumber + 1) * sizeof(char);
\r
833 // ʹÓõ÷ÓÃÕß´«ÈëµÄ»º³å
\r
834 if ( pOutBuf && nOutBufSize > 0 )
\r
836 m_pszData = pOutBuf;
\r
837 m_nDataSize = nOutBufSize;
\r
839 // ×Ô¼ºÉêÇëÄڴ滺³å
\r
842 m_pszData = (char*)new BYTE[m_nDataSize];
\r
845 ::AfxThrowMemoryException ();
\r
848 m_bNewBuffer = TRUE;
\r
850 memset ( m_pszData, 0, m_nDataSize );
\r
852 if ( bOrgIsUnicode )
\r
854 m_nCharactersNumber = WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, m_nCharactersNumber, (LPSTR)m_pszData, m_nDataSize/sizeof(char)-1, NULL, NULL );
\r
855 if ( m_nCharactersNumber < 1 ) m_nCharactersNumber = (int)strlen ( m_pszData );
\r
859 m_nCharactersNumber = __min ( m_nCharactersNumber, (int)(m_nDataSize/sizeof(char)-1) );
\r
860 strncpy ( m_pszData, (const char*)lpszOrg, m_nCharactersNumber );
\r
861 m_nCharactersNumber = (int)strlen ( m_pszData );
\r
863 m_nDataSize = ( m_nCharactersNumber + 1 ) * sizeof(char);
\r
866 CMultiByteString::~CMultiByteString ()
\r
868 if ( m_bNewBuffer && m_pszData )
\r
870 delete[] m_pszData;
\r
875 // ½« lpszOrg ת»»Îª¸Ã³ÌÐòʹÓõıàÂë×Ö·û´®£¬Èç¹û¸Ã³ÌÐòÊÇ UNICODE ¾ÍתΪ UNICODE£¬Èç¹ûÊÇ ANSI ¾ÍתΪ ANSI µÄ
\r
877 CString GetCompatibleString ( LPVOID lpszOrg, BOOL bOrgIsUnicode, int nOrgLength/*=-1*/ )
\r
879 if ( !lpszOrg ) return _T("");
\r
884 if ( bOrgIsUnicode )
\r
886 if ( nOrgLength > 0 )
\r
888 WCHAR *szRet = new WCHAR[nOrgLength+1];
\r
889 if ( !szRet ) return _T("");
\r
890 memset ( szRet, 0, (nOrgLength+1)*sizeof(WCHAR) );
\r
891 memcpy ( szRet, lpszOrg, nOrgLength*sizeof(WCHAR) );
\r
892 CString csRet = szRet;
\r
896 else if ( nOrgLength == 0 )
\r
899 return (LPCTSTR)lpszOrg;
\r
902 if ( nOrgLength < 0 )
\r
903 nOrgLength = (int)strlen((const char*)lpszOrg);
\r
904 int nWideCount = nOrgLength + 1;
\r
905 WCHAR *wchar = new WCHAR[nWideCount];
\r
906 if ( !wchar ) return _T("");
\r
907 memset ( wchar, 0, nWideCount*sizeof(WCHAR) );
\r
908 ::MultiByteToWideChar(CP_ACP, 0, (LPCSTR)lpszOrg, nOrgLength, wchar, nWideCount);
\r
909 CString csRet = wchar;
\r
913 if ( !bOrgIsUnicode )
\r
915 if ( nOrgLength > 0 )
\r
917 char *szRet = new char[nOrgLength+1];
\r
918 if ( !szRet ) return _T("");
\r
919 memset ( szRet, 0, (nOrgLength+1)*sizeof(char) );
\r
920 memcpy ( szRet, lpszOrg, nOrgLength*sizeof(char) );
\r
921 CString csRet = szRet;
\r
925 else if ( nOrgLength == 0 )
\r
928 return (LPCTSTR)lpszOrg;
\r
931 if ( nOrgLength < 0 )
\r
932 nOrgLength = (int)wcslen((WCHAR*)lpszOrg);
\r
933 int nMultiByteCount = nOrgLength + 1;
\r
934 char *szMultiByte = new char[nMultiByteCount];
\r
935 if ( !szMultiByte ) return _T("");
\r
936 memset ( szMultiByte, 0, nMultiByteCount*sizeof(char) );
\r
937 ::WideCharToMultiByte ( CP_ACP, 0, (LPCWSTR)lpszOrg, nOrgLength, (LPSTR)szMultiByte, nMultiByteCount, NULL, NULL );
\r
938 CString csRet = szMultiByte;
\r
939 delete[] szMultiByte;
\r
952 CString FormatDateTime ( COleDateTime &DateTime, LPCTSTR pFormat )
\r
954 // If null, return empty string
\r
955 if ( DateTime.GetStatus() == COleDateTime::null || DateTime.GetStatus() == COleDateTime::invalid )
\r
959 if (S_OK != VarUdateFromDate(DateTime.m_dt, 0, &ud))
\r
965 tmTemp.tm_sec = ud.st.wSecond;
\r
966 tmTemp.tm_min = ud.st.wMinute;
\r
967 tmTemp.tm_hour = ud.st.wHour;
\r
968 tmTemp.tm_mday = ud.st.wDay;
\r
969 tmTemp.tm_mon = ud.st.wMonth - 1;
\r
970 tmTemp.tm_year = ud.st.wYear - 1900;
\r
971 tmTemp.tm_wday = ud.st.wDayOfWeek;
\r
972 tmTemp.tm_yday = ud.wDayOfYear - 1;
\r
973 tmTemp.tm_isdst = 0;
\r
976 LPTSTR lpszTemp = strDate.GetBufferSetLength(256);
\r
977 _tcsftime(lpszTemp, strDate.GetLength(), pFormat, &tmTemp);
\r
978 strDate.ReleaseBuffer();
\r
983 CString FormatString ( LPCTSTR lpszStr, ... )
\r
986 // Ñ»·¸ñʽ»¯×Ö·û´®£¬Èç¹û»º³å²»¹»Ôò½«»º³å¼Ó´óÈ»ºóÖØÊÔÒÔ±£Ö¤»º³å¹»ÓÃͬʱÓÖ²»ÀË·Ñ
\r
987 for ( int nBufCount = 1024; nBufCount<5*1024*1024; nBufCount += 1024 )
\r
989 buf = new TCHAR[nBufCount];
\r
992 ::AfxThrowMemoryException ();
\r
995 memset ( buf, 0, nBufCount*sizeof(TCHAR) );
\r
998 va_start (va, lpszStr);
\r
999 int nLen = _vsnprintf_hw ((TCHAR*)buf, nBufCount-sizeof(TCHAR), lpszStr, va);
\r
1001 if ( nLen <= (int)(nBufCount-sizeof(TCHAR)) )
\r
1003 delete[] buf; buf = NULL;
\r
1010 CString csMsg = buf;
\r
1011 delete[] buf; buf = NULL;
\r
1015 /********************************************************************************
\r
1016 * Function Type : Global
\r
1017 * Parameter : lpFileName - Îļþ·¾¶
\r
1018 * Return Value : -1 - ʧ°Ü
\r
1020 * Description : »ñÈ¡ÎļþÊôÐÔ ( Îļþ´óС¡¢´´½¨Ê±¼ä )
\r
1021 *********************************************************************************/
\r
1022 int hwGetFileAttr ( LPCTSTR lpFileName, OUT CFileStatus *pFileStatus/*=NULL*/ )
\r
1024 if ( !lpFileName || lstrlen(lpFileName) < 1 ) return -1;
\r
1026 CFileStatus fileStatus;
\r
1027 fileStatus.m_attribute = 0;
\r
1028 fileStatus.m_size = 0;
\r
1029 memset ( fileStatus.m_szFullName, 0, sizeof(fileStatus.m_szFullName) );
\r
1030 BOOL bRet = FALSE;
\r
1033 if ( CFile::GetStatus(lpFileName,fileStatus) )
\r
1038 CATCH (CFileException, e)
\r
1050 if ( pFileStatus )
\r
1052 pFileStatus->m_ctime = fileStatus.m_ctime;
\r
1053 pFileStatus->m_mtime = fileStatus.m_mtime;
\r
1054 pFileStatus->m_atime = fileStatus.m_atime;
\r
1055 pFileStatus->m_size = fileStatus.m_size;
\r
1056 pFileStatus->m_attribute = fileStatus.m_attribute;
\r
1057 pFileStatus->_m_padding = fileStatus._m_padding;
\r
1058 lstrcpy ( pFileStatus->m_szFullName, fileStatus.m_szFullName );
\r
1062 return (int)fileStatus.m_size;
\r
1066 // ½«Ò»¸ö±íʾ×Ö½ÚµÄÊýÓÿɶÁÐԺõÄ×Ö·û´®À´±íʾ£¬ÀýÈ罫 12345678 ×Ö½Úת»»Îª£º
\r
1068 // nFlag - 0 : ×Ô¶¯Æ¥Å䵥λ
\r
1069 // 1 : ÒÔ Kb Ϊµ¥Î»
\r
1070 // 2 : ÒÔ Mb Ϊµ¥Î»
\r
1071 // 3 : ÒÔ Gb Ϊµ¥Î»
\r
1073 CString FormatBytes ( double fBytesNum, BOOL bShowUnit/*=TRUE*/, int nFlag/*=0*/ )
\r
1078 if ( fBytesNum >= 1024.0 && fBytesNum < 1024.0*1024.0 )
\r
1079 csRes.Format ( _T("%.2f%s"), fBytesNum / 1024.0, bShowUnit?_T(" K"):_T("") );
\r
1080 else if ( fBytesNum >= 1024.0*1024.0 && fBytesNum < 1024.0*1024.0*1024.0 )
\r
1081 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0), bShowUnit?_T(" M"):_T("") );
\r
1082 else if ( fBytesNum >= 1024.0*1024.0*1024.0 )
\r
1083 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0*1024.0), bShowUnit?_T(" G"):_T("") );
\r
1085 csRes.Format ( _T("%.2f%s"), fBytesNum, bShowUnit?_T(" B"):_T("") );
\r
1087 else if ( nFlag == 1 )
\r
1089 csRes.Format ( _T("%.2f%s"), fBytesNum / 1024.0, bShowUnit?_T(" K"):_T("") );
\r
1091 else if ( nFlag == 2 )
\r
1093 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0), bShowUnit?_T(" M"):_T("") );
\r
1095 else if ( nFlag == 3 )
\r
1097 csRes.Format ( _T("%.2f%s"), fBytesNum / (1024.0*1024.0*1024.0), bShowUnit?_T(" G"):_T("") );
\r
1106 BOOL WaitForThreadEnd ( HANDLE *phThread, DWORD dwWaitTime /*=10*1000*/ )
\r
1109 ASSERT ( phThread );
\r
1110 if ( !(*phThread) ) return TRUE;
\r
1111 if ( ::WaitForSingleObject ( *phThread, dwWaitTime ) == WAIT_TIMEOUT )
\r
1114 ::TerminateThread ( *phThread, 0 );
\r
1116 ::CloseHandle ( *phThread );
\r
1117 (*phThread) = NULL;
\r