Solved

Binary values & strings

Posted on 1998-12-25
8
338 Views
Last Modified: 2010-04-04
Hi

I need to retrieve the Outlook default profile key from the Registry and then to access it.

If I get Profile UID from HKEY_CURRENT_USER\Software\Microsoft\Windows Messaging Subsystem\Profiles\Microsoft Outlook , I get a string value.

In the Registry it is a binary value.

I need to get the binary value as a string

For example, in Regedit I see the value as :
C0 B3 74 44 91 9A D2 11 A8 CE 00 40 95 A0 5F 99 09

This binary value means À³tD‘šÒ¨Î , if I have the string, how can I have the binary value as a string? (String:='C0 B3 74 44 91 9A D2 11 A8 CE 00 40 95 A0 5F 99 09')


I hope you'll understand me.

Saar


0
Comment
Question by:saar2
  • 4
  • 3
8 Comments
 
LVL 5

Expert Comment

by:heathprovost
ID: 1352922
I think I can answer this, but you need to clarify more - do you want to convert the value of one of the keys in a profile to a string representation of it?  for example:
key value = C0 B3 74 44 91 9A D2 11 A8 CE 00 40 95 A0 5F 99 09

you want to get a string that represents this like
 'C0 B3 74 44 91 9A D2 11 A8 CE 00 40 95 A0 5F 99 09'?

Is this what you are trying to do?
0
 
LVL 3

Expert Comment

by:williams2
ID: 1352923
This must be it then..

I must warn you, that the buffer length is just a fictive value.

Function ReadBinaryKey: String;
var
  i,Len: Integer;
  Buf: PByteArray;
  Registry: TRegistry;
Begin
  Registry:= TRegistry.Create;
  Registry.RootKey:= HKEY_CURRENT_USER;
  If Registry.OpenKey('Software\Microsoft\Windows Messaging Subsystem\Profiles\Microsoft Outlook',False) then
  Begin
    Buf:= AllocMem($FFFF);
    Len:= Registry.ReadBinaryData('Profile',Buf^,$FFFF);
    Result:= '';
    For i:= 0 to Len-1 do Result:= Result+IntToHex(Buf[i],2)+' ';
    If Len>0 then Delete(Result,Length(Result),1); //Delete last space
    FreeMem(Buf,$FFFF);
  End else
    ShowMessage('Didn''t find key!');
  Registry.free;
End;

procedure TForm1.Button1Click(Sender: TObject);
var
  S: String;
begin
  S:= ReadBinaryKey;
  If S<>'' then ShowMessage(S);
end;


Regards,
Williams
0
 
LVL 4

Author Comment

by:saar2
ID: 1352924
williams2, I forgot to say I use Delphi 1. There is no Tregistry component.

Saar
0
 
LVL 3

Accepted Solution

by:
williams2 earned 50 total points
ID: 1352925
You certainly did, Saar!

Use this instead then: make a button and a ButtonClick event procedure, then paste this to unit1

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const
  HKEY_CLASSES_ROOT     = $80000000;
  HKEY_CURRENT_USER     = $80000001;
  HKEY_LOCAL_MACHINE    = $80000002;
  HKEY_USERS            = $80000003;
  HKEY_PERFORMANCE_DATA = $80000004;
  HKEY_CURRENT_CONFIG   = $80000005;
  HKEY_DYN_DATA         = $80000006;

type
  HKEY = Integer;

  TRegDataType = (rdUnknown, rdString, rdExpandString, rdInteger, rdBinary);

  TRegDataInfo = record
    RegData: TRegDataType;
    DataSize: Integer;
  end;

  TMyReg = class
  private
    CurrentKey: HKEY;
    function GetDataInfo(const ValueName: string; var Value: TRegDataInfo): Boolean;
  public
    CurrentPath: String;
    Root: HKEY;
    Constructor Create;
    Destructor Destroy; override;
    Function OpenKey(const Key: String): Boolean;
    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    function GetData(const Name: string; Buffer: Pointer;
      BufSize: Integer; var RegData: TRegDataType): Integer;
    Procedure CloseKey;
  End;

  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

Constructor TMyReg.Create;
Begin
  Root:= HKEY_CLASSES_ROOT;
End;

Function TMyReg.OpenKey(const Key: String): Boolean;
var
  TempKey: HKey;
begin
  TempKey := 0;
  Result := RegOpenKeyEx(Root, PChar(Key), 0, KEY_ALL_ACCESS, TempKey) = ERROR_SUCCESS;
  if Result then
  begin
    If CurrentKey<>0 then CloseKey;
    CurrentKey:= TempKey;
  end;
end;

function DataTypeToRegData(Value: Integer): TRegDataType;
begin
  if Value = REG_SZ then Result := rdString
  else if Value = REG_EXPAND_SZ then Result := rdExpandString
  else if Value = REG_DWORD then Result := rdInteger
  else if Value = REG_BINARY then Result := rdBinary
  else Result := rdUnknown;
end;

function TMyReg.GetDataInfo(const ValueName: string; var Value: TRegDataInfo): Boolean;
var
  DataType: Integer;
begin
  FillChar(Value, SizeOf(TRegDataInfo), 0);
  Result := RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, nil,
    @Value.DataSize) = ERROR_SUCCESS;
  Value.RegData := DataTypeToRegData(DataType);
end;

function TMyReg.GetData(const Name: string; Buffer: Pointer;
  BufSize: Integer; var RegData: TRegDataType): Integer;
var
  DataType: Integer;
begin
  DataType := REG_NONE;
  if RegQueryValueEx(CurrentKey, PChar(Name), nil, @DataType, PByte(Buffer),
    @BufSize) <> ERROR_SUCCESS then
  Begin
    ShowMessage('Failed to get data');
    Application.Terminate;
  End;
  Result := BufSize;
  RegData := DataTypeToRegData(DataType);
end;

function TMyReg.ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
var
  RegData: TRegDataType;
  Info: TRegDataInfo;
begin
  if GetDataInfo(Name, Info) then
  begin
    Result := Info.DataSize;
    RegData := Info.RegData;
    if (RegData = rdBinary) and (Result <= BufSize) then
      GetData(Name, @Buffer, Result, RegData)
    else
    begin
      ShowMessage('Registry Error: '+Name);
      Application.Terminate;
    End;
  end else
    Result := 0;
end;

Procedure TMyReg.CloseKey;
Begin
  RegCloseKey(CurrentKey);
  CurrentKey:= 0;
End;

Destructor TMyReg.Destroy;
Begin
  If CurrentKey<>0 then RegCloseKey(CurrentKey);
  inherited Destroy;
End;

Function ReadBinaryKey: String;
var
  i,Len: Integer;
  Buf: PByteArray;
  MyReg: TMyReg;
Begin
  MyReg:= TMyReg.Create;
  MyReg.Root:= HKEY_CURRENT_USER;
  If MyReg.OpenKey('Software\Microsoft\Windows Messaging Subsystem\Profiles\Microsoft Outlook') then
  Begin
    Buf:= AllocMem($FFFF);
    Len:= MyReg.ReadBinaryData('Profile',Buf^,$FFFF);
    Result:= '';
    For i:= 0 to Len-1 do Result:= Result+IntToHex(Buf[i],2)+' ';
    If Len>0 then Delete(Result,Length(Result),1); //Delete last space
    FreeMem(Buf,$FFFF);
  End else
    ShowMessage('Didn''t find key!');
  MyReg.free;
End;

procedure TForm1.Button1Click(Sender: TObject);
var
  S: String;
begin
  S:= ReadBinaryKey;
  If S<>'' then ShowMessage(S);
end;

end.


If the API functions are unknown to you, I will provide the imports to you.

Regards,
Williams
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 4

Author Comment

by:saar2
ID: 1352926
When I compile this Unit I get an error saying :
"Error in module Unit1: Call to RegisterClasses is missing or incorrect"

What does it mean?

Saar
0
 
LVL 3

Expert Comment

by:williams2
ID: 1352927
I'm not sure, but to replace the TMyReg class type:

  TMyReg = class(TPersistent)
  private
    CurrentKey: HKEY;
    function GetDataInfo(const ValueName: string; var Value: TRegDataInfo): Boolean;
  public
    CurrentPath: String;
    Root: HKEY;
    Constructor Create;
    Destructor Destroy; override;
    Function OpenKey(const Key: String): Boolean;
    function ReadBinaryData(const Name: string; var Buffer; BufSize: Integer): Integer;
    function GetData(const Name: string; Buffer: Pointer;
      BufSize: Integer; var RegData: TRegDataType): Integer;
    Procedure CloseKey;
  End;

and replace this too:

Constructor TMyReg.Create;
Begin
  inherited create;
  Root:= HKEY_CLASSES_ROOT;
End;

Another thing:

Try debug the code, and tell me EXACTLY at witch codeline the error is being raised!

BTW: Why don't you upgrade your Delphi to a newer version? There's too many things that is not registrated, even Delphi 2 can provide 5 times more tah version 1.

Regards,
Williams
0
 
LVL 4

Author Comment

by:saar2
ID: 1352928
My school decided to buy Delphi 4.0 .
I'll get it next week and try again.

Saar
0
 
LVL 3

Expert Comment

by:williams2
ID: 1352929
Good for you :-)
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

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 Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

746 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

11 Experts available now in Live!

Get 1:1 Help Now