Solved

Real serial number of cd ( not the volume number )

Posted on 2004-09-08
17
253 Views
Last Modified: 2010-04-05
Hi, I copy the installation of my software to a cd-rom. Then, I create an image of this cd, and burn this image in another cd. So, the 2 cds has the same volume number. I would like to identify each disc solely, because anyone can create an image of the original disk and distribute this cd, or something else. So, I would like to recognize when the software was copied to another cd, like a manufacturer's number, so, if it is a copy of the original cd, it has another manufacturer number.

Thanks.
0
Comment
Question by:emu10k1
  • 5
  • 5
  • 2
  • +2
17 Comments
 
LVL 2

Expert Comment

by:Bobcsi
ID: 12013388
Windows creates a "Virtual Series Number" for Audio CDs. You can use the following code to get the VSN of an audio CD:

type
  TNumbBase = 1..36;

function NumbToStr(Numb: LongInt; Base: TNumbBase): string;
const
  NumbDigits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
begin
  Result := EmptyStr;
  while Numb > 0 do
  begin
    Result := NumbDigits[(Numb mod Base) + 1] + Result;
    Numb := Numb div Base;
  end;
  if Result = EmptyStr then
    Result := '0';
end;

function GetCDID(Drive: string): string;
var
  Serial: DWord;
  T: Cardinal;
begin
  if GetVolumeInformation(PChar(Drive), nil, 0, @Serial, T, T, nil, 0) then
    Result := NumbToStr(Serial, 16)
  else
    Result := EmptyStr;
end;

Drive should be the name of the root directory of your CD drive. Use it like

