Você está na página 1de 11

Manipulando o registro do Windows - Delphi

Pgina 1

Manipulando o registro do Windows - Delphi


Verso Imprimvel

dark_side
Manipulando o registro do Windows - Delphi Hi,

10 Dec 2006, 19:24

No artigo de hoje, veremos como manipular o registro do windows utilizando o Delphi. Geralmente, utilizamos as funes: RegOpenKey, RegCreateKey, RegSetValue, RegSetValue, RegDeleteKey, RegDeleteValue, RegCloseKey e suas variantes e extenses para realizar tarefas bsicas no registro, tais como, criar ou deletar uma chave, adicionar ou modificar um valor, dentre outras. Estas funes fazem parte da API do Windows. No Delphi, entretanto, temos uma maneira muito mais fcil e rpida de manipular o registro - utilizando o componente TRegistry. Mas afinal, o que esse registro do Windows? Basicamente, poderamos dizer que o registro do Windows um local onde temos toda a configurao do sistema operacional. Seria como arquivos .INI, onde temos determinadas sees, chaves e valores. Porm, no registro do Windows, acessamos estes valores como se estivssimos trabalhando com pastas - afinal, as chaves so mostradas como pastas. Voc pode ter uma idia maior executando o editor de registro: 1) V at o menu iniciar executar; 2) Digite "regedit.exe" e d OK. Na parte esquerda da janela h as chaves principais: Citao:

HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS HKEY_CURRENT_CONFIG


Se voc explorar qualquer uma destas chaves, ver que existem outras subpastas e ,notar ainda que, direita, so mostrados o nome, tipo e valor para cada subchave. Uma observao importante a ser feita que devemos tomar muito cuidado ao manipular dados do registro, uma vez em que, alterando um ou mais valores vitais do sistema, voc pode comprometer o seu funcionamento. Aps uma breve introduo, partiremos para a prtica =) Antes de podermos manipular o registro, necessrio incluir a unit "Registry" na clusula Uses: Citao:

// Note que as units inicias foram mantidas =) uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,Registry;
Agora sim podemos continuar ;) Iremos comear criando uma chave no registro. Existem duas maneiras. 1) Utilizando o mtodo Create Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.CreateKey('Minha Chave'); reg.Free; end;

Nota-se que, previamente, inserimos um boto no formulrio: Button1. Vamos analisar cada trecho:

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


Cdigo:
var reg: TRegistry;

Pgina 2

Declaramos uma varivel do tipo TRegistry; serve de referncia ao registro.

Cdigo:
reg := TRegistry.Create;

Ns criamos uma nova instncia para podermos realizar operaes com o registro. Cdigo:
reg.RootKey := HKEY_CURRENT_USER;

Definimos a chave primria (ou raiz) na qual iremos trabalhar. Cdigo:


reg.CreateKey('Minha Chave');

Acima, temos a linha responsvel por efetivamente criar a chave no registro: Minha Chave. Se voc abrir novamente o editor de registro, ver que, na chave principal HKEY_CURRENT_USER, existir uma subchave chamada 'Minha Chave' - bvio no ;)? Aps criar a subchave, liberamos a instncia criada: Cdigo:
reg.Free;

2) Utilizando o mtodo OpenKey: Cdigo:


procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',True); reg.CloseKey(); reg.Free; end;

Veja o mtodo utilizado: Cdigo:


reg.OpenKey('Minha Chave',True);

Acima, o programa tenta abrir a chave "Minha Chave" dentro de "HKEY_CURRENT_USER".H um pequeno detalhe: se a chave no existir ele criada. Vamos entender isso melhor analisando a sintaxe da funo: Citao:

reg.OpenKey(NOME_CHAVE,CRIAR); NOME_CHAVE: nome da chave que se deseja abrir; CRIAR: um valor BOOL, isto , FALSE ou TRUE. Se FALSE, caso a chave no exista, ela no ser criada, se TRUE, a chave ser criada caso no exista. Observando a sintaxe vemos que, como o segundo parmetro foi passado como 'True', a chave seria criada =)
Uma observao a ser feita que, para podermos trabalhar com valores dentro de uma chave, deve-se abri-la previamente atravs de OpenKey. Portanto, mais simples utilizar este mtodo mesmo quando formos criar uma chave, uma vez em que esta criada e aberta de uma s vez =) Aps realizar as devidas tarefas com uma chave do registro, devemos fech-la: Cdigo:

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


reg.CloseKey();

Pgina 3

O mtodo fecha a chave atual aberta, no caso, Minha Chave. Ainda trabalhando com a chave 'Minha Chave', veremos como criar um simples valor: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',True); // Abrimos (e criamos se necessrio) a chave // Escrevemos o valor 'Valor1' dentro da chave tendo 'LOL' como contedo; reg.WriteString('Valor1','LOL'); reg.CloseKey(); reg.Free; end;

A sintaxe bsica seria: Citao:

reg.WriteString(NOME_VALOR,CONTEUDO); NOME_VALOR: nome do valor a ser inserido; CONTEUDO: dados do valor.


Se voc reparar bem, o mtodo utilizado foi WriteString, ou seja, iremos escrever um valor do tipo string na chave =) Alm de strings, podemos escrever inteiros, floats, valores booleanos, dentre outros. Exemplo: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',True); // Abrimos (e criamos se necessrio) a chave reg.WriteString('Valor String','LOL'); reg.WriteInteger('Valor Inteiro',100); reg.WriteFloat('Valor Float',10.5); reg.WriteBool('Valor Bool',FALSE); reg.CloseKey(); reg.Free; end;

Bem simples no? Porm, as notaes so diferentes no editor do registro. O que eu quero dizer que se escrevemos um valor Inteiro na chave, este no ir aparecer como o tipo Integer, necessariamente. Voc se lembra que, no incio do artigo, me referir ao nome, tipo e dados de um valor? Pois bem, analise: Cdigo:
reg.WriteString('Valor String','LOL');

Citao:

Valor String - nome do valor; LOL - contedo do valor (dados) ???? - tipo
Pois bem, no registro, temos a seguinte associao: Citao:

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi

Pgina 4

String = REG_SZ Integer = REG_DWORD Float = REG_BINARY Bool = REG_DWORD


Existe ainda outro tipo: REG_EXPAND_SZ, que criado quando escrevemos um valor utilizando o mtodo reg.WriteExpandString() seria uma expanso para o tipo REG_SZ. Podemos ler valores escritos em chaves do registro atravs do mtodo reg.Read...(), onde ... seria o tipo de dado a ser lido. Veja o exemplo: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; str:string; inteiro:integer; float:single; bool:boolean; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',True); str := reg.ReadString('Valor String'); inteiro := reg.ReadInteger('Valor Inteiro'); float := reg.ReadFloat('Valor Float'); bool := reg.ReadBool('Valor Bool'); ShowMessage(str); ShowMessage(IntToStr(inteiro)); ShowMessage(FloatToStr(float)); ShowMessage(BoolToStr(bool)); reg.CloseKey(); reg.Free; end;

Vejamos: Cdigo:
str:string; // string inteiro:integer; // integer float:single; // float bool:boolean; // boolean

Declaramos as variveis para cada tipo de dado. Para ler cada valor fazemos: Cdigo:
str := reg.ReadString('Valor String'); // L inteiro := reg.ReadInteger('Valor Inteiro'); float := reg.ReadFloat('Valor Float'); // L bool := reg.ReadBool('Valor Bool'); // L um um valor // L um um valor valor do do tipo string (REG_SZ) valor do tipo inteiro (REG_DWORD) do tipo float (REG_BINARY) tipo boolean (REG_DWORD)

Em seguida, mostramos os valores: Cdigo:


ShowMessage(str); // Mostra a string ShowMessage(IntToStr(inteiro)); // Converte o valor inteiro para string e mostra-o ShowMessage(FloatToStr(float)); // Converte o float para string e mostra-o ShowMessage(BoolToStr(bool)); // Converte o boolean inteiro para string e mostra-o

At agora, trabalhamos apenas com valores dentro da chave "Minha Chave" contida em HKEY_CURRENT_USER. Veremos a seguir como proceder para criar uma subchave dentro de "Minha Chave": Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave\LOL',True);

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


reg.CloseKey(); reg.Free; end;

Pgina 5

O trecho acima cria a subchave 'LOL' dentro da chave 'Minha Chave'. Veja agora o exemplo: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave\LOL',True); reg.WriteString('Teste','XXX'); reg.CloseKey(); reg.Free; end;

Se voc observar bem, ver que o valor 'Teste' seria escrito dentro da subchave 'LOL' e no dentro de 'Minha Chave'. Portanto, para criar subchaves, fazemos: Cdigo:
reg.OpenKey('CHAVE\SUBCHAVE1\SUBCHAVE2,...',True);

Note que o parmetro 'True' deve ser obrigatrio neste caso, j que iremos criar as subchaves. Agora que j brincamos com o registro, iremos desfazer as alteraes. Para isso, utilizamos os mtodos reg.DeleteKey() e reg.DeleteValue(), respectivamente, para deletar chaves e valores. Veja: Exemplo 1: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',True); // Abrimos a chave 'Minha Chave' // Deletamos todos os valores que criamos ao decorrer do artigo reg.DeleteValue('Valor1'); reg.DeleteValue('Valor String'); reg.DeleteValue('Valor Inteiro'); reg.DeleteValue('Valor Float'); reg.DeleteValue('Valor Bool'); reg.CloseKey(); reg.Free; end;

A sintaxe muito simples: Cdigo:


reg.DeleteValue(NOME_DO_VALOR);

Aps a execuo do programa acima, ir constar no registro a chave 'Minha Chave' vazia, com a subchave 'LOL' contendo o valor 'Teste'. Iremos deletar ambas as chaves. Veja: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; Reg.DeleteKey('Minha Chave'); reg.Free; end;

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi

Pgina 6

Com isso, deletamos a subchave 'LOL' e a chave 'Minha Chave'. Note que no foi preciso abrir nenhuma chave, por qu? Simplesmente pois a chave 'Minha Chave' estava dentro de HKEY_CURRENT_ USER, e quando utilizamos o mtodo reg.DeleteKey, deletamos a subchave especificada dentro da chave atual. Veja: Citao:

HKEY_CURRENT_USER; // Chave principal [...] [...] [Minha Chave] // subchave [...] [...]
Quando fazemos reg.DeleteKey('Minha Chave'); deletamos a subchave especificada dentro da chave atual, que no caso seria 'HKEY_CURRENT_USER'. Quando deletemos uma chave, todos seus valores, subchaves, valores destas subchaves (lolz) so deletados tambm. o mesmo que ocorre com uma pasta normal: Se voc criar a chave "Teste", e inserir as subchaves "SUB1", "SUB2" e "SUB3", por lgica, caso a chave "Teste" seja deletada, todas estas ltimas sero tambm =) Com base nisso, veremos uma situao onde deletamos somente a subchave 'LOL' dentro de 'Minha Chave': Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',True); reg.DeleteKey('LOL'); reg.CloseKey(); reg.Free; end;

importante observar que devemos abrir a chave 'Minha Chave' previamente pois a subchave 'LOL' est dentro dela. A chave 'Minha Chave' continuaria existindo aps a execuo do programa acima =) Temos dois mtodos muito interessantes: reg.GetKeyNames e reg.GetValueNames. O primeiro nos permite obter o nome de todas as subchaves dentro de uma chave; o ltimo nos permite obter o nome de todos os valores dentro da chave atual. Exemplo 1: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; chaves: TStringList; i:integer; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('SoftWare',false); // Abre a chave chaves := TStringList.Create; reg.GetKeyNames(chaves); for i :=0 to chaves.Count -1 do ShowMessage(chaves.strings[i]); reg.CloseKey(); chaves.free; // Libera instncia reg.free; end;

O cdigo acima mostraria todas as subchaves contidas em 'HKEY_CURRENT_USER\Software'. Vamos destacar alguns pontos importantes: Cdigo:
chaves: TStringList; i:integer;

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


Chaves - varivel do tipo TStringList; servir para armazenar os nomes de cada chave; i - varavel que ir nos auxiliar no loop - mostrar os nomes. Cdigo:
chaves := TStringList.Create;

Pgina 7

Criamos uma nova instncia para a varivel. Cdigo:


reg.GetKeyNames(chaves);

Obtemos o nome de cada chave e fazemos com que estes sejam armazenados em "chaves". Por fim, fazemos um loop que nos motra cada valor: Cdigo:
for i :=0 to chaves.Count -1 do ShowMessage(chaves.strings[i]);

Cada chave est armazenada da seguinte forma: Cdigo:


chaves.strings[0] = nome da primeira chave; chaves.strings[1] = nome da segunda chave; chaves.strings[2] = nome da terceira chave; [...]

E se por acaso, ao invs de mostrar as subchaves de 'SoftWare', quisssemos mostrar as subchaves dentro de 'HKEY_CURRENT_USER'? Bem simples, basta utilizar o mtodo reg.OpenKey passando o primeiro parmetro vazio: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; chaves: TStringList; i:integer; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('',false); // Abre a prpria chave principal chaves := TStringList.Create; reg.GetKeyNames(chaves); for i :=0 to chaves.Count -1 do ShowMessage(chaves.strings[i]); reg.CloseKey(); reg.free; end;

Exemplo 2: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; valores: TStringList; i:integer; begin reg := TRegistry.Create; reg.RootKey := HKEY_LOCAL_MACHINE; // Note que a chave agora no mais HKEY_CURRENT_USER // Abrimos a subchave que armazena informaes sobre o windows reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion',false); valores := TStringList.Create; reg.GetValueNames(valores); for i :=0 to valores.Count -1 do ShowMessage(valores.strings[i]); reg.CloseKey(); reg.free;

Temos basicamente a mesma situao, porm, desta vez, obtemos o nome dos valores da subchave. importante notar que obtemos o nome de cada valor e no os dados de cada um. Exemplo: Citao:

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi

Pgina 8

CommonFilesDir = nome do valor C:\Arquivos de programas\Arquivos comuns = dados


Mas se voc observar bem, podemos obter os dados de um valor atravs do seu nome utilizando o mtodo reg.ReadString() - quando o valor uma string. A partir dai, podemos combinar o mtodo no loop, veja: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; valores: TStringList; i:integer; nome_valor: string; // Nome do valor dados_valor:string; // Dados do valor begin reg := TRegistry.Create; reg.RootKey := HKEY_LOCAL_MACHINE; reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion',false); valores := TStringList.Create; reg.GetValueNames(valores); for i :=0 to valores.Count -1 do begin nome_valor := valores.Strings[i]; dados_valor := reg.ReadString(nome_valor); ShowMessage(nome_valor + ' = ' + dados_valor); end; reg.CloseKey(); reg.free; end;

A parte que devemos destacar : Cdigo:


nome_valor := valores.Strings[i]; // Obtm o nome do valor dados_valor := reg.ReadString(nome_valor); // Obtm os dados deste mesmo valor ShowMessage(nome_valor + ' = ' + dados_valor); // Mostra: [VALOR] = [DADOS]

Note que, como o valor retirado da chave que foi aberta previamente, podemos utilizar o mtodo reg.ReadString sem problemas ;) Para finalizar o artigo, iremos tratar um pouco de validao. 1) Verificando se uma chave existe

Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; if reg.KeyExists('Minha Chave') then // Verifica se a chave 'Minha Chave' existe ShowMessage('A chave existe!') else ShowMessage('A chave no existe!'); reg.free; end;

O mtodo reg.KeyExists() retorna FALSE se uma chave ou subchave no existir, ou TRUE caso exista. Outro exemplo: Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; if reg.KeyExists('Minha Chave\LOL') then ShowMessage('A chave existe!') else ShowMessage('A chave no existe!');

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


reg.free; end;

Pgina 9

Desta vez, verificamos se a subchave 'LOL' existe dentro de 'Minha Chave'. 2) Verificando se um valor existe Cdigo:
procedure TForm1.Button1Click(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Minha Chave',FALSE); if reg.ValueExists('Valor1') then ShowMessage('O valor existe!') else ShowMessage('O valor no existe!'); reg.CloseKey(); reg.free; end;

O mtodo reg.ValueExists() retorna TRUE se um valor existir, ou FALSE do contrrio. Bem, sei que ficou cansativo mas isso... Bye ;)

victin.rlz
Caramba ficou muito bem explicado. Nota 10 pra voce Dark Side.

11 Dec 2006, 13:35

O legal do delphi que ele facinante mesmo, acho que o forum j merece uma area destinada para a linguagem Delphi. Show de bola, tpico perfeito!

Tche Guevara
VLW tch, to migrando do vb pro delphi e modificar registro no vb era bem pior... Aqui como vc apaga o username no Mu Online, util pra keyloggers pegarem o user tb: Cdigo:
procedure TForm1.TimerRegistrouserTimer(Sender: TObject); var reg: TRegistry; begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Software\Webzen\Mu\Config',True); // Abrimos (e criamos se necessrio) a chave reg.WriteString('ID','');

12 Dec 2006, 18:30

reg.CloseKey(); reg.Free; end; end.

Agora vo tenta pega o user e j mandar no e-mail do log...

CROSSBR

15 Dec 2006, 08:54

interessante, sempre que se manipula com o registro, mais especialmente ao ler dados, e abrir chaves, usa o recurso try.

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


try reg.openkey(...) except messagebox(impossivel abrir a chave) end;

Pgina 10

DarthBalls
Dark sempre postando coisa nova nesse forum xD Pena q eu nao sei Delphi... Aew dark... sera q vc pudia posta sobre registros do windows em C/C++ fui tenta aprende soh q soh dah erro lah xP

15 Dec 2006, 12:33

jonnew
Re: Manipulando o registro do Windows - Delphi tava procurando isso mano ta de parabens

25 Jul 2009, 23:23

andhx11
Re: Manipulando o registro do Windows - Delphi dark_side parabns, muito bom, veio na hora certa! Abrasss;

26 Jul 2009, 12:19

netsoul
Re: Manipulando o registro do Windows - Delphi Bom tpico amigo, eu gostei. Eu queria aprender Delphi mas to sem tempo. :)

26 Jul 2009, 17:37

North Dakota
Re: Manipulando o registro do Windows - Delphi aw cara parabens Agora eu vou poder colocar meu programas para iniciar com o windows. Mas vc poderia me falar um jeito d auto copiar me arquivo a hora q ele for executado?

26 Aug 2009, 17:20

Pq eu estava querendo mandar meu trojan pra uns conhecidos aqui, mas a hora q eles verem q o program q eu criei "no funciona", pq nao vai aparecer nada eles vo excluir neh. Se tiver jeito me explica isso. Vlw

North Dakota
Re: Manipulando o registro do Windows - Delphi aqui outra duvida: pra eu colocar o meu programa pra iniciar com o windows tem q estar no"....USER" OU NO "...MACHINE" ?

26 Aug 2009, 17:29

OutlanderBr
Re: Manipulando o registro do Windows - Delphi muito bom.. cara esse tutorial! tentei usar as dicas citada aqui pra mudar valores de chaves tipo --> HKEY_CURRENT_USER\Control Panel\Desktop ai ir em "MenuShowDelay"="400" e mudar de 400 para ''1''

26 Sep 2009, 18:15

OutlanderBr
http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

26 Sep 2009, 19:13

18/07/2011 08:27:08

Manipulando o registro do Windows - Delphi


Re: Manipulando o registro do Windows - Delphi Deu certo muito bom mesmo vou fazer um programinha pra modificar algumas entradas no regedit begin reg := TRegistry.Create; reg.RootKey := HKEY_CURRENT_USER; reg.OpenKey('Control Panel\Desktop',True); reg.WriteString('MenuShowDelay','1'); reg.CloseKey(); reg.Free; showmessage('Chave Modificada com sucesso'); end; end.

Pgina 11

Todos horrios so GMT -3. Hora atual: 08:26. Powered by vBulletin Version 4.1.3 Copyright 2011 vBulletin Solutions, Inc. All rights reserved.

http://www.forum-invaders.com.br/vb/printthread.php?t=14762&pp=40

18/07/2011 08:27:08

Você também pode gostar