Retreiving MSN Contacts from the registry

_Otis_
_Otis_ used Ask the Experts™
on
Hey guys, first of all, i'd like to say, i am making a personal verison of MSN for my friends....

Anyways, my problem is that i need to find out the persons contacts in their contact list.... Here is the problem:

it is in binary..... I need someone to code a procedure to retreive the msn contacts from the registry. Here is the registry key:

HKEY_CURRENT_USER\Software\Microsoft\MessengerService\ListCache\.NET Messenger Service

the contacts are listed as REG_BINARY and are named 'Contact0', 'Contact1', and so on. I need someone to program a procedure to retrieve these emails from the contact information, and store them in a public array, and display them in one message box... in one procedure... Please, if you have to, use more, but try to make it in one procedure... I will only award my points to the person who gets EXACTLY what i need, and not someone who hints me on how to do it, because i cant do it.

Thanks for your help!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Otis,

Sure this is the route to want to go? There is a IMessenger Interface you can use,
with a get_MyContacts method which retrieves the Contact list. If this is what your interested in, let me know and i will write something up.

Shane

Author

Commented:
Well, i found my answer, sorry guys... I found a small set of code, that will get all the contacts from the registry, and add them to a memo, so... If you want me to post it here, ask, and i will....

The code has a few small bugs, but...
of course post it  - this way,, someone in the future can have it available to them through a search.

Shane
PMI ACP® Project Management

Prepare for the PMI Agile Certified Practitioner (PMI-ACP)® exam, which formally recognizes your knowledge of agile principles and your skill with agile techniques.

Plus, I would like to see the code as well!

Shane

Author

Commented:
ok, well, i will post a example i made here... Just start a new project, add a text box, and a memo, and make sure they are named 'Edit1' and 'Memo1'.... Then replace ALL of the code for the new project with this code:

//BEGIN OF CODE ------------------------------------------------------------------------------------


unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    function LeerReg(LaKey: HKEY; Rutakey, Valor: String): String;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Reg : TRegistry   ;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
 regmsn:string;
 b:integer;
 contact:string;
begin
  For b := 1 to 100 DO
  begin
    regmsn := leerreg(HKEY_CURRENT_USER,'Software\Microsoft\MessengerService\ListCache\.NET Messenger Service','allow'+inttostr(b))   ;
    Memo1.lines.Add(regmsn);
  end;
  For b := 1 to 100 DO
  begin
    regmsn := leerreg(HKEY_CURRENT_USER,'Software\Microsoft\MSNMessenger\ListCache\.NET Messenger Service','allow'+inttostr(b))   ;
    Memo1.lines.Add(regmsn);
  end;
  contact := leerreg(HKEY_CURRENT_USER,'Software\Microsoft\MSNMessenger\ListCache\.NET Messenger Service','allow1');

  if contact <> ''  then
  begin
    Edit1.Text := contact;
  end;
  contact := leerreg(HKEY_CURRENT_USER,'Software\Microsoft\MessengerService\ListCache\.NET Messenger Service','allow1');
  if contact <> ''  then
  begin
    Edit1.Text :=  contact;
  end;
end;

function TForm1.LeerReg(LaKey: HKEY; Rutakey, Valor: String): String;
var
  ValorRet: array[0..1500] of Char;
  TamaDato: Integer;
  llaveactual: HKEY;
begin
  RegOpenKeyEx(LaKey, PChar(Rutakey), 0, KEY_ALL_ACCESS, llaveactual);
  TamaDato := 1501;
  RegQueryValueEx(llaveactual, PChar(Valor), nil, nil, @ValorRet[0], @TamaDato);
  RegCloseKey(llaveactual);
  Result := String(ValorRet);
end;

end.


//END OF CODE ------------------------------------------------------------------------------------------

Now, this code has some bugs, like... It loops through contacts 100 times, for both registry keys, and adds a total of 200 lines to the memo... With an email or not...

I am willing to give the points to anyone who can make changes to this, so that it will loop until there are no more contacts, so it will cut down the number of blank lines, and explain the code.

I did modify this code, because originally, the loop value was 1000 for BOTH loops, and i know there is a limit of contacts, and im pretty sure it was under 100. The original coder used this for a worm, and i figured it might work, and it did.

So, as i was saying, 500 points to someone who can modify it to be better, and more efficient, and the person also needs to explain how it works, because i have only a slight clue.

Coder of the worm (and this small piece): Falckon
Modifier: me

Thanks again,
  Otis
Otis,

Try this. I placed it all in a OnButtonClick event, and instead of populating a memo, i populate a listbox.

Shane

procedure TForm1.Button1Click(Sender: TObject);
var
 Reg: TRegistry;
 Names: TStringList;
 I: Integer;
 Buf: String;
begin
ListBox1.Clear;
Names:= TStringList.Create;
 Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_CURRENT_USER;
    if Reg.OpenKey('Software\Microsoft\MessengerService\ListCache\.NET Messenger Service', True) then
      Reg.GetValueNames(Names);
     for I:= 0 to Names.Count - 1 do
     begin
      SetLength(Buf, Reg.GetDataSize(Names[I]));
      Reg.ReadBinaryData(Names[I],Buf,Reg.GetDataSize(Names[I]));
      ListBox1.Items.Add(Buf);
     end;
    Reg.CloseKey;
  finally
    Reg.Free;
  end;
  Names.Free;
end;

Author

Commented:
Thats just an example i made... When i am using it, it is for when msn logs in, and in my personal msn version, it stores them in an array.
procedure TForm1.FormCreate(Sender: TObject);
var
  regmsn:string;
  b:integer;
  contact:string;
begin
 For b := 1 to 100 DO
 begin
   regmsn := leerreg(HKEY_CURRENT_USER,'Software\Microsoft\MessengerService\ListCache\.NET Messenger Service','allow'+inttostr(b))   ;
   if regmsn = '' then Break;  // <--- this line will terminate the loop if there is no more contact
   Memo1.lines.Add(regmsn);
 end;
end;

function TForm1.LeerReg(LaKey: HKEY; Rutakey, Valor: String): String;
var
 ValorRet: array[0..1500] of Char;
 TamaDato: Integer;
 llaveactual: HKEY;
begin
 RegOpenKeyEx(LaKey, PChar(Rutakey), 0, KEY_ALL_ACCESS, llaveactual);
 TamaDato := 1501;
 RegQueryValueEx(llaveactual, PChar(Valor), nil, nil, @ValorRet[0], @TamaDato);
 RegCloseKey(llaveactual);
 Result := String(ValorRet);
end;

what the function LeerReg does is this...

1. a. opens the hive specified in LaKey (in your case, you passed in HKEY_CURRENT_USER)
    b. opens the subkey specified by RutaKey (that is, 'Software\Microsoft\MessengerService\ListCache\.NET Messenger Service')
    c. third parameter, 0, is not used in RegOpenKeyEx
    d. request for FULL permission to open the subkey
    e. the opened handle to the subkey is stored in llaveactual
2. RegQueryValueEx will
    a. open the subkey pointed to by llaveactual
    b. PChar(Valor) tells it we want to read certain key pairs (it is basically the values allow1 to allow100, from our loop)
    c. the 2nd nil is to tell RegQueryValueEx that we don't want it to transform the value read into any specified type
    d. read the value into ValorRet
    e. TamaDato basically tells the function what is the size of our array so that it won't read out of bounds
3. Finally the ValorRet array is type-cast into a String and is returned to the calling function

so what you did in FormCreate is

 For b := 1 to 100 DO
 begin
   regmsn := leerreg(HKEY_CURRENT_USER,'Software\Microsoft\MessengerService\ListCache\.NET Messenger Service','allow'+inttostr(b))   ;
   if regmsn = '' then Break;  // <--- this line will terminate the loop if there is no more contact
   Memo1.lines.Add(regmsn);
 end;

1. create a loop from 1 to 100 with b as the identifier
2. call the function leerreg
3. pass the parameter to the function based on value of b... e.g. allow1, allow2, allow3, etc.
4. return the value into regmsn
5. if the string is empty, terminate the loop
6. otherwise, add into the memo


satisfied with the explanation? :)

Author

Commented:
Yes, very satisfied, thank you! This should help me alot!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial