Solved

Searching a binary file for an hex pattern

Posted on 2006-11-26
3
589 Views
Last Modified: 2010-04-05
Greetings,

One of the applications I'm currently trying to integrate with uses a thing called Btrieve, for which almost no support is left. I decided then to read the (if we may call it so) database BTR files into a memory stream and perform a manual search for what I need (there's an index-like structure inside and I have all the info I need to start with).

My approach is to read this binary file into a TMemoryStream (no problem here) and perform a search into it using StrPos. What happens is that if my search string has a #0, StrPos always returns nil... Any hints how to get this done ?!?! Should I search by chars or bytes ? Is this approach the best one ? Thank you for any help on this ! Using D7.

type
  TFormMain = class(TForm)
...
  private
      { Private declarations }
      Ms1, Ms2: TMemoryStream;
...
end;
...

const
  search_arg: const = #0#0#0#128#0#5;

procedure TFormMain.Ms1LoadFromFileClick(Sender: TObject);
begin
  try
    Ms1.LoadFromFile(my_file[0].name);
    HowToReturnOffsetFromStreamHere(Ms1, search_arg);  <---  ? ? ?
  except
    Showmessage('Couldn''t read the file !' + #13 + SysErrorMessage(GetLastError));
  end;
end;
0
Comment
Question by:FK4
3 Comments
 
LVL 17

Expert Comment

by:mokule
ID: 18015977
Hi,
StrPos is for handling null terminated strings.
So the first occurabce of #0 terminates the string and the rest is ignored.
To allow searching for #0 use Pos() function.
0
 
LVL 4

Accepted Solution

by:
Meldrachaun earned 300 total points
ID: 18017955
There's a SearchBuf function in StrUtils that does what you want:


procedure TForm1.Button1Click(Sender: TObject);
const
  DATA = 'testing' + #0 + 'one' + #0 + 'two' + #0 + 'three' + #0;

var
  stream: TStringStream;
  ms: TMemoryStream;
  p1, p2: pointer;
  x, size, gap: integer;
  locations: string;

begin
  stream := TStringStream.Create(DATA);
  ms := TMemoryStream.Create;
  try
    ms.LoadFromStream(stream);
    p1 := ms.Memory;
    locations := '';
    size := ms.Size;
    repeat
      p2 := Pointer(SearchBuf(PChar(p1), size,0,0,#0, [soDown]));
      if p2 <> nil then
      begin
        gap := integer(p2) - integer(p1) + 1;
        dec(Size, gap);
        p1 := pointer(integer(p2)+1);

        x := integer(p2) - integer(ms.Memory);
        locations := locations + IntToStr(x)+ '  ';
      end;
    until p2 = nil;
  finally
    stream.free;
    ms.free;
  end;
  ShowMessage(locations);
end;
0
 

Author Comment

by:FK4
ID: 18021813
Meldrachaun, your base sample is 98% correct but fit me 100%.

The ms in yor sample does not actually load from 'stream', but from my source file, and the argument SearchString in SearchBuf is actually your DATA constant, not #0... but again, solved my problem.

Thanks,

Fernando
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

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…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

760 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

20 Experts available now in Live!

Get 1:1 Help Now