Win32 API 日本語リファレンス
ホームSystem.Ioctl › USN_RECORD_V4

USN_RECORD_V4

構造体
サイズx64: 80 バイト / x86: 80 バイト

サイズ=各フィールドのバイト数(x64/x86 で異なる場合は x64/x86 と併記)。x64/x86 列=フィールドのバイトオフセット(HSPで dupptr / lpoke / wpoke 等に使用)。

フィールド

フィールドサイズx64x86説明
HeaderUSN_RECORD_COMMON_HEADER8+0+0レコードの長さ、メジャーバージョン、マイナーバージョンを記述する USN_RECORD_COMMON_HEADER 構造体です。
FileReferenceNumberFILE_ID_12816+8+8

このレコードが変更を記録する対象のファイルまたはディレクトリの 128 ビットの序数です。

この値は任意に割り当てられる値であり、ジャーナルレコードとファイルを関連付けます。

ParentFileReferenceNumberFILE_ID_12816+24+24

このレコードに関連付けられているファイルまたはディレクトリが存在するディレクトリの 128 ビットの序数です。

この値は任意に割り当てられる値であり、ジャーナルレコードと親ディレクトリを関連付けます。

UsnLONGLONG8+40+40このレコードの USN です。
ReasonDWORD4+48+48

このファイルまたはディレクトリのジャーナルレコードにおいて、そのファイルまたはディレクトリが開かれてから累積された変更の理由を識別するフラグです。

ファイルまたはディレクトリが閉じられると、USN_REASON_CLOSE フラグが設定された最終的な USN レコードが生成されます。次の変更 (たとえば次に開く操作や削除の後) では、新しい理由フラグのセットを持つ新しいレコードが開始されます。

名前の変更または移動の操作では、2 つの USN レコードが生成されます。1 つは項目の以前の親ディレクトリを記録し、もう 1 つは新しい親を記録します。

次の表に、指定可能なフラグを示します。

メモ 未使用のビットは予約済みです。
意味
USN_REASON_BASIC_INFO_CHANGE
0x00008000
ユーザーが 1 つ以上のファイルまたはディレクトリの属性 (読み取り専用、隠し、システム、アーカイブ、スパースなどの属性)、あるいは 1 つ以上のタイムスタンプを変更しました。
USN_REASON_CLOSE
0x80000000
ファイルまたはディレクトリが閉じられました。
USN_REASON_COMPRESSION_CHANGE
0x00020000
ファイルまたはディレクトリの圧縮状態が、圧縮済みから、または圧縮済みへ変更されました。
USN_REASON_DATA_EXTEND
0x00000002
ファイルまたはディレクトリが拡張されました (追加されました)。
USN_REASON_DATA_OVERWRITE
0x00000001
ファイルまたはディレクトリ内のデータが上書きされました。
USN_REASON_DATA_TRUNCATION
0x00000004
ファイルまたはディレクトリが切り詰められました。
USN_REASON_EA_CHANGE
0x00000400
ユーザーがファイルまたはディレクトリの拡張属性を変更しました。

これらの NTFS ファイルシステムの属性は、Windows ベースのアプリケーションからはアクセスできません。

USN_REASON_ENCRYPTION_CHANGE
0x00040000
ファイルまたはディレクトリが暗号化または復号化されました。
USN_REASON_FILE_CREATE
0x00000100
ファイルまたはディレクトリが初めて作成されました。
USN_REASON_FILE_DELETE
0x00000200
ファイルまたはディレクトリが削除されました。
USN_REASON_HARD_LINK_CHANGE
0x00010000
NTFS ファイルシステムのハードリンクが、ファイルまたはディレクトリに追加されたか、そこから削除されました。

NTFS ファイルシステムのハードリンクは、POSIX のハードリンクと同様に、同一のファイルまたはディレクトリを参照する複数のディレクトリエントリのうちの 1 つです。

USN_REASON_INDEXABLE_CHANGE
0x00004000
ユーザーが FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 属性を変更しました。

つまり、コンテンツのインデックスを作成できるファイルまたはディレクトリから作成できないものへ、またはその逆へ変更しました。コンテンツのインデックス作成では、選択されたコンテンツのデータベースを構築することで、データの高速な検索を可能にします。

USN_REASON_INTEGRITY_CHANGE
0x00800000
ユーザーが、指定されたストリームの FILE_ATTRIBUTE_INTEGRITY_STREAM 属性の状態を変更しました。

ReFS ファイルシステムでは、整合性ストリームはそのストリームのすべてのデータのチェックサムを保持するため、読み取りまたは書き込み操作時にファイルの内容を検証できます。

USN_REASON_NAMED_DATA_EXTEND
0x00000020
ファイルの 1 つ以上の名前付きデータストリームが拡張されました (追加されました)。
USN_REASON_NAMED_DATA_OVERWRITE
0x00000010
ファイルの 1 つ以上の名前付きデータストリーム内のデータが上書きされました。
USN_REASON_NAMED_DATA_TRUNCATION
0x00000040
ファイルの 1 つ以上の名前付きデータストリームが切り詰められました。
USN_REASON_OBJECT_ID_CHANGE
0x00080000
ファイルまたはディレクトリのオブジェクト識別子が変更されました。
USN_REASON_RENAME_NEW_NAME
0x00002000
ファイルまたはディレクトリの名前が変更され、USN_RECORD_V4 構造体内のファイル名は新しい名前です。
USN_REASON_RENAME_OLD_NAME
0x00001000
ファイルまたはディレクトリの名前が変更され、USN_RECORD_V4 構造体内のファイル名は以前の名前です。
USN_REASON_REPARSE_POINT_CHANGE
0x00100000
ファイルまたはディレクトリに含まれる再解析ポイントが変更されたか、再解析ポイントがファイルまたはディレクトリに追加された、あるいはそこから削除されました。
USN_REASON_SECURITY_CHANGE
0x00000800
ファイルまたはディレクトリへのアクセス権が変更されました。
USN_REASON_STREAM_CHANGE
0x00200000
名前付きストリームがファイルに追加された、ファイルから削除された、または名前付きストリームの名前が変更されました。
USN_REASON_TRANSACTED_CHANGE
0x00400000
指定されたストリームが、コミットされた TxF トランザクションによって変更されました。
SourceInfoUSN_SOURCE_INFO_ID4+52+52

FSCTL_MARK_HANDLE による DeviceIoControl 操作によって設定される、変更のソースに関する追加情報です。

スレッドが新しい USN レコードを書き込むとき、直前のレコードのソース情報フラグは、そのスレッドが同じフラグを設定した場合にのみ引き続き保持されます。したがって、ソース情報の構造により、アプリケーションは既知のソース (たとえばウイルス対策フィルター) によってのみ設定された USN レコードを除外できます。

次のいずれかの値を設定できます。

意味
USN_SOURCE_AUXILIARY_DATA
0x00000002
この操作は、ファイルまたはディレクトリにプライベートなデータストリームを追加します。

一例として、ウイルス検出プログラムがチェックサム情報を追加する場合があります。ウイルス検出プログラムが項目を変更すると、システムは USN レコードを生成します。USN_SOURCE_AUXILIARY_DATA は、その変更がアプリケーションのデータを変更していないことを示します。

USN_SOURCE_DATA_MANAGEMENT
0x00000001
この操作は、オペレーティングシステムによって行われたファイルまたはディレクトリへの変更に関する情報を提供します。

代表的な用途は、リモート記憶域システムが外部記憶域からローカル記憶域へデータを移動する場合です。リモート記憶域は階層記憶域管理ソフトウェアです。このような移動では、通常、少なくとも USN_REASON_DATA_OVERWRITE フラグが USN レコードに追加されます。しかし、ユーザーの観点ではデータは変更されていません。SourceInfo メンバーに USN_SOURCE_DATA_MANAGEMENT が示されていることに注目すれば、その項目に対して書き込み操作が実行されたにもかかわらず、データは変更されていないと判断できます。

USN_SOURCE_REPLICATION_MANAGEMENT
0x00000004
この操作は、レプリカセットの別のメンバーに存在する同じファイルの内容と一致するように、ファイルを変更しています。
USN_SOURCE_CLIENT_REPLICATION_MANAGEMENT
0x00000008
この操作は、クラウドに存在する同じファイルの内容と一致するように、クライアントシステム上のファイルを変更しています。
RemainingExtentsDWORD4+56+56現在の USN_RECORD_V4 レコードの後に残っているエクステントの数です。特定のファイルの変更されたエクステントをすべて記述するために、複数のバージョン 4.0 レコードが必要になる場合があります。RemainingExtents メンバーが 0 の場合、現在の USN_RECORD_V4 レコードが、そのファイルに対する最後の USN_RECORD_V4 レコードです。特定のファイルに対する最後の USN_RECORD_V4 エントリの後には、常に、少なくとも USN_REASON_CLOSE フラグが設定された USN_RECORD_V3 レコードが続きます。
NumberOfExtentsWORD2+60+60現在の USN_RECORD_V4 エントリ内のエクステントの数です。
ExtentSizeWORD2+62+62Extents メンバー内の各 USN_RECORD_EXTENT 構造体のサイズ (バイト単位) です。
ExtentsUSN_RECORD_EXTENT16+64+64USN_RECORD_V4 エントリ内のエクステントを表す USN_RECORD_EXTENT 構造体の配列です。

公式ドキュメント

更新シーケンス番号 (USN) 変更ジャーナルのバージョン 4.0 レコードの情報を格納します。バージョン 2.0 および 3.0 のレコードは、それぞれ USN_RECORD_V2 (USN_RECORD とも呼ばれます) 構造体と USN_RECORD_V3 構造体で定義されます。

解説(Remarks)

USN_RECORD_V4 レコードは、範囲追跡が有効になっていて、かつファイルサイズが RangeTrackFileSizeThreshold メンバーの値以上である場合にのみ出力されます。ユーザーは常に、1 つ以上の USN_RECORD_V4 レコードを受け取り、その後に 1 つの USN_RECORD_V3 レコードを受け取ります。

変更ジャーナルのクライアントに将来の互換性への道筋を提供するため、Microsoft は USN_RECORD_V4 構造体に変更ジャーナルソフトウェアのメジャーバージョン番号とマイナーバージョン番号を用意しています。コードではこれらの値を確認し、変更ジャーナルソフトウェアとの互換性を検査したうえで、必要に応じて非互換性を適切に処理してください。

マイナーバージョン番号の変更は、既存の USN_RECORD_V4 構造体のメンバーは引き続き有効であるものの、最後から 2 番目のメンバーと、可変長の文字列である最後のメンバーとの間に新しいメンバーが追加されている可能性があることを示します。

このような変更に適切に対処するため、コードでは最後のメンバーの位置に依存するコンパイル時のポインター演算を行わないでください。たとえば、マイナーバージョン番号が変更されると、sizeof(USN_RECORD) の呼び出しは信頼できなくなります。代わりに、RecordLength メンバーを使用した実行時の計算に頼ってください。

変更ジャーナルソフトウェアのメジャーバージョン番号の増加は、USN_RECORD_V4 構造体に大きな変更が加えられ、現在の定義が信頼できない可能性があることを示します。コードが変更ジャーナルソフトウェアのメジャーバージョン番号の変更を検出した場合、そのコードは変更ジャーナルを扱うべきではありません。

詳細については、「変更ジャーナルの作成、変更、および削除」を参照してください。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での定義

#include <windows.h>

// USN_RECORD_COMMON_HEADER  (x64 8 / x86 8 バイト)
typedef struct USN_RECORD_COMMON_HEADER {
    DWORD RecordLength;
    WORD MajorVersion;
    WORD MinorVersion;
} USN_RECORD_COMMON_HEADER;

// FILE_ID_128  (x64 16 / x86 16 バイト)
typedef struct FILE_ID_128 {
    BYTE Identifier[16];
} FILE_ID_128;

// USN_RECORD_EXTENT  (x64 16 / x86 16 バイト)
typedef struct USN_RECORD_EXTENT {
    LONGLONG Offset;
    LONGLONG Length;
} USN_RECORD_EXTENT;

// USN_RECORD_V4  (x64 80 / x86 80 バイト)
typedef struct USN_RECORD_V4 {
    USN_RECORD_COMMON_HEADER Header;
    FILE_ID_128 FileReferenceNumber;
    FILE_ID_128 ParentFileReferenceNumber;
    LONGLONG Usn;
    DWORD Reason;
    USN_SOURCE_INFO_ID SourceInfo;
    DWORD RemainingExtents;
    WORD NumberOfExtents;
    WORD ExtentSize;
    USN_RECORD_EXTENT Extents[1];
} USN_RECORD_V4;
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct USN_RECORD_COMMON_HEADER
{
    public uint RecordLength;
    public ushort MajorVersion;
    public ushort MinorVersion;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct FILE_ID_128
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] Identifier;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct USN_RECORD_EXTENT
{
    public long Offset;
    public long Length;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct USN_RECORD_V4
{
    public USN_RECORD_COMMON_HEADER Header;
    public FILE_ID_128 FileReferenceNumber;
    public FILE_ID_128 ParentFileReferenceNumber;
    public long Usn;
    public uint Reason;
    public uint SourceInfo;
    public uint RemainingExtents;
    public ushort NumberOfExtents;
    public ushort ExtentSize;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public USN_RECORD_EXTENT[] Extents;
}
Imports System.Runtime.InteropServices

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure USN_RECORD_COMMON_HEADER
    Public RecordLength As UInteger
    Public MajorVersion As UShort
    Public MinorVersion As UShort
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure FILE_ID_128
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=16)> Public Identifier() As Byte
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure USN_RECORD_EXTENT
    Public Offset As Long
    Public Length As Long
End Structure

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)>
Public Structure USN_RECORD_V4
    Public Header As USN_RECORD_COMMON_HEADER
    Public FileReferenceNumber As FILE_ID_128
    Public ParentFileReferenceNumber As FILE_ID_128
    Public Usn As Long
    Public Reason As UInteger
    Public SourceInfo As UInteger
    Public RemainingExtents As UInteger
    Public NumberOfExtents As UShort
    Public ExtentSize As UShort
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=1)> Public Extents() As USN_RECORD_EXTENT
End Structure
import ctypes
from ctypes import wintypes

class USN_RECORD_COMMON_HEADER(ctypes.Structure):
    _fields_ = [
        ("RecordLength", wintypes.DWORD),
        ("MajorVersion", ctypes.c_ushort),
        ("MinorVersion", ctypes.c_ushort),
    ]

class FILE_ID_128(ctypes.Structure):
    _fields_ = [
        ("Identifier", ctypes.c_ubyte * 16),
    ]

class USN_RECORD_EXTENT(ctypes.Structure):
    _fields_ = [
        ("Offset", ctypes.c_longlong),
        ("Length", ctypes.c_longlong),
    ]

class USN_RECORD_V4(ctypes.Structure):
    _fields_ = [
        ("Header", USN_RECORD_COMMON_HEADER),
        ("FileReferenceNumber", FILE_ID_128),
        ("ParentFileReferenceNumber", FILE_ID_128),
        ("Usn", ctypes.c_longlong),
        ("Reason", wintypes.DWORD),
        ("SourceInfo", wintypes.DWORD),
        ("RemainingExtents", wintypes.DWORD),
        ("NumberOfExtents", ctypes.c_ushort),
        ("ExtentSize", ctypes.c_ushort),
        ("Extents", USN_RECORD_EXTENT * 1),
    ]
#[repr(C)]
pub struct USN_RECORD_COMMON_HEADER {
    pub RecordLength: u32,
    pub MajorVersion: u16,
    pub MinorVersion: u16,
}

#[repr(C)]
pub struct FILE_ID_128 {
    pub Identifier: [u8; 16],
}

#[repr(C)]
pub struct USN_RECORD_EXTENT {
    pub Offset: i64,
    pub Length: i64,
}

#[repr(C)]
pub struct USN_RECORD_V4 {
    pub Header: USN_RECORD_COMMON_HEADER,
    pub FileReferenceNumber: FILE_ID_128,
    pub ParentFileReferenceNumber: FILE_ID_128,
    pub Usn: i64,
    pub Reason: u32,
    pub SourceInfo: u32,
    pub RemainingExtents: u32,
    pub NumberOfExtents: u16,
    pub ExtentSize: u16,
    pub Extents: [USN_RECORD_EXTENT; 1],
}
import "golang.org/x/sys/windows"

type USN_RECORD_COMMON_HEADER struct {
	RecordLength uint32
	MajorVersion uint16
	MinorVersion uint16
}

type FILE_ID_128 struct {
	Identifier [16]byte
}

type USN_RECORD_EXTENT struct {
	Offset int64
	Length int64
}

type USN_RECORD_V4 struct {
	Header USN_RECORD_COMMON_HEADER
	FileReferenceNumber FILE_ID_128
	ParentFileReferenceNumber FILE_ID_128
	Usn int64
	Reason uint32
	SourceInfo uint32
	RemainingExtents uint32
	NumberOfExtents uint16
	ExtentSize uint16
	Extents [1]USN_RECORD_EXTENT
}
type
  USN_RECORD_COMMON_HEADER = record
    RecordLength: DWORD;
    MajorVersion: Word;
    MinorVersion: Word;
  end;

  FILE_ID_128 = record
    Identifier: array[0..15] of Byte;
  end;

  USN_RECORD_EXTENT = record
    Offset: Int64;
    Length: Int64;
  end;

  USN_RECORD_V4 = record
    Header: USN_RECORD_COMMON_HEADER;
    FileReferenceNumber: FILE_ID_128;
    ParentFileReferenceNumber: FILE_ID_128;
    Usn: Int64;
    Reason: DWORD;
    SourceInfo: DWORD;
    RemainingExtents: DWORD;
    NumberOfExtents: Word;
    ExtentSize: Word;
    Extents: array[0..0] of USN_RECORD_EXTENT;
  end;
const USN_RECORD_COMMON_HEADER = extern struct {
    RecordLength: u32,
    MajorVersion: u16,
    MinorVersion: u16,
};

const FILE_ID_128 = extern struct {
    Identifier: [16]u8,
};

const USN_RECORD_EXTENT = extern struct {
    Offset: i64,
    Length: i64,
};

const USN_RECORD_V4 = extern struct {
    Header: USN_RECORD_COMMON_HEADER,
    FileReferenceNumber: FILE_ID_128,
    ParentFileReferenceNumber: FILE_ID_128,
    Usn: i64,
    Reason: u32,
    SourceInfo: u32,
    RemainingExtents: u32,
    NumberOfExtents: u16,
    ExtentSize: u16,
    Extents: [1]USN_RECORD_EXTENT,
};
type
  USN_RECORD_COMMON_HEADER {.bycopy.} = object
    RecordLength: uint32
    MajorVersion: uint16
    MinorVersion: uint16

  FILE_ID_128 {.bycopy.} = object
    Identifier: array[16, uint8]

  USN_RECORD_EXTENT {.bycopy.} = object
    Offset: int64
    Length: int64

  USN_RECORD_V4 {.bycopy.} = object
    Header: USN_RECORD_COMMON_HEADER
    FileReferenceNumber: FILE_ID_128
    ParentFileReferenceNumber: FILE_ID_128
    Usn: int64
    Reason: uint32
    SourceInfo: uint32
    RemainingExtents: uint32
    NumberOfExtents: uint16
    ExtentSize: uint16
    Extents: array[1, USN_RECORD_EXTENT]
struct USN_RECORD_COMMON_HEADER
{
    uint RecordLength;
    ushort MajorVersion;
    ushort MinorVersion;
}

struct FILE_ID_128
{
    ubyte[16] Identifier;
}

struct USN_RECORD_EXTENT
{
    long Offset;
    long Length;
}

struct USN_RECORD_V4
{
    USN_RECORD_COMMON_HEADER Header;
    FILE_ID_128 FileReferenceNumber;
    FILE_ID_128 ParentFileReferenceNumber;
    long Usn;
    uint Reason;
    uint SourceInfo;
    uint RemainingExtents;
    ushort NumberOfExtents;
    ushort ExtentSize;
    USN_RECORD_EXTENT[1] Extents;
}

HSP用 定義

HSP3.7/3.8 は構造体機能が無いため4byte整数配列(dim)+peek/poke で操作(32/64bitでサイズ・位置が異なる場合はタブで分割)。IronHSP は NSTRUCT(#defstruct/stdim/->)で32/64bit共通。

; HSP3.7/3.8 は構造体機能が無いため、4byte整数の配列変数で操作します。(x64 レイアウト)
; USN_RECORD_V4 サイズ: 80 バイト(x64)
dim st, 20    ; 4byte整数×20(構造体サイズ 80 / 4 切り上げ)
; Header : USN_RECORD_COMMON_HEADER (+0, 8byte)  varptr(st)+0 を基点に操作(8byte:入れ子/配列)
; FileReferenceNumber : FILE_ID_128 (+8, 16byte)  varptr(st)+8 を基点に操作(16byte:入れ子/配列)
; ParentFileReferenceNumber : FILE_ID_128 (+24, 16byte)  varptr(st)+24 を基点に操作(16byte:入れ子/配列)
; Usn : LONGLONG (+40, 8byte)  qpoke st,40,値 / qpeek(st,40)  ※IronHSPのみ。3.7/3.8は lpoke st,40,下位 : lpoke st,44,上位
; Reason : DWORD (+48, 4byte)  st.12 = 値  /  値 = st.12   (lpoke/lpeek も可)
; SourceInfo : USN_SOURCE_INFO_ID (+52, 4byte)  st.13 = 値  /  値 = st.13   (lpoke/lpeek も可)
; RemainingExtents : DWORD (+56, 4byte)  st.14 = 値  /  値 = st.14   (lpoke/lpeek も可)
; NumberOfExtents : WORD (+60, 2byte)  wpoke st,60,値  /  値 = wpeek(st,60)
; ExtentSize : WORD (+62, 2byte)  wpoke st,62,値  /  値 = wpeek(st,62)
; Extents : USN_RECORD_EXTENT (+64, 16byte)  varptr(st)+64 を基点に操作(16byte:入れ子/配列)
; ※4byte境界の整数は添字 st.N(N=オフセット/4)で読み書き可。それ以外は peek/poke 系を使用。
; IronHSP は NSTRUCT(構造体)をサポート。32bit/64bit どちらでも同じコードで動作します。
; ※GUID・入れ子構造体はデフォルト型でないため、依存する #defstruct を先に定義(下記に同梱)。
#defstruct global USN_RECORD_COMMON_HEADER
    #field int RecordLength
    #field short MajorVersion
    #field short MinorVersion
#endstruct

#defstruct global FILE_ID_128
    #field byte Identifier 16
#endstruct

#defstruct global USN_RECORD_EXTENT
    #field int64 Offset
    #field int64 Length
#endstruct

#defstruct global USN_RECORD_V4
    #field USN_RECORD_COMMON_HEADER Header
    #field FILE_ID_128 FileReferenceNumber
    #field FILE_ID_128 ParentFileReferenceNumber
    #field int64 Usn
    #field int Reason
    #field int SourceInfo
    #field int RemainingExtents
    #field short NumberOfExtents
    #field short ExtentSize
    #field USN_RECORD_EXTENT Extents 1
#endstruct

stdim st, USN_RECORD_V4        ; NSTRUCT 変数を確保
st->Usn = 100
mes "Usn=" + st->Usn