Форум: "Система";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];
ВнизСчитывание серийного номера Найти похожие ветки
← →
Alex000 (2003-04-15 08:52) [0]Господа! Подскажите как в Delphi программно считать серийный номер жеского диска, или CD?
← →
Zazoo (2003-04-15 09:26) [1]procedure GetDiskInfo(Value: Char);
var
VolumeLabel, FileSystem: Array[0..$FF] of Char;
SerialNumber, DW, SysFlags: DWord;
begin
GetVolumeInformation("C:\", VolumeLabel, SizeOf(VolumeLabel),
@SerialNumber, DW, SysFlags,
FileSystem, SizeOf(FileSystem));
FSerialNumber := SerialNumber;
FSerialNumberStr := Format("%0x",[SerialNumber]);
Insert("-", FSerialNumberStr, 5);
FVolumeLabel := VolumeLabel;
FFileSystem := FileSystem;
FDriveType := TDriveType(GetDriveType(PChar(Value + ":\")));
FDiskSize := SysUtils.DiskSize(Byte(Value) - $40);
FDiskFree := SysUtils.DiskFree(Byte(Value) - $40);
end;
PS. Соответств. Переменные надо повводить ;)
← →
kostik78ua (2003-04-15 09:31) [2]function GetIdeDiskSerialNumber : String;
type
TSrbIoControl = packed record
HeaderLength : ULONG;
Signature : Array[0..7] of Char;
Timeout : ULONG;
ControlCode : ULONG;
ReturnCode : ULONG;
Length : ULONG;
end;
SRB_IO_CONTROL = TSrbIoControl;
PSrbIoControl = ^TSrbIoControl;
TIDERegs = packed record
bFeaturesReg : Byte;
bSectorCountReg : Byte;
bSectorNumberReg : Byte;
bCylLowReg : Byte;
bCylHighReg : Byte;
bDriveHeadReg : Byte;
bCommandReg : Byte;
bReserved : Byte;
end;
IDEREGS = TIDERegs;
PIDERegs = ^TIDERegs;
TSendCmdInParams = packed record
cBufferSize : DWORD;
irDriveRegs : TIDERegs;
bDriveNumber : Byte;
bReserved : Array[0..2] of Byte;
dwReserved : Array[0..3] of DWORD;
bBuffer : Array[0..0] of Byte;
end;
SENDCMDINPARAMS = TSendCmdInParams;
PSendCmdInParams = ^TSendCmdInParams;
TIdSector = packed record
wGenConfig : Word;
wNumCyls : Word;
wReserved : Word;
wNumHeads : Word;
wBytesPerTrack : Word;
wBytesPerSector : Word;
wSectorsPerTrack : Word;
wVendorUnique : Array[0..2] of Word;
sSerialNumber : Array[0..19] of Char;
wBufferType : Word;
wBufferSize : Word;
wECCSize : Word;
sFirmwareRev : Array[0..7] of Char;
sModelNumber : Array[0..39] of Char;
wMoreVendorUnique : Word;
wDoubleWordIO : Word;
wCapabilities : Word;
wReserved1 : Word;
wPIOTiming : Word;
wDMATiming : Word;
wBS : Word;
wNumCurrentCyls : Word;
wNumCurrentHeads : Word;
wNumCurrentSectorsPerTrack : Word;
ulCurrentSectorCapacity : ULONG;
wMultSectorStuff : Word;
ulTotalAddressableSectors : ULONG;
wSingleWordDMA : Word;
wMultiWordDMA : Word;
bReserved : Array[0..127] of Byte;
end;
PIdSector = ^TIdSector;
const
IDE_ID_FUNCTION = $EC;
IDENTIFY_BUFFER_SIZE = 512;
DFP_RECEIVE_DRIVE_DATA = $0007c088;
IOCTL_SCSI_MINIPORT = $0004d008;
IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;
DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;
BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;
W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;
var
hDevice : THandle;
cbBytesReturned : DWORD;
pInData : PSendCmdInParams;
pOutData : Pointer;
Buffer : Array[0..BufferSize-1] of Byte;
srbControl : TSrbIoControl absolute Buffer;
procedure ChangeByteOrder( var Data; Size : Integer );
var ptr : PChar;
i : Integer;
c : Char;
begin
ptr := @Data;
for i := 0 to (Size shr 1)-1 do
begin
c := ptr^;
ptr^ := (ptr+1)^;
(ptr+1)^ := c;
Inc(ptr,2);
end;
end;
begin
Result := "";
FillChar(Buffer,BufferSize,#0);
if Win32Platform=VER_PLATFORM_WIN32_NT then
begin
hDevice := CreateFile("\\.\Scsi0:",
// Note: "\\.\C:" required administrative privileges.
GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, 0, 0);
if hDevice=INVALID_HANDLE_VALUE then Exit;
try
srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
System.Move("SCSIDISK",srbControl.Signature,8);
srbControl.Timeout := 2;
srbControl.Length := DataSize;
srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
pInData := PSendCmdInParams(PChar(@Buffer)
+SizeOf(SRB_IO_CONTROL));
pOutData := pInData;
with pInData^ do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
bDriveNumber := 0;
with irDriveRegs do
begin
bFeaturesReg := 0;
bSectorCountReg := 1;
bSectorNumberReg := 1;
bCylLowReg := 0;
bCylHighReg := 0;
bDriveHeadReg := $A0;
bCommandReg := IDE_ID_FUNCTION;
end;
end;
if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT,
@Buffer, BufferSize, @Buffer, BufferSize,
cbBytesReturned, nil ) then Exit;
finally
CloseHandle(hDevice);
end;
end
else
begin // Windows 95 OSR2, Windows 98, Windows ME
hDevice := CreateFile( "\\.\SMARTVSD", 0, 0, nil,
CREATE_NEW, 0, 0 );
if hDevice=INVALID_HANDLE_VALUE then Exit;
try
pInData := PSendCmdInParams(@Buffer);
pOutData := @pInData^.bBuffer;
with pInData^ do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
bDriveNumber := 0;
with irDriveRegs do
begin
bFeaturesReg := 0;
bSectorCountReg := 1;
bSectorNumberReg := 1;
bCylLowReg := 0;
bCylHighReg := 0;
bDriveHeadReg := $A0;
bCommandReg := IDE_ID_FUNCTION;
end;
end;
if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA,
pInData, SizeOf(TSendCmdInParams)-1, pOutData,
W9xBufferSize, cbBytesReturned, nil ) then Exit;
finally
CloseHandle(hDevice);
end;
end;
with PIdSector(PChar(pOutData)+16)^ do
begin
ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));
SetString(Result,sSerialNumber,SizeOf(sSerialNumber));
end;
end;
← →
Alex Konshin (2003-04-15 11:07) [3]http://home.earthlink.net/~akonshin/index.htm
← →
destiny (2003-04-15 18:40) [4]Серийный номер винчестера
procedure TForm1.Button1Click(Sender: TObject);
var
SerialNum : dword;
a, b : dword;
Buffer : array [0..255] of char;
begin
if GetVolumeInformation("c:\", Buffer, SizeOf(Buffer), @SerialNum, a, b, nil, 0) then
Label1.Caption := IntToStr(SerialNum);
end;
Получение идентификатора диска
const
MCI_INFO_PRODUCT = $00000100;
MCI_INFO_FILE = $00000200;
MCI_INFO_MEDIA_UPC = $00000400;
MCI_INFO_MEDIA_IDENTITY = $00000800;
MCI_INFO_NAME = $00001000;
MCI_INFO_COPYRIGHT = $00002000;
{ блок параметров для командного сообщения MCI_INFO }
type
PMCI_Info_ParmsA = ^TMCI_Info_ParmsA;
PMCI_Info_ParmsW = ^TMCI_Info_ParmsW;
PMCI_Info_Parms = PMCI_Info_ParmsA;
TMCI_Info_ParmsA = record
dwCallback: DWORD;
lpstrReturn: PAnsiChar;
dwRetSize: DWORD;
end;
TMCI_Info_ParmsW = record
dwCallback: DWORD;
lpstrReturn: PWideChar;
dwRetSize: DWORD;
end;
TMCI_Info_Parms = TMCI_Info_ParmsA;
Идентификатор возвращается функцией MCI_INFO_MEDIA_IDENTITY в виде строки с десятичным числом. Для получения дополнительной информации обратитесь к электронной справке (Win32 и компонент TMediaPlayer).
Исправления
--------------------------------------------------------------------------------
// метка диска
procedure GetDriveInfo(VolumeName: string; var VolumeLabel, SerialNumber, FileSystem: string);
var
VolLabel, FileSysName :array [0..255] of char;
SerNum :pdword;
MaxCompLen, FileSysFlags :dword;
begin
New(SerNum);
GetVolumeInformation(PChar(VolumeName), VolLabel, 255, SerNum, MaxCompLen, FileSysFlags, FileSysName, 255);
VolumeLabel:=VolLabel;
SerialNumber:=Format("%x",[SerNum^]);
FileSystem:=FileSysName;
Dispose(SerNum);
end;
// далее
var
VolLabel, SN, FileSystem, S : string;
begin
s := "g:\"; // имя CD дисковода
GetDriveInfo(S, VolLabel, SN, FileSystem);
получаем:
VolLabel - "ARMSTRONG" // метка диска
SN - B5FF77AD // номер серийный
FileSystem - CDFS // тип файловой системы
Работает не только для CD для всех типов дисков ... Далее:
--------------------------------------------------------------------------------
// метка диска
procedure GetAllDrive(Sender: TObject);
var
i, mask : integer;
s : string;
begin
mask := GetLogicalDrives; i := 0;
while mask<>0 do
begin
s:= chr( ord("a") + i ) + ":\";
if (mask and 1) <> 0 then
case GetDriveType(PChar(s)) of
0 : ListBox1.Items.Add(s + " unknown.");
1 : ListBox1.Items.Add(s + " not exist.");
DRIVE_REMOVABLE : ListBox1.Items.Add(s + " removable."); // floppy,zip
DRIVE_FIXED : ListBox1.Items.Add(s + " fixed.");
DRIVE_REMOTE : ListBox1.Items.Add(s + " network.");
DRIVE_CDROM : ListBox1.Items.Add(s + " CD-ROM.");
DRIVE_RAMDISK : ListBox1.Items.Add(s + " RAM.");
end;
inc(i); mask := mask shr 1;
end;
end;
В ListBox1 получаем все диски на данном компьютере.
← →
Alex Konshin (2003-04-15 20:17) [5]Нет, ну не умеют люди читать.
GetVolumeInformation НЕ возвращает серийный номер диска.
Ну не знаете, так не путайте других.
← →
Qw88 (2003-04-15 22:22) [6]2 Alex Konshin: чем тебе не нравится ответ от kostik78ua
← →
Alex Konshin (2003-04-16 07:03) [7]Отсутствие копирайта :)
Зачем приводить исковерканный текст, если можно дать ссылку.
← →
ws (2003-04-16 14:13) [8]пример от kostik78ua, кстати, у меня на 2к не сработал...
2Alex Konshin: а какую ссылку?
← →
Alex Konshin (2003-04-17 08:38) [9]Да на мою страницу,
http://home.earthlink.net/~akonshin/index.htm
Там есть несколько примеров по данному вопросу.
Собственно, тот пример "от костика" там и живет.
← →
kostik78ua (2003-04-17 09:22) [10]2 Alex Konshin
Прошу прощения, за отсутствие копирайта. Но я потерял первоисточник. Код исковеркан т.к. сообщение не может быть больше 5К. Пришлось урезать :)
2 ws
У меня win2k professional и все работает.
← →
ruslanyd (2003-04-17 14:34) [11]а есть способ узнать серийный номер винта (не тома)
на дисках, не поддерживающих S.M.A.R.T. технологию?
их, кажется, большинство
а если делать привязку программы на этот серийник, то он должен работать на любых винтах (или почти на любых)
← →
Alex Konshin (2003-04-18 07:25) [12]Где ты видел сейчас ATA винчестеры, которые не поддерживают S.M.A.R.T.? Он уже давно является частью стандарта ATA.
Смотри http://www.t13.org/
← →
ruslanyd (2003-04-18 12:09) [13]проверил
действительно так
просто далеко не все производители винтов явно указывают
на поддержку этого стандарта
у нас большинство винтов IBM
посмотрел на сайте их спецификации и узнал для себя многое :)
← →
Alex000 (2003-04-18 14:40) [14]У меня совершенно идиотская проблема. Я реализовал пример от Zazoo и все работает. С жестким диском , с CD-R (после записи), а вот после перезаписи CD-RW каждый раз выдается новый серийный номер.
Так и должно быть?
← →
ruslanyd (2003-04-18 15:45) [15]проблема совершенно не идиотская
ту уже было неоднократно сказано, что GetVolumeInformation
возвращает не S/N винта, а серийный номер тома, которых для одного винта может быть много (на каждый отдельный том)
и этот S/N формируется и записывается при форматировании
тома
что-то похожее происходит и с CD-RW
а вот алгоритм Коншина позволяет считать именно серийник
винта, если он поддерживает технологию S.M.A.R.T.
← →
ruslanyd (2003-04-18 15:51) [16]кстати, серийник тома легко меняется утилитами типа diskedit
или еще проще - тулзой volumeid ( тут где-то пробегала
ссылка на нее )
так что если серийник нужен для привязки своего софта к харду
то гораздо эффективнее будет метод, любезно бредоставленный
Коншиным
← →
ruslanyd (2003-04-18 15:53) [17]классная очепятка получилась в предыдущем посте :)
Страницы: 1 вся ветка
Форум: "Система";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.027 c