⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcsylist.cpp

📁 这个是集合几种关于硬盘的序列号的获取方式的DLL
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// TcsyList.cpp 扇区内注册管理双向链表类声明及实现,标准C++版本
// CopyRight(C) 1996,2008   TCSY 公司
// Pentium Working Room   ShanChengKun   2004.05.27   更新
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "HDiskSN.h"
#include "TcsyList.h"
#include "Resource.h"

/////////////////////////////////////////////////////////////////////////////
// CSearchBin类相关函数实现定义:

// 二进制查找类:默认构造函数
CSearchBin::CSearchBin()
{
	memset(m_BinEntry, 0, sizeof(m_BinEntry));
	m_byPattern = NULL; m_nLenPatt = 0L;
}

// 二进制查找类:自定义构造函数
CSearchBin::CSearchBin(const BYTE *byPattern, long nLenPatt, long nStyle)
{
	SetBinEntry(byPattern, nLenPatt, nStyle);
}

// 修正应用通配符情况下的模板串:除去两端的通配符
void CSearchBin::ReviseTokenPatt(BYTE *&pDes, long &nDesLen,
								 long nStyle, BYTE byToken)
{
	if((nStyle & 0x04) == 0) return;                 // 是否使用通配符
	BYTE *pCurr = pDes;                              // 处理二进制串首
	while(pCurr < pDes + nDesLen) {if(*pCurr != byToken) break; pCurr++;}
	nDesLen -= (pCurr - pDes); pDes = pCurr;         // 修正指针及长度
	pCurr = pDes + nDesLen - 1;                      // 处理二进制串尾
	while(pCurr >= pDes) {if(*pCurr != byToken) break; pCurr--;}
	nDesLen = pCurr - pDes + 1;                      // 修正二进制串长
}

// 设置匹配模板,并初始化256级位置入口记录
void CSearchBin::SetBinEntry(const BYTE *byPattern, long nLenPatt, long nStyle)
{
	m_byPattern = byPattern;
	m_nLenPatt = nLenPatt;
	m_nSearchStyle = nStyle;
	bool bCapCase = (bool)((nStyle & 0x02) != 0);
	long k = 0; BYTE byNth = 0;
	for(k=0; k<256; k++) m_BinEntry[k] = m_nLenPatt + 1;
	for(k=0; k<m_nLenPatt; k++)
	{
		if(bCapCase) byNth = m_byPattern[k];
		else byNth = ToUpper(m_byPattern[k]);
		m_BinEntry[byNth] = m_nLenPatt - k;
	}
}

//-------------------------------------------------------------------------//

// 查找匹配二进制串算法主体(改进BMH),并目标计数、或返回位置(零起始)
long CSearchBin::FindBin(const BYTE *byStream, long nLength)
{
	if(m_nLenPatt > nLength) return (-1);            // 长度安检
	long nStyle = m_nSearchStyle, nCount = 0;        // 查找类型
	long k = m_nLenPatt - 1, i = 0, j = 0;
	bool bGainPos = (bool)((nStyle & 0x01) != 0);    // 返回首位
	while(k < nLength)
	{
		j = m_nLenPatt - 1;                          // 尾部开始
		i = k;
		while(j >= 0 && m_byPattern[j] == byStream[i])
		{
			j--; i--;                                // 前一字符
		}
		if(j < 0)                                    // 找到目标
		{
			if(bGainPos) return (i + 1);             // 串首位置
			else {nCount++; k++;}                    // 目标计数
		}
		else k += m_BinEntry[byStream[k + 1]];       // 移动模板
	}
	return (!bGainPos ? nCount : -1);                // 返回结果
}

// 查找匹配二进制串算法主体(改进BMH),并目标计数、或返回位置(零起始)
long CSearchBin::FindBinEx(const BYTE *byStream, long nLength, BYTE byToken)
{
	if(m_nLenPatt > nLength) return (-1);            // 长度的安检
	long nStyle = m_nSearchStyle, nCount = 0;        // 查找的方式
	long k = m_nLenPatt - 1, i = 0, j = 0;
	long nOffPos = 0; BYTE byNth = 0;                // 位移和入口
	bool bGainPos = (bool)((nStyle & 0x01) != 0);    // 返回首位置
	bool bCapCase = (bool)((nStyle & 0x02) != 0);    // 大小写敏感
	bool bTokenIt = (bool)((nStyle & 0x04) != 0);    // 是否用通配
	while(k < nLength)
	{
		j = m_nLenPatt - 1;                          // 尾部开始
		i = k;
		while(j >= 0 && (byStream[i] == m_byPattern[j] ||
			(bTokenIt && ToUpper(m_byPattern[j]) == byToken) ||
			(!bCapCase && ToUpper(byStream[i]) == ToUpper(m_byPattern[j]))))
		{
			j--; i--;                                // 前一字符
		}
		if(j < 0)                                    // 找到目标
		{
			if(bGainPos) return (i + 1);             // 串首位置
			else {nCount++; k++;}                    // 目标计数
		}
		else                                         // 模板不匹
		{
			if(bCapCase) byNth = byStream[k + 1];    // 计数入口
			else byNth = ToUpper(byStream[k + 1]);
			nOffPos = m_BinEntry[byNth];             // 修正位移
			if(bTokenIt && nOffPos > m_BinEntry[byToken])
				nOffPos = m_BinEntry[byToken];       // 取小的量
			k += nOffPos;                            // 移动模板
		}
	}
	return (!bGainPos ? nCount : -1);                // 返回结果
}

