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

📄 diskserialnumber.cpp

📁 本程序是VC为平台开发的股票资讯系统
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				case 't': case 'T': id += 29; break;
				case 'u': case 'U': id += 30; break;
				case 'v': case 'V': id += 31; break;
				case 'w': case 'W': id += 32; break;
				case 'x': case 'X': id += 33; break;
				case 'y': case 'Y': id += 34; break;
				case 'z': case 'Z': id += 35; break;
			}	
		}
	}

	return id;
}

BOOL CDiskSerialNumber::ReadIdeDriveAsScsiDriveInNT()
{
	BOOL done = FALSE;
	HANDLE hScsiDriveIOCTL = 0;

	// Try to get a handle to PhysicalDrive IOCTL, report failure
	// and exit if can't.
	char driveName[256] = _T("\\\\.\\Scsi0:");

	// Windows NT, Windows 2000, any rights should do
	hScsiDriveIOCTL = CreateFile(driveName,
		GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | 
		FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

	if(hScsiDriveIOCTL != INVALID_HANDLE_VALUE)
	{
		char buffer[sizeof(SRB_IO_CONTROL) + SENDIDLENGTH];
		SRB_IO_CONTROL *p = (SRB_IO_CONTROL *)buffer;
		SENDCMDINPARAMS *pin = (SENDCMDINPARAMS *)(buffer + sizeof(SRB_IO_CONTROL));
		DWORD dummy;
   
		memset(buffer, 0, sizeof(buffer));
		p->HeaderLength = sizeof(SRB_IO_CONTROL);
		p->Timeout = 10000;
		p->Length = SENDIDLENGTH;
		p->ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
		strncpy((char *)p->Signature, _T("SCSIDISK"), 8);
  
		pin->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
		pin->bDriveNumber = 0;

		if(DeviceIoControl(hScsiDriveIOCTL, 
			IOCTL_SCSI_MINIPORT, buffer,
			sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1,
			buffer, sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,
			&dummy, NULL))
		{
			SENDCMDOUTPARAMS *pOut = (SENDCMDOUTPARAMS *)(buffer + sizeof(SRB_IO_CONTROL));
			IDSECTOR *pId = (IDSECTOR *)(pOut->bBuffer);
			if(pId->sModelNumber[0])
			{
				DWORD diskdata[256];
				int ijk = 0;
				USHORT *pIdSector = (USHORT *)pId;
          
				for(ijk = 0; ijk < 256; ijk++)
					diskdata [ijk] = pIdSector [ijk];

				strcpy(HardDriveSerialNumber, ConvertToString (diskdata, 10, 19));

				done = TRUE;
			}
		}
	}
	CloseHandle(hScsiDriveIOCTL);

	return done;
}

BOOL CDiskSerialNumber::ReadDrivePortsInWin9X()
{
	BOOL done = FALSE;

	InitializeWinIo();   

	// Get IDE Drive info from the hardware ports
	// loop thru all possible drives
	DWORD diskdata[256];
	WORD  baseAddress = 0x1f0;   //  Base address of drive controller 
	DWORD portValue = 0;
	int waitLoop = 0;
	int index = 0;
 
	// Wait for controller not busy 
	waitLoop = 100000;
	while(--waitLoop > 0)
	{
		GetPortVal((WORD)(baseAddress + 7), &portValue, (BYTE)1);
		// drive is ready
		if((portValue & 0x40) == 0x40) break;
		// previous drive command ended in error
		if((portValue & 0x01) == 0x01) break;
	}

	// Set Master or Slave drive
	SetPortVal((WORD)(baseAddress + 6), 0xA0, 1);

	// Get drive info data
	SetPortVal((WORD)(baseAddress + 7), 0xEC, 1);

	// Wait for data ready 
	waitLoop = 100000;
	while(--waitLoop > 0)
	{
		GetPortVal((WORD)(baseAddress + 7), &portValue, 1);
		// see if the drive is ready and has it's info ready for us
		if((portValue & 0x48) == 0x48) break;
		// see if there is a drive error
		if((portValue & 0x01) == 0x01) break;
	}

	// read drive id information
	for(index = 0; index < 256; index++)
	{
		diskdata[index] = 0;   //  init the space
		GetPortVal(baseAddress, &(diskdata[index]), 2);
	}		
   
	strcpy(HardDriveSerialNumber, ConvertToString (diskdata, 10, 19));

	done = TRUE;

	ShutdownWinIo();

	return done;
}

BOOL CDiskSerialNumber::InitializeWinIo()
{
	char szExePath[MAX_PATH];
	PSTR pszSlash;

	IsNT = IsWinNT();

	if(IsNT)
	{
		if(!GetModuleFileName(GetModuleHandle(NULL), szExePath, sizeof(szExePath)))
			return FALSE;

		pszSlash = strrchr(szExePath, '\\');

		if(pszSlash)
			pszSlash[1] = 0;
		else
			return FALSE;

		strcat(szExePath, _T("winio.sys"));

		// UnloadDeviceDriver(_T("WINIO"));
		// if (!LoadDeviceDriver(_T("WINIO"), szExePath, &hDriver))
		// return FALSE;
	}
  
	IsWinIoInitialized = TRUE;

	return TRUE;
}

BOOL CDiskSerialNumber::GetPortVal(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
	BOOL Result;
	DWORD dwBytesReturned;
	struct tagPort32Struct Port32Struct;

	if(IsNT)
	{
		if(!IsWinIoInitialized)
			return FALSE;

		Port32Struct.wPortAddr = wPortAddr;
		Port32Struct.bSize = bSize;

		if(!DeviceIoControl(hDriver, IOCTL_WINIO_READPORT, &Port32Struct,
			sizeof(struct tagPort32Struct), &Port32Struct, 
			sizeof(struct tagPort32Struct), &dwBytesReturned, NULL))
			return FALSE;
		else
			*pdwPortVal = Port32Struct.dwPortVal;
	}
	else
	{
		Result = CallRing0((PVOID)Ring0GetPortVal, wPortAddr, pdwPortVal, bSize);

		if(Result == FALSE)
			return FALSE;
	}

  	return TRUE;
}

BOOL CDiskSerialNumber::SetPortVal(WORD wPortAddr, DWORD dwPortVal, BYTE bSize)
{
	DWORD dwBytesReturned;
	struct tagPort32Struct Port32Struct;

	if(IsNT)
	{
		if(!IsWinIoInitialized)
			return FALSE;

		Port32Struct.wPortAddr = wPortAddr;
		Port32Struct.dwPortVal = dwPortVal;
		Port32Struct.bSize = bSize;

		if(!DeviceIoControl(hDriver, IOCTL_WINIO_WRITEPORT, &Port32Struct,
			sizeof(struct tagPort32Struct), NULL, 0, &dwBytesReturned, NULL))
			return FALSE;
	}
	else
		return CallRing0((PVOID)Ring0SetPortVal, wPortAddr, &dwPortVal, bSize);
	
	return TRUE;
}

void CDiskSerialNumber::ShutdownWinIo()
{
// if (IsNT)
// UnloadDeviceDriver(_T("WINIO"));
}

BOOL CDiskSerialNumber::IsWinNT()
{
	OSVERSIONINFO OSVersionInfo;
	
	OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	
	GetVersionEx(&OSVersionInfo);
	
	return OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

// Makes it possible to call ring 0 code from a ring 3 application.
BOOL CDiskSerialNumber::CallRing0(PVOID pvRing0FuncAddr, 
		WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize)
{
	struct GDT_DESCRIPTOR *pGDTDescriptor;
	struct GDTR gdtr;
	WORD CallgateAddr[3];
	WORD wGDTIndex = 1;

	_asm Sgdt[gdtr]

	// Skip the null descriptor
	pGDTDescriptor = (struct GDT_DESCRIPTOR *)(gdtr.dwGDTBase + 8);

	// Search for a free GDT descriptor
	for(wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++)
	{
		if(pGDTDescriptor->Type == 0 &&
			pGDTDescriptor->System == 0 &&
			pGDTDescriptor->DPL == 0 &&
			pGDTDescriptor->Present == 0)
		{
			// Found one !
			// Now we need to transform this descriptor into a callgate.
			// Note that we're using selector 0x28 since it corresponds
			// to a ring 0 segment which spans the entire linear address
			// space of the processor (0-4GB).
			struct CALLGATE_DESCRIPTOR *pCallgate;
			pCallgate =	(struct CALLGATE_DESCRIPTOR *)pGDTDescriptor;
			pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr);
			pCallgate->Selector = 0x28;
			pCallgate->ParamCount =	0;
			pCallgate->Unused = 0;
			pCallgate->Type = 0xc;
			pCallgate->System = 0;
			pCallgate->DPL = 3;
			pCallgate->Present = 1;
			pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr);

			// Prepare the far call parameters
			CallgateAddr[0] = 0x0;
			CallgateAddr[1] = 0x0;
			CallgateAddr[2] = (wGDTIndex << 3) | 3;

			// Please fasten your seat belts!
			// We're about to make a hyperspace jump into RING 0.
			_asm Mov DX, [wPortAddr]
			_asm Mov EBX, [pdwPortVal]
			_asm Mov CL, [bSize]
			_asm Call FWORD PTR [CallgateAddr]

			// We have made it !
			// Now free the GDT descriptor
			memset(pGDTDescriptor, 0, 8);

			// Our journey was successful. Seeya.
      		return TRUE;
		}

		// Advance to the next GDT descriptor
		pGDTDescriptor++; 
	}
	// Whoops, the GDT is full
	return FALSE;
}

⌨️ 快捷键说明

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