Solved

Protecting programs from piracy

Posted on 1997-05-05
5
148 Views
Last Modified: 2010-04-06
How can I get the hard disk's serial number in order to protect my program from running elsewhere that in that particular hard disk ?
0
Comment
Question by:sime
[X]
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
  • 3
5 Comments
 
LVL 1

Accepted Solution

by:
jackb022197 earned 50 total points
ID: 1335929
See the unit below...

unit SerNum;

Interface

uses WinProcs, WinTypes;

function GetSerialNumber (drive: Byte): LongInt;
function SetSerialNumber (drive: Byte; serNum: LongInt): Bool;

Implementation

type
    PMIDINFO = ^MIDINFO;
    MIDINFO = record
                  InfoLevel:  Word;
                  SerialNum:  Longint;
                  VolLabel:   array[0..10] of Char;
                  FileSystem: array [0..7] of Char;
              end;

var
    R: record     { Real mode call structure }
           di, si, bp, Reserved, bx, dx, cx, ax : Longint;
           Flags, es, ds, fs, gs, ip, sp, ss: Word;
       end;

{----------------------------------------------------------------------------}
{    Name:    GetSetMid                                                      }
{    Purpose: Low level code to get or set a MIDINFO data structure for the  }
{             specified drive.  RealModeAX = $6900 for a get and $6901 for a }
{             set operation.                                                 }
{----------------------------------------------------------------------------}

function GetSetMid (Drive: Byte; MID: PMIDINFO; RealModeAX: Word): Bool;
var
    Error: Byte;
begin
    { Assume everything ok }

    Error := 0;
    GetSetMid := True;

    R.ax := RealModeAX;
    R.bx := Drive;
    R.ds := HiWord (Longint (MID));              { Subtle !!! }
    R.dx := LoWord (Longint (MID));

    asm
        mov bx, 0021h     { set flags to $00, Real mode interrupt $21 }
        xor cx, cx        { copy 0 words from protected mode stack }
        mov ax, seg R
        mov es, ax        { selector of real mode call structure }
        mov di, offset R  { offset of real mode call structure }
        mov ax, 0300h     { DPMI simulate real mode interrupt }
        int 31h           { do the business }
        jnc @@1           { branch if no error }
        inc Error
    @@1:
    end;

    if Error = 1 then GetSetMid := False;
end;

{----------------------------------------------------------------------------}
{    Name:    GetMid                                                         }
{    Purpose: Get the MIDINFO record for a specified drive.                  }
{             Uses GetSetMid.  Returns TRUE if successful.                   }
{----------------------------------------------------------------------------}

function GetMid (drive: Byte; var mid: MIDINFO): Bool;
var
    p: LongInt;
begin
    { Assume failure }
    GetMid := False;

    { Allocate a MIDINFO data structure in DOS address-space }
    p := GlobalDOSAlloc (sizeof (MIDINFO));

    if GetSetMid (drive, Ptr (HiWord (p), 0), $6900) then
    begin
        mid := PMIDINFO (Ptr (LoWord (p), 0))^;
        GetMid := True;
    end;

    GlobalDOSFree (LoWord (p));
end;

{----------------------------------------------------------------------------}
{    Name:    SetMid                                                         }
{    Purpose: Set the MIDINFO record for a specified drive.                  }
{             Uses GetSetMid.  Returns TRUE if successful.                   }
{----------------------------------------------------------------------------}

function SetMid (drive: Byte; var mid: MIDINFO): Bool;
var
    p: LongInt;
begin
    { Assume failure }
    SetMid := False;

    { Allocate a MIDINFO data structure in DOS address-space }
    p := GlobalDOSAlloc (sizeof (MIDINFO));
    PMIDINFO (Ptr (LoWord (p), 0))^ := mid;
    if GetSetMid (drive, Ptr (HiWord (p), 0), $6901) then SetMid := True;
    GlobalDOSFree (LoWord (p));
end;

{----------------------------------------------------------------------------}
{    Name:    GetSerialNumber                                                }
{    Purpose: Get the serial number for a specified drive.                   }
{             If an error occurs, then 0 is returned as the serial number.   }
{----------------------------------------------------------------------------}

function GetSerialNumber (drive: Byte): LongInt;
var
    mid: MIDINFO;
begin
    if GetMid (drive, mid) then GetSerialNumber := mid.SerialNum
    else GetSerialNumber := 0;
end;

{----------------------------------------------------------------------------}
{    Name:    SetSerialNumber                                                }
{    Purpose: Set the serial number for a specified drive.                   }
{             If no error, TRUE is returned as the function result.          }
{----------------------------------------------------------------------------}

function SetSerialNumber (drive: Byte; serNum: LongInt): Bool;
var
    mid: MIDINFO;
begin
    SetSerialNumber := False;
    if GetMid (drive, mid) then
    begin
        mid.SerialNum := serNum;
        SetSerialNumber := SetMid (drive, mid);
    end;
end;

end.
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335930
If you can set the serial number...what would prevent some
other program from doing the same thing, thus rendering
your program inoperable...thus pissing off your customer??

Reading drive serial numbers is just a bad idea.  Think about
it?  If it was a good idea, every major piece of software
would be doing it.

Also, what's to stop someone from just pirating your setup
disk??  Your setup doesn't know, ahead of time, the serial
number of the drive it is going to be installed to.
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335931
What kind of software are you writing that you think it will
be so rampantly pirated?

If you are writing shareware or something, a better bet might
be to just supply demos that are time-stamped and will not
allows installs after an initial one has expired.

If you want some tips on how to do this effectively, I can
supply as an answer if you don't like the answer already given.
0
 
LVL 2

Expert Comment

by:javiertb
ID: 1335932
And what if you change the system date? You could still be using the program.
0
 
LVL 3

Expert Comment

by:mheacock
ID: 1335933
I've already taken into account changing the system date...
system date changes are a really simple problem to solve.

The simplest, though not the only solution, is to hard code
a date into your program that it cannot run before.  If
you created your program July 1996...you certainly would
not allow it to run with a system date of June 1996 or earlier.

There are a lot of other little things that you can do to
make it extremely difficult for anyone to try and circumvent
time-stamping.  It will always be possible to circumvent,
but if you make it a pain in the ass to do so, most folks will
stop bothering to try.

And you always have human error to rely on...the moment someone
forgets to set back the clock and run your program, it'll
make it very difficult for them to re-run it once it has
expired.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

687 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