Ir para conteúdo
Fórum Script Brasil
  • 0

Como Faço Para Expirar Um Programa?


Walter Gazzarrini Neto

Pergunta

Posts Recomendados

  • 0
Como faço para expirar um programa e pedir uma senha quando expirar e caso esteja correta funcionar normalmente?

vlw agradeço desde já!!!...

Amigo que banco de dados você usa e delphi?

Pois no meu utilizo um que quando expira a chave re liberação ele pede quando inicia o programa ou mesmo assim em uso do mesmo, e utilizo um outro programinha para cadastrar a estação no caso o pc que se o usuario instalar e querer copiar os dados em outro pc ele dá erro, falando que o mesmo não pode ser utilizado no pc.

Link para o comentário
Compartilhar em outros sites

  • 0
Amigo que banco de dados você usa e delphi?

Pois no meu utilizo um que quando expira a chave re liberação ele pede quando inicia o programa ou mesmo assim em uso do mesmo, e utilizo um outro programinha para cadastrar a estação no caso o pc que se o usuario instalar e querer copiar os dados em outro pc ele dá erro, falando que o mesmo não pode ser utilizado no pc.

Uso Delphi 7 e My Sql 4.1, se puder me ajudar vlw, que programas são esses que você utiliza?

Abraços vlw!

Editado por Walter Gazzarrini Neto
Link para o comentário
Compartilhar em outros sites

  • 0

Cara o negocio é muito instenso, mas vou passando aos poucos para você e ai você vai ter que colocar de acordo com o seu programa e banco de dados, pois utilizo o firebird 2.0.3.

1ª Etapa

Instala esse componente no delphi:

DiskCaps

Esse componente ele retorna os dado que estão gravados no seu banco de dados e verifica a chave do do seu programa no Windows.

E faça essas tabelas no banco de dados:

CREATE TABLE FATEST (

ESTCOD INTEGER NOT NULL,

ESTDES VARCHAR (50) CHARACTER SET NONE NOT NULL COLLATE NONE,

ESTUSU VARCHAR (30) CHARACTER SET NONE NOT NULL COLLATE NONE,

ESTDTC DATE NOT NULL,

ESTDUC DATE,

ESTHUC TIME,

ESTSTA SMALLINT DEFAULT 0 NOT NULL);

CREATE TABLE FATCF2 (

CFGCP1 VARCHAR (100) CHARACTER SET NONE NOT NULL COLLATE NONE,

CFGCP2 VARCHAR (100) CHARACTER SET NONE NOT NULL COLLATE NONE,

CFGCP3 VARCHAR (100) CHARACTER SET NONE NOT NULL COLLATE NONE,

CFGCP4 VARCHAR (100) CHARACTER SET NONE NOT NULL COLLATE NONE,

CFGCP5 VARCHAR (100) CHARACTER SET NONE NOT NULL COLLATE NONE

);

Me informa se no seu Projeto você tem uma unit de Funcoes para o seu projeto?

E se você tem algum aruivo de Incialização, tipo uma janela Splash?

Link para o comentário
Compartilhar em outros sites

  • 0

Esse é o programinha que vai cadastrar a estação, quer dizer o pc!

Estações

E isso você vai fazer no seu programa:

DECLARAR uma variavel chamada vAut do tipo boleana no formulario principal 
(junto com o vCab, vCpo) e duas outras chamadas vSer e vEst do tipo string


// isso vai no arquivo de funcoes
// incluir na clausula uses da interface do funcoes.pas a unidade REGISTRY

Function VerificaEstacao( pNEs, pSHD : String ) : Boolean;
var nPro,
    nCPr,
    nHDS,
    nPa1,
    nPa2,
    nSer : String;
    i : Integer;
    nRes : Extended;
    vAut : Boolean;
begin
   vAut := True;
   if ( not Pesquisa( 'fatEst', 'estSta', 'WHERE estCod=' + pNEs ) ) then
      begin
         //Mensagem( 'Estação não registrada!' );
         vAut := False;
         Exit;
      end;
   {
   else
      begin
         if ( LeDados( 'estSta' ) >= 1 ) then
            begin
               Mensagem( 'Problemas com a conexão. A operação será abortada!' );
               vAut := False;
               Exit;
            end;
      end;
   }
   if ( not Pesquisa( 'fatCf2', 'cfgCp2', 'WHERE cfgCp1=' + #39 +
                     Codifica( pNEs ) + #39 ) ) then
      begin
         //Mensagem( 'Estação não registrada!' );
         vAut := False;
         Exit;
      end
   else
      begin
         if not VerificaSerial( pSHD, DeCodifica( LeDados( 'cfgCp2' ) ) ) then
            begin
               //Mensagem( 'Estação não registrada!' );
               vAut := False;
               sSta := 3;
            end;
      end;
   VerificaEstacao := vAut;
end;



function VerificaSerial( pSHD, pSEs : String ) : Boolean;
var nPro, nCPr, nHDS, nPa1, nPa2, nSer : String;
    i : Integer;
    nRes : Extended;
    vReg : TRegistry;
    vAut : Boolean;
begin
   vAut         := True;
   vReg         := TRegistry.Create;
   vReg.RootKey := HKEY_LOCAL_MACHINE;
   // le a chave ProductID
   vReg.OpenKey( 'SOFTWARE\Microsoft\Windows\CurrentVersion', False );
   nPro  := vReg.ReadString( 'ProductID' );
   // remove todos os caracteres não numericos da chave do produto
   nCPr  := '';
   for i := 1 to Length( nPro ) do
      begin
         if ENumero( Copy( nPro, i, 1 ) ) then
            nCPr := nCPr + Copy( nPro, i, 1 );
      end;
   // remove todos os caracteres não numericos do serial do HD
   nHDS  := '';
   for i := 1 to Length( pSHD ) do
      begin
         if ENumero( Copy( pSHD, i, 1 ) ) then
            nHDS := nHDS + Copy( pSHD, i, 1 );
      end;
   // calcula o serial do programa
   nRes := ( StrToFloat( nCPr ) * StrToFloat( nCPr ) ) + StrToFloat( nHDS );
   nRes := nRes / ( StrToFloat( nHDS ) * 2 );
   i    := Pos( ',', FloatToStr( nRes ) );
   // verifica se foi encontrada alguma virgula no numero definido
   if ( i > 0 ) then
      begin
         nPa1 := Copy( FloatToStr( nRes ), 01, ( i - 1 ) );
         nPa2 := Copy( FloatToStr( nRes ), ( i + 1 ), ( Length( FloatToStr( nRes ) ) - i  ) );
      end;
   if Length( nPa1 ) > Length( nPa2 ) then
      nSer := nPa1
   else
      nSer := nPa2;
   // compara o serial encontrado, com o que esta gravado no registro da estacao
   if ( pSEs <> nSer ) then
      begin
//         Mensagem( 'Cópia ilegal!' );
         vAut := False;
      end;
   VerificaSerial := vAut;
end;

function VerificaLicenca : Boolean;
var nCon : Integer;
    nDtE,
    nDtL : TDate;
    vAut : Boolean;
begin
   Result := True;
   vAut   := True;
   // le os dados da tabela de configuracao
   if ( not Pesquisa( 'fatCf2', 'cfgCp5', 'WHERE cfgCp1=' +
        #39 + Codifica( vEst ) + #39 ) ) then
      begin
         vAut := False;
         sSta := 3;
         Exit;
      end;

   if ( not Pesquisa( 'fatEst', 'estDUC, estHUC, estSta', 'WHERE estCod=' + vEst ) ) then
      begin
         //Mensagem( 'Estação não registrada!' );
         vAut := False;
         sSta := 3;
         Exit;
      end;

   if ( sSta <> 2 ) then
      begin
         // le os dados da tabela de estacoes
         nDtE := LeDados( 'estDUC' );
         //nHor := LeDados( 'estHUC' );

         // le os dados da configuracao
         if ( not Pesquisa( 'fatCf2', 'cfgCp3', 'WHERE cfgCp1=' + #39 + Codifica( vEst ) + #39 ) ) then
            begin
               //Mensagem( 'Estação não registrada!' );
               vAut := False;
               sSta := 3;
               Exit;
            end
         else
            begin
               nDtL := StrToDate( DeCodifica( LeDados( 'cfgCp3' ) ) );
            end;
         // se faltar 5 dias ou menos para expirar o prazo, avisa ao usuario
         if ( ( Trunc( nDtL - Date() ) <= 5 ) and
              ( Trunc( nDtL - Date() ) > 0 ) and
              ( ( SysUtils.Time()-vHra ) >= StrToTime( '1:00:00' ) ) ) then
            begin
               Mensagem( DeCodifica( LM_EXPIRACAO ) + ' ' +
                         IntToStr( Trunc( nDtL - Date() ) ) );
               vHra := SysUtils.Time();
            end;

         // verifica se a data limite é maior que a data atual
         if ( nDtL < Date() ) then
            begin
               // a licenca expirou
               with TfrmLibSof.Create( Application ) do
                  try
                     ShowModal;
                  finally
                     Free;
                  end;
            end;
         // verifica se a data da ultima execucao é menor ou igual a data atual
         if ( nDtE > Date() ) then
            begin
               // o usuario alterou a data/hora do sistema
               vAut := False;
               sSta := 3;
               Exit;
            end;
      end
   else
      begin
         vAut := False;
         sSta := 3;
      end;
   VerificaLicenca := vAut;
end;

procedure Revisa;
var vLet, vAlf : String; i : Integer;
begin
   vAlf := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';

   vLet := '';

   for i := 1 to 3 do vLet := vLet + vAlf[ Random( Length( vAlf ) ) + 1 ];

   // se retornar determinadas letras, mostra a mensagem e trava o programa.
   if ( ( Pos( 'A', vLet ) > 0 ) or
        ( Pos( 'D', vLet ) > 0 ) or
        ( Pos( 'X', vLet ) > 0 ) or
        ( Pos( 'P', vLet ) > 0 ) or
        ( Pos( 'K', vLet ) > 0 ) or
        ( Pos( 'Y', vLet ) > 0 ) or
        ( Pos( 'I', vLet ) > 0 ) or
        ( Pos( 'H', vLet ) > 0 ) or
        ( Pos( '8', vLet ) > 0 ) or
        ( Pos( '3', vLet ) > 0 ) or
        ( Pos( '0', vLet ) > 0 )
                                 ) then
      begin
         if ( not VerificaEstacao( vEst, vSer ) ) or
              ( not VerificaLicenca ) or ( sSta >= 2 ) then
            begin
               Mensagem( DeCodifica( LM_APLIC_NAO_LIB ) );
               DesconectaEstacao;
               frmPrincipal.dbaTMg.Connected := False;
               Application.Terminate;
            end;
      end;
end;






// NO FORMULARIO DE SPLASH

   // abre a chave do software
   vApp.OpenKey( 'SOFTWARE\AQUI COLOQUE O NOME DE SEU SOFTWARE', False );

   // numero da estacao de trabalho
   vEst := vApp.ReadString( 'WorkStation' );




   // atualiza os dados do componente TDiskCaps
   dskSer.ExamineDrive;

   if ( VerificaEstacao( vEst, dskSer.DiskSerial ) ) then VerificaLicenca;

   //
   vSer := dskSer.DiskSerial;

   // exibe a mensagem de prazo de licenca do software
   Pesquisa( 'fatCf2', 'cfgCp3', '' );
   panSta.Caption := 'Sua licença expira em ' +
                     DeCodifica( LeDados( 'cfgCp3' ) ) + '.';

Link para o comentário
Compartilhar em outros sites

  • 0

beleza vlw......desculpa não entendi como usa esse programinha de gerar serial!, esse outro código só vai permitir que o programa seje instalado em um hd como funciona esse código?e se eu compilar o programa aqui em minha casa e dar o instalador do meu programa pra outra pessoa ele vai conseguir rodr?

to fazendo oque você me pediu quando terminar posto aqui,obrigado abraços!!!

Amigo to tentando adaptar ao meu banco de dados oque essa linha faz?:CHARACTER SET NONE NOT NULL COLLATE NONE,

no meu da que não conhece caracter set 'NONE'!

Abs

Eu retirei a linha CHARACTER SET NONE NOT NULL COLLATE NONE aí foi !!!!! se tiver alguma serventia me fala....rsrsr

Abraços

Esse código do form splash eu ponho que evento? create?

se for já terminei ....obrigado

Link para o comentário
Compartilhar em outros sites

  • 0
beleza vlw......desculpa não entendi como usa esse programinha de gerar serial!, esse outro código só vai permitir que o programa seje instalado em um hd como funciona esse código?e se eu compilar o programa aqui em minha casa e dar o instalador do meu programa pra outra pessoa ele vai conseguir rodr?

to fazendo oque você me pediu quando terminar posto aqui,obrigado abraços!!!

Amigo to tentando adaptar ao meu banco de dados oque essa linha faz?:CHARACTER SET NONE NOT NULL COLLATE NONE,

no meu da que não conhece caracter set 'NONE'!

Abs

Eu retirei a linha CHARACTER SET NONE NOT NULL COLLATE NONE aí foi !!!!! se tiver alguma serventia me fala....rsrsr

Abraços

Esse código do form splash eu ponho que evento? create?

se for já terminei ....obrigado

Cara essa parte do banco de dados não fui eu que desenvolvi, então vamos aqui no meu fiz um teste e por enquanto não deu nada.

beleza vlw......desculpa não entendi como usa esse programinha de gerar serial!, esse outro código só vai permitir que o programa seje instalado em um hd como funciona esse código?e se eu compilar o programa aqui em minha casa e dar o instalador do meu programa pra outra pessoa ele vai conseguir rodr?

Sobre esse assunto, você quando for instalar o seu projeto você primeiro vai ter que rodar esse programinha de estações pois ele vai ter que cadastrar o serial do pc, pois se alguém for querer instalar ele em outro pc não vai dar!

Link para o comentário
Compartilhar em outros sites

  • 0
beleza entendi!!!!!!!!vlw

mas e o o código do splash eu coloquei no create e deu um monte de coisa não declarada!!!

obrigado...

Sim tem algumas coisas que você vai ter colocar de acordo com seu projeto, mas isso você tem que fazer:

// isso vai no arquivo de funcoes

// incluir na clausula uses da interface do funcoes.pas a unidade REGISTRY

E essa na Private:

private
    vReg : TRegistry;
    vApp : TRegistry;
    vLog : String;
    iLog : TBitMap;

Calma que tem muita coisas ainda para fazer, é que estou meio apurado e assim que dá eu vou colocando mais coisas.

Editado por robinhocne
Link para o comentário
Compartilhar em outros sites

  • 0

Esse é um arquivo chaves, tipo o arquivo patch, esse é o de registro do windows, então ele você vai clicar com o botão direito e editar do jeito que o seu programa necessita, primeiro é o caminho do registro aquele mesmo que tem no formulário de splash e o outro é do caminho do banco de dados, mude conforme o seu necessário.

Registros

Agora vou lhe passar arquivos .pas para você implementar em seu programa, agora é om você, pois estou lhe passando algumas coisas de criptografia! que é muito util.

Pas

Esse aqui é o form de cadastro da liberação.

Liberação

Implemente agora do jeito que seu programa necessita

Link para o comentário
Compartilhar em outros sites

  • 0
Ta ok vlw!!!!,beleza to conseguindo so 2 dúvidas!, O patch do programa é o do project ou o instalador? Como faço essas variáveis pesquisa e Enumero ?

obrigado.....

O Patch é uma chave de registro para você registrar o seu programa no Windows e serve para conectar o banco de dados (chaves)

O Pesquisa é porque eu uso uma função para fazer as pesquisas:

function consultaregistros (ptabela, pcampos, pcondicao :string) : boolean;
var instrucaosql :string;
begin
   instrucaosql := 'select ' + pcampos + ' from ' + ptabela;
   if (pcondicao<>'') then
      begin
      instrucaosql := instrucaosql+' where ' + pcondicao;
      end;
   //showmessage (instrucaosql);
   with dtmiza.qryiza do
      begin
         close;
         sql.Clear;
         sql.add (instrucaosql);
         open;
      end;
   result := (not dtmiza.qryiza.IsEmpty);

end;
E o Enumero:
function enumero (numero:string) : boolean; 
var resultado : boolean;
   begin
      resultado := true;
      try
         strtofloat (numero);
      except
         resultado := false;
      end;
      result := resultado;
   end;

Link para o comentário
Compartilhar em outros sites

  • 0
Guest --Walter --

Bom, ainda não consegui concluir , esses exemplos me parecem ser incompatíveis com o mysql!!!!!!!!

Alguém poderia me ajudar? como faço para expirar meu programa?, sendo que uso Mysql 4.1 e delphi 7!!!!

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0
Bom, ainda não consegui concluir , esses exemplos me parecem ser incompatíveis com o mysql!!!!!!!!

Alguém poderia me ajudar? como faço para expirar meu programa?, sendo que uso Mysql 4.1 e delphi 7!!!!

o link que postei anteriormente estava causando falha ao "clická-lo", então vou sugerir novamente que você dê uma olhada no componente TMXProtector veja no site MaxComponents (ao clicar em download, na tela que se segue, clique sobre a versão do seu compilador delphi e aguarde iniciar o download. Tem demos para vários tipos de expirações - talvez algum lhe interesse)

Link para o comentário
Compartilhar em outros sites

  • 0
hum valeu parece ser exatamente o que eu preciso....,mas não entendi direito seu funcionamento!,você tem algum exemplo ou tutorial?
Walter, como disse antes, acompanham "demos". Após a instalação, você deve localizar a pasta onde você instalou o componente. Nesta pasta há sub-pastas e em uma delas vários demos (para cada aplicação). Dê uma olhada.

Link para o comentário
Compartilhar em outros sites

  • 0

Opa

Uns tempos atrás eu perdi vários meses estudando quais eram as melhores formas de fazer um programa

Shareware, ou seja, que expire...

Testei várias formas e métodos, os componentes mais conhecidos e tudo mais, inclusive os da Max.

Mas de todos que passei, não havia nenhum melhor que o OnGuard.

É gratuito e de código aberto, ele é PRO

Nele vem todo tipo de exemplo, expiração por data, dia, uso, rede, etc...

Fora que ele usa criptografia das mais avançadas...

Compensa você dar uma olhada, leia o manual e estude os exemplos pra você entender...

Mas se voce não manjar inglês voce não vai se dar muito bem que é meio complexo tem que estudar ele...

OnGuard

abraçx

Link para o comentário
Compartilhar em outros sites

  • 0

Opa

Vai na Type Library do Delphi e adicione a pasta Source do Onguard

aqui em casa não tenho o Delphi não me lembro de cabeça o nome dos Menus

e tal mas se não souber fazer isso eu te explico melhor do serviço.

Deve ser algo Tools > Environment Options > Type Library

Clique em Add, procure a pasta Source do Onguard e adicione...

abraços

Link para o comentário
Compartilhar em outros sites

  • 0
Opa

Vai na Type Library do Delphi e adicione a pasta Source do Onguard

aqui em casa não tenho o Delphi não me lembro de cabeça o nome dos Menus

e tal mas se não souber fazer isso eu te explico melhor do serviço.

Deve ser algo Tools > Environment Options > Type Library

Clique em Add, procure a pasta Source do Onguard e adicione...

abraços

~~

Ok consegui ....obrigado!

Link para o comentário
Compartilhar em outros sites

  • 0

Olá, estou usando o tmxprotector , primeiramente eu queria bloquear o usuário de alterar data então usei o eveto 'mxProtectorInvalidSystemTime' porém ele da esse erro:

[Error]Unit35.pas(26): Overloaded procedure 'mxProtectorInvalidSystemTime' must be marked with the 'overload' directive

Depois eu queria tipo quando expirasse uma data e o usuário digitasse a senha correta,q alterasse a data e altere a senha junto , como faço isso?

por enquanto está assim:

unit Unit35;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, QuickRpt, QRCtrls, StdCtrls, jpeg, Buttons, ComCtrls,
  mxProtector,Shellapi, OnGuard;

type
  TFormbs = class(TForm)
    Image1: TImage;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    BitBtn1: TBitBtn;
    ProgressBar1: TProgressBar;
    lbl_Remaining: TLabel;
    lbl_Message: TLabel;
    mxProtector1: TmxProtector;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BitBtn1Click(Sender: TObject);
    Procedure mxProtectorInvalidSystemTime( Sender: TObject );
    Procedure mxProtectorExpiration( Sender: TObject );
    Procedure mxProtectorTimeTrial( Sender: TObject; DaysRemained: Integer );
    Procedure mxProtectorInvalidSystemTime( Sender: TObject );
    procedure BitBtn2Click(Sender: TObject);
    
  private
//  Trayicondata: TNotifyIconData;
  
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Formbs: TFormbs;

implementation

uses Unit19, Unit10, Unit1;

{$R *.dfm}

procedure TFormbs.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
action:=cafree;

end;

procedure TFormbs.BitBtn1Click(Sender: TObject);
begin

if Edit1.Text<>mxProtector1.CodeKey then
     begin
      MessageDlg( 'Senha Incorreta!!!', mtError, [ mbOK ], 0 );
         end;



if edit1.Text=mxProtector1.CodeKey then
begin
 formbs.Close;
//  Shell_NotifyIcon(NIM_DELETE,@trayicondata);
try

  formlogin := Tformlogin.Create ( Application );
finally
 Formlogin.Show;
 dm.ZTLogin.Edit;
 dm.ZTLogin.FieldByName('Nivel_login').Value:=null;
 dm.ztcontrole.edit;
 dm.ZTControle.FieldByName('Data_saida').Value:=FormatDateTime('DD"/"MM"/"yyyy',date);
 dm.ZTControle.FieldByName('hora_saida').Value:=FormatDateTime('HH:MM:SS AM/PM',TIME);
 dm.ZTControle.Post;

end;
    end;
   end;
   





// *************************************************************************************
// ** Tfrm_MainWindow.mxProtectorExpiration, 8/22/01 10:50:58 AM
// *************************************************************************************

Procedure TFormbs.mxProtectorExpiration( Sender: TObject );
Begin
     lbl_Remaining.Caption := '0 days remained';
     lbl_Message.Caption := 'This licence has expired';
     Bitbtn1.Enabled := true;
     ProgressBar1.Max := 0;
     ProgressBar1.Position := 0;

End;

// *************************************************************************************
// ** Tfrm_MainWindow.mxProtectorTimeTrial, 8/27/01 3:53:08 PM
// *************************************************************************************

Procedure TFormbs.mxProtectorTimeTrial( Sender: TObject; DaysRemained: Integer );
Begin
     lbl_Message.Caption := Format( 'This software licence will expire on %s', [ DateToStr( mxProtector1.Expiration ) ] );
     lbl_Remaining.Caption := Format( '%d days remaining', [ DaysRemained ] );
   //  btn_Reset.Enabled := FALSE;
     Bitbtn1.Enabled := TRUE;
     ProgressBar1.Max := mxProtector1.GetLicencedDayNumber;
     ProgressBar1.Position := DaysRemained;
End;

// *************************************************************************************
// ** Tfrm_MainWindow.mxProtectorInvalidSystemTime, 9/12/01 9:46:41 AM
// *************************************************************************************

Procedure TFormbs.mxProtectorInvalidSystemTime( Sender: TObject );
Begin
     MessageDlg( 'A data/hora do seu sistema está inválida.' + #13 + #10 + 'Por favor corrija a data e hora para continuar.', mtError, [ mbOK ], 0 );
     //Application.Terminate;


     end;
end;


end.

obrigado...........

Editado por Walter Gazzarrini Neto
Link para o comentário
Compartilhar em outros sites

  • 0

Opa

Como você quer que seu programa trabalhe, entre datas?

exemplo, você libera pro cara de hoje até julho do ano que vem

Quer que trabalha por um serial ou seja, digitou o serial o programa é liberado?

Como você quer trabalhar com esta parte de Expirar?

Baseado no que você disser, se eu fizer um exemplo pra você no OnGuard tem interesse?

abraços

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,2k
×
×
  • Criar Novo...