ShowMessage(GetCDID('I:\'));

or

ShowMessage(GetCDID('\\Computer2\\CDDrive\'));


Solve 2:

You have to use the API-call GetVolumeInformation. But first, you have to implement it correctly:


function GetVolumeInformation(lpRootPathName: PAnsiChar; lpVolumeNameBuffer: PAnsiChar; nVolumeNameSize: DWORD; var lpVolumeSerialNumber, lpMaximumComponentLength,
lpFileSystemFlags: DWORD; lpFileSystemNameBuffer: PAnsiChar; nFileSystemNameSize: DWORD): bool; stdcall; external kernel32 name 'GetVolumeInformationA';


In your application:


function GetCDId: string;
var
  root: string;
  VolumeNameBuffer, FileSystemNameBuffer: PChar;
  VolumeSerialNumber, FileSystemFlags, MaximumComponentLength: LongInt;

  function Int2Hex(number: LongInt): string;
  var
    i: LongInt;
    s: string;
  begin
    s := '';
    i := 0;
    while number > 0 do
    begin
      i := number mod 16;
      case i of
        0..9: s := IntToStr(i) + s;
        10: s := 'A' + s;
        11: s := 'B' + s;
        12: s := 'C' + s;
        13: s := 'D' + s;
        14: s := 'E' + s;
        15: s := 'F' + s;
      end;
      number := number - i * 16;
    end;
    Result := s;
  end;

begin
  root := 'x:\'; {where X is the drive letter of your CD drive}
  VolumeNameBuffer := StrAlloc(256);
  FileSystemNameBuffer := StrAlloc(256);
  if GetVolumeInformation(PChar(root), VolumeNameBuffer, 255, VolumeSerialNumber,
    MaximumComponentLength, FileSystemFlags, FileSystemNameBuffer, 255) then
    Result := Int2Hex(VolumeSerialNumber);
else
  Result := '';
end;

Bobcsi
0
 
LVL 4

Expert Comment

by:tobjectpascal
ID: 12013873
Using GetVolumeInformation is NOT the way to go, since this way you'll get different serial numbers for win9x and winNT for the same CD, don't ask me why...

I'm using the following code, which is a bit similar to Motaz' code, however, it doesn't need that MediaPlayer, furthermore it works also if you have more than one CD drive (I don't see how you could ask the serial number for specific cd drives with Motaz' code).

function GetCDSerialNo(drive: char) : cardinal;
var mo : TMCI_OPEN_PARMS;
mp : TMCI_INFO_PARMS;
mg : TMCI_GENERIC_PARMS;
s1 : string;
arrCh : array [0..255] of char;
begin
result := 0;
s1 := drive + ':';
ZeroMemory(@mo, sizeOf(mo));
ZeroMemory(@mp, sizeOf(mp));
ZeroMemory(@mg, sizeOf(mg));
mo.lpstrDeviceType := pchar(MCI_DEVTYPE_CD_AUDIO);
mo.lpstrElementName := pchar(s1);
mp.lpstrReturn := arrCh;
mp.dwRetSize := sizeOf(arrCh) - 1;
if mciSendCommand(0, MCI_OPEN,
MCI_OPEN_ELEMENT or MCI_OPEN_SHAREABLE or
MCI_OPEN_TYPE or MCI_OPEN_TYPE_ID or MCI_WAIT,
cardinal(@mo)) = 0 then
try
if mciSendCommand(mo.wDeviceID, MCI_INFO, MCI_INFO_MEDIA_IDENTITY, cardinal(@mp)) = 0 then
result := cardinal(StrToIntDef(arrCh, 0));
finally mciSendCommand(mo.wDeviceID, MCI_CLOSE, 0, cardinal(@mg)) end;
end;

0
 
LVL 4

Expert Comment

by:tobjectpascal
ID: 12013894
uses MMsystem;

procedure TForm1.Button1Click(Sender: TObject);
Var
 drv: Char;
begin
 Drv:='D'; //whatever
 Edit1.Text:=IntToStr(GetCDSerialNo(Drv));
end;
0
 

Author Comment

by:emu10k1
ID: 12022994
Bobcsi: I try the first solve that you say... and it didn't work, it get the same number for the two cds, so, it didn't identify each cd, it shows me the volume number, that is the same if the first cd is a image of the second cd.

and your second solve, it freeze when i call GetCDId. And I change  VolumeSerialNumber, FileSystemFlags, MaximumComponentLength: LongInt; for VolumeSerialNumber, FileSystemFlags, MaximumComponentLength: Cardinal; because it shows me "Types of actual and formal var parameters must be identical" .

emu10k1
0
 

Author Comment

by:emu10k1
ID: 12023013
tobjectpascal: it shows me the same number in the two cds. This code get the volume number, and the volume number is the same if the first cd is an image of the second cd. I want the manufacturer number, a number that is unique, so, this number never will be the same of another cd.

Thanks, and please help if you know how to solve this problem.

emu10k1
0
 
LVL 4

Accepted Solution

by:
tobjectpascal earned 500 total points
ID: 12025263
if it's an identical clone which is what an image is, of course it will be identical, otherwise the program would not run if one of the security measures is checking the serial of the CD.
0
 

Author Comment

by:emu10k1
ID: 12025490
your code shows me the number 3579 in two cds(original and clone). so, if anyone burn an image, the program will run normally.
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 4

Expert Comment

by:tobjectpascal
ID: 12026367
well if the second disk showed ANY OTHER serial number other than the one you cloned, it would NOT BE A CLONE now would it!
0
 

Author Comment

by:emu10k1
ID: 12026537
yeah... I would like to the second disk show any other serial number, not the same serial of the first disk... but this didn't happen... it shows me the same serial number for the first and second disk...
0
 
LVL 4

Expert Comment

by:tobjectpascal
ID: 12026612
and third and fourth and fith, i don't think you quite understand the word "clone" if two frogs looked identical expect one had red eyes and the other had blue eyes, it would no longer be a clone, if it was a clone the serial number included would be identical otherwise it would not be a clone, what you're asking for is impossible, all a CD is plastic which gets grooves cut into it, 0 or 1 right, from start to finish it would be exactly the same as your other CD, the serial you're refering to is not something that can be extracted, it sits in the rim where the laser does not go, that's the manufacture serial, and as far as i am aware you can not get it.
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 12046086
MessageDlg(
  'Serial number: ' +
  Format( '%X', [ GetDiskVolSerialID( 'E' ) ] ),
  mtInformation, [mbOk], 0 );
0
 

Author Comment

by:emu10k1
ID: 12061342
ginsonic: where are declared this function "GetDiskVolSerialID" ?
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 12061379
0
 

Expert Comment

by:sad_man
ID: 12515246
here is some code of mine
u can use this

uses MMSystem, MPlayer;

procedure TForm1.Button1Click(Sender: TObject);
var
mp : TMediaPlayer;
msp : TMCI_INFO_PARMS;
MediaString : array[0..255] of char;
ret : longint;

begin
mp := TMediaPlayer.Create(nil);
mp.Visible := false;
mp.Parent := Application.MainForm;
mp.Shareable := true;
mp.DeviceType := dtCDAudio;
mp.FileName := 'D:';
mp.Open;
Application.ProcessMessages;
FillChar(MediaString, sizeof(MediaString), #0);
FillChar(msp, sizeof(msp), #0);
msp.lpstrReturn := @MediaString;
msp.dwRetSize := 255;
ret := mciSendCommand(Mp.DeviceId,
MCI_INFO,
MCI_INFO_MEDIA_IDENTITY,
longint(@msp));
if Ret <> 0 then
begin
MciGetErrorString(ret, @MediaString, sizeof(MediaString));
Memo1.Lines.Add(StrPas(MediaString));
end
else
Memo1.Lines.Add(StrPas(MediaString));
mp.Close;
Application.ProcessMessages;
mp.free;
end;
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
indy Tmemory stream non latin charcter issue 2 98
Delphi : could not find program, '...exe' 2 148
find a node in VST 2 64
How to load 2 images in same column in Delphi 2 33
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Windows 10 is mostly good. However the one thing that annoys me is how many clicks you have to do to dial a VPN connection. You have to go to settings from the start menu, (2 clicks), Network and Internet (1 click), Click VPN (another click) then fi…
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now