Maison > développement back-end > C++ > le corps du texte

Comment détecter efficacement les modifications de fichiers sur un volume NTFS à l'aide de FSCTL_ENUM_USN_DATA ?

Patricia Arquette
Libérer: 2024-10-30 13:03:26
original
808 Les gens l'ont consulté

 How Can You Efficiently Detect File Changes on an NTFS Volume Using FSCTL_ENUM_USN_DATA?

Détection efficace des modifications de fichiers sur un volume NTFS à l'aide de FSCTL_ENUM_USN_DATA

Arrière-plan

Les méthodes de sauvegarde existantes, qui vérifient le bit d'archive de chaque fichier, peuvent devenir lentes et inefficace pour les grands systèmes de fichiers. Cette approche nécessite d'analyser tous les fichiers, y compris les fichiers temporaires, et peut entraîner de longs processus de sauvegarde.

Approche alternative utilisant le système de fichiers USN

Une méthode plus efficace consiste à utiliser le système de fichiers USN (séquence de mise à jour Numéro) journal des changements. Le système de fichiers USN fournit un enregistrement pour chaque modification apportée au système de fichiers, y compris la création, la suppression et la modification de fichiers.

Comment fonctionne FSCTL_ENUM_USN_DATA

Pour détecter les modifications sur un volume NTFS, nous pouvons utiliser le Code de contrôle FSCTL_ENUM_USN_DATA. Ce code de contrôle :

  • Énumère tous les fichiers d'un volume, y compris uniquement ceux actuellement existants.
  • Récupère les données critiques pour chaque fichier, notamment :

    • Drapeaux de fichiers
    • USN
    • Noms de fichiers
    • Numéros de référence des fichiers parents

Implémentation de la détection des changements

Pour détecter les changements :

  1. Obtenir les données USN du système de fichiers : Utilisez FSCTL_QUERY_USN_JOURNAL pour obtenir l'USN maximum du système (maxusn).
  2. Énumérer les enregistrements USN : Utilisez une boucle pour parcourir les enregistrements USN à l'aide de FSCTL_ENUM_USN_DATA.
  3. Identifier les enregistrements pertinents : Vérifiez les indicateurs et comparez les USN pour détecter les fichiers créés, supprimés ou modifiés.
  4. Résoudre les chemins parents : Faites correspondre les numéros de référence des fichiers parents avec les numéros de référence des répertoires pour obtenir des chemins de fichiers complets.

Exemple de code en C

Voici un extrait de code qui illustre l'approche :

<code class="c++">DWORDLONG nextid;
DWORDLONG filecount = 0;
DWORD starttick, endtick;

// Allocate memory for USN records
void * buffer = VirtualAlloc(NULL, BUFFER_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

// Open volume handle
HANDLE drive = CreateFile(L"\\?\c:", GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_FLAG_NO_BUFFERING, NULL);

// Get volume USN journal data
USN_JOURNAL_DATA * journal = (USN_JOURNAL_DATA *)buffer;
if (!DeviceIoControl(drive, FSCTL_QUERY_USN_JOURNAL, NULL, 0, buffer, BUFFER_SIZE, &bytecount, NULL)) {
  (...)
}
maxusn = journal->MaxUsn;

MFT_ENUM_DATA mft_enum_data;
mft_enum_data.StartFileReferenceNumber = 0;
mft_enum_data.LowUsn = 0;
mft_enum_data.HighUsn = maxusn;

while (...) {
  if (!DeviceIoControl(drive, FSCTL_ENUM_USN_DATA, &mft_enum_data, sizeof(mft_enum_data), buffer, BUFFER_SIZE, &bytecount, NULL)) {
    (...)
  }

  nextid = *((DWORDLONG *)buffer);
  USN_RECORD * record = (USN_RECORD *)((USN *)buffer + 1);
  USN_RECORD * recordend = (USN_RECORD *)(((BYTE *)buffer) + bytecount);

  while (record < recordend) {
    filecount++;
    // Check flags and USNs to identify changes
    (...)
    record = (USN_RECORD *)(((BYTE *)record) + record->RecordLength);
  }
  mft_enum_data.StartFileReferenceNumber = nextid;
}</code>
Copier après la connexion

Considérations relatives aux performances

L'approche utilisant FSCTL_ENUM_USN_DATA offre :

  • Processus d'énumération rapide : Capable de traiter plus de 6 000 enregistrements par seconde.
  • Filtrage efficace : Seuls les enregistrements de modifications de fichiers pertinents sont analysés, éliminant ainsi la surcharge des fichiers temporaires.
  • Potentiel limitations :Les performances peuvent varier sur de très gros volumes, mais elles sont généralement plus efficaces que la vérification des bits d'archive.

Notes supplémentaires

  • Remplacez MFT_ENUM_DATA par MFT_ENUM_DATA_V0 sous Windows versions ultérieures à Windows 7.
  • Les numéros de référence des fichiers sont imprimés en 32 bits, ce qui est une erreur. Dans le code de production, il est recommandé d'utiliser des valeurs 64 bits.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!