// 在给定的二进制区域中搜索指定长度的连续空域,并返回首位置
BYTE *CSearchBin::SearchEmptyArea(BYTE bySrc[], long nSrcLen,
								  long nEmptyLen, BYTE byEmpty)
{
	BYTE *pFirstOccur = NULL;                        // 首次出现
	long i = 0, nAreaSize = 0, nEndPosit = nSrcLen - nEmptyLen - 1;
	for(i=0; i<nSrcLen; i++)                         // 遍历区域
	{
		if(bySrc[i] == byEmpty)                      // 发现空闲
		{
			if(pFirstOccur) {if(++nAreaSize >= nEmptyLen) break;}
			else {pFirstOccur = &bySrc[i]; nAreaSize = 1;}
		}
		else if(pFirstOccur) {pFirstOccur = NULL; nAreaSize = 0;}
		if(nEndPosit + nAreaSize < i) {pFirstOccur = NULL; break;}
	}
	return pFirstOccur;                              // 返回指针
}

/////////////////////////////////////////////////////////////////////////////
// CTcsyRegistList类相关函数实现定义:

// 在New申请的空间中,首尾要写入相关的记录数据,用于确认写单元
VOID CTcsyRegistList::WriteNewFlag(BYTE *pStart, WORD wDataSize)
{
	if(pStart == NULL || wDataSize < 1) return;      // 检查入口数据
	BYTE *pOccur = pStart - NEW_RECSIZE - EXTEND_BYTES;
	memset(pOccur, BYTE_EMPTY, EXTEND_BYTES);        // 清空首延拓值
	*(pOccur + EXTEND_BYTES) = EXTEND_BYTES;         // 记录延拓大小
	*((WORD *)(pStart - sizeof(WORD))) = wDataSize;  // 实际数据大小
	memset(pStart + wDataSize, BYTE_EMPTY, EXTEND_BYTES);// 尾部延拓
}

// 校验Znn文件是否正确:文件路径及名称需先生成
BOOL CTcsyRegistList::IsCorrectZnnFile(const char *chFile)
{
	HANDLE hFile = CreateFile(chFile, GENERIC_READ, FILE_SHARE_READ |
		FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
	SFileRegistHead sHead;                           // 临时文件标头
	DWORD dwReturn = 0L;                             // 返回读取大小
	BOOL bCorrect = FALSE;                           // 标头是否正确
	if(hFile != INVALID_HANDLE_VALUE &&              // 开始读取数据
		GetFileSize(hFile, NULL) == (DWORD)ZNN_FILE_SIZE &&
		ReadFile(hFile, &sHead, sizeof(sHead), &dwReturn, NULL) &&
		dwReturn == sizeof(sHead))                   // 大小都已正确
	{
		bCorrect = sHead.DecodeHead();               // 解包是否成功
	}
	if(hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
	return bCorrect;                                 // 返回是否正确
}

// 检查Znn映象文件中的标头数据中是否标记已更新过
BOOL CTcsyRegistList::IsZnnFileUpdate(VOID)
{
	BYTE *pBase = m_ZnnFile.GetMapPtr();             // 获取映象基址
	if(pBase == NULL) return FALSE;                  // 文件尚未映象
	SFileRegistHead sHead;                           // 临时文件标头
	memcpy(&sHead, pBase, sizeof(sHead));            // 读取出源数据
	if(!sHead.DecodeHead()) return FALSE;            // 解包校验失败
	return sHead.bUpdateRecent;                      // 返回是否更新
}

// 将更新的情况写入Znn文件映象中的标头
BOOL CTcsyRegistList::SaveZnnFileHead(BOOL bUpdate)
{
	BYTE *pBase = m_ZnnFile.GetMapPtr();             // 获取映象基址
	if(pBase == NULL) return FALSE;                  // 文件尚未映象
	SFileRegistHead sHead;                           // 临时文件标头
	memcpy(&sHead, pBase, sizeof(sHead));            // 读取出源数据
	if(!sHead.DecodeHead()) return FALSE;            // 解包校验失败
	if(!sHead.EncodeHead(bUpdate)) return FALSE;     // 返回打包结果
	memcpy(pBase, &sHead, sizeof(sHead));            // 将数据写入扇
	return TRUE;                                     // 成功更新数据
}

//-------------------------------------------------------------------------//

// 从当前指针开始是否有nLen长度的连续的byData
BOOL CTcsyRegistList::IsKeepAs(BYTE *pCurr, LONG nLen, BYTE byData)
{
	while((--nLen) >= 0)                             // 全长搜索目标
		{if(pCurr[nLen] != byData) return FALSE;}
	return TRUE;                                     // 含有指定长度
}

// 所给的地址是否有效,在合法的范围内
inline BOOL CTcsyRegistList::IsValidAddr(const STcsyRegistAddr &sAddr)
{
	return (sAddr.dwSectNum >= MIN_SECT_NUM && sAddr.dwSectNum <= MAX_SECT_NUM
		&& sAddr.nByteOffs >= 0 && sAddr.nByteOffs < DISK_SECTOR_SIZE);
}

// 判断给定的两个地址是否相同
inline BOOL CTcsyRegistList::IsSameAddr(const STcsyRegistAddr &sAddr,
										const STcsyRegistAddr &dAddr)
{
	return ((sAddr.dwSectNum == dAddr.dwSectNum) &&
		(sAddr.nByteOffs == dAddr.nByteOffs));
}

// 测试读写扇区的功能是否可以使用:先读出来再写回去
inline BOOL CTcsyRegistList::IsEnableDiskIO(VOID)
{
	BYTE byBuff[DISK_SECTOR_SIZE] = {0};             // 扇区临时缓冲
	BOOL bEnable = (BOOL)DiskSectorIO(USE_WHICH_DISK, USE_DISK_NUM,
			MAX_SECT_NUM, 1, (LONG)byBuff, READ_SECT);
	if(bEnable) bEnable = (BOOL)DiskSectorIO(USE_WHICH_DISK, USE_DISK_NUM,
			MAX_SECT_NUM, 1, (LONG)byBuff, WRITE_SECT);
	return bEnable;                                  // 读取磁盘扇区
}

// 释放磁盘上扇区空间:方便自己测试专用的
BOOL CTcsyRegistList::DirectRemove(DWORD dwNumb, LONG nOffs)
{
	STcsyRegistAddr sAddr;                           // 转换成本地址
	sAddr.dwSectNum = dwNumb;
	sAddr.nByteOffs = nOffs;
	return Delete(sAddr);                            // 直接删除目标
}

//-------------------------------------------------------------------------//

// 获取磁盘注册单元的数,因断链有处理,故若>=0则与映象节点总数相同
LONG CTcsyRegistList::GetItemCount()
{
	return TcsyHead.nItemCount;
}

// 获取注册数据的标头,以提供所占用扇区的信息
VOID CTcsyRegistList::GetTcsyHead(STcsyRegistHead *pHead)
{
	if(pHead) *pHead = TcsyHead;
}

// 移动当前指针到:假=首节点、真=尾节点
VOID CTcsyRegistList::ToRewind(BOOL bEndOrNot)
{
	PtrCurr = bEndOrNot ? PtrEnd : PtrStart;
}

// 移动当前指针到上一节点
BOOL CTcsyRegistList::ToPrior(VOID)
{
	if(!PtrCurr || !PtrCurr->PtrPrior) return FALSE;
	PtrCurr = PtrCurr->PtrPrior; return TRUE;
}

// 移动当前指针到下一节点
BOOL CTcsyRegistList::ToNext(VOID)
{
	if(!PtrCurr || !PtrCurr->PtrNext) return FALSE;
	PtrCurr = PtrCurr->PtrNext; return TRUE;
}

// 读当前节的内存数据拷贝,与磁盘对应的相同:要先解密
BOOL CTcsyRegistList::ReadCurr(STcsyRegistData *pData)
{
	if(!PtrCurr || !pData) return FALSE;             // 当前指针无效
	*pData = PtrCurr->ItemData.RegData;
	CryptXOR((BYTE *)pData, sizeof(STcsyRegistData));
	return TRUE;                                     // 返回当前拷贝
}

// 更新当前节到内存,并保存磁盘的对应扇区:要再加密
BOOL CTcsyRegistList::WriteCurr(const STcsyRegistData *pData)
{
	if(!PtrCurr || !pData) return FALSE;             // 当前指针无效
	STcsyRegistData &rData = PtrCurr->ItemData.RegData;
	PtrCurr->ItemData.RegData = *pData;
	CryptXOR((BYTE *)(&rData), sizeof(STcsyRegistData));
	return SaveDiskItem(PtrCurr->ItemData);          // 存到磁盘扇区
}

// 文件底层模拟扇区操作:功能和位置相当于DiskSectorIO(...)函数
inline BOOL CTcsyRegistList::FileSectorIO(BYTE *pSector,
										  DWORD dwStart,
										  LONG bOpera)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -