www.pudn.com > 大型远程控制软件(偷窥者)源码大公开.zip > PeeperLib.cpp


/////////////////////////////////////////////////////////////////////////////// 
// 远程控制软件-偷窥者  开发库                                               // 
// 日期:2001/10/02                                                           // 
// 作者:刘东发                                                               // 
// Email:dongfa@yeah.net                                                     // 
// http://dongfa.yeah.net                                                    // 
// OICQ:5584173  阿东                                                        // 
// 作者声明:                                                                 // 
//     此部分代码全是作者所写,可以随便传播,但要保持文件的完整性,有问题     // 
// 或者意见请来信,谢谢!                                                      // 
/////////////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "PeeperLib.h" 
#include "PeeperZip.h" 
#include "Base64.h" 
#include  
#pragma comment(lib, "Wininet.lib") 
 
BOOL WINAPI PL_InitSocket() 
{ 
#define MAJOR_VERSION 1 
#define MINOR_VERSION 2 
 
	int nStatus = 0; 
	WORD wMajorVersion = MAJOR_VERSION; 
	WORD wMinorVersion = MINOR_VERSION; 
	WORD wVersionReqd = MAKEWORD(wMajorVersion, wMinorVersion); 
	WSADATA lpmyWSAData; 
	nStatus = ::WSAStartup(wVersionReqd, &lpmyWSAData);	 
	if(nStatus != 0) 
	{ 
		return FALSE; 
	} 
	 
	return TRUE; 
} 
 
BOOL WINAPI PL_TermSocket() 
{ 
	return (::WSACleanup() == 0)?TRUE : FALSE; 
} 
 
int WINAPI PL_SendSocketData(SOCKET s, BYTE *chData, int nLen, BYTE chFlag, UINT uFlag) 
{ 
	int nRet = INVALID_SOCKET; 
	if(s != INVALID_SOCKET) 
	{ 
		char *chTemp = new char[nLen + 3]; 
		ZeroMemory(chTemp, nLen + 3); 
		if(chFlag == PL_NONE) // only data 
		{ 
			if(chData != NULL) 
			{ 
				if(uFlag == MSG_OOB) 
				{ 
					//实际数据大小为N,以MSG_OOB发送时数据长度要加1 
					nLen += 1; 
				} 
				nRet = ::send(s, (char *)chData, nLen, uFlag); 
			} 
			else 
			{ 
				nRet = 0; 
			} 
		} 
		else  
		{ 
			chTemp[0] = chFlag; 
			if(chData != NULL) 
			{ 
				memcpy(chTemp + 1, chData, nLen); 
			} 
			else 
			{ 
				nLen = 0; 
			} 
			if(uFlag == MSG_OOB) 
			{ 
				//实际数据大小为N,以MSG_OOB发送时数据长度要加1 
				nLen += 1; 
			} 
			nRet = ::send(s, chTemp, nLen+1, uFlag); 
		} 
		delete []chTemp; 
	} 
 
	return nRet; 
} 
 
int WINAPI PL_ReadSocketData(SOCKET s, BYTE *chData, int nLen, BYTE *chFlag, UINT uFlag) 
{ 
	int nRet = INVALID_SOCKET; 
	if(s != INVALID_SOCKET) 
	{ 
		nRet = ::recv(s, (char *)chData, nLen, uFlag); 
		if(nRet > 0) 
		{ 
			if(chFlag != NULL) 
			{ 
				*chFlag = chData[0]; 
			} 
		} 
	} 
	return nRet; 
} 
 
HGLOBAL WINAPI PL_LZ77_Zip(HGLOBAL hUnZip) 
{ 
	int _n = ::GetTickCount(); 
 
	int nSize = ::GlobalSize(hUnZip); 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip); 
	HGLOBAL hZip = NULL; 
	if(nSize > 0 && lpData != NULL) 
	{ 
		const int nMax = 65536; 
		BYTE byTemp[nMax + 16]; 
		CCompressLZ77 cc; 
		WORD wFlag1 = 0; 
		WORD wFlag2 = 0; 
		int nLast = nSize; 
		int nReal = 0; 
		hZip = ::GlobalAlloc(GHND, nMax+16); 
		LPBYTE lpZipData = (LPBYTE)::GlobalLock(hZip); 
		int nPos = 0; 
		int nZipPos = 0; 
		while(nLast > 0) 
		{ 
			nReal = min(nLast, nMax); 
			nLast -= nReal; 
			if(nReal == nMax) 
			{ 
				wFlag1 = 0; 
			} 
			else 
			{ 
				wFlag1 = nReal; 
			} 
			memcpy(lpZipData + nZipPos, &wFlag1, sizeof(WORD)); 
			nZipPos += sizeof(WORD); 
			int nRetLen = 0; 
			nRetLen = cc.Compress(lpData + nPos, nReal, byTemp); 
			if(nRetLen == 0)		// can't compress the block 
			{ 
				wFlag2 = wFlag1; 
				memcpy(lpZipData + nZipPos, &wFlag2, sizeof(WORD)); 
				nZipPos += sizeof(WORD); 
				memcpy(lpZipData + nZipPos, lpData + nPos, nReal); 
				nZipPos += nReal; 
			} 
			else 
			{ 
				wFlag2 = (WORD)nRetLen; 
				memcpy(lpZipData + nZipPos, &wFlag2, sizeof(WORD)); 
				nZipPos += sizeof(WORD); 
				memcpy(lpZipData + nZipPos, byTemp, nRetLen); 
				nZipPos += nRetLen; 
			} 
			nPos += nReal; 
			::GlobalUnlock(hZip); 
			if(nLast > 0) 
			{ 
				hZip = ::GlobalReAlloc(hZip, nZipPos + nMax, 0); 
			} 
			else 
			{ 
				hZip = ::GlobalReAlloc(hZip, nZipPos, 0); 
			} 
 
			lpZipData = (LPBYTE)::GlobalLock(hZip); 
		} 
		::GlobalUnlock(hZip); 
	} 
	TRACE(_T("PL_LZ77_Zip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip)); 
	return hZip; 
} 
 
HGLOBAL WINAPI PL_LZ77_UnZip(HGLOBAL hZip) 
{ 
	int _n = ::GetTickCount(); 
	int nSize = ::GlobalSize(hZip); 
	LPBYTE lpZipData = (LPBYTE)::GlobalLock(hZip); 
	HGLOBAL hUnZip = NULL; 
	if(nSize > 0 && lpZipData != NULL) 
	{ 
		const int nMax = 65536; 
		BYTE byTemp[nMax + 16]; 
		CCompressLZ77 cc; 
		WORD wFlag1 = 0; 
		WORD wFlag2 = 0; 
		int nLast = nSize; 
		int nReal = 0; 
		hUnZip = ::GlobalAlloc(GHND, nMax+16); 
		LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip); 
		int nPos = 0; 
		int nZipPos = 0; 
		while(nLast > 0) 
		{ 
			memcpy(&wFlag1, lpZipData + nZipPos, sizeof(WORD)); 
			nZipPos += sizeof(WORD); 
			memcpy(&wFlag2, lpZipData + nZipPos, sizeof(WORD)); 
			nZipPos += sizeof(WORD); 
			nLast -= 2*sizeof(WORD); 
			if(wFlag1 == 0) 
			{ 
				nReal = nMax; 
			} 
			else 
			{ 
				nReal = wFlag1; 
			} 
			nLast -= wFlag2 ? (wFlag2) : nReal; 
			if(wFlag2 == wFlag1) 
			{ 
				memcpy(byTemp, lpZipData + nZipPos, nReal); 
				nZipPos += nReal; 
			} 
			else 
			{ 
//				if(AfxIsValidAddress(lpZipData + nZipPos, nReal)) 
				{ 
					if(!cc.Decompress(byTemp, nReal, lpZipData + nZipPos)) 
					{ 
						break ; 
					} 
				} 
				nZipPos += wFlag2; 
			} 
			memcpy(lpData + nPos, byTemp, nReal); 
			nPos += nReal; 
			::GlobalUnlock(hUnZip); 
			if(nLast > 0) 
			{ 
				if((::GlobalSize(hUnZip) - nPos) < nMax) 
				{ 
					hUnZip = ::GlobalReAlloc(hUnZip, nPos + nMax, 0); 
				} 
			} 
			else 
			{ 
				hUnZip = ::GlobalReAlloc(hUnZip, nPos, 0); 
			} 
			lpData = (LPBYTE)::GlobalLock(hUnZip); 
		} 
		::GlobalUnlock(hUnZip); 
	} 
	TRACE(_T("PL_LZ77_UnZip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip)); 
	return hUnZip; 
} 
 
HGLOBAL WINAPI PL_LZSS_Zip(HGLOBAL hUnZip) 
{ 
	int _n = ::GetTickCount(); 
 
	HGLOBAL hZip = NULL; 
 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip); 
	if(lpData != NULL) 
	{ 
		int nLen = ::GlobalSize(hUnZip); 
		C_LZSS lz; 
		hZip = lz.Encode((char *)lpData, nLen); 
		::GlobalUnlock(hUnZip); 
	} 
	TRACE(_T("PL_LZSS_Zip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip)); 
	return hZip; 
} 
 
HGLOBAL WINAPI PL_LZSS_UnZip(HGLOBAL hZip) 
{ 
	int _n = ::GetTickCount(); 
 
	HGLOBAL hUnZip = NULL; 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hZip); 
	if(lpData != NULL) 
	{ 
		int nLen = ::GlobalSize(hZip); 
		C_LZSS lz; 
		hUnZip = lz.Decode((char *)lpData, nLen); 
		::GlobalUnlock(hZip); 
	} 
 
	TRACE(_T("PL_LZSS_UnZip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip)); 
 
	return hUnZip; 
} 
 
HGLOBAL WINAPI PL_ARI_Zip(HGLOBAL hUnZip) 
{ 
	int _n = ::GetTickCount(); 
	HGLOBAL hZip = NULL; 
 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip); 
	if(lpData != NULL) 
	{ 
		int nLen = ::GlobalSize(hUnZip); 
		C_ARI lz; 
		hZip = lz.Encode((char *)lpData, nLen); 
		::GlobalUnlock(hUnZip); 
	} 
	TRACE(_T("PL_ARI_Zip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip)); 
 
	return hZip; 
} 
 
HGLOBAL WINAPI PL_ARI_UnZip(HGLOBAL hZip) 
{ 
	int _n = ::GetTickCount(); 
 
	HGLOBAL hUnZip = NULL; 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hZip); 
	if(lpData != NULL) 
	{ 
		int nLen = ::GlobalSize(hZip); 
		C_ARI lz; 
		hUnZip = lz.Decode((char *)lpData, nLen); 
		::GlobalUnlock(hZip); 
	} 
 
	TRACE(_T("PL_ARI_UnZip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip)); 
 
	return hUnZip; 
} 
 
HGLOBAL WINAPI PL_LZW_Zip(HGLOBAL hUnZip) 
{ 
	int _n = ::GetTickCount(); 
	HGLOBAL hZip = NULL; 
 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hUnZip); 
	if(lpData != NULL) 
	{ 
		int nLen = ::GlobalSize(hUnZip); 
		C_LZW lz; 
		hZip = lz.Encode((char *)lpData, nLen); 
		::GlobalUnlock(hUnZip); 
	} 
	TRACE(_T("PL_LZW_Zip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hUnZip), GlobalSize(hZip)); 
 
	return hZip; 
} 
 
HGLOBAL WINAPI PL_LZW_UnZip(HGLOBAL hZip) 
{ 
	int _n = ::GetTickCount(); 
 
	HGLOBAL hUnZip = NULL; 
	LPBYTE lpData = (LPBYTE)::GlobalLock(hZip); 
	if(lpData != NULL) 
	{ 
		int nLen = ::GlobalSize(hZip); 
		C_LZW lz; 
		hUnZip = lz.Decode((char *)lpData, nLen); 
		::GlobalUnlock(hZip); 
	} 
 
	TRACE(_T("PL_LZW_UnZip--Time:%d, %d-->%d.\n"), 
		GetTickCount() - _n, GlobalSize(hZip), GlobalSize(hUnZip)); 
 
	return hUnZip; 
} 
 
BOOL WINAPI PL_Bmp2Gry(HBITMAP hBmp, LPBYTE *lpGryData, SIZE *szGrySize) 
{ 
	//目前只支持256色 
	LPBYTE	lpBitsData = NULL; 
	int		nBmpSize = 0; 
	 
	BITMAPINFO *pInfo = NULL; 
	BITMAP  bm; 
	GetObject(hBmp, sizeof(BITMAP), &bm); 
	if(bm.bmBitsPixel != 8) 
	{ 
		return FALSE; 
	} 
	 
	szGrySize->cx = bm.bmWidth; szGrySize->cy = bm.bmHeight; 
	 
	nBmpSize = ((((bm.bmWidth * bm.bmBitsPixel) + 31) & ~31) >> 3) * bm.bmHeight; 
	lpBitsData = new BYTE[nBmpSize]; 
	memset(lpBitsData, 0, nBmpSize); 
	 
	pInfo = (BITMAPINFO*)new BYTE[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)]; 
	pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
	pInfo->bmiHeader.biWidth = bm.bmWidth; 
	pInfo->bmiHeader.biHeight = bm.bmHeight; 
	pInfo->bmiHeader.biPlanes = bm.bmPlanes; 
	pInfo->bmiHeader.biBitCount = bm.bmBitsPixel; 
	pInfo->bmiHeader.biCompression = BI_RGB; 
	pInfo->bmiHeader.biSizeImage = nBmpSize; 
	pInfo->bmiHeader.biXPelsPerMeter = 0; 
	pInfo->bmiHeader.biYPelsPerMeter = 0; 
	pInfo->bmiHeader.biClrUsed = 0; 
	pInfo->bmiHeader.biClrImportant = 0; 
	 
	HDC           hMemDC; 
	HBITMAP       hOldBitmap; 
	RGBQUAD       rgb[256]; 
	 
	memset(rgb, 0, 256); 
	hMemDC = CreateCompatibleDC(NULL); 
	hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBmp); 
	// Get the DIBSection's color table 
	GetDIBColorTable(hMemDC, 0, 256, rgb); 
	// Populate BITMAPINFO header info 
	// Now actually get the bits 
	CClientDC cdc( CWnd::GetDesktopWindow() ); 
	::GetDIBits(cdc.GetSafeHdc(), hBmp, 
		0, (WORD)bm.bmHeight, lpBitsData, pInfo, DIB_RGB_COLORS); 
	 
	*lpGryData = new BYTE[nBmpSize]; 
	memset(*lpGryData, 0, nBmpSize); 
	for(int i = 0; i < nBmpSize; i ++) 
	{ 
		int nIndex = lpBitsData[i]; 
		double r = (double)(rgb[nIndex].rgbRed); 
		double g = (double)(rgb[nIndex].rgbGreen); 
		double b = (double)(rgb[nIndex].rgbBlue); 
		BYTE c = (BYTE)(r*0.29900 + g*0.58700 + b*0.11400); 
		int pos = ((bm.bmHeight - (i/bm.bmWidth) - 1)*bm.bmWidth) + (i % bm.bmWidth); 
		(*lpGryData)[pos] = c; 
	} 
	SelectObject(hMemDC, hOldBitmap); 
	DeleteDC(hMemDC); 
	 
	delete []lpBitsData; 
	lpBitsData = NULL; 
 
	return TRUE; 
} 
 
BOOL WINAPI PL_DrawGry(HDC hDC, LPBYTE lpGryData, SIZE szGrySize) 
{ 
	//暂不实现 
	return TRUE; 
} 
 
HBITMAP WINAPI PL_GetBitmap(HWND hWnd) 
{ 
	HDC hWndDC = NULL; 
	HDC hMemDC = NULL; 
	HBITMAP hMemBmp = NULL; 
	HBITMAP hOldBmp = NULL; 
	RECT rect; 
	int w = 0, h = 0; 
 
	if(hWnd == NULL) 
	{ 
		hWnd = ::GetDesktopWindow(); 
	} 
	hWndDC = ::GetWindowDC(hWnd); 
	hMemDC = ::CreateCompatibleDC(hWndDC); 
	::GetWindowRect(hWnd, &rect); 
	w = rect.right - rect.left; 
	h = rect.bottom - rect.top; 
 
	hMemBmp = ::CreateCompatibleBitmap(hWndDC, w, h); 
 
	hOldBmp = (HBITMAP)::SelectObject(hMemDC, hMemBmp); 
	::BitBlt(hMemDC, 0, 0, w, h, hWndDC, 0, 0, SRCCOPY); 
 
	// Why??? 
	hMemBmp = (HBITMAP)::SelectObject(hMemDC, hOldBmp); 
 
	::DeleteObject(hOldBmp); 
	::ReleaseDC(NULL, hMemDC); 
	::ReleaseDC(NULL, hWndDC); 
 
	return hMemBmp; 
} 
 
BOOL WINAPI PL_DrawBmp(HDC hDC, LPRECT lpDCRect, HBITMAP hBmp, LPRECT lpBmpRect, CPalette* pPal) 
{ 
	HDC hMemDC = NULL; 
	BITMAP bm; 
 
	hMemDC = ::CreateCompatibleDC(hDC); 
	::GetObject(hBmp, sizeof(bm), &bm); 
	::SelectObject(hMemDC, hBmp); 
 
	if(lpBmpRect == NULL) 
	{ 
		if(lpDCRect != NULL) 
		{ 
			::SetStretchBltMode(hDC, COLORONCOLOR); 
			::StretchBlt(hDC, lpDCRect->left, lpDCRect->top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), 
				hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); 
		} 
		else 
		{ 
			::BitBlt(hDC, 0, 0, bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY); 
		} 
	} 
	else 
	{ 
		if(lpDCRect != NULL) 
		{ 
			::SetStretchBltMode(hDC, COLORONCOLOR); 
			::StretchBlt(hDC, lpDCRect->left, lpDCRect->top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect),  
				hMemDC, lpBmpRect->left, lpBmpRect->top, RECTWIDTH(lpBmpRect), RECTHEIGHT(lpBmpRect), SRCCOPY); 
		} 
		else 
		{ 
			::BitBlt(hDC, 0, 0, RECTWIDTH(lpBmpRect), RECTHEIGHT(lpBmpRect),  
				hMemDC, lpDCRect->left, lpDCRect->top, SRCCOPY); 
		} 
	} 
	::ReleaseDC(NULL, hMemDC); 
 
	return TRUE; 
} 
 
int WINAPI PL_ColorsNum(LPBYTE lpbi) 
{ 
	WORD wBitCount = 0; 
	if(IS_WIN30_DIB(lpbi)) 
	{ 
		DWORD dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed; 
		if(dwClrUsed != 0) 
			return dwClrUsed; 
	} 
	if(IS_WIN30_DIB(lpbi)) 
		wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; 
	else 
		wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount; 
 
	switch (wBitCount) 
	{ 
		case 1: 
			return 2; 
 
		case 4: 
			return 16; 
 
		case 8: 
			return 256; 
 
		default: 
			return 0; 
	} 
} 
 
int WINAPI PL_DIBWidth(LPBYTE lpDIB) 
{ 
	LPBITMAPINFOHEADER lpbmi; 
	LPBITMAPCOREHEADER lpbmc; 
 
	lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
	lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
	if (IS_WIN30_DIB(lpDIB)) 
		return lpbmi->biWidth; 
	else 
		return lpbmc->bcWidth; 
} 
 
int WINAPI PL_DIBHeight(LPBYTE lpDIB) 
{ 
	LPBITMAPINFOHEADER lpbmi; 
	LPBITMAPCOREHEADER lpbmc; 
 
	lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
	lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
	if (IS_WIN30_DIB(lpDIB)) 
		return lpbmi->biHeight; 
	else 
		return lpbmc->bcHeight; 
} 
 
int WINAPI PL_PaletteSize(LPBYTE lpbi) 
{ 
   if(IS_WIN30_DIB(lpbi)) 
	  return (WORD)(::PL_ColorsNum(lpbi)*sizeof(RGBQUAD)); 
   else 
	  return (WORD)(::PL_ColorsNum(lpbi)*sizeof(RGBTRIPLE)); 
} 
 
HDIB WINAPI PL_BmpToDIB(HBITMAP hBitmap, HPALETTE hPal, int nBits) 
{ 
    BITMAP              bm; 
    BITMAPINFOHEADER    bi; 
    LPBITMAPINFOHEADER  lpbi; 
    DWORD               dwLen; 
    HANDLE              hDIB, h; 
    HDC                 hDC; 
    WORD                biBits; 
 
    if(!hBitmap) 
        return NULL; 
 
    if(!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm)) 
        return NULL; 
    if (hPal == NULL) 
        hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); 
    biBits = bm.bmPlanes * bm.bmBitsPixel; 
    if (biBits <= 1) 
        biBits = 1; 
    else if (biBits <= 4) 
        biBits = 4; 
    else if (biBits <= 8) 
        biBits = 8; 
    else 
        biBits = 24; 
	if(nBits != -1) 
	{ 
		if(nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24) 
		{ 
			biBits = nBits; 
		} 
	} 
    bi.biSize = sizeof(BITMAPINFOHEADER); 
    bi.biWidth = bm.bmWidth; 
    bi.biHeight = bm.bmHeight; 
    bi.biPlanes = 1; 
    bi.biBitCount = biBits; 
    bi.biCompression = BI_RGB; 
    bi.biSizeImage = 0; 
    bi.biXPelsPerMeter = 0; 
    bi.biYPelsPerMeter = 0; 
    bi.biClrUsed = 0; 
    bi.biClrImportant = 0; 
    dwLen = bi.biSize + PL_PaletteSize((LPBYTE)&bi); 
 
    hDC = GetDC(NULL); 
    hPal = SelectPalette(hDC, hPal, FALSE); 
    RealizePalette(hDC); 
    hDIB = GlobalAlloc(GHND, dwLen); 
    if (!hDIB) 
    { 
      SelectPalette(hDC, hPal, TRUE); 
      RealizePalette(hDC); 
      ReleaseDC(NULL, hDC); 
      return NULL; 
    } 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 
    *lpbi = bi; 
    GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi, 
        DIB_RGB_COLORS); 
    bi = *lpbi; 
    GlobalUnlock(hDIB); 
 
    if (bi.biSizeImage == 0) 
        bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight; 
    dwLen = bi.biSize + PL_PaletteSize((LPBYTE)&bi) + bi.biSizeImage; 
 
    if (h = GlobalReAlloc(hDIB, dwLen, 0)) 
        hDIB = h; 
    else 
    { 
        GlobalFree(hDIB); 
        hDIB = NULL; 
        SelectPalette(hDC, hPal, TRUE); 
        RealizePalette(hDC); 
        ReleaseDC(NULL, hDC); 
        return NULL; 
    } 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 
    if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi + 
            (WORD)lpbi->biSize + PL_PaletteSize((LPBYTE)lpbi), (LPBITMAPINFO)lpbi, 
            DIB_RGB_COLORS) == 0) 
    { 
        GlobalUnlock(hDIB); 
        hDIB = NULL; 
        SelectPalette(hDC, hPal, TRUE); 
        RealizePalette(hDC); 
        ReleaseDC(NULL, hDC); 
        return NULL; 
    } 
 
    bi = *lpbi; 
    GlobalUnlock(hDIB); 
    SelectPalette(hDC, hPal, TRUE); 
    RealizePalette(hDC); 
    ReleaseDC(NULL, hDC); 
 
    return (HDIB) hDIB; 
} 
 
BOOL WINAPI PL_CreateDIBPalette(HDIB hDIB, CPalette* pPal) 
{ 
	LPLOGPALETTE lpPal = NULL; 
	HANDLE hLogPal = NULL; 
	HPALETTE hPal = NULL; 
	int i;                   // loop index 
	WORD wNumColors;         // number of colors in color table 
	LPSTR lpbi;              // pointer to packed-DIB 
	LPBITMAPINFO lpbmi;      // pointer to BITMAPINFO structure (Win3.0) 
	LPBITMAPCOREINFO lpbmc;  // pointer to BITMAPCOREINFO structure (old) 
	BOOL bWinStyleDIB;       // flag which signifies whether this is a Win3.0 DIB 
	BOOL bResult = FALSE; 
	 
	if (hDIB == NULL) 
		return FALSE; 
	 
	lpbi = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); 
	 
	lpbmi = (LPBITMAPINFO)lpbi; 
	 
	lpbmc = (LPBITMAPCOREINFO)lpbi; 
	 
	wNumColors = ::PL_ColorsNum((LPBYTE)lpbi); 
	 
	if (wNumColors != 0) 
	{ 
		hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) 
			+ sizeof(PALETTEENTRY) * wNumColors); 
		 
		if (hLogPal == 0) 
		{ 
			::GlobalUnlock((HGLOBAL) hDIB); 
			return FALSE; 
		} 
		 
		lpPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL) hLogPal); 
		 
		lpPal->palVersion = PALVERSION; 
		lpPal->palNumEntries = (WORD)wNumColors; 
		 
		bWinStyleDIB = IS_WIN30_DIB(lpbi); 
		for (i = 0; i < (int)wNumColors; i++) 
		{ 
			if (bWinStyleDIB) 
			{ 
				lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; 
				lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; 
				lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; 
				lpPal->palPalEntry[i].peFlags = 0; 
			} 
			else 
			{ 
				lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; 
				lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; 
				lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; 
				lpPal->palPalEntry[i].peFlags = 0; 
			} 
		} 
		 
		bResult = pPal->CreatePalette(lpPal); 
		::GlobalUnlock((HGLOBAL) hLogPal); 
		::GlobalFree((HGLOBAL) hLogPal); 
	} 
	 
	::GlobalUnlock((HGLOBAL) hDIB); 
	 
	return bResult; 
} 
 
LPBYTE WINAPI PL_DIBBits(LPBYTE lpbi) 
{ 
	return (lpbi + *(LPDWORD)lpbi + ::PL_PaletteSize(lpbi)); 
} 
 
BOOL WINAPI PL_DrawDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB,  
					   LPRECT lpDIBRect, CPalette* pPal) 
{ 
	LPSTR    lpDIBHdr; 
	LPSTR    lpDIBBits; 
	BOOL     bSuccess = FALSE; 
	HPALETTE hPal = NULL; 
	HPALETTE hOldPal = NULL; 
	 
	if(hDIB == NULL) 
		return -1; 
	lpDIBHdr  = (LPSTR)::GlobalLock((HGLOBAL) hDIB); 
	lpDIBBits = (LPSTR)::PL_DIBBits((LPBYTE)lpDIBHdr); 
	 
	if(pPal != NULL) 
	{ 
		hPal = (HPALETTE) pPal->m_hObject; 
		hOldPal = ::SelectPalette(hDC, hPal, TRUE); 
	} 
 
	if(lpDIBRect == NULL) 
	{ 
		if(lpDCRect != NULL) 
		{ 
			::SetStretchBltMode(hDC, COLORONCOLOR); 
			 
			bSuccess = ::StretchDIBits(hDC, lpDCRect->left, lpDCRect->top, 
				RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), 0, 0,  
				PL_DIBWidth((LPBYTE)lpDIBHdr), PL_DIBHeight((LPBYTE)lpDIBHdr), 
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); 
		} 
		else 
		{ 
			bSuccess = ::SetDIBitsToDevice(hDC, 0, 0, 
				PL_DIBWidth((LPBYTE)lpDIBHdr), PL_DIBHeight((LPBYTE)lpDIBHdr), 
				0, 0, 0, PL_DIBHeight((LPBYTE)lpDIBHdr), 
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS); 
		} 
	} 
	else 
	{ 
		if(lpDCRect != NULL) 
		{ 
			::SetStretchBltMode(hDC, COLORONCOLOR); 
	 
			bSuccess = ::StretchDIBits(hDC, lpDCRect->left, lpDCRect->top, 
				RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), 
				lpDIBRect->left, lpDIBRect->top,  
				RECTWIDTH(lpDIBRect), RECTHEIGHT(lpDIBRect), 
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY); 
 
		} 
		else 
		{ 
			bSuccess = ::SetDIBitsToDevice(hDC, 0, 0, 
				RECTWIDTH(lpDIBRect), RECTHEIGHT(lpDIBRect), 
				0, 0, 0, RECTHEIGHT(lpDIBRect), 
				lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS); 
 
		} 
	} 
 
	::GlobalUnlock((HGLOBAL)hDIB); 
	if (hOldPal != NULL) 
	{ 
		::SelectPalette(hDC, hOldPal, TRUE); 
	} 
	 
	return bSuccess; 
} 
 
SIZE WINAPI PL_GetScreenSize() 
{ 
	SIZE sz; 
	sz.cx = ::GetSystemMetrics(SM_CXSCREEN); 
	sz.cy = ::GetSystemMetrics(SM_CYSCREEN); 
	return sz; 
} 
 
void WINAPI PL_MouseMove(POINT point) 
{ 
	::SetCursorPos(point.x, point.y); 
} 
 
void WINAPI PL_MouseLButtonDown(POINT point, BOOL bMove) 
{ 
	if(bMove) 
	{ 
		::PL_MouseMove(point); 
	} 
	::mouse_event(MOUSEEVENTF_LEFTDOWN, point.x, point.y, 0, 0); 
} 
 
void WINAPI PL_MouseLButtonUp(POINT point, BOOL bMove) 
{ 
	if(bMove) 
	{ 
		::PL_MouseMove(point); 
	} 
	::mouse_event(MOUSEEVENTF_LEFTUP, point.x, point.y, 0, 0); 
} 
 
void WINAPI PL_MouseRButtonDown(POINT point, BOOL bMove) 
{ 
	if(bMove) 
	{ 
		::PL_MouseMove(point); 
	} 
	::mouse_event(MOUSEEVENTF_RIGHTDOWN, point.x, point.y, 0, 0); 
} 
 
void WINAPI PL_MouseRButtonUp(POINT point, BOOL bMove) 
{ 
	if(bMove) 
	{ 
		::PL_MouseMove(point); 
	} 
	::mouse_event(MOUSEEVENTF_RIGHTUP, point.x, point.y, 0, 0); 
} 
 
void WINAPI PL_MouseLButtonDblClk(POINT point, BOOL bMove) 
{ 
	if(bMove) 
	{ 
		::PL_MouseMove(point); 
	} 
	::PL_MouseLButtonDown(point); 
	::PL_MouseLButtonUp(point); 
	::PL_MouseLButtonDown(point); 
	::PL_MouseLButtonUp(point); 
} 
 
void WINAPI PL_MouseRButtonDblClk(POINT point, BOOL bMove) 
{ 
	if(bMove) 
	{ 
		::PL_MouseMove(point); 
	} 
	::PL_MouseRButtonDown(point); 
	::PL_MouseRButtonUp(point); 
	::PL_MouseRButtonDown(point); 
	::PL_MouseRButtonUp(point); 
} 
 
void WINAPI PL_KeyDown(UINT uChar, UINT uFlag) 
{ 
	::keybd_event((BYTE)uChar, (BYTE)uChar, 0, 0); 
} 
 
void WINAPI PL_KeyUp(UINT uChar, UINT uFlag) 
{ 
	::keybd_event((BYTE)uChar, (BYTE)uChar, KEYEVENTF_KEYUP, 0); 
} 
 
BOOL WINAPI PL_GetHostName(char *chIP, char *chName) 
{ 
	BOOL bRet = FALSE; 
	char chTemp[256]; 
	hostent* pEnt = NULL; 
	ZeroMemory(chTemp, 256); 
	int nRet = ::gethostname(chTemp, 256); 
	if(nRet == 0) 
	{ 
		if(AfxIsValidAddress(chName, strlen(chTemp))) 
		{ 
			strcpy(chName, chTemp); 
			bRet = TRUE; 
		} 
		if(AfxIsValidAddress(chIP, 16)) 
		{ 
			pEnt = ::gethostbyname(chTemp); 
			if(pEnt) 
			{ 
				sprintf(chIP, "%d.%d.%d.%d",  
					BYTE(pEnt->h_addr_list[0][0]), BYTE(pEnt->h_addr_list[0][1]), 
					BYTE(pEnt->h_addr_list[0][2]), BYTE(pEnt->h_addr_list[0][3])); 
				bRet = TRUE; 
			} 
			else 
			{ 
				bRet = FALSE; 
			} 
		} 
	} 
	return bRet; 
} 
 
int WINAPI PL_ExecuteCommand(char *chCommandLine) 
{ 
	return ::WinExec(chCommandLine, SW_NORMAL); 
} 
 
void WINAPI PL_LockDesktop(BOOL bLock) 
{ 
	::ShowCursor(!bLock); 
	::SystemParametersInfo(SPI_SETFASTTASKSWITCH, (int)(!bLock), NULL, 0); 
	::SystemParametersInfo(SPI_SCREENSAVERRUNNING, (int)bLock, NULL, 0); 
	::EnableWindow(::GetDesktopWindow(), !bLock); 
} 
 
BOOL WINAPI PL_ExitWindow(UINT uFlag) 
{ 
	HANDLE hToken = NULL; 
	TOKEN_PRIVILEGES tkp; 
	BOOL fResult = FALSE; 
	if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
	{ 
		if(LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) 
		{ 
			tkp.PrivilegeCount = 1; 
			tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
			if(AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0)) 
			{ 
				return ::ExitWindowsEx(uFlag, 0); 
			} 
		} 
	} 
	 
	return ::ExitWindowsEx(uFlag, 0); 
} 
 
void WINAPI PL_Send_CtrlAltDel() 
{ 
	::PL_KeyDown(VK_CONTROL, 0); 
	::PL_KeyDown(VK_MENU, 0); 
	::PL_KeyDown(VK_DELETE, 0); 
	::Sleep(2000); 
	::PL_KeyUp(VK_CONTROL, 0); 
	::PL_KeyUp(VK_MENU, 0); 
	::PL_KeyUp(VK_DELETE, 0); 
} 
 
BOOL WINAPI PL_CopyFileClient(CString strIP, UINT uPort, char *chSrc,  
							  BOOL bSend, HWND hNotifyWnd) 
{ 
	BOOL bRet = FALSE; 
	CSocket sckClient; 
	CFile file; 
	do 
	{ 
		if(bSend) 
		{ 
			bRet = file.Open(chSrc, CFile::modeRead); 
		} 
		else 
		{ 
			bRet = file.Open(chSrc, CFile::modeCreate | CFile::modeWrite); 
		} 
		if(!bRet) 
		{ 
			break ; 
		} 
		bRet = sckClient.Create(); 
		if(!bRet) 
		{ 
			break ; 
		} 
		bRet = sckClient.Connect(strIP, uPort); 
		if(!bRet) 
		{ 
			break ; 
		} 
		BYTE *chFileData = new BYTE[PL_SOCKET_MAXBYTES+1]; 
		char chData[10]; 
		int nSize = 0; 
		if(bSend) 
		{ 
			nSize = file.GetLength(); 
			int nRead = nSize; 
			ZeroMemory(chData, 10); 
			memcpy(chData, &nSize, sizeof(int)); 
			int nRet = sckClient.Send(chData, sizeof(int)); 
			if(nRet <= 0) 
			{ 
				bRet = FALSE; 
				break ; 
			} 
			while(nRead > 0) 
			{ 
				int n1 = min(nRead, PL_SOCKET_MAXBYTES); 
				int n2 = file.Read(chFileData, n1); 
				nRead -= n2; 
				nRet = sckClient.Send(chFileData, n2); 
				if(nRet <= 0) 
				{ 
					bRet = FALSE; 
					break ; 
				} 
				if(hNotifyWnd != NULL) 
				{ 
					int nProgress = (int)(((float)(nSize - nRead))*100.0f/((float)nSize)); 
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE,  
						(WPARAM)nProgress, NULL); 
				} 
				bRet = TRUE; 
			} 
		} 
		else 
		{ 
			char chData[10]; 
			ZeroMemory(chData, 10); 
			nSize = 0; 
			int nRet = sckClient.Receive(chData, 10);//读文件大小 
			if(nRet <= 0) 
			{ 
				bRet = FALSE; 
				break ; 
			} 
			nSize = *((int*)(chData)); 
			if(nSize <= 0) 
			{ 
				bRet = FALSE; 
				break ; 
			} 
			BYTE *chFileData = new BYTE[PL_SOCKET_MAXBYTES+1]; 
			int nWrite = 0; 
			while(nWrite < nSize) 
			{ 
				nRet = sckClient.Receive(chFileData, PL_SOCKET_MAXBYTES); 
				if(nRet <= 0) 
				{ 
					bRet = FALSE; 
					break ; 
				} 
				file.Write(chFileData, nRet); 
				nWrite += nRet; 
				if(hNotifyWnd != NULL) 
				{ 
					int nProgress = (int)(((float)nWrite)*100.0f/((float)nSize)); 
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE,  
						(WPARAM)nProgress, NULL); 
				} 
				bRet = TRUE; 
			} 
		} 
		delete []chFileData; 
		if(!bRet) // 送文件数据出错. 
		{ 
			break ; 
		} 
	}while(0); 
	if(sckClient.m_hSocket !=	INVALID_SOCKET) 
	{ 
		sckClient.Close(); 
	} 
	if(file.m_hFile != CFile::hFileNull) 
	{ 
		file.Close(); 
	} 
 
	return bRet; 
} 
 
BOOL WINAPI PL_CopyFileServer(UINT uPort, char *chDes, BOOL bSend, HWND hNotifyWnd) 
{ 
	BOOL bRet = FALSE; 
	CFile file; 
	CSocket sckServer; 
	CSocket sckClient; 
	do 
	{ 
		if(!bSend) 
		{ 
			bRet = file.Open(chDes, CFile::modeCreate | CFile::modeWrite); 
		} 
		else 
		{ 
			bRet = file.Open(chDes, CFile::modeRead); 
		} 
		if(!bRet) 
		{ 
			break ; 
		} 
		bRet = sckServer.Create(uPort); 
		if(!bRet) 
		{ 
			break ; 
		} 
		bRet = sckServer.Listen(); 
		if(!bRet) 
		{ 
			break ; 
		} 
		bRet = sckServer.Accept(sckClient); 
		if(!bRet) 
		{ 
			break ; 
		} 
		char chData[10]; 
		BYTE *chFileData = new BYTE[PL_SOCKET_MAXBYTES+1]; 
		int nSize = 0; 
		if(!bSend) 
		{ 
			ZeroMemory(chData, 10); 
			int nRet = sckClient.Receive(chData, 10);//读文件大小 
			if(nRet <= 0) 
			{ 
				bRet = FALSE; 
				break ; 
			} 
			nSize = *((int*)(chData)); 
			if(nSize <= 0) 
			{ 
				bRet = FALSE; 
				break ; 
			} 
			int nWrite = 0; 
			while(nWrite < nSize) 
			{ 
				nRet = sckClient.Receive(chFileData, PL_SOCKET_MAXBYTES); 
				if(nRet <= 0) 
				{ 
					bRet = FALSE; 
					break ; 
				} 
				file.Write(chFileData, nRet); 
				nWrite += nRet; 
				if(hNotifyWnd != NULL) 
				{ 
					int nProgress = (int)(((float)nWrite)*100.0f/((float)nSize)); 
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE,  
						(WPARAM)nProgress, NULL); 
				} 
				bRet = TRUE; 
			} 
		} 
		else 
		{ 
			nSize = file.GetLength(); 
			int nRead = nSize; 
			ZeroMemory(chData, 10); 
			memcpy(chData, &nSize, sizeof(int)); 
			int nRet = sckClient.Send(chData, sizeof(int)); 
			if(nRet <= 0) 
			{ 
				bRet = FALSE; 
				break ; 
			} 
			while(nRead > 0) 
			{ 
				int n1 = min(nRead, PL_SOCKET_MAXBYTES); 
				int n2 = file.Read(chFileData, n1); 
				nRead -= n2; 
				nRet = sckClient.Send(chFileData, n2); 
				if(nRet <= 0) 
				{ 
					bRet = FALSE; 
					break ; 
				} 
				if(hNotifyWnd != NULL) 
				{ 
					int nProgress = (int)(((float)(nSize - nRead))*100.0f/((float)nSize)); 
					::PostMessage(hNotifyWnd, PL_PEEPER_NOTIFY_COPYFILE,  
						(WPARAM)nProgress, NULL); 
				} 
				bRet = TRUE; 
			} 
		} 
		delete []chFileData; 
	}while(0); 
	if(sckClient.m_hSocket != INVALID_SOCKET) 
	{ 
		sckClient.Close(); 
	} 
	if(sckServer.m_hSocket != INVALID_SOCKET) 
	{ 
		sckServer.Close(); 
	} 
	if(file.m_hFile != CFile::hFileNull) 
	{ 
		file.Close(); 
	} 
 
	return bRet; 
} 
 
BOOL WINAPI PL_DeleteFile(char *chFileName) 
{ 
	BOOL bRet = FALSE; 
	DWORD dwFlag = ::SetFileAttributes(chFileName, FILE_ATTRIBUTE_NORMAL); 
	if(dwFlag != 0xFFFFFFFF) 
	{ 
		bRet = ::DeleteFile(chFileName); 
	} 
 
	return bRet; 
} 
 
BOOL WINAPI PL_MoveFile(char *chSrcFileName, char *chDesFileName) 
{ 
	BOOL bRet = FALSE; 
	DWORD dwFlag = ::SetFileAttributes(chSrcFileName, FILE_ATTRIBUTE_NORMAL); 
	if(dwFlag != 0xFFFFFFFF) 
	{ 
		bRet = ::MoveFile(chSrcFileName, chDesFileName); 
	} 
 
	return bRet; 
} 
 
BOOL WINAPI PL_SendMail(CString strSMTP, CString strFrom,  
						CString strTo, CString strSubject, CString strBody) 
{ 
	BOOL bRet = FALSE; 
	CSocket sckSmtp; 
	if(sckSmtp.Create()) 
	{ 
		char chMonth[][12] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",  
			"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; 
		SYSTEMTIME sm; 
		::GetLocalTime(&sm); 
		CString strDate; 
		//                  日  月  年    时  分  秒   
		strDate.Format(_T("%02d %s %02d %02d:%02d:%02d"),  
			sm.wDay, chMonth[sm.wMonth-1], sm.wYear%100,  
			sm.wHour, sm.wMinute, sm.wSecond); 
		char chTemp[1024]; 
 
		int nRet = -1; 
		if(sckSmtp.Connect(strSMTP, 25)) 
		{ 
			do 
			{ 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//欢迎用户 
				 
				TCHAR local_host[80]; 
				ZeroMemory(local_host, 80*sizeof(TCHAR)); 
				::gethostname(local_host, 80); 
				CString strUser = CString(local_host); 
 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "HELO %s\r\n", strUser); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//mail from 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "MAIL FROM: <%s>\r\n", strFrom); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//rcpt to 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "RCPT TO: <%s>\r\n", strTo); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//Data 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "DATA\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//信件内容 
				//时间 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "Date: %s\r\n", strDate); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//From 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "From:%s\r\n", strFrom); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//To 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "To:%s\r\n", strTo); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//CC 
				//			ZeroMemory(chTemp, 1024); 
				//			sprintf(chTemp, "CC:%s\r\n", strCC); 
				//			sckSmtp.Send(chTemp, strlen(chTemp)); 
				//Subject 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "Subject:%s\r\n", strSubject); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//内容 
				int nLen = strBody.GetLength() + 5; 
				char *chBody = new char[nLen]; 
				ZeroMemory(chBody, nLen); 
				sprintf(chBody, "%s\r\n", strBody); 
				nRet = sckSmtp.Send(chBody, strlen(chBody)); 
				delete []chBody; 
				if(nRet < 0) 
					break ; 
				//结束 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, ".\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//退出 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "QUIT\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				bRet = TRUE; 
			}while(0); 
		} 
		sckSmtp.Close(); 
	} 
 
	return bRet; 
} 
 
BOOL WINAPI PL_SendMail2(CString strSMTP, CString strFrom, CString strAuth,  
							  CString strPass, CString strTo, CString strSubject,  
							  CString strBody) 
{ 
	BOOL bRet = FALSE; 
	CSocket sckSmtp; 
	if(sckSmtp.Create()) 
	{ 
		char chMonth[][12] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN",  
			"JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; 
		SYSTEMTIME sm; 
		::GetLocalTime(&sm); 
		CString strDate; 
		//                  日  月  年    时  分  秒   
		strDate.Format(_T("%02d %s %02d %02d:%02d:%02d"),  
			sm.wDay, chMonth[sm.wMonth-1], sm.wYear%100,  
			sm.wHour, sm.wMinute, sm.wSecond); 
		char chTemp[1024]; 
 
		int nRet = -1; 
		if(sckSmtp.Connect(strSMTP, 25)) 
		{ 
			do 
			{ 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//欢迎用户 
				 
				char local_host[80]; 
				ZeroMemory(local_host, 80); 
				DWORD dwLen = 80; 
				GetUserName(local_host, &dwLen); 
 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "EHLO %s\r\n", local_host); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				// auto login 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "AUTH LOGIN\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				// verify user(Base64) 
				CBase64 cb; 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "%s\r\n", cb.Encode(strAuth.GetBuffer(0), strAuth.GetLength())); 
				strAuth.ReleaseBuffer(); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				// verify password 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "%s\r\n", cb.Encode(strPass.GetBuffer(0), strPass.GetLength())); 
				strPass.ReleaseBuffer(); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
 
				//mail from 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "MAIL FROM: <%s>\r\n", strFrom); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//rcpt to 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "RCPT TO: <%s>\r\n", strTo); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//Data 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "DATA\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//信件内容 
				//时间 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "Date: %s\r\n", strDate); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//From 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "From:%s\r\n", strFrom); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//To 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "To:%s\r\n", strTo); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//CC 
				//			ZeroMemory(chTemp, 1024); 
				//			sprintf(chTemp, "CC:%s\r\n", strCC); 
				//			sckSmtp.Send(chTemp, strlen(chTemp)); 
				//Subject 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "Subject:%s\r\n", strSubject); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//内容 
				int nLen = strBody.GetLength() + 5; 
				char *chBody = new char[nLen]; 
				ZeroMemory(chBody, nLen); 
				sprintf(chBody, "%s\r\n", strBody); 
				nRet = sckSmtp.Send(chBody, strlen(chBody)); 
				delete []chBody; 
				if(nRet < 0) 
					break ; 
				//结束 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, ".\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				//接收信息 
				ZeroMemory(chTemp, 1024); 
				nRet = sckSmtp.Receive(chTemp, 1024); 
				if(nRet < 0) 
					break ; 
				if(strncmp(chTemp, "220", 3) != 0 && 
				   strncmp(chTemp, "250", 3) != 0 && 
				   strncmp(chTemp, "334", 3) != 0 && 
				   strncmp(chTemp, "235", 3) != 0 && 
				   strncmp(chTemp, "354", 3) != 0 && 
				   strncmp(chTemp, "221", 3) != 0) // 220, 250, 354, 221成功 
					break ; 
				//退出 
				ZeroMemory(chTemp, 1024); 
				sprintf(chTemp, "QUIT\r\n"); 
				nRet = sckSmtp.Send(chTemp, strlen(chTemp)); 
				if(nRet < 0) 
					break ; 
				bRet = TRUE; 
			}while(0); 
		} 
		sckSmtp.Close(); 
	} 
 
	return bRet; 
} 
 
BOOL WINAPI PL_DetectInternetConnect(CString strHTTP) 
{ 
	BOOL bRet = FALSE; 
	HINTERNET hSession = NULL; 
	hSession = ::InternetOpen(_T("peeper"), PRE_CONFIG_INTERNET_ACCESS, NULL, NULL, 0); 
	if(hSession) 
	{ 
		HINTERNET hHTTPSession = ::InternetOpenUrl(hSession, 
			strHTTP, NULL, 0, INTERNET_FLAG_RELOAD, 0); 
		if(hHTTPSession) 
		{ 
			bRet = TRUE; 
			::InternetCloseHandle(hHTTPSession); 
		} 
		::InternetCloseHandle(hSession); 
	} 
	return bRet; 
} 
 
HGLOBAL WINAPI PL_ReadDataFromFile(CString strFile) 
{ 
	HGLOBAL hData = NULL; 
	CFile file; 
	if(file.Open(strFile, CFile::modeRead)) 
	{ 
		int nLen = file.GetLength(); 
		hData = ::GlobalAlloc(GHND, nLen); 
		if(hData != NULL) 
		{ 
			LPVOID lpData = ::GlobalLock(hData); 
			file.ReadHuge(lpData, nLen); 
			GlobalUnlock(hData); 
		} 
		file.Close(); 
	} 
	return hData; 
} 
 
BOOL WINAPI PL_WriteDataToFile(CString strFile, HGLOBAL hData) 
{ 
	BOOL bRet = FALSE; 
	CFile file; 
	if(file.Open(strFile, CFile::modeCreate | CFile::modeWrite)) 
	{ 
		if(hData != NULL) 
		{ 
			int nLen = ::GlobalSize(hData); 
			LPVOID lpData = ::GlobalLock(hData); 
			file.WriteHuge(lpData, nLen); 
			GlobalUnlock(hData); 
			bRet = TRUE; 
		} 
		file.Close(); 
	} 
	return bRet; 
}