¿Cómo obtiene VC++ MFC el ID de la CPU y el número de serie del disco duro?
void CIntelCPUIDDlg::OnBtnCPUID()
{
Unsigned long s1, S2;
p >Carácter sin firmar seller_id[]= "-"; //ID del proveedor de CPU
CString str1, str2, str3
// Lo siguiente es para obtener el lenguaje ensamblador de la CPU. instrucciones para la identificación.
_asm //Obtener información del proveedor de CPU
{
Xor eax, eax //Borrar eax.
Cpuid //Obtener el comando de Cpuid
mov dword ptr identificación de proveedor, ebx
mov identificación de proveedor de puntero de doble palabra [+4], edx
p>
mov identificación de proveedor de puntero de palabra doble [+8], ecx
}
str1. Formato (" %s ", proveedor_id);
_asm //Obtiene los 32 bits superiores del ID de la CPU.
{
mov eax, 01h
xor edx
cpuid
mov s2, eax
}
str2. Formato ("%08X-", S2);
_asm //Obtiene los 64 bits inferiores del ID de la CPU.
{
mov eax, 03h
xor ecx, ecx
xor edx
cpuid
mov s1, edx
mov s2, ecx
}
str3. format(" %08X-%08X\n ", s1, S2);
cadena 2 = cadena 2+cadena 3
m _Editar proveedor. SetWindowText(cadena 1);
m_editCPUID. SetWindowText(str 2);
}
//gethdserial.CPP: Implementación de la clase CGetHDSerial.
//
////////////////////////////////// // //////////////////////////////////////
#Contiene " stdafx.h "
#Contiene " GetHDSerial.h "
char m _ buffer[256];
WORD m _ serial[256]; p>
DWORD m _ OldInterruptAddress
DWORD IDTR;
//Esperando a que el disco duro esté inactivo
Static unsigned int WaitHardDiskIdle()
{
byTemp bytes;
Esperar:
_asm
{
mov dx, 0x1f7 p>
In al, dx
cmp al, 0x80
jb end wait
jmp wait
}
Finalizar espera:
_asm
{
Mover por temperatura
}
Return byTemp
}
//Programa de servicio de interrupción
void _declspec(naked)InterruptProcess(void)
{
int byTemp
int I;
WORD temp
//Guardar valor de registro
_asm p>
{
Empujar eax
Empujar ebx
Empujar ecx
Empujar edx
Empujar esi
}
waithardiskdidle(); //Espera a que el disco duro esté inactivo.
_asm
{
mov dx, 0x1f6
0xa0 mov al
Salida dx, al
p>}
byTemp = waitharddiskdidle(); // Si el comando de espera se ejecuta directamente en el nivel Ring3, entrará en un bucle infinito.
if((byTemp & amp; 0x50)!=0x50)
{
_asm //Restaura el sitio de interrupción y sale de la rutina del servicio de interrupción.
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
_asm
{
Mov dx, 0x1f6 // Puerto de comando 1f6, seleccione la unidad 0.
Mov al de 0xa0
Salida dx, al
Dx de la empresa
mov al, 0xec
Salida dx , al //Enviar un comando para leer los parámetros del inversor.
}
byTemp = waitharddiskdidle();
if((byTemp & amp; 0x58)!=0x58)
{
_asm //Restaurar el sitio de interrupción y salir de la rutina del servicio de interrupción.
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
//Leer toda la información del controlador del disco duro
for(I = 0;i<256;i++)
{
_asm
{
mov dx, 0x1f0 p >
En ax, dx
Temperatura en movimiento, ax
}
m_serial[I]= temp;
}
_asm
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
////// /// ////////////////////////////////////////////////// //////////////
//Construcción/Destrucción
///////////////// / ///////////////////////////////////////////////// //// ///
CGetHDSerial::CGetHDSerial()
{
}
CGetHDSerial::~CGetHDSerial()
{
}
//Función de lectura del número de serie del disco duro
char* CGetHDSerial::GetHDSerial()
{
m _ buffer[0]= '\n';
//Obtener la versión actual del sistema operativo
Información de la versión del sistema operativo Versión del sistema operativo info;
OSVERSIONINFO . dwosversioninfosize = sizeof(OSVERSIONINFO);
GetVersionEx(&información de la versión del sistema operativo);
if (OSVersionInfo.dwPlatformId!= plataforma VER WIN32 NT)
{
//Leer// el número de serie del disco duro en Windows 9x/ME.
WORD m _ wwin 9 xhdserial[256];
win 9 xreadhdserial(m _ wwin 9 xhdserial);
strcpy (m_buffer, WORDToChar (m_wWin9xHDSerial, 10,19));
}
Otros
{
//Leer el disco duro en Windows NT/2000/XP Número de serie
DWORD m_wWinNTHDSerial[256];
//Determine si hay un disco duro SCSI.
If (!WinNTReadIDEHDSerial(m_wWinNTHDSerial))
WinNTReadSCSIHDSerial(m_wWinNTHDSerial);
strcpy (m_buffer, DWORDToChar (m_wWinNTHDSerial, 10, 19)); p>
}
Devolver m_buffer
}
//Leer//secuencia del disco duro en el número del sistema Windows9X/ME.
void _ stdcall CGetHDSerial::win 9 xreadhdserial(WORD * buffer)
{
int I;
for(I = 0;i<256;i++)
buffer[i] = 0;
_asm
{
push eax
p >//Obtiene la dirección del descriptor de interrupción (puerta de interrupción) de la interrupción modificada.
IDTR de Alemania Occidental
mov eax, dword ptr [m_IDTR+02h]
Agregar eax, 3*08h+04h
Moneda Interfaz de línea de comando del indicador (abreviatura de indicador de nivel de moneda) (interfaz de línea de comando para secuencias de comandos por lotes)
// Guarde la dirección de entrada de interrupción original.
Push ecx
mov ecx, puntero de palabra doble [eax]
mov cx, palabra ptr [eax-04h]
mov dword ptr m _ OldInterruptAddress, ecx
pop ecx
//Establezca la dirección de entrada de interrupción modificada a la nueva dirección de entrada del controlador de interrupciones.
Empujar ebx
lea ebx, interrumpir proceso
mov word ptr [eax-04h], bx
shr ebx, 10h
mov word ptr [eax+02h], bx
pop ebx
//Interrumpir la ejecución, ir al anillo 0 (similar al principio del virus CIH) p>
int 3h
//Restaurar la dirección de entrada de interrupción original
Push ecx
mov ecx, dword ptr m_OldInterruptAddress
mov palabra ptr [eax-04h], cx
shr ecx, 10h
mov palabra ptr [eax+02h], cx
pop ecx
p>Inventarios de herramientas estándar
pop eax
}
for(I = 0;i<256;i++)
buffer[I]= m_serial[I];
}
//En // Sistema Windows 9x/ME, información del disco duro tipo WORD Convertir a tipo de caracteres (char ).
char * CGetHDSerial::WORDToChar(datos del disco WORD[256], int firstIndex, int lastIndex)
{
Cadena de caracteres estáticos[1024] <; /p>
int index = 0;
int position = 0;
//Coloque el contenido de la matriz de palabras diskdata en el orden del byte alto primero y el byte bajo. última tienda en cadena.
for(index = primer índice; índice & lt= lastIndexindex++)
{
//El byte de orden superior almacenado en la palabra
string[position]=(char)(disk data[index]/256);
position++;
//El byte de orden inferior almacenado en la palabra p>
cadena[posición]=(char)(diskdata[index]% 256);
posición++;
}
//Fin de agregando cadena Bandera
cadena[posición]= ' \ 0 ';
//Eliminar espacios en la cadena
for(index = posición-1; índice & gt0 & amp& amp' = = string[index] index -)
string[index]= '\0';
Devolver cadena;
}
//En el sistema Windows NT/2000/XP, la información del disco duro de tipo doble palabra (DWORD) se convierte a tipo de carácter (char).
char * CGetHDSerial::DWORDToChar(datos del disco DWORD[256], int firstIndex, int lastIndex)
{
Cadena de caracteres estáticos[1024]; /p>
int index = 0;
int position = 0;
//En el orden del byte alto primero y el byte bajo al final, coloque las palabras dobles en el La palabra baja se almacena en la cadena.
for(index = primer índice; índice & lt= lastIndexindex++)
{
//El byte de orden superior se almacena en la palabra de orden inferior
string[position]=(char)(disk data[index]/256);
position++;
//El byte de orden inferior almacenado en la palabra de orden inferior
string[position]=(char)(diskdata[index]% 256);
position++;
}
//Fin de agregar cadena Bandera
string[position]= ' \ 0 ';
//Eliminar espacios en la cadena
for( índice = posición-1; índice & gt0 & amp& amp' = = cadena[índice] -)
cadena[index]= '\0';
Devolver cadena;
}
//Leer el número de serie del disco duro IDE en Windows NT/2000/XP
BOOL CGetHDSerial::WinNTReadIDEHDSerial(DWORD * buffer)
{
BYTE IdOutCmd[sizeof(SENDCMDOUTPARAMS)+IDENTIFY _ BUFFER _ TAMAÑO-1]
BOOL bFlag = FALSE
int drive = 0;
char nombre de unidad[256];
Manejar hpphysicaldriveioctl = 0;
sprintf (nombre de unidad, "\\\\.\\PhysicalDrive%d" , unidad);
p>//La creación de archivos en Windows NT/2000/XP requiere derechos de administrador.
hpphysicaldriveioctl = crear archivo(nombredeunidad,
Generic_READ | Generic_WRITE,
Lectura de archivo compartido|Escritura de archivo compartido, vacío,
OPEN_EXISTING , 0, NULL);
if (hpphysicaldriveioctl! = valor de identificador no válido)
{
getversionoputparams versión params;
DWORD cbBytesReturned = 0;
//Obtenga la versión del controlador IO de la unidad.
memset((void *)& VersionParams, 0, tamaño de (parámetros de versión));
if (dispositivo iocontrol(hpphysicaldriveioctl, IOCTL_GET_VERSION,
Valor nulo, 0 y parámetro de versión,
sizeof(parámetro de versión),
& ampcbBytesReturned, NULL))
{
if(version params . bidevicemap> 0)
{
byte bid cmd = 0; // comando de reconocimiento IDE o ATAPI
SENDCMDINPARAMS scip
//Si la unidad es una unidad óptica, utilice el comando IDE_ATAPI_IDENTIFY, comando,
//De lo contrario, utilice el comando IDE_ATA_IDENTIFY para leer la información de la unidad.
bid cmd = (version params. bidevicemap > & gtdriving and entertainment. 0x10)?
IDE_ATAPI_IDENTIFY:IDE_ATA_IDENTIFY;
memset(& scip, 0, tamaño de(scip));
memset (IdOutCmd, 0, tamaño de(IdOutCmd));
//Obtener información de la unidad
if(WinNTGetIDEHDInfo(hpphysicaldriveioctl,
& ampscip,
(PSENDCMDOUTPARAMS)IdOutCmd,
(Bytes)bIDCmd,
(Bytes)Driver,
&cbBytesReturned))
{
int m = 0 ;
USHORT *pIdSector = (USHORT *)
((PSENDCMDOUTPARAMS)IdOutCmd)-& gt; bBuffer
for(m = 0; m & lt256 ;m++)
buffer[m]= sector PID[m];
bFlag = TRUE//Leer la información del disco duro con éxito.
}
}
}
close handle(hpphysicaldriveioctl); //Cerrar el identificador
}
Volver a bFlag
}
//Lea el número de serie del disco duro SCSI en el sistema Windows NT/2000/XP.
BOOL CGetHDSerial::WinNTReadSCSIHDSerial(DWORD * buffer)
{
buffer[0]= '\n';
int controlador = 0;
HANDLE hScsiDriveIOCTL = 0;
char nombre_unidad[256]
sprintf (nombre_unidad, " \\\\.\\Scsi% d:", controlador);
//Cualquier permiso se puede ejecutar en Windows NT/2000/XP.
hScsiDriveIOCTL = crear archivo(nombredeunidad,
Generic_READ | Generic_WRITE,
Lectura de archivo compartido|Escritura de archivo compartido, vacío,
OPEN_EXISTING , 0, NULL);
if (hScsiDriveIOCTL! = valor de identificador no válido)
{
int drive = 0
DWORD; ficticio
for(drive = 0; drive<2;drive++)
{
búfer de caracteres[sizeof(SRB _ IO _ CONTROL)+sendilength]; p>
SRB _ IO _ CONTROL * p = (SRB _ IO _ CONTROL *) buffer
SENDCMDINPARAMS *pin =
(SENDCMDINPARAMS *)(buffer+sizeof( SRB _ IO _ CONTROL));
//Preparar parámetros
memset (búfer, 0, tamaño de (búfer)).
p->;longitud del encabezado = sizeof(SRB_IO_CONTROL);
p->;timeout = 10000;
p->;Longitud = SENDIDLENGTH p>
p->; código de control = IOCTL_SCSI_MINIPORT_IDENTIFY;
strncpy((char *)p->firma, "SCSIDISK", 8) ;
pin-> ;irdriveregs.bcommandreg = IDE_ATA_IDENTIFY;
pin->;bDriveNumber = unidad
//Obtener información del disco duro SCSI
if(device iocontrol(hScsiDriveIOCTL,IOCTL_SCSI_MINIPORT ,
búfer,
tamaño de (SRB_IO_CONTROL) +
tamaño de(SENDCMDINPARAMS)-1 ,
búfer,
sizeof(SRB _ IO _ CONTROL)+sendilength,
& elemento ficticio amp, valor nulo))
{
SENDCMDOUTPARAMS *pOut = p>
(SENDCMDOUTPARAMS *)(buffer+sizeof(SRB _ IO _ CONTROL));
id sector * pId = (id sector *)(pOut-& gt;bBuffer); p>
if(pId->sNúmeroModelo [0])
{
int n = 0;
USHORT * pId sector =(USHORT *)pId;
for(n = 0; n & lt256;n++)
búfer[n ]= sector PID[n];
Devuelve VERDADERO //leer correctamente
}
}
}
cerrar handle(hScsiDriveIOCTL); //Cerrar identificador
}
Return FALSE //Lectura fallida
}
//Leer información del dispositivo IDE en Windows NT/2000/XP
BOOL CGetHDSerial::WinNTGetIDEHDInfo(HANDLE hpphysicaldriveioctl, PSENDCMDINPARAMS pSCIP,
PSENDCMDOUTPARAMS pSCOP, byte biIDCmd, byte bDriveNum,
PDWORD lpcbBytesReturned)
{
//Parámetros para leer información del dispositivo
PSP CIP->; cBufferSize = IDENTIFY_BUFFER_SIZE;
PSP CIP->irdriveregs.bfeaturesreg = 0;
PSP CIP->irdriveregs.bsectorcountreg = 1;
PSP CIP->irdriveregs.bsectornumberreg=1;
PSP CIP->irdriveregs.bcyllowreg=0;
PSP CIP->irdriveregs.bcylhighreg=0;
//Calcular ubicación de la unidad
PSP CIP->irdriveregs.bdriveheadreg = 0xa 0 |((bDriveNum&1)< <4);
/ /establecer comando de lectura
PSP CIP->irdriveregs.bcommandreg = oferta cmd
PSP CIP->bDriveNumber = bDriveNum
PSP CIP-> ;cBufferSize = IDENTIFY _ BUFFER _ SIZE;
//Leer información de la unidad
return(device iocontrol(hpphysicaldriveioctl, IOCTL_GET_DRIVE_INFO,
(LPVOID) pSCIP,
tamaño de(SENDCMDINPARAMS)-1,
(LPVOID) pSCOP,
tamaño de(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE-1, p>
lpcbBytesReturned, NULL));
}