Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

computer's BIOS date

Posted on 1997-08-15
7
Medium Priority
?
294 Views
Last Modified: 2010-04-06
how can i retrieve the computer's BIOS date with Delphi Pascal (16 bits version)?

I tried memory location Mem[$FFFF:$0005] but this gives a general protection error.

I made a DOS-program in Turbo Pascal 4.0 about 6 year's ago which retrieves 8 bytes starting at memory location $FFFF:$0005. This 8 bytes contain the BIOS date of the computer. The program worked well with the three generations of computers i owned (286, 486 Pentium 166).

But in Delphi i get a general protection failure at run time in the line marked with {*} in the function below.

function
  BiosDate: string;
var
  Offset: Word;
begin
  Result := '';
  for Offset := $0005 to $000C do
    Result := Result + Char(Byte(Ptr($FFFF, Offset)^));  {*}
end;
0
Comment
Question by:rj
  • 4
  • 3
7 Comments
 
LVL 1

Expert Comment

by:peter_vc
ID: 1341569
I think I have an easy solution, but I need to know if $FFFF:$0005 is really the correct location.  The Undocumented PC and Undocumented DOS don't seem to have that info.


0
 

Author Comment

by:rj
ID: 1341570
Edited text of question
0
 

Author Comment

by:rj
ID: 1341571
i expanded my question about biosdate with some more info.
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 1

Accepted Solution

by:
peter_vc earned 800 total points
ID: 1341572
Sorry this isn't as clean as it could be, but it works.

Be aware that you may have to call FreeSelector to deallocate the selector created with AllocSelector.

var
  d : Byte;
  dp : ^Byte;
  c : LongInt;
  I : integer;
  date : array[0..7] of char;
begin

c := 1048565;  { $ffff:$0005 }
dp := CreateFarPointer(c,8);
for I:= 0 to 7 do
begin
     d := Byte(dp^);
     Inc(dp);
     date[I] := Chr(d);
end;
end;


function CreateFarPointer(phys:LongInt; length:Cardinal) : Pointer;
var
   limit : Cardinal;
   sel : Cardinal;
begin
    limit := length - 1;

    asm MOV sel,DS end;

    sel := AllocSelector(sel);
    SetSelectorBase(sel, phys);
    SetSelectorLimit(sel, limit);
    Result:=Ptr(sel,0);

end;

0
 

Author Comment

by:rj
ID: 1341573
Thanks for your answer. You're a real expert.
I added your source to my project and it worked!

I have just one question: what is the meaning of the assembler line in your source (asm MOV sel,DS end;)? I tried to run without this line and this gave also the same result.

bye, robbert-jan

0
 
LVL 1

Expert Comment

by:peter_vc
ID: 1341574
It stores the data segment register into the variable sel.  It just ensures that its using the proper parameters to allocate the selector.  You should leave it in.

As you are testing it, put a call to it in a loop a few thousand times and let me know what happens.  I'm wondering if a call to FreeSelector is needed.  I think you'll need to free it once your done with the pointer.  I really should have done this, but ...

Credit for this actually goes to Andrew Shulman, author of Undocumented Windows and many other titles.



0
 

Author Comment

by:rj
ID: 1341575
Hi,
I rewrited your code according to my programming standards. (see below). I tested the code with and without the FreeSelector command, calling the routine 30000 times. Without FreeSelector the program is crashing leaving Windows in an instable state. With the FreeSelector command there is no problem. So I think your advise on using FreeSelector is a right one.

I have rated your solution as excellent! I also had dropped my question in the Pascal topic area, sou you can get another 200 pionts by locking this question in that area.

If you have more comments, please contact me at RJM@XS4ALL.NL

(* begin of code *)

uses
  WinProcs;

function
  fBiosDate: string;
{this routine returns the BIOS-date of the computer}
var
  Selector: Word;
  CharacterIndex: Integer;
begin
  Result := '';

  asm {this assembler code ensures a proper allocation of the Selector}
    MOV Selector, DS;
  end;

  Selector := AllocSelector(Selector);
  try
    SetSelectorBase(Selector, 16*$FFFF + $0005);
    SetSelectorLimit(Selector, 8 - 1);

    for CharacterIndex := 0 to 7 do
      Result := Result + Chr(Byte(Ptr(Selector, CharacterIndex)^));
  finally
    FreeSelector(Selector);
  end;
end;

(* end of code *)
0

Featured Post

Technology Partners: 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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
This video shows how to quickly and easily deploy an email signature for all users in Office 365 and prevent it from being added to replies and forwards. (the resulting signature is applied on the server level in Exchange Online) The email signat…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Suggested Courses

810 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