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

📄 tcsylist.cpp

📁 这个是集合几种关于硬盘的序列号的获取方式的DLL
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	if(dwStart < MIN_SECT_NUM || dwStart > MAX_SECT_NUM || \
		!m_ZnnFile.GetMapPtr()) return FALSE;        // 超出扇区范围
	BYTE *pBase = m_ZnnFile.GetMapPtr();             // 文件开始基址
	DWORD dwOffset = dwStart * DISK_SECTOR_SIZE;     // 扇区地址偏移
	if(bOpera == READ_SECT)                          // 读取扇区数据
		memcpy(pSector, &pBase[dwOffset], DISK_SECTOR_SIZE);
	else                                             // 写入扇区数据
		memcpy(&pBase[dwOffset], pSector, DISK_SECTOR_SIZE);
	return TRUE;                                     // 返回成功标志
}

// 直接处理扇区(磁盘、或文件):起始号码,读或写操作,一次只有处理一扇
inline BOOL CTcsyRegistList::HandleSectorIO(BYTE *pSector,
											DWORD dwStart,
											LONG  bOpera)
{
	if(dwStart < MIN_SECT_NUM || dwStart > MAX_SECT_NUM)
		return FALSE;                                // 超出扇区范围
	BOOL bSuccess = FALSE; BYTE *pBase = NULL;       // 操作结果标志
	if((pBase = m_ZnnFile.GetMapPtr()) != NULL)      // 文件开始基址
	{
		DWORD dwOffset = dwStart * DISK_SECTOR_SIZE; // 扇区地址偏移
		if(bOpera == READ_SECT && m_nOperAlow != ALL_ACCESS)
			memcpy(pSector, &pBase[dwOffset], DISK_SECTOR_SIZE);
		else if(bOpera == WRITE_SECT)                // 写入扇区数据
			memcpy(&pBase[dwOffset], pSector, DISK_SECTOR_SIZE);
		bSuccess = TRUE;                             // 设置成功标志
	}
	if(m_nOperAlow != ALL_ACCESS) return bSuccess;   // 只能读写文件
	return (BOOL)DiskSectorIO(USE_WHICH_DISK, USE_DISK_NUM,
		dwStart, 1, (LONG)pSector, bOpera);          // 直接读写扇区
}

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

// 默认构造函数:仅初始化数据,不提取磁盘链表
CTcsyRegistList::CTcsyRegistList()
{
	m_nNodeCount = 0;                                // 置成员初始值
	PtrStart = PtrEnd = PtrCurr = NULL;
	m_bUserRegisted = FALSE;                         // 没有用户登陆
	m_bFirstRunRegist = FALSE;                       // 首运行不注册

	m_nOperAlow = NO_ENOUGH;                         // 默认权限不足
	if(IsEnableDiskIO()) m_nOperAlow = ALL_ACCESS;   // 扇区文件可用
	else if(IsHaveDiskPrivilege()) m_nOperAlow = SCSI_DISK;

	int nLen = GetRecyclerDirectory(m_chFileName);   // 取回收站路径
	CryptXOR((BYTE *)(&m_chFileName[nLen]), ZNN_FILE_NAME, sizeof(ZNN_FILE_NAME));

	if(IsFileExist(m_chFileName) && !IsCorrectZnnFile(m_chFileName))
	{
		SetFileAttributes(m_chFileName, FILE_ATTRIBUTE_ARCHIVE);
		DeleteFile(m_chFileName);                    // 删除错误文件
	}
	if(IsFileExist(m_chFileName) == FALSE)           // 不存在则创建
	{
		HANDLE hFile = CreateFile(m_chFileName, GENERIC_WRITE, 0,
			NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
		if(hFile != INVALID_HANDLE_VALUE)            // 成功打开文件
		{
			BYTE byBuff[ZNN_FILE_SIZE] = {0};        // 临时扇区数据
			memset(byBuff, 0x00, sizeof(byBuff));    // 初始扇区为零
			SFileRegistHead sHead;                   // 临时文件标头
			sHead.EncodeHead(FALSE);                 // 生成加密标头
			memcpy(byBuff, &sHead, sizeof(sHead));   // 写入文件标头
			DWORD dwRet = 0L;                        // 以零填充文件
			WriteFile(hFile, byBuff, sizeof(byBuff), &dwRet, NULL);
			CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
		}
	}
	if(IsFileExist(m_chFileName) && IsCorrectZnnFile(m_chFileName))
	{
		SetFileAttributes(m_chFileName, FILE_ATTRIBUTE_ARCHIVE |
			FILE_ATTRIBUTE_HIDDEN);                  // 设置隐藏属性
		m_ZnnFile.OpenExistFile(m_chFileName, 0L);   // 映象扇区文件
	}
}

// 复位链表:在DestroyList()全部移除扇区记录及标头时使用
VOID CTcsyRegistList::ResetListData(VOID)
{
	m_nNodeCount = 0;
	PtrStart = PtrEnd = PtrCurr = NULL;
	STcsyRegistHead TempHead; TcsyHead = TempHead;
	m_bUserRegisted = FALSE;
	AddrRegist.Set(0L, 0L);
}

// 默认析构函数:仅释放内存,不移除磁盘数据
CTcsyRegistList::~CTcsyRegistList()
{
	DestroyList(FALSE, FALSE);                       // 释放链表内存
}

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

// 设置在有时限的注册方式时,是否在第一次运行时启动注册
VOID CTcsyRegistList::SetFirstRunRegist(BOOL bRegist)
{
	m_bFirstRunRegist = bRegist;                     // 是否首次注册
}

// 保存自定义硬盘序列号注册成功后的注册信息(sData是明文)
BOOL CTcsyRegistList::SaveRegistFile(const STcsyRegistData &sData)
{
	char chFileName[MAX_PATH] = "C:\\";              // 操作文件名称
	int nLen = lstrCpy(&chFileName[3], (char *)sData.byProductNum);
	lstrcpy(&chFileName[nLen], ".INI");
	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; BOOL bReturn = FALSE;
	const BYTE byCrLf[2] = {'\r', '\n'}, byLink = '-';
	try                                              // 写入注册数据
	{
		WriteFile(hFile, "用户名=", 8, &dwWritten, NULL);
		nLen = lstrlen((char *)sData.byUserName);
		WriteFile(hFile, sData.byUserName, nLen, &dwWritten, NULL);
		WriteFile(hFile, byCrLf, 2, &dwWritten, NULL);

		WriteFile(hFile, "注册码=", 8, &dwWritten, NULL);
		WriteFile(hFile, &sData.byRegistCode[0], 8, &dwWritten, NULL);
		WriteFile(hFile, &byLink, 1, &dwWritten, NULL);
		WriteFile(hFile, &sData.byRegistCode[8], 8, &dwWritten, NULL);
		WriteFile(hFile, &byLink, 1, &dwWritten, NULL);
		WriteFile(hFile, &sData.byRegistCode[16], 8, &dwWritten, NULL);
		WriteFile(hFile, &byLink, 1, &dwWritten, NULL);
		WriteFile(hFile, &sData.byRegistCode[24], 8, &dwWritten, NULL);
		bReturn = TRUE;
	}
	catch(...)                                       // 捕获操作异常
	{
		bReturn = FALSE; goto TheEnd;
	}

TheEnd: /* 函数的统一出口,用于关闭已打开的文件 */
	CloseHandle(hFile);
	if(bReturn) SetFileAttributes(chFileName, FILE_ATTRIBUTE_ARCHIVE |
		FILE_ATTRIBUTE_HIDDEN);                      // 设置隐藏属性
	return bReturn;                                  // 返回操作结果
}

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

// 反向搜索最终有效的单元,并得到反向到此还有多少有效的单元
LONG CTcsyRegistList::ReverseSearchValid(const STcsyRegistHead &sHead,
						const STcsyRegistAddr &eAddr,// 发生断链的点
						const STcsyRegistAddr &fAddr,// 最后有效的点
						STcsyRegistItem &sItem)      // 返回最终有效
{
	if(sHead.nItemCount < 1) return 0L;              // 原来就为空链
	LONG nSumLeft = 0L;                              // 还有多少有效
	STcsyRegistItem TempItem;                        // 临时单元数据
	TempItem.AddrSelf = sHead.AddrEnd;
	memset(&sItem.AddrSelf, 0x00, sizeof(STcsyRegistAddr));
	for(nSumLeft=0; nSumLeft<sHead.nItemCount; nSumLeft++)
	{
		if(IsSameAddr(TempItem.AddrSelf, eAddr) == TRUE)
			break;                                   // 此处发生断链
		if(IsSameAddr(TempItem.AddrSelf, fAddr) == TRUE)
			break;                                   // 此点已提取过
		if(IsSameAddr(TempItem.AddrSelf, sItem.AddrSelf))
			break;                                   // 避免循环发生

		if(!LoadDiskItem(TempItem)) break;           // 装载单元失败
		sItem = TempItem;                            // 记录反终有效
		TempItem.AddrSelf = sItem.AddrPrior;         // 上一个单元位
	}
	sItem.AddrPrior = fAddr; return nSumLeft;        // 反向有效个数
}

// 从磁盘加载链表数据:重新构造内存映象
BOOL CTcsyRegistList::LoadListFromDisk(const STcsyRegistHead *pHead, BOOL bFind)
{
	if(!DestroyList(FALSE, FALSE)) return FALSE;     // 复位所有数据
	BOOL bSuccess = TRUE;                            // 成功标志变量
	LONG i = 0; STcsyRegistItem TempItem;            // 临时单元数据
	STcsyRegistHead TempHead = TcsyHead;             // 临时的标识头

	// 从扇区搜索链表标头并加载它
	if(TempHead.nItemCount < 0)                      // 标头尚未加载
	{
		TempHead.nItemCount = 0;                     // 为New1使用的
		if(pHead) TempHead = *pHead;                 // 使用给定标头
		else if(!bFind) bSuccess = FALSE;            // 已经禁止查找
		else bSuccess = FindListHeadInDisk(&TempHead); // 要不就搜索

		if(!bSuccess) bSuccess = New(TempHead.AddrSelf, sizeof(TempHead),
			(BYTE *)(&TempHead));                    // 没有就建一个
		if(!bSuccess) return FALSE;                  // 提取标头失败
	}
	if(bSuccess == TRUE)                             // 初始化新标头
	{
		TcsyHead = TempHead; TcsyHead.nItemCount = 0;
		STcsyRegistAddr sAddr;                       // 现在是准标头
		TcsyHead.AddrStart = sAddr; TcsyHead.AddrEnd = sAddr;
	}

	// 从扇区加载链表的所有节点,含对断链的处理
	STcsyRegistItem BegnItem;                        // 正向有效末点
	TempItem.AddrSelf = TempHead.AddrStart;          // 第一个单元位
	for(i=0; i<TempHead.nItemCount; i++)             // 提取所有节点
	{
		if(AddEndDiskItem(TempItem) == FALSE)        // 异外发生断链
		{
			if(i != m_nNodeCount) {bSuccess = FALSE; break;}
			if(m_nOperAlow != NO_ENOUGH) Delete(TempItem.AddrSelf);
			STcsyRegistItem RendItem;                // 反向最末有效
			LONG nSumLeft = ReverseSearchValid(TempHead, TempItem.AddrSelf,
				BegnItem.AddrSelf, RendItem);        // 搜反向末有效

			if(nSumLeft < 1)                         // 反向无有效的
			{
				TempHead.nItemCount = m_nNodeCount;  // 记当前有效数
				TempHead.AddrEnd = BegnItem.AddrSelf;
				if(m_nNodeCount >= 1)                // 已经加载若干
				{
					BegnItem.AddrNext = RendItem.AddrSelf;
					if(m_nOperAlow != NO_ENOUGH && bSuccess == TRUE)
						bSuccess = SaveDiskItem(BegnItem);
					PtrEnd->ItemData = BegnItem;     // 更新内存尾点
				}
				else                                 // 首节点就无效
				{
					TempHead.AddrStart = BegnItem.AddrSelf;
				}
			}
			else                                     // 找到若干有效
			{
				if(m_nOperAlow != NO_ENOUGH) Delete(RendItem.AddrPrior);
				TempHead.nItemCount = m_nNodeCount + nSumLeft;
				if(m_nNodeCount >= 1)                // 已经加载若干
				{
					BegnItem.AddrNext = RendItem.AddrSelf;
					RendItem.AddrPrior = BegnItem.AddrSelf;
					if(m_nOperAlow != NO_ENOUGH && bSuccess == TRUE)
					{
						bSuccess = SaveDiskItem(BegnItem);
						if(bSuccess) bSuccess = SaveDiskItem(RendItem);
					}
					PtrEnd->ItemData = BegnItem;     // 更新内存尾点
				}
				else                                 // 首节点就无效
				{
					TempHead.AddrStart = RendItem.AddrSelf;
					RendItem.AddrPrior = BegnItem.AddrSelf;
				}
			}
			if(m_nOperAlow != NO_ENOUGH && bSuccess == TRUE)
				bSuccess = SaveDiskHead(TempHead);   // 记录新的标头

			if(bSuccess == FALSE) {DestroyList(FALSE, FALSE); break;}
			i--;                                     // 断链成功修复
			TempItem = RendItem;                     // 可以继续装载
		}
		else
		{
			BegnItem = TempItem;                     // 记录正向末点
			TempItem.AddrSelf = BegnItem.AddrNext;   // 下一个单元位
		}
	}

	// 如果加载成功,则检查文件是否有新的最近运行时间,有则更新到扇区
	if(bSuccess) bSuccess = (i == m_nNodeCount);     // 数目是否相等
	if(bSuccess) bSuccess = (m_nNodeCount == TempHead.nItemCount);
	if(bSuccess) TcsyHead = TempHead;                // 最终设置标头
	if(bSuccess && m_nOperAlow == ALL_ACCESS && IsZnnFileUpdate() == TRUE)
	{
		SaveZnnFileHead(FALSE);                      // 设置为未更新
		STcsyRegistItem TempItem;                    // 临时单元数据
		STcsyRegistData srcData, desData;            // 临时记录数据
		STcsyRegistNode *pNode = PtrStart;           // 从首节点开始
		for(i=0; i<m_nNodeCount; i++)                // 遍历查询最新
		{
			TempItem.AddrSelf = pNode->ItemData.AddrSelf;
			if(LoadDiskItem(TempItem, TRUE) == FALSE)// 读取映象扇区
				goto TheContinue;

			srcData = pNode->ItemData.RegData;       // 扇区中数据
			CryptXOR((BYTE *)(&srcData), sizeof(STcsyRegistData));
			desData = TempItem.RegData;              // 文件中数据
			CryptXOR((BYTE *)(&desData), sizeof(STcsyRegistData));
			if(IsDiffTime(desData.byRecentRun, srcData.byRecentRun) == FALSE)
				goto TheContinue;                    // 没有更新时间

			CryptXOR((BYTE *)(&desData), sizeof(STcsyRegistData));
			memcpy(pNode->ItemData.RegData.byRecentRun, desData.byRecentRun,
				sizeof(desData.byRecentRun));        // 存新时到内存
			SaveDiskItem(pNode->ItemData);           // 存最新到扇区
TheContinue:
			pNode = pNode->PtrNext;                  // 查询下一节点
		}
	}

	// 若从磁盘扇区加载成功,则将扇区数据重写到映象文件中,以防不测
	if(bSuccess && m_nOperAlow == ALL_ACCESS)
	{
		SaveDiskHead(TcsyHead, TRUE);                // 先将标头存贮

⌨️ 快捷键说明

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