Developpez.com - Delphi
X

Choisissez d'abord la catégorieensuite la rubrique :

Nono40.developpez.com
Le petit coin du web de Nono40
SOURCES TESTS DELPHI WIN32 AUTOMATISMES DELPHI .NET QUICK-REPORT
Retour à l'accueil
66 - LECTURE DES FICHIERS LOG DE WINDOWS

PRÉSENTATION : Les fichiers log de Windows visibles habituellement dans la gestion de l'ordinateur.
ZIP : Téléchargez le zip APERÇUS :

NOTES : Le programme présenté ici permet de lire les fichiers standard "Application", "Security" et "System". Pour les fichiers utilisateurs, il suffit de donner le nom l'ors de l'ouverture de fichier évènements.

Ces fichiers et fonctions ne sont utilisables que sous Windows NT/2000 ou XP

CODE :
Unit Unit1;
//
// Sujet : Lecture des fichiers LOG de Windows
//
// Par Nono40 : http://nono40.developpez.com  http://nono40.fr.st
//              mailto:nono40@fr.st
//
// Le 10/11/2003
//
Interface

Uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ExtCtrls;

Type
  TForm1 = Class(TForm)
    Panel1: TPanel;
    btnAppli: TButton;
    Liste: TListView;
    btnSecu: TButton;
    btnSys: TButton;
    Procedure ListeClick(Sender: TObject);
    Procedure btnAppliClick(Sender: TObject);
    Procedure btnSecuClick(Sender: TObject);
    Procedure btnSysClick(Sender: TObject);
  Private
    { Déclarations privées }
    Procedure AfficherLog(NomLog:String);
  Public
    { Déclarations publiques }
  End;

Var
  Form1: TForm1;

Implementation

{$R *.dfm}

// Définition du type d'enregistrement utilisé
// pour la lecture des évènements.
// Attention, il n'y a ici que la partie fixe.
// le reste de la structure étant variable d'un
// évènement à l'autre, il n'est pas défini ici.
Type
  PEventLogRecord = ^TEventLogRecord;
  TEventLogRecord = Packed Record
    Length              : DWord; // Longueur totale
                                 // y compris la partie variable
    Reserved            : DWord;
    RecordNumber        : DWord; // Numéro enregistrement
    TimeGenerated       : DWord; // Heure de l'évènement
    TimeWritten         : DWord; // Heure de son enregistrement
    EventID             : DWord; // ID ( Dépend de la source )
    EventType           : Word;  // Type d'évènement
    NumStrings          : Word;  // Nombre de chaines de détail
    EventCategory       : Word;  // Catégorie ( Dépend de la source )
    ReservedFlags       : Word;
    ClosingRecordNumber : DWord;
    StringOffset        : DWord; // Offset de la première chaine de détail
    UserSidLength       : DWord; // Longueur du SID
    UserSidOffset       : DWord; // Offset du début du SID
    DataLength          : DWord; // Longueur des données
    DataOffset          : DWord; // Offset du début des données
  End;

Const
// Définition des constantes d'accès aux fichiers LOG
  EVENTLOG_SEQUENTIAL_READ = $0001;
  EVENTLOG_SEEK_READ       = $0002;
  EVENTLOG_FORWARDS_READ   = $0004;
  EVENTLOG_BACKWARDS_READ  = $0008;

// Taille par défaut du buffer de lecture
  buffer_size=100000;

Var
// Vriables contenant le fichier Log en cours de lecture
  LogEnCours:String='';

Procedure TForm1.AfficherLog(NomLog: String);
Var
  hLog           : THandle;
  pEvent         : PEventLogRecord ;
  bBuffer        : Array[0..BUFFER_SIZE-1]Of Char;
  dwRead         : DWord;
  dwNeeded       : DWord;

  Source         : String;
  Ordinateur     : String;
  Utilisateur    : Array[0..255]Of Char;
  lUtilisateur   : DWord;
  Domaine        : Array[0..255]Of Char;
  lDomaine       : DWord;
  SidUse         : Cardinal;
  pStr           : PChar;
  DateBase       : TDateTime;
  DateHeure      : TDateTime;
Begin
  // Mémorisation du fichier LOG en cours de lecture
  LogEnCours := NomLog;

  // Les dates/heures inclues dans les fichiers log
  // sont données en secondes à partir du 01/01/1970 à 00:00
  DateBase:=EncodeDate(1970,1,1);

  // Ouverture du fichier LOG
  hLog := OpenEventLog( Nil,          // Ordinateur local
                  PChar(LogEnCours)); // Fichier voulu
  If hLog = 0 Then
  Begin
    ShowMessage('Impossible d''ouvrir le fichier LOG');
    Exit;
  End;

  // On fait pointer pEvent sur le début du buffer
  pEvent := PEventLogRecord(@bBuffer);

  // Effacement de la liste
  Liste.Clear;
  Liste.Items.BeginUpdate;
  Try
    // L'ouverture du fichier Log place la lecture en début de
    // fichier. Il est donc possible de le lire de façon séquetielle.
    While ReadEventLog(hLog,               // Handle du fichier
                EVENTLOG_FORWARDS_READ Or  // Lecture en avant
                EVENTLOG_SEQUENTIAL_READ,  // Lecture séquentielle
                0,                         // Position ignorée en séquentielle
                pEvent,                    // Pointeur vers le buffer
                BUFFER_SIZE,               // Taille du buffer
                dwRead,                    // Nombre d'octets lus
                dwNeeded) Do               // Nombre d'octets demandés
    Begin
      // Il est possible de lire plusieurs enregistrement en une fois
      // il faut donc balayer tout le buffer
      While (dwRead > 0Do
      Begin
        // Affichage des informations
        With Liste.Items.Add Do
        Begin
          // La propriété Data va contenir le numéro d'enregistrement
          // pour pouvoir le lire directement lors du double-click
          Data:=Pointer(pEvent.RecordNumber);

          // Type d'évènement
          Case pEvent^.EventType Of
            EVENTLOG_ERROR_TYPE       : Caption:='Erreur';
            EVENTLOG_WARNING_TYPE     : Caption:='Avertissement';
            EVENTLOG_INFORMATION_TYPE : Caption:='Information';
            EVENTLOG_AUDIT_SUCCESS    : Caption:='Audit réussi';
            EVENTLOG_AUDIT_FAILURE    : Caption:='Erreur audit';
          End;

          // Date et Heure de l'évènement
          DateHeure:=DateBase+pEvent.TimeGenerated/24/3600;
          SubItems.Add(FormatDateTime('DD/MM/YYYY',DateHeure));
          SubItems.Add(FormatDateTime('HH:NN:SS'  ,DateHeure));

          // Catégorie
          If pEvent.EventCategory=0
            Then SubItems.Add('Aucune')
            Else SubItems.Add(IntToStr(pEvent.EventCategory));
          SubItems.Add(IntToStr(pEvent.EventID And $FFFF));

          // Utilisateur lié à lévènement
          If pEvent.UserSidLength=0 Then
          Begin
            SubItems.Add('N/A')
          End Else
          Begin
            // Il faut lire les informations du SID contenu
            // dans l'enregistrement. Ce SID est à UserSidOffset octets
            // du début de l'enregistrement.
            pStr   := PChar(pEvent);
            Inc(pStr,pEvent.UserSidOffset);
            lUtilisateur := SizeOf(Utilisateur);
            lDomaine     := SizeOf(Domaine);
            LookUpAccountSID(Nil,pStr,Utilisateur,lUtilisateur,Domaine,lDomaine,SidUse);
            SubItems.Add(Utilisateur)
          End;

          // Lecture de la source et du nom de l'ordinateur
          // Ces infos sont situées à la suite de la partie
          // fixe de l'enregistrement.
          pStr   := PChar(pEvent);
          Inc(pStr,sizeof(TEventLogRecord));
          Source := pStr;
          Inc(pStr,Length(Source)+1);
          Ordinateur := pStr;
          SubItems.Add(Ordinateur);
          SubItems.Add(Source);

          // Affichage si des chaines de détails sont présentes.
          If pEvent.NumStrings<>0
            Then SubItems.Add('Oui')
            Else SubItems.Add('Non');
        End;

        // Réduction de la longueur lue
        DwRead:=DWRead - pEvent.Length;

        // Passage à l"enregistrement suivant.
        Inc(PByte(pEvent),pEvent.Length);
      End;

      // Remise du pointeur en début de buffer pour
      // la prochaine lecture
      pEvent := PEventLogRecord(@bBuffer);
    End;
  Finally
    Liste.Items.EndUpdate;
  End;

  // Fermeture du handle
  CloseEventLog(hLog);
End;

Procedure TForm1.ListeClick(Sender: TObject);
Var
  hLog      : THandle;
  pEvent    : PEventLogRecord ;
  bBuffer   : Array[0..BUFFER_SIZE-1]Of Char;
  dwRead    : DWord;
  dwNeeded  : DWord;
  pStr      : PChar;
  UneChaine : String;
  LesChaine : String;
  i         : Integer;
Begin
  // Si pas de fichier en cours on sort
  If LogEnCours='' Then Exit;

  // Si pas de ligne sélectionnée on sort
  If Liste.Items[Liste.ItemIndex]=Nil Then Exit;

  // Ouverture du fichier LOG
  hLog := OpenEventLog( Nil,          // Ordinateur local
                  PChar(LogEnCours)); // Fichier voulu
  If hLog = 0 Then
  Begin
    ShowMessage('Impossible d''ouvrir le fichier LOG');
    Exit;
  End;

  // On fait pointer pEvent sur le début du buffer
  pEvent := PEventLogRecord(@bBuffer);

  // Lecture d'un enregistrement
  If ReadEventLog(hLog,                  // Handle
              EVENTLOG_SEEK_READ Or      // Lecture directe
              EVENTLOG_FORWARDS_READ,    // Lecture en avant
                // On se sert du champ Data pour connaitre le
                // numéro d'enregistrement à lire
              Cardinal(Liste.Items[Liste.ItemIndex].Data),
              pEvent,                    // Pointeur vers le buffer
              BUFFER_SIZE,               // Taille du buffer
              dwRead,                    // Nombre d'octets lus
              dwNeeded) Then               // Nombre d'octets demandés
  Begin
    // Recherche de l'adresse de la première chaine
    pStr   := PChar(pEvent);
    Inc(pStr,pEvent.StringOffset);

    LesChaine:='';
    // Lecture des chaines de détail
    For i:=1 To pEvent.NumStrings Do
    Begin
      UneChaine:=pStr;
      // Les chaines se suivent les unes
      // derrière les autres, ( chaine à zéro terminal )
      Inc(pStr,Length(UneChaine)+1);
      LesChaine:=LesChaine+UneChaine+#13;
    End;
  End;

  // Fermeture du fichier
  CloseEventLog(hLog);

  // Affichage des chaines de détail
  If LesChaine<>'' Then ShowMessage(LesChaine);
End;

Procedure TForm1.btnAppliClick(Sender: TObject);
Begin
  AfficherLog('Application');
End;

Procedure TForm1.btnSecuClick(Sender: TObject);
Begin
  AfficherLog('Security');
End;

Procedure TForm1.btnSysClick(Sender: TObject);
Begin
  AfficherLog('System');
End;

end.

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2003 Bruno Guérangé. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -