Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros temas > Trucos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Los mejores trucos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 11-10-2006
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Numero de serie del disco duro

Este truco sirve para obtener información sobre dispositivos de almacenamiento (discos duros, disquetes, memorias usb), aunque la información disponible puede variar de un tipo de dispositivo a otro.

Código Delphi [-]
const
  METHOD_BUFFERED = 0;
  FILE_ANY_ACCESS = 0;
  FILE_DEVICE_MASS_STORAGE = $2D;
  IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;

  IOCTL_STORAGE_QUERY_PROPERTY =
    (IOCTL_STORAGE_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
    ($500 shl 2) or  METHOD_BUFFERED;

type
  PSTORAGE_DESCRIPTOR_HEADER = ^TSTORAGE_DESCRIPTOR_HEADER;
  TSTORAGE_DESCRIPTOR_HEADER = packed record
    Version: ULONG;
    Size: ULONG;
  end;

  PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR;
  STORAGE_DEVICE_DESCRIPTOR = packed record
    Version: ULONG;
    Size: ULONG;
    DeviceType: UCHAR;
    DeviceTypeModifier: UCHAR;
    RemovableMedia: Boolean;
    CommandQueueing: Boolean;
    VendorIdOffset: ULONG;
    ProductIdOffset: ULONG;
    ProductRevisionOffset: ULONG;
    SerialNumberOffset: ULONG;
    BusType: ULONG;
    RawPropertiesLength: ULONG;
    RawDeviceProperties: array[0..0] of UCHAR;
  end;

// Descodifica el numero de serie
function DecodeSerialNumber(SerialNumber: string): string;
var
  i: Integer;
begin
  Result:= EmptyStr;
  while Length(SerialNumber) > 0 do
  begin
    if TryStrToInt('$'+Copy(SerialNumber,1,4),i) then
    begin
      Result:= Result + Char(Lo(i)) + Char(Hi(i));
      Delete(SerialNumber,1,4);
    end else
    begin
      Result:= EmptyStr;
      Exit;
    end;
  end;
  Result:= Trim(Result);
end;

// Obtiene la informacion sobre el dispositivo
// Parametros:
//   Letra: Letra de la unidad (A,B,C,D...)
//   VendorId: Identificacion del vendedor
//   ProductId: Identificacion del producto
//   SerialNumber: Numero de serie
//   Extraible: Indica si el dispositivo es extraible (disquete, memoria usb)
//
function GetSerialNumber(Letra: Char; var VendorId: string; var ProductId: string;
  var SerialNumber: string; var Extraible: Boolean): string;
var
  Disk: THandle;
  Size: Cardinal;
  Buffer: Pointer;
  DeviceDescriptor: PSTORAGE_DEVICE_DESCRIPTOR;
begin
  Result:= EmptyStr;
  Disk:= CreateFile(PChar('\\.\' + Letra + ':'),GENERIC_READ,FILE_SHARE_READ
    or FILE_SHARE_WRITE,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if Disk <> INVALID_HANDLE_VALUE then
  begin
    GetMem(Buffer,12);
    try
      FillChar(Buffer^,12,0);
      if DeviceIOControl(Disk, IOCTL_STORAGE_QUERY_PROPERTY,
        Buffer,12,Buffer,12,Size, nil) then
      begin
        FreeMem(Buffer);
        Size:= PSTORAGE_DESCRIPTOR_HEADER(Buffer).Size;
        GetMem(Buffer, Size);
        FillChar(Buffer^,Size,0);
        if DeviceIOControl(Disk, IOCTL_STORAGE_QUERY_PROPERTY,
          Buffer,12,Buffer,Size,Size, nil) then
          begin
            DeviceDescriptor:= Buffer;
            Extraible:= DeviceDescriptor.RemovableMedia;
            if DeviceDescriptor.VendorIdOffset > 0 then
              VendorId:= String(PChar(Buffer) + DeviceDescriptor.VendorIdOffset)
            else
              VendorId:= EmptyStr;
            if DeviceDescriptor.ProductIdOffset > 0 then
              ProductId:= String(PChar(Buffer) + DeviceDescriptor.ProductIdOffset)
            else
              ProductId:= EmptyStr;
            if (DeviceDescriptor.SerialNumberOffset > 0) and
               (DeviceDescriptor.SerialNumberOffset < Size) then
              SerialNumber:= String(PChar(Buffer) + DeviceDescriptor.SerialNumberOffset)
            else
              SerialNumber:= EmptyStr;
          end else Result:= SysErrormessage(GetLastError);
      end else Result:= SysErrormessage(GetLastError);
    finally
      FreeMem(Buffer);
    end;
    CloseHandle(Disk);
  end else Result:= SysErrormessage(GetLastError);
end;

Un ejemplo de uso
Código Delphi [-]
var
  VendorId: string;
  ProductId: string;
  SerialNumber: string;
  Extraible: Boolean;
  Mensaje: string;
begin
  Mensaje:= GetSerialNumber('C', VendorId, ProductId, SerialNumber, Extraible);
  if Mensaje = EmptyStr then
  begin
    ShowMessage
    (
      'VendorId: '     + VendorID     + #13 +
      'ProductId: '    + ProductId    + #13 +
      'SerialNumber: ' + DecodeSerialNumber(SerialNumber) + #13 +
      'Extraible: '    + BoolToStr(Extraible,TRUE)
     );
  end else
    ShowMessage(Mensaje);
end;

En el ejemplo anterior intentamos obtener la información del Disco C, si no podemos mostramos el mensaje de error que nos devuelve la función GetSerialNumber. También hay que fijarse en que el numero de serie necesita ser descodificado, y que algunas memorias usb no muestran el numero de serie.
Responder Con Cita
  #2  
Antiguo 02-12-2006
zarzuela zarzuela is offline
Registrado
 
Registrado: nov 2006
Posts: 7
Poder: 0
zarzuela Va por buen camino
ESTE TRUCO ESTA MUY BUENO, ME GUSTARIA QUE ME ENVIEN UNO DE COMO PASAR DIRECTORIOS DE UN DISCO A ATRO
Responder Con Cita
  #3  
Antiguo 04-01-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 16
ArdiIIa Va por buen camino
Muy bueno Seoane y muy completo parece, aunque seguramente con una llamda al API
Código Delphi [-]
GetVolumeInformation
en la mayoría de los casos sobra...
Responder Con Cita
  #4  
Antiguo 04-01-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 16
ArdiIIa Va por buen camino
Lo siento, quería decir que con una simple llamada al API
GetVolumeInformation, En la mayoria de los casos bastaría.
Responder Con Cita
  #5  
Antiguo 04-01-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Ardilla, el numero de serie que devuelve GetVolumeInformation, no se corresponde con el numero de serie físico del disco duro, solo sirve para identificar a la partición (compruebalo, cada partición devuelve un numero distinto aunque pertenezcan al mismo disco duro) y además cambia al formatear la partición. Son cosas completamente diferentes ...
Responder Con Cita
  #6  
Antiguo 10-02-2007
Avatar de rretamar
[rretamar] rretamar is offline
Miembro Premium
 
Registrado: ago 2006
Ubicación: San Francisco, Córdoba, Argentina
Posts: 1.104
Poder: 13
rretamar Va camino a la fama
Había un componente que daba los datos fisicos de un HD (fabricante, número de serie, y varias cosas más), pero era un componente (comercial) que usaba llamadas a una librería VXD (en Win9X) o un archivo .SYS (en versión para Win NT o superior). Se llamaba TVICPORT y es comercial.

Fuera de ese componente, no he encontrado la forma de obtener esos valores. Es una época los usaba como una medida de protección contra copia para un software que escribí.

Saludos, Tux
Responder Con Cita
  #7  
Antiguo 22-04-2007
Gangster Gangster is offline
Miembro
 
Registrado: nov 2006
Posts: 36
Poder: 0
Gangster Va por buen camino
Hola una Pregunta esta funcion la estoy implementando dentro de un form nuevo toda esta funcion la pongo dentro de un unit nuevo todo esto lo pongo abajo de Implementation en el unit y lo corro y solo me da el product ID del disco duro no me da lo demas que necesito que es el serial el que me interesa no se qu eeste haciendo mal tengo el disco con dos particiones pero no me da el serial solo el producto ID no se si tenga mal eso de que este todo debajo del Implementation por favor si me pueden decir como ponerlo este truquito en Delphi 7 para que me trabaje Gracias.

Espero Respuesta
Responder Con Cita
  #8  
Antiguo 23-04-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Ganster, si el ProductId que obtienes es correcto, es que la función y lo demás funciona correctamente. El problema puede ser que algunos fabricantes no incluyen el numero de serie en sus discos, sobre todo si se trata de un disco usb. ¿Es un disco usb?
Responder Con Cita
  #9  
Antiguo 24-04-2007
Gangster Gangster is offline
Miembro
 
Registrado: nov 2006
Posts: 36
Poder: 0
Gangster Va por buen camino
es un disco Tipo Ide Marca Hitachi, y ya lo probe en mi casa con un disco marca western tipo IDE y tambn me da el puro product ID entonces no se porque no me da bn lo otro que viene en el showmessage, asi como tal esta ahi asi la copie y la meti en un project nuevo, todo en un solo UNIT ojala y pueda decirme alguna otra razon o algo mal que este haciendo y gracias por contestar, Estoy trabajando en delphi 7.
Responder Con Cita
  #10  
Antiguo 24-04-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Pues Gangster, lo acabo de volver a probar por si al copiarlo se me hubiera pasado algo, pero a mi me funciona bien. Así que no se que puede estar ocurriendo.

¿Seguro que lo copias exactamente como yo lo pongo? Si haces algún cambio, por pequeño que sea, puede que sea ese el problema.
Responder Con Cita
  #11  
Antiguo 24-04-2007
Gangster Gangster is offline
Miembro
 
Registrado: nov 2006
Posts: 36
Poder: 0
Gangster Va por buen camino
Hola Seoane ya lo probe con discos que solo tienen la particion C y si trabaja tu funcion, pero en los discos que tienen otra letra mas al C como particion ahi es cuando me falla la funcion, no sabes que letra es la que se le pasa en la funcion getserialnumber, cuando tienes en un solo disco Duro pero con la particion C y D o dos particiones gracias por tus respuestas y por tratar de darme razones en lo que haya hecho mal.
Responder Con Cita
  #12  
Antiguo 24-04-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Gangster, vamos a probar una cosa. En esta linea:
Código Delphi [-]
Disk:= CreateFile(PChar('\\.\' + Letra + ':'),GENERIC_READ,FILE_SHARE_READ

Realiza este cambio, y vuelve a probar:
Código Delphi [-]
Disk:= CreateFile(PChar('\\.\PHYSICALDRIVE0'),GENERIC_READ,FILE_SHARE_READ
De esta manera te tendría que dar los datos del primer disco duro, \\.\PHYSICALDRIVE1 los del segundo, etc. Si te funciona no te sera muy difícil cambiar la función para que reciba como parámetro el número en vez de la letra.
Responder Con Cita
  #13  
Antiguo 24-04-2007
Gangster Gangster is offline
Miembro
 
Registrado: nov 2006
Posts: 36
Poder: 0
Gangster Va por buen camino
Hola Seoane lo probe y me da lo mismo se me hace que me explique mal es que tengo un solo disco duro, pero lo tengo partido en dos pedazos un pedazo para el C y otro para la letra D, donde el C tengo el windows XP y el otro solo de almacen, entonces al ponerle la letra C a la funcion, me da el modelo de mi disco pero no me da el serial nummber, esa es mi duda que lo probe con otros discos con la pura letra C osea una sola particion completa del disco duro y si sirve y estos que tienen partido el disco duro no lo encuentra gracias por tus respuestas.
Responder Con Cita
  #14  
Antiguo 24-04-2007
Gangster Gangster is offline
Miembro
 
Registrado: nov 2006
Posts: 36
Poder: 0
Gangster Va por buen camino
Hola Seoane lo probe y me da lo mismo se me hace que me explique mal es que tengo un solo disco duro, pero lo tengo partido en dos pedazos un pedazo para el C y otro para la letra D, donde el C tengo el windows XP y el otro solo de almacen, entonces al ponerle la letra C a la funcion, me da el modelo de mi disco pero no me da el serial nummber, esa es mi duda que lo probe con otros discos con la pura letra C osea una sola particion completa del disco duro y si sirve y estos que tienen partido el disco duro no lo encuentra gracias por tus respuestas.
Responder Con Cita
  #15  
Antiguo 24-04-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Te entendí perfectamente Gangster, por eso te dije lo de \\.\PHYSICALDRIVE0, ya que este hace referencia al disco duro físico, sin importar las particiones. No se lo que esta pasando, a mi me funciona, lo probé en mi equipo que también tiene el disco participando y funciona. Y el hecho de que a ti te funcione en unos equipos y en otros no, me hace pensar que le problema este en tu sistema. Pero la verdad es que no se me ocurre donde ....
Responder Con Cita
  #16  
Antiguo 24-04-2007
Gangster Gangster is offline
Miembro
 
Registrado: nov 2006
Posts: 36
Poder: 0
Gangster Va por buen camino
Hola Seoane ya la probe con mas discos duros tu funcion y si es buena pero en algunos modelos de discos duros, que son pues de marcas comerciales, porque pues aqui donde trabajo y hago mis aplicaciones en delphi,usamos discos de un tipo y no sirvio esta funcion pero en otros si, entonces en donde no sirvio tu funcion los probe con un programa llamado everest que te dice informacion interna de cualquier ordenador y este si me daba el numero de serie fisico de los discos duros donde esta funcion no trabajaba, de todos modos si sirve esta funcion,en algunos discos duros entonces no queda mas que usarla y que te toque un disco duro que si la acepte, gracias por tus respuestas y seguiremos por aqui en este foro porque me queda mucho por seguir aprendiendo de dlephi gracias por todo.
Responder Con Cita
  #17  
Antiguo 23-10-2007
Avatar de JoAnCa
JoAnCa JoAnCa is offline
Miembro
 
Registrado: jul 2005
Ubicación: Cuba
Posts: 367
Poder: 13
JoAnCa Va por buen camino
Hola Seoane
Gracias por tu truco, este codigo hace rato lo estaba buscando, el que me diera el ProductoID de los discos duros (al fin lo encontré)
Otra cosa, como obtener la capacidad total del Disco independientemente de las particiones que tenga, en los trucos y foros, lo que me he encontrado me dan la de la particion seleccionada, no la del disco total.
Responder Con Cita
  #18  
Antiguo 24-10-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 17
seoane Va por buen camino
Jose Caceres, prueba con esto:
http://www.clubdelphi.com/foros/showpost.php?p=182741&postcount=5
Responder Con Cita
  #19  
Antiguo 11-03-2009
Avatar de MAXIUM
MAXIUM MAXIUM is offline
Miembro
 
Registrado: may 2005
Posts: 1.313
Poder: 14
MAXIUM Va por buen camino
Efectivamente puedo dar fe de que no funciona en todos los discos duros, lo probé en un SATA II particionado con S.O. WinXP.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 13:02:47.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi