Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

How to get "disk serial number"

Posted on 1997-06-10
2
318 Views
Last Modified: 2010-04-03
I need compare a decrypted string with the serial number of the disk where it is installed, as a way to avoid people to duplicate the software I deliver to them. I have not heard from a clever method to get access to that serial number string.
I presently achieve it (Delphi 1 Windows 3.11) with a not very clever method, though efficient : I use ShellExecute passing the command "command.com /c dir c:\ >text.tmp", launching the DOS command interpreter, using the DIR command, and redirecting the output into a text file, from which I read the line where the useful information is written. Do you have any clever method avoiding this call to DOS ?
0
Comment
Question by:pousticrousti
2 Comments
 
LVL 4

Accepted Solution

by:
erajoj earned 200 total points
ID: 1336957
With Win32, this is easy. But with Windows 3.x & Delphi 1, it's worth the 200 pts.
This code is tested and it works fine:

var
  Form1   : TForm1;
  SerialNo: LongInt;

implementation

{$R *.DFM}

type
  TDriveChar = '@'..'Z'; {'@' = current, 'A', 'B', etc.}

  PRealModeRegs = ^TRealModeRegs;
  TRealModeRegs = record
    case Integer of
      0: (
        EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint;
        Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word);
      1: (
        DI, DIH, SI, SIH, BP, BPH, XX, XXH: Word;
        case Integer of
          0: (
            BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word);
          1: (
            BL, BH, BLH, BHH, DL, DH, DLH, DHH,
            CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte));
  end;

function RealModeInt(Int: Byte; var Regs: TRealModeRegs): Boolean;
{ procedure invokes int 31h function 0300h to simulate a real mode }
{ interrupt from protected mode. }
var
  ErrorFlag: Boolean;
begin
  asm
    mov ErrorFlag, 0       { assume success }
    mov ax, 0300h          { function 300h }
    mov bl, Int            { real mode interrupt to execute }
    mov bh, 0              { required }
    mov cx, 0              { stack words to copy, assume zero }
    les di, Regs           { es:di = Regs }
    int 31h                { DPMI int 31h }
    jnc @@End              { carry flag set on error }
  @@Error:
    mov ErrorFlag, 1       { return false on error }
  @@End:
  end;
  Result := not ErrorFlag;
end;

function GetVolSerNo(Drive: TDriveChar): LongInt;
type
  PDiskInfo = ^TDiskInfo;
  TDiskInfo = record
    InfoLevel: Word;
    DiskSerNum: LongInt;
    VolumeLabel: array[0..10] of Byte;
    FileSysType: array[0..7] of Byte;
  end;
var
  L: LongInt;
  P: PDiskInfo;
  R: TRealModeRegs;
begin
  Result := 0;
  L := GlobalDOSAlloc(SizeOf(TDiskInfo));
  if L <> 0 then
  try
    P := Ptr(LoWord(L),0);
    FillChar(P^,sizeof(TDiskInfo),0);
    FillChar(R,sizeof(R),0);
    with R do
    begin
      AX := $6900;
      BL := Ord(Drive)-64;
      BH := 0;
      DS := HiWord(L);
      DX := 0;
    end;
    if RealModeInt($21,R) then
      Result := P^.DiskSerNum
  finally
    GlobalDosFree(LoWord(L));
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  SerialNo := GetVolSerNo('C');
  Label1.Caption := Format('%04x-%04x', [HiWord(SerialNo), LoWord(SerialNo)]); { Only to make it look like the "dir" output }
end;

Enjoy!

/// John

0
 

Author Comment

by:pousticrousti
ID: 1336958
Thank you very much for this super fast answer. I trust I can rely on it, and will implement it right now. It's worth 200 points for you !
Olivier de Saint Leger
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
code issue 8 152
Convert a string into a TDateTime 5 63
can't find the executable in Simulator 1 100
CheckListBox usage 3 71
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…

791 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