Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Система";
Текущий архив: 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
14-84700
AZ
2003-06-03 21:18
2003.06.26
А вы умеете мечтать?


14-84580
Sheng
2003-06-08 11:12
2003.06.26
Глюк в ХР


1-84403
adogg
2003-06-09 15:55
2003.06.26
StringGrid


1-84180
Doc
2003-06-11 17:21
2003.06.26
String, TObject и т.д. - Pointer?


1-84194
Schredder
2003-06-12 10:45
2003.06.26
Richview или Memo





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский