www.pudn.com > ScanDlg.rar > TcScan.cpp


// TcScan.cpp : Defines the class behaviors for the application. 
// 
 
#include "stdafx.h" 
#include "TcScan.h" 
#include "TcScanDlg.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
 
PTcScan TcScan = NULL;						// 驱动扫描仪 
PSelectScanner SelectScanner = NULL;		// 选择源设备 
 
///////////////////////////////////////////////////////////////////////////// 
// CTcScanApp 
 
BEGIN_MESSAGE_MAP(CTcScanApp, CWinApp) 
	//{{AFX_MSG_MAP(CTcScanApp) 
		// NOTE - the ClassWizard will add and remove mapping macros here. 
		//    DO NOT EDIT what you see in these blocks of generated code! 
	//}}AFX_MSG 
	ON_COMMAND(ID_HELP, CWinApp::OnHelp) 
END_MESSAGE_MAP() 
 
///////////////////////////////////////////////////////////////////////////// 
// CTcScanApp construction 
 
CTcScanApp::CTcScanApp() 
{ 
	// TODO: add construction code here, 
	m_hTcScan = NULL; 
	// Place all significant initialization in InitInstance 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// The one and only CTcScanApp object 
 
CTcScanApp theApp; 
 
///////////////////////////////////////////////////////////////////////////// 
// CTcScanApp initialization 
 
BOOL CTcScanApp::InitInstance() 
{ 
	AfxEnableControlContainer(); 
 
	// Standard initialization 
	// If you are not using these features and wish to reduce the size 
	//  of your final executable, you should remove from the following 
	//  the specific initialization routines you do not need. 
 
#ifdef _AFXDLL 
	Enable3dControls();			// Call this when using MFC in a shared DLL 
#else 
	Enable3dControlsStatic();	// Call this when linking to MFC statically 
#endif 
 
	CTcScanDlg dlg; 
	m_pMainWnd = &dlg; 
 
	m_hTcScan = LoadLibrary("TcScan.DLL"); 
	if(m_hTcScan != NULL) 
	{ 
		TcScan = (PTcScan)GetProcAddress(m_hTcScan, "TcScan"); 
		SelectScanner = (PSelectScanner)GetProcAddress(m_hTcScan, "SelectScanner"); 
		if(TcScan == NULL || SelectScanner == NULL) 
		{ 
			TcScan = NULL; SelectScanner = NULL; 
			FreeLibrary(m_hTcScan); m_hTcScan=NULL; 
		} 
	} 
 
	int nResponse = dlg.DoModal(); 
	if (nResponse == IDOK) 
	{ 
		// TODO: Place code here to handle when the dialog is 
		//  dismissed with OK 
	} 
	else if (nResponse == IDCANCEL) 
	{ 
		// TODO: Place code here to handle when the dialog is 
		//  dismissed with Cancel 
	} 
 
	if(m_hTcScan) {FreeLibrary(m_hTcScan); m_hTcScan=NULL;} 
	// Since the dialog has been closed, return FALSE so that we exit the 
	//  application, rather than start the application's message pump. 
	return FALSE; 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// 本系统所用的全局变量及函数的定义(实现部分) 
// CopyRight(C)   1996,2008   TCSY 公司 
// Pentium Working Room   ShanChengKun   2004.04.04   更新 
///////////////////////////////////////////////////////////////////////////// 
//=== Begin ===============================================================// 
 
// 以"与或"的方式使数据流面目全非或完璧归赵:写回自身 
void CryptXOR(BYTE bySrc[], LONG nLen, BYTE byPatt) 
{ 
	while((--nLen) >= 0) bySrc[nLen] ^= byPatt; 
} 
 
// 以"与或"的方式使数据流面目全非或完璧归赵:写到新串 
void CryptXOR(BYTE byDes[], const BYTE bySrc[], LONG nLen, BYTE byPatt) 
{ 
	memcpy(byDes, bySrc, nLen); 
	while((--nLen) >= 0) byDes[nLen] ^= byPatt; 
} 
 
// 当前的操作系统是否是WindowsNT、Windows2000或WindowsXP系统 
BOOL IsWindowsNT(void) 
{ 
	OSVERSIONINFO OSVersionInfo; 
	OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); 
	GetVersionEx(&OSVersionInfo); 
	return (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT); 
} 
 
// 处理路径加or减"\\",nCut==0 为加上"\\" 
void HandleSckPath(char *pStr, int nCut) 
{ 
	int nLen = lstrlen(pStr); 
	if(pStr == NULL || nLen <= 0) return; 
	char *p = pStr + nLen - 1; 
	if(!nCut && *p != '\\') {*(++p) = '\\'; *(++p) = '\0';} 
	else if(nCut && *p == '\\') *p = '\0'; 
} 
 
// 检查给定的文件是否存在(若文件长度指针不为NULL则返回实际值) 
BOOL IsFileExist(const char chFile[], DWORD *pLength) 
{ 
	WIN32_FIND_DATA findData; 
	HANDLE hFindFile = ::FindFirstFile(chFile, &findData); 
	if(hFindFile == INVALID_HANDLE_VALUE) return FALSE; 
	if(pLength != NULL) *pLength = findData.nFileSizeLow; 
	::FindClose(hFindFile); return TRUE; 
} 
 
// 确认指定路径存在,尾部有无'\\'均可 
BOOL MakeSurePath(const char chPath[]) 
{ 
	DWORD dwAttr = GetFileAttributes(chPath); 
	if((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && 
		dwAttr != (DWORD)(-1)) return TRUE; 
 
	SetLastError(ERROR_SUCCESS); 
	if(CreateDirectory(chPath, NULL) == FALSE) 
	{ 
		if(GetLastError() != ERROR_ALREADY_EXISTS) 
			return FALSE; 
	} 
	return TRUE; 
} 
 
// 确认给定文件所在的路径,以'\\'之前作为目录有效标识 
BOOL MakeFilePath(const char chFile[]) 
{ 
	char chTemp[2048] = "", *pDes = chTemp; 
	const char *pSrc = chFile; 
	DWORD dwAttr = (DWORD)(-1); 
	while(*pSrc != '\0') 
	{ 
		*(pDes++) = *(pSrc++); 
		if(*(pDes - 1) != '\\' || *(pDes - 2) == ':') continue; 
		if(pDes - chTemp + 1 > 2048) break; 
		*pDes = '\0'; 
 
		dwAttr = GetFileAttributes(chTemp); 
		if((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && 
			dwAttr != (DWORD)(-1)) continue; 
 
		SetLastError(ERROR_SUCCESS); 
		if(CreateDirectory(chTemp, NULL) == FALSE) 
		{ 
			if(GetLastError() != ERROR_ALREADY_EXISTS) 
				return FALSE; 
		} 
	} 
	return TRUE; 
} 
 
// 将给定的二进制区保存成指定文件(自动确认文件路径) 
BOOL SaveBinaryFile(const char *chFileName, const BYTE *pBuffData, DWORD dwBuffSize) 
{ 
	if(!chFileName || !pBuffData || dwBuffSize < 1L) return FALSE; 
	if(MakeFilePath(chFileName) == FALSE) return FALSE; 
	SetFileAttributes(chFileName, FILE_ATTRIBUTE_ARCHIVE); 
	HANDLE hFile = CreateFile(chFileName, GENERIC_WRITE, 0, 
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL); 
	if(hFile == INVALID_HANDLE_VALUE) return FALSE; 
	DWORD dwWritten = 0L; 
	if(!WriteFile(hFile, pBuffData, dwBuffSize, &dwWritten, NULL) || 
			dwWritten != dwBuffSize) 
		dwWritten = 0L; 
	CloseHandle(hFile); return (dwWritten == dwBuffSize); 
} 
 
// 装载指定文件到给定的二进制区(自动确认使用内存) 
BOOL LoadBinaryFile(const char *chFileName, BYTE *&pBuffData, DWORD &dwBuffSize) 
{ 
	DWORD dwLength = 0L; 
	if(IsFileExist(chFileName, &dwLength) == FALSE) return FALSE; 
	if(dwLength < 1L) {dwBuffSize = 0L; return TRUE;} 
	if(pBuffData == NULL || dwBuffSize != dwLength) 
		{if(pBuffData) delete[] pBuffData; pBuffData = new BYTE[dwLength];} 
	if(!pBuffData) return FALSE; dwBuffSize = dwLength; 
	HANDLE hFile = CreateFile(chFileName, GENERIC_READ, FILE_SHARE_READ | 
		FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL); 
	if(hFile == INVALID_HANDLE_VALUE || !ReadFile(hFile, pBuffData, dwLength, 
		&dwBuffSize, NULL) || dwBuffSize != dwLength) 
		{delete[] pBuffData; pBuffData = NULL; dwBuffSize = 0L;} 
	CloseHandle(hFile); return (dwBuffSize == dwLength); 
} 
 
// 将内部的资源文件导出为二进制的文件 
BOOL ExportResAsBinFile(LPCTSTR lpFile, HMODULE hModule, DWORD dwName, LPCTSTR lpType) 
{ 
	if(!lpFile || !hModule || !lpType) return FALSE; 
	BOOL bSuccess = FALSE; 
	HRSRC hRes = FindResource(hModule, MAKEINTRESOURCE(dwName), lpType); 
	DWORD dwSize = SizeofResource(hModule, hRes); 
	HGLOBAL hMem = LoadResource(hModule, hRes); 
	BYTE *pData = (BYTE *)LockResource(hMem); 
	if(pData && dwSize > 0) bSuccess = SaveBinaryFile(lpFile, pData, dwSize); 
	FreeResource(hMem); return bSuccess; 
} 
 
// 自定义信息框的加密后标题,可以防止客户简单方法改标题 
static const BYTE MsgBoxTitle[] = 
{ 
	0xAD, 0x8A, 0x26, 0x03, 0x88, 0xC2, 0xF0, 0x21, 0x81, 0xD3, 
	0x97, 0xB2, 0xA2, 0xCD, 0x0B, 0x04, 0x14, 0xE0, 0x5C, 0x47, 
	0x8E, 0xAB, 0xCC, 0xD0, 0x3F, 0x75, 0x76, 0x1B, 0x36, 0xEF, 
	0x11, 0x9B, 0xD1, 0xAF, 0x5D, 0x00 
}; 
 
// 系统用信息对话框:窗口句柄,按钮类型,信息字符串 
int MsgBox(HWND hWnd, UINT utype, const char *chfmt, ...) 
{ 
	char chbuff[888] = ""; 
	va_list argptr; 
	va_start(argptr, chfmt); 
	vsprintf(chbuff, chfmt, argptr); 
	va_end(argptr); 
 
	BYTE byKeys[sizeof(DATA_KEYS)]; 
	CryptXOR(byKeys, DATA_KEYS, sizeof(DATA_KEYS)); 
	char chTitle[sizeof(MsgBoxTitle)]; 
	memcpy(chTitle, MsgBoxTitle, sizeof(MsgBoxTitle)); 
	SckDesBin(1, (BYTE *)chTitle, sizeof(MsgBoxTitle), byKeys); 
	return (MessageBox(hWnd, chbuff, chTitle, utype)); 
} 
 
// 精度为毫秒级的延迟函数(不采用inline方式) 
void SckMsDelay(DWORD dwDelay) 
{ 
	register DWORD dwStart = GetTickCount(); 
	for(;;) 
	{ 
		if(GetTickCount() - dwStart >= dwDelay) break; 
	} 
} 
 
//--- Static CRC table : 静态CRC32表 --------------------------------------// 
 
static const DWORD Crc32Table[256] = 
{ 
	0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 
	0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
	0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 
	0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
	0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 
	0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
	0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 
	0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
	0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 
	0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
	0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 
	0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
	0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 
	0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
	0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 
	0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
 
	0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 
	0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
	0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 
	0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
	0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 
	0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
	0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 
	0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
	0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 
	0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
	0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 
	0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
	0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 
	0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
	0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 
	0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
 
	0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 
	0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
	0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 
	0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
	0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 
	0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
	0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 
	0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
	0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 
	0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
	0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 
	0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
	0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 
	0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
	0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 
	0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
 
	0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 
	0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
	0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 
	0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
	0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 
	0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
	0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 
	0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
	0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 
	0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
	0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 
	0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
	0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 
	0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
	0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 
	0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D, 
}; 
 
// 给定一个数据区及其长度,求出它的CRC32检验码 
DWORD GenerateCRC32(const BYTE *pData, long nLength) 
{ 
	if(!pData) return 0L; 
	DWORD dwCrc32 = 0xFFFFFFFF; 
	while((nLength--) > 0) 
	{ 
		dwCrc32 = (dwCrc32 >> 8) ^ Crc32Table[(*pData++) ^ (dwCrc32 & 0xFF)]; 
	} 
	return (~dwCrc32); 
} 
 
// 创建绘制256色BMP位图所需要的信息头和调色板 
BOOL CreateSCKPalette(CBitmapInfo &bmi, CPalette &cPal, short nWide, short nHigh) 
{ 
	WORD wNumColors      = 256;						// 调色板颜色数目 
	bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);// 信息头大小 
	bmi.bmiHeader.biWidth          = nWide;			// 图像宽度 
	bmi.bmiHeader.biHeight         = nHigh;			// 图像高度 
	bmi.bmiHeader.biPlanes         = 1;				// 必须为1 
	bmi.bmiHeader.biBitCount       = 8;				// 8位,256色 
	bmi.bmiHeader.biCompression    = 0;				// 数据不压缩 
	bmi.bmiHeader.biSizeImage      = 0;				// 不压缩时可以为0 
	bmi.bmiHeader.biXPelsPerMeter  = 0;				// 设备水平分辨率 
	bmi.bmiHeader.biYPelsPerMeter  = 0;				// 设备垂直分辨率 
	bmi.bmiHeader.biClrUsed        = 0;				// 2^biBitCount为0 
	bmi.bmiHeader.biClrImportant   = 0;				// 所有的都重要为0 
	for(WORD i = 0; i < wNumColors; i++)			// 创建BMP调色板 
	{ 
		bmi.bmiColors[i].rgbBlue     = (BYTE) i;	// 读取红色分量 
		bmi.bmiColors[i].rgbGreen    = (BYTE) i;	// 读取绿色分量 
		bmi.bmiColors[i].rgbRed      = (BYTE) i;	// 读取蓝色分量 
		bmi.bmiColors[i].rgbReserved = (BYTE) 0;	// 保留位置为零 
	} 
 
	// 分配为逻辑256色调色板内存 
	HANDLE hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE) 
		+ sizeof(PALETTEENTRY) * wNumColors); 
	if(hLogPal == NULL) return FALSE; 
	LPLOGPALETTE lpLogPal = (LPLOGPALETTE) ::GlobalLock((HGLOBAL)hLogPal); 
	if(lpLogPal == NULL) return FALSE; 
 
	lpLogPal->palVersion = 0x300;					// 设置版本号 
	lpLogPal->palNumEntries = wNumColors;			// 设置颜色数目 
	for(WORD j = 0; j < wNumColors; j++)			// 读取调色板 
	{ 
		lpLogPal->palPalEntry[i].peRed   = (BYTE) j;// 读取红色分量 
		lpLogPal->palPalEntry[i].peGreen = (BYTE) j;// 读取绿色分量 
		lpLogPal->palPalEntry[i].peBlue  = (BYTE) j;// 读取蓝色分量 
		lpLogPal->palPalEntry[i].peFlags = (BYTE) 0;// 保留位置为零 
	} 
 
	// 按照逻辑调色板创建调色板,并返回指针 
	BOOL bResult = cPal.CreatePalette(lpLogPal);	// 创建新调色板 
	::GlobalUnlock((HGLOBAL) hLogPal);				// 解除锁定 
	::GlobalFree((HGLOBAL) hLogPal);				// 释放逻辑调色板 
	return bResult;									// 返回创建结果 
} 
 
//-------------------------------------------------------------------------// 
 
// 获取数据区的标识信息头:同时进行校验,若需要就返回原文件名称 
static BOOL GetFilePackHeader(const BYTE *pSrc, LONG nSrcLen, 
					   SFilePackHeader *pHeader = NULL, 
					   char *chName = NULL)			// 提取原文件名 
{ 
	if(!pSrc || nSrcLen <= sizeof(SFilePackHeader)) return FALSE; 
	SFilePackHeader tHeader;						// 临时文件标头 
	memcpy(&tHeader, pSrc, sizeof(SFilePackHeader));// 文件标头校验 
	if(!tHeader.DecodePack() || nSrcLen != (LONG)(tHeader.headSize + \ 
		tHeader.nameSize + tHeader.dataSize)) return FALSE; 
	const BYTE *pCurr = pSrc + sizeof(SFilePackHeader); 
	if(chName != NULL && tHeader.nameSize > 1)		// 要返回文件名 
	{ 
		memcpy(chName, pCurr, tHeader.nameSize); 
		CryptXOR((BYTE *)chName, tHeader.nameSize); 
		chName[tHeader.nameSize - 1] = '\0';		// 强制末尾为零 
	} 
	pCurr += tHeader.nameSize;						// 数据区首位置 
	if(GenerateCRC32(pCurr, tHeader.dataSize) != tHeader.dataChck) 
		return FALSE;								// 校验数据失败 
	if(pHeader) *pHeader = tHeader; return TRUE;	// 是有效压缩区 
} 
 
// 压缩/解压缩指定的数据包,写到指定的文件,chName压缩时用(可选) 
static BOOL DeinFlateFilePack(BYTE bStyle, const BYTE *pSrc, LONG nSrcLen, 
					   const char chFile[], const char *chName = NULL) 
{ 
	if(!pSrc || nSrcLen < 1) return FALSE;			// 校验入口参数 
	CMemMapFile	desFile; BYTE *pDes = NULL;			// 创建目标文件 
	CSckLzw sckLzw;									// 压解缩算法类 
	MakeFilePath(chFile);							// 确认目标路径 
	SetFileAttributes(chFile, FILE_ATTRIBUTE_ARCHIVE); 
	DeleteFile(chFile);								// 确认目标不在 
	SFilePackHeader sHeader; 
	if(bStyle == 0)									// 压缩源数据区 
	{ 
		DWORD nmSz = chName ? (DWORD)(lstrlen(chName) + 1) : 0L; 
		DWORD ogSz = (DWORD)nSrcLen;				// 原文件的长度 
		DWORD ogCk = GenerateCRC32(pSrc, (LONG)ogSz);// 原文件校验码 
		DWORD dtSz = 0L, dtCk = 0L;					// 其它标头参数 
		DWORD dwSum = sizeof(sHeader) + nmSz + ogSz * 2 + 2048; 
		pDes = (BYTE *)desFile.CreateNewFile(chFile, dwSum); 
		if(pDes == NULL) return FALSE;				// 映象文件失败 
		memset(pDes, 0x00, dwSum);					// 以零填充区域 
		BYTE *pCurr = pDes + sizeof(sHeader); 
		if(nmSz > 0)								// 拷贝源文件名 
		{ 
			memcpy(pCurr, chName, nmSz);			// 先复制到目地 
			CryptXOR(pCurr, nmSz);					// 对原值来解密 
		} 
		pCurr += nmSz;								// 依名字长步进 
		dtSz = sckLzw.LZW_Encode(pSrc, ogSz, pCurr);// 编码到新文件 
		dtCk = GenerateCRC32(pCurr, dtSz);			// 生成数据校验 
		sHeader.EncodePack(nmSz, ogSz, ogCk, dtSz, dtCk); 
		*((SFilePackHeader *)pDes) = sHeader;		// 生成新文件头 
		dwSum = sizeof(sHeader) + nmSz + dtSz;		// 目标文件总长 
		desFile.CloseSizeFile(dwSum);				// 等大结束目标 
		return TRUE;								// 成功保存文件 
	} 
	else											// 解压源数据区 
	{ 
		if(nSrcLen <= sizeof(SFilePackHeader)) return FALSE; 
		sHeader = *((SFilePackHeader *)pSrc);		// 分析文件标头 
		if(!sHeader.DecodePack() || nSrcLen != (LONG)(sHeader.headSize 
			+ sHeader.nameSize + sHeader.dataSize)) return FALSE; 
		const BYTE *pCurr = pSrc + sHeader.headSize + sHeader.nameSize; 
		if(sHeader.dataChck != GenerateCRC32(pCurr, sHeader.dataSize)) 
			return FALSE;							// 数据校验失败 
		pDes = (BYTE *)desFile.CreateNewFile(chFile, sHeader.orgzSize); 
		if(pDes == NULL) return FALSE;				// 映象文件失败 
		memset(pDes, 0x00, sHeader.orgzSize);		// 以零填充区域 
		DWORD dwRet = sckLzw.LZW_Decode(pCurr, pDes);// 解码到新文件 
		if(dwRet != sHeader.orgzSize) return FALSE;	// 校验生成结果 
		if(sHeader.orgzChck != GenerateCRC32(pDes, dwRet)) return FALSE; 
		desFile.CloseSizeFile(sHeader.orgzSize);	// 等大结束目标 
		return TRUE;								// 成功保存文件 
	} 
	return FALSE;									// 返回处理结果 
} 
 
// 获取系统回收站的路径,包含尾部的反斜杠'\\',入口MAX_PATH长度 
INT GetRecyclerDirectory(CHAR chPath[]) 
{ 
	if(chPath == NULL) return 0L; 
	DWORD dwAttr = (DWORD)(-1);						// -1表示有错误 
	BOOL bFind = FALSE; 
	BOOL bIsNT = IsWindowsNT(); 
 
	char chTemp[2][MAX_PATH] = {"", ""}; 
	CryptXOR((BYTE *)chTemp[0], PATH_BASE_NT, sizeof(PATH_BASE_NT)); 
	CryptXOR((BYTE *)chTemp[1], PATH_BASE_9X, sizeof(PATH_BASE_9X)); 
 
	int nWhich = bIsNT ? 0 : 1;						// 正常默认查找 
	dwAttr = GetFileAttributes(chTemp[nWhich]); 
	bFind = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && dwAttr != (DWORD)(-1)); 
 
	if(bFind == FALSE)								// 调换名称再查 
	{ 
		nWhich = bIsNT ? 1 : 0; 
		dwAttr = GetFileAttributes(chTemp[nWhich]); 
		bFind = ((dwAttr & FILE_ATTRIBUTE_DIRECTORY) && dwAttr != (DWORD)(-1)); 
	} 
 
	if(bFind == FALSE)								// 创建对应目标 
	{ 
		nWhich = bIsNT ? 0 : 1; 
		SetFileAttributes(chTemp[nWhich], FILE_ATTRIBUTE_ARCHIVE); 
		DeleteFile(chTemp[nWhich]);					// 确认没有文件 
		SetLastError(ERROR_SUCCESS); 
		bFind = (CreateDirectory(chTemp[nWhich], NULL) || (GetLastError() == \ 
			ERROR_ALREADY_EXISTS)); 
	} 
 
	INT nLen = 0L;									// 获取临时路径 
	if(bFind == FALSE) nLen = (INT)GetTempPath(MAX_PATH, chPath); 
	else {lstrcpy(chPath, chTemp[nWhich]); nLen = lstrlen(chPath);} 
 
	if(nLen < 1) {lstrcpy(chPath, "C:\\"); nLen = 3L;} 
	else if(chPath[nLen - 1] != '\\') {chPath[nLen++] = '\\'; \ 
		chPath[nLen] = '\0';}						// 确认尾部'\\' 
	SetFileAttributes(chPath, FILE_ATTRIBUTE_SYSTEM | \ 
		FILE_ATTRIBUTE_HIDDEN); return nLen;		// 系统隐藏长度 
} 
 
// 将内部压缩的资源数据导出为驱动程序文件 
BOOL ExportZipResToDrvFile(DWORD dwName, LPCTSTR lpType, CHAR *chFile) 
{ 
	HMODULE hModule = AfxGetResourceHandle();		// 本地资源句柄 
	if(!hModule || !lpType || !chFile) return FALSE; 
	HRSRC hRes = FindResource(hModule, MAKEINTRESOURCE(dwName), lpType); 
	LONG nSize = (LONG)SizeofResource(hModule, hRes); 
	HGLOBAL hMem = LoadResource(hModule, hRes);		// 加载目标资源 
	BYTE *pSource = (BYTE *)LockResource(hMem); 
	if(!pSource || nSize < 1) return FALSE;			// 锁定内存失败 
	SFilePackHeader sHeader; 
	char chPath[MAX_PATH], chName[MAX_PATH] = ""; 
	BOOL bSuccess = FALSE;							// 导出结果标志 
 
	if(GetFilePackHeader(pSource, nSize, &sHeader, chName) && chName[0]) 
	{ 
		int nLen = GetRecyclerDirectory(chPath);	// 取回收站路径 
		lstrcpy(&chPath[nLen], chName);				// 生成文件名称 
 
		DWORD dwFileSize = 0L; 
		if(IsFileExist(chPath, &dwFileSize) && dwFileSize) 
		{ 
			const BYTE *pMap = NULL;				// 校验已有文件 
			CMemMapFile mapFile; 
			if((pMap = (BYTE *)mapFile.OpenReadFile(chPath)) != NULL) 
			{ 
				if(GenerateCRC32(pMap, dwFileSize) == \ 
					sHeader.orgzChck) bSuccess = TRUE; 
			} 
		} 
		if(!bSuccess) bSuccess = DeinFlateFilePack(1, pSource, nSize, chPath); 
		SetFileAttributes(chPath, FILE_ATTRIBUTE_ARCHIVE | 
			FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM); 
		if(bSuccess) lstrcpy(chFile, chPath);		// 返回生成文件 
	} 
	FreeResource(hMem); return bSuccess;			// 释放临时资源 
} 
 
//-------------------------------------------------------------------------// 
 
// 申请动态二维数组空间模板(申请块内存,DOS下有64K限制,简单数据类型) 
BOOL NewByte(BYTE **&pImage, short nWide, short nHigh) 
{ 
	pImage = new BYTE*[nHigh];						// 申请行内存 
	if(pImage == NULL) return FALSE;				// 申请块内存 
	BYTE *pBuffer = new BYTE[(long)nWide * (long)nHigh]; 
	if(pBuffer == NULL) {delete[] pImage; pImage = NULL; return FALSE;} 
	for(register short j=0; j