Ver Mensaje Individual
  #10  
Antiguo 31-05-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Reputación: 24
seoane Va por buen camino
Pues yo sigo aquí, de fisgón, aquí les dejo un programa que busca los archivos "thumb.db" (al parecer en Vista se llaman thumbcache_xxxx.db) creados por el explorer cuando vemos una carpeta con imágenes utilizando las "Vistas en miniatura". Lo "divertido" es que tiene el mal habito de no borrar las miniaturas almacenadas en la cache cuando se borra la imagen original, así que podemos encontrarnos con alguna sorpresa.

Es una aplicación de consola:
Código Delphi [-]
program Fisgon;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Classes;

procedure Recover(Origen: TStream; FormatStr: String; var Index: Integer);
var
  Destino: TMemoryStream;
  Buffer: array[0..$FFFF] of Byte;
  Header: array[1..4] of Byte;
  Size: Integer;
begin
  Destino:= TMemoryStream.Create;
  try
    // Escribimos los 2 primeros bytes del archivo
    Header[1]:= $FF;  Header[2]:= $D8;
    Destino.WriteBuffer(Header,2);
    Origen.Seek(-1,soFromCurrent);
    // En este bucle vamos copiando segmento a segmento
    while TRUE do
    begin
      Origen.ReadBuffer(Header,4);
      Size:= ((Header[3] shl 8) + Header[4]) - 2;
      case Header[2] of
        $01,$D0..$D8: begin
                        // Estos segmentos solo miden dos bytes,
                        // asi que escribimos 2 bytes y
                        Destino.WriteBuffer(Header,2);
                        // retrocedemos otros dos hacia atras.
                        Origen.Seek(-2,soFromCurrent);
                      end;
        $D9: begin
               // Este indica que llegamos al final del archivo jpeg
               Destino.WriteBuffer(Header,2);
               // Guardamos el archivo usando la plantilla
               Destino.SaveToFile(Format(FormatStr,[Index]));
               Writeln('Recuperada: ' + Format(FormatStr,[Index]));
               // Incrementamos el indice
               inc(Index);
               // Salimos del procedure
               Exit;
             end;
        $DA: begin
               // Este segmento no tiene tamaño
               Destino.WriteBuffer(Header,2);
               Origen.Seek(-2,soFromCurrent);
               // Buscamos el final byte a byte
               while TRUE do
               begin
                 Origen.ReadBuffer(Buffer,1);
                 // Posible comienzo de otro segmento
                 if Buffer[0] = $FF then
                 begin
                   Origen.ReadBuffer(Buffer,1);
                   // $FF00 = Secuencia de escape
                   // $FFD0 .. $FFD7 = Se deben de ignorar
                   if (Buffer[0] <> 0) and not (Buffer[0] in [$D0..$D7]) then
                   begin
                     // Si encontramos el comienzo de otro segmento,
                     // retrocedemos dos bytes, y volvemos al bucle principal
                     Origen.Seek(-2,soFromCurrent);
                     break;
                   end else
                   begin
                     // Si no es el comienzo de otro segmento, escribimos
                     // y continuamos
                     Header[1]:= $FF;
                     Header[2]:= Buffer[0];
                     Destino.WriteBuffer(Header,2);
                   end;  
                 end else
                   Destino.WriteBuffer(Buffer,1);
               end;
             end
        else
        begin
          // Cualquier otro segmento lo copiamos directamente
          Origen.ReadBuffer(Buffer,Size);
          Destino.WriteBuffer(Header,4);
          Destino.WriteBuffer(Buffer,Size);
        end;
      end;
    end;
  finally
    Destino.Free;
  end;
end;

procedure Scanfile(Stream: TStream; FormatStr: String; var Index: Integer);
var
  B: Byte;
  Leidos: Integer;
  Posicion: int64;
begin
  // Vamos leyendo byte a byte el archivo
  Leidos:= Stream.Read(B,1);
  while Leidos = 1 do
    if B = $FF then
    begin
      Leidos:= Stream.Read(B,1);
      if Leidos = 1 then
        if B = $D8 then
        begin
          Leidos:= Stream.Read(B,1);
          if Leidos = 1 then
            if B = $FF then
            begin
              // Hasta encontrar la combinacion $FFD8FF
              Writeln('Encontrada una posible imagen.');
              // Guardamos la posicion
              Posicion:= Stream.Position;
              try
                // Intentamos recuperar la imagen
                Recover(Stream,FormatStr,Index);
              except
                // Si se produce un error lo mostramos, pero no salimos del bucle
                On E: Exception do
                   Writeln('Error: ' + E.Message);
              end;
              // Volvemos a la posicion en la que estabamos
              Stream.Position:= Posicion;
            end;
        end;
    end else
      Leidos:= Stream.Read(B,1);
end;

procedure Buscar(Path: string; var Index: Integer);
var
  SR: TSearchRec;
  Stream: TFileStream;
begin
  if Path = '' then exit;
  if copy(Path, Length(Path), 1) <> '\' then Path := Path + '\';
  if FindFirst(Path + '*', faDirectory, SR) = 0 then
  repeat
    if (SR.Name <> '.') and (SR.Name <> '..') then
      Buscar(Path + SR.Name, Index);
  until FindNext(SR) <> 0;
  FindClose(SR);
  if FindFirst(Path + 'thumb*.db',faAnyfile, SR) = 0 then
  repeat
    Stream:= TFileStream.Create(Path + SR.Name,fmOpenRead);
    try
      Writeln('Explorando el archivo: ' + Path + SR.Name);
      Scanfile(Stream,ParamStr(2),Index);
    finally
      Stream.Free;
    end;
  until FindNext(SR) <> 0;
  FindClose(SR);
end;

var
  i: Integer;
begin
  if ParamCount = 2 then
  try
    // Comprobamos que se pueden crear archivos en la ruta indicada
    TFileStream.Create(Format(ParamStr(2),[0]),fmCreate).Free;
    // Borramos el archivo de prueba
    DeleteFile(Format(ParamStr(2),[0]));
    // Buscamos en la ruta indicada
    i:= 0;
    Buscar(ParamStr(1),i);
  except
    // Si se produce un error, lo mostramos
    On E: Exception do
      Writeln('Error: ' + E.Message);
  end;
end.

Por ejemplo:
Código:
Fisgon C:\ %d.jpg
A fisgonear
Responder Con Cita