앨리스의 토끼

javahawk.egloos.com

포토로그 방명록


최근 포토로그


IRP_MJ_DIRECTORY_CONTROL by Kircheis

User-mode application의 경우에는 다음의 함수들의 호출에 기인한다.
ReadDirectoryChangesW, FindNextVolumeMountPoint

Kernel-mode component의 경우에는 다음의 native API의 호출에 기인한다.
ZwQueryDirectoryFile


I. IrpSp->MinorFunction은 다음의 두 가지로 분류된다.

 1. IRP_MN_NOTIFY_CHANGE_DIRECTORY
 - Directory에 변경이 가해졌을 경우에 감지된다.

 2. IRP_MN_QUERY_DIRECTORY
 - Directory query요청에 대하여 다음의 9가지 유형으로 분류된다.

  1) FileBothDirectoryInformation
  2) FileDirectoryInformation
  3) FileFullDirectoryInformation
  4) FileIdBothDirectoryInformation
  5) FileIdFullDirectoryInformation
  6) FileNamesInformation
  7) FileObjectIdInformation
  8) FileReparsePointInformation

  9) FileQuotaInformation도 있는데, IRP_MJ_QUERY_QUOTA로 별도 분리되었단다.


II. IrpSp->FileObject
- FILE_OBJECT구조체의 RelatedFileObject 필드의 포인터를 포함한다. 이 포인터는 열려있는 파일에 대한 정보이다.
- 자세한 정보는 FILE_OBJECT 구조체를 확인한다.


III. IrpSp->Flags
- 이 때의 Flags는 다음의 4가지 값이 가능하다.


 1. SL_INDEX_SPECIFIED
 - 이 값의 경우 IrpSp->Parameters.QueryDirectory.FileIndex에 의해 주어진 디렉토리 인덱스의 entry에서 scanning을 시작한다.


 2. SL_RESTART_SCAN
 - 이 경우에는 디렉토리의 first entry부터 scan을 한다.
 - 만약 이 값이 설정되지 않았다면 이전의 IRP_MN_QUERY_DIRECTORY 요청으로부터 다시 scanning을 시작한다.
 - 말이 어려운데 MSDN에 소개된 내용은 다음과 같다.
 - If this flag is not set, resume the scan from a previous IRP_MN_QUERY_DIRECTORY request.


 3. SL_RETURN_SINGLE_ENTRY
 - 이건 간단하다. first entry 만을 반환한다.
 - Return only the first entry that is found.

 이에 더해서 IRP_MN_NOTIFY_CHANGE_DIRECTORY에 대해서만 다음의 한 가지가 더 가능하다.


 4. SL_WATCH_TREE
 - 이 경우에는 subdirectory에 대한 검색 여부에 따라서 TRUE, FALSE를 설정한다(?)


IV. IrpSp->Parameters.NotifyDirectory.CompletionFilter
- FsRtlNotifyFullChangeDirectory 함수의 CompletionFilter의 설명을 보란다.
- 이것에 대한 내용이 상당히 많다. 다음에 다뤄본다.


V. IrpSp->Parameters.NotifyDirectory.Length
- Irp->UserBuffer로 지정된 버퍼의 사이즈


VI. IrpSp->Parameters.QueryDirectory.FileIndex
- SL_INDEX_SPECIFIED가 필수이다. 없으면 무의미한 값이 된다.
- 이 경우에는 Win32함수나 kernel-mode support routine에서 지정될 수 없다.
- 대개는 NTVDM(NT virtual DOS machine)에서 사용된다.
- NTFS 같은 경우에는 sorting order에 따라 변경이 가능하다.


VII. IrpSp->Parameters.QueryDirectory.FileInformationClass
- 이건 위의 IRP_MN_QUERY_DIRECTORY에서 나열된 9가지 중의 하나가 될 수 있다.
- 각각의 클래스에 대해 파일별로 다음의 구조체를 반환받는다.
- 해당하는 각 구조체들에 대한 정보는 IRP의 UserBuffer로부터 형 변환으로 받아올 수 있다.


 1. FileBothDirectoryInformation - FILE_BOTH_DIR_INFORMATION
 - 포함된 모든 시간은 시스템의 절대 시간을 기준으로 한다.
 - 절대 시간은 1601년을 시작으로 하는 100-nano 초 단위의 간격으로 매겨진다.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.


typedef struct _FILE_BOTH_DIR_INFORMATION {
 ULONG         NextEntryOffset;
 // 다음의 FILE_BOTH_DIR_INFORMATION의 offset. 만약 다음 대상이 없으면 NULL값이 된다.
 ULONG         FileIndex;
 // 부모 디렉토리 기준의 파일에 대한 byte offset. NTFS에서는 sorting order에 따라 변경된다.
 LARGE_INTEGER CreationTime;        // 파일 생성 시간
 LARGE_INTEGER LastAccessTime;   // 파일 접근 시간
 LARGE_INTEGER LastWriteTime;       // 최종적으로 쓰여진 시간 시간
 LARGE_INTEGER ChangeTime;         // 파일이 변경된 시간
 LARGE_INTEGER EndOfFile;             // byte offset으로 지정된 포지션.
 LARGE_INTEGER AllocationSize;
 // File allocation size, in bytes. 이 경우에는 물리 디바이스의 섹터나 클러스터 사이즈에 따라 multiple하다.
 ULONG         FileAttributes;       // 이 값은 여러값의 조합이다. 가능한 조합은 아래에 나열한다.
 ULONG         FileNameLength;  // byte 단위
 ULONG         EaSize;               // 파일의 EA(Extended attributes)에 대한 바이트단위 사이즈
 CCHAR         ShortNameLength;
 WCHAR         ShortName[12];   // 8.3 기준 short name의 Unicode string
 WCHAR         FileName[1];       // 파일명의 첫 문자로 지정
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;


 - FileAttributes의 가능 조합
 FILE_ATTRIBUTE_READONLY
 FILE_ATTRIBUTE_HIDDEN
 FILE_ATTRIBUTE_SYSTEM
 FILE_ATTRIBUTE_DIRECTORY
 FILE_ATTRIBUTE_ARCHIVE
 FILE_ATTRIBUTE_DEVICE
 FILE_ATTRIBUTE_NORMAL
 FILE_ATTRIBUTE_TEMPORARY
 FILE_ATTRIBUTE_SPARSE_FILE
 FILE_ATTRIBUTE_REPARSE_POINT
 FILE_ATTRIBUTE_COMPRESSED
 FILE_ATTRIBUTE_OFFLINE
 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
 FILE_ATTRIBUTE_ENCRYPTED


 2. FileDirectoryInformation - FILE_DIRECTORY_INFORMATION
 - 포함된 모든 시간은 시스템의 절대 시간을 기준으로 한다.
 - 절대 시간은 1601년을 시작으로 하는 100-nano 초 단위의 간격으로 매겨진다.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.
 - 중복된 필드에 대한 설명은 제외한다.


typedef struct _FILE_DIRECTORY_INFORMATION {
 ULONG         NextEntryOffset;
 ULONG         FileIndex;
 LARGE_INTEGER CreationTime;
 LARGE_INTEGER LastAccessTime;
 LARGE_INTEGER LastWriteTime;
 LARGE_INTEGER ChangeTime;
 LARGE_INTEGER EndOfFile;
 LARGE_INTEGER AllocationSize;
 ULONG         FileAttributes;
 ULONG         FileNameLength;  // 파일명의 길이
 WCHAR         FileName[1];  // 파일명의 첫 문자로 지정
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;


 - FileAttributes의 가능 조합
 FILE_ATTRIBUTE_READONLY
 FILE_ATTRIBUTE_HIDDEN
 FILE_ATTRIBUTE_SYSTEM
 FILE_ATTRIBUTE_DIRECTORY
 FILE_ATTRIBUTE_ARCHIVE
 FILE_ATTRIBUTE_NORMAL
 FILE_ATTRIBUTE_TEMPORARY
 FILE_ATTRIBUTE_COMPRESSED


 3. FileFullDirectoryInformation - FILE_FULL_DIR_INFORMATION
 - 포함된 모든 시간은 시스템의 절대 시간을 기준으로 한다.
 - 절대 시간은 1601년을 시작으로 하는 100-nano 초 단위의 간격으로 매겨진다.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.
 - 중복된 필드에 대한 설명은 제외한다.


typedef struct _FILE_FULL_DIR_INFORMATION {
 ULONG         NextEntryOffset;
 ULONG         FileIndex;
 LARGE_INTEGER CreationTime;
 LARGE_INTEGER LastAccessTime;
 LARGE_INTEGER LastWriteTime;
 LARGE_INTEGER ChangeTime;
 LARGE_INTEGER EndOfFile;
 LARGE_INTEGER AllocationSize;
 ULONG         FileAttributes;
 ULONG         FileNameLength;
 ULONG         EaSize;
 WCHAR         FileName[1];
} FILE_FULL_DIR_INFORMATION, *PFILE_FULL_DIR_INFORMATION;


 - FileAttributes의 가능한 값은 다음과 같다.
 FILE_ATTRIBUTE_READONLY
 FILE_ATTRIBUTE_HIDDEN
 FILE_ATTRIBUTE_SYSTEM
 FILE_ATTRIBUTE_DIRECTORY
 FILE_ATTRIBUTE_ARCHIVE
 FILE_ATTRIBUTE_NORMAL
 FILE_ATTRIBUTE_TEMPORARY
 FILE_ATTRIBUTE_COMPRESSED


 4. FileIdBothDirectoryInformation - FILE_ID_BOTH_DIR_INFORMATION
 - 포함된 모든 시간은 시스템의 절대 시간을 기준으로 한다.
 - 절대 시간은 1601년을 시작으로 하는 100-nano 초 단위의 간격으로 매겨진다.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.
 - 중복된 필드에 대한 설명은 제외한다.


typedef struct _FILE_ID_BOTH_DIR_INFORMATION {
 ULONG         NextEntryOffset;
 ULONG         FileIndex;
 LARGE_INTEGER CreationTime;
 LARGE_INTEGER LastAccessTime;
 LARGE_INTEGER LastWriteTime;
 LARGE_INTEGER ChangeTime;
 LARGE_INTEGER EndOfFile;
 LARGE_INTEGER AllocationSize;
 ULONG         FileAttributes;
 ULONG         FileNameLength;
 ULONG         EaSize;
 CCHAR         ShortNameLength;
 WCHAR         ShortName[12];
 LARGE_INTEGER FileId;
 // 파일 시스템에서 생성하여 배정한 8 byte file reference number.
 // Win 2K를 위해 NTFS에 추가된 16-byte의 "file objectID와는 다른 값이며,
 // 최적화 등에 의해서 변질될 수 있는 값이지만, 항상 unique하게 지정된다.
 WCHAR         FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;


 - FileAttributes의 가능한 값은 다음과 같다.
 FILE_ATTRIBUTE_READONLY
 FILE_ATTRIBUTE_HIDDEN
 FILE_ATTRIBUTE_SYSTEM
 FILE_ATTRIBUTE_DIRECTORY
 FILE_ATTRIBUTE_ARCHIVE
 FILE_ATTRIBUTE_NORMAL
 FILE_ATTRIBUTE_TEMPORARY
 FILE_ATTRIBUTE_COMPRESSED


 5. FileIdFullDirectoryInformation - FILE_ID_FULL_DIR_INFORMATION
 - 포함된 모든 시간은 시스템의 절대 시간을 기준으로 한다.
 - 절대 시간은 1601년을 시작으로 하는 100-nano 초 단위의 간격으로 매겨진다.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.
 - 중복된 필드에 대한 설명은 제외한다.


typedef struct _FILE_ID_FULL_DIR_INFORMATION {
 ULONG         NextEntryOffset;
 ULONG         FileIndex;
 LARGE_INTEGER CreationTime;
 LARGE_INTEGER LastAccessTime;
 LARGE_INTEGER LastWriteTime;
 LARGE_INTEGER ChangeTime;
 LARGE_INTEGER EndOfFile;
 LARGE_INTEGER AllocationSize;
 ULONG         FileAttributes;
 ULONG         FileNameLength;
 ULONG         EaSize;
 LARGE_INTEGER FileId;
 WCHAR         FileName[1];
} FILE_ID_FULL_DIR_INFORMATION, *PFILE_ID_FULL_DIR_INFORMATION;


 - FileAttributes의 가능한 값은 다음과 같다.
 FILE_ATTRIBUTE_READONLY
 FILE_ATTRIBUTE_HIDDEN
 FILE_ATTRIBUTE_SYSTEM
 FILE_ATTRIBUTE_DIRECTORY
 FILE_ATTRIBUTE_ARCHIVE
 FILE_ATTRIBUTE_NORMAL
 FILE_ATTRIBUTE_TEMPORARY
 FILE_ATTRIBUTE_COMPRESSED


 6. FileNamesInformation - FILE_NAME_INFORMATION
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.
 - 중복된 필드에 대한 설명은 제외한다.


typedef struct _FILE_NAMES_INFORMATION {
 ULONG NextEntryOffset;
 ULONG FileIndex;
 ULONG FileNameLength;
 WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;


 7. FileObjectIdInformation - FILE_OBJECTID_INFORMATION
 - NTFS에서는 object ID에 file reference number를 더해서 파일을 열어볼 수 있도록 허용한다.
 - File system filter drivers that use file object IDs should be tested for interoperability with DFS, the Replicator service, and the Distributed Link Tracking service, all of which use and manipulate file object IDs.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.
 - 중복된 필드에 대한 설명은 제외한다.


typedef struct _FILE_OBJECTID_INFORMATION {
 LONGLONG FileReference;  // 8-byte file reference number. NTFS에서 파일 생성될 때마다 자동으로 생성한다.
 UCHAR    ObjectId[16];  // 16-byte file object ID. 드라이버나 어플리케이션의 요청에 의해 NTFS가 생성하는 할당한다. 해당 파일이 있는 volume에서 unique하다.
 union {
  struct {
   UCHAR BirthVolumeId[16];  // 파일이 있는 volume의 object ID. 복사, 이동 등의 파일작업 후에는 같은 값을 유지하지 못한다.
   UCHAR BirthObjectId[16];  // 파일 생성되었을 때의 파일의 object ID.
   UCHAR DomainId[16];  // Reserved; 0
  };
  UCHAR  ExtendedInfo[48];  // User-provided data. 위의 세가지 멤버를 사용할 수 있으며, 별도의 구조체를 선언할 수 있다.
 };
} FILE_OBJECTID_INFORMATION, *PFILE_OBJECTID_INFORMATION;


 8. FileReparsePointInformation - FILE_REPARSE_POINT_INFORMATION
 - 이것의 경우에는 파일이 아닌 디렉토리에 대한 구조체이다.
 - 사용하는 헤더는 Ntifs.h(또는 Fltkernel.h)를 사용한다.


typedef struct _FILE_REPARSE_POINT_INFORMATION {
 LONGLONG FileReference;
 ULONG    Tag;    // Reparse point tag. The ReparseTag member indicates the structure of the user-defined reparse data
} FILE_REPARSE_POINT_INFORMATION, *PFILE_REPARSE_POINT_INFORMATION;


 9. FileQuotaInformation
 - 이 클래스는  IRP_MJ_QUERY_QUOTA로 대치되어 별도의 구조체가 없다.


VIII. IrpSp->Parameters.QueryDirectory.FileName
- Optional name of a file within the specified directory
- 별다른 설명이 없다.


IX. IrpSp->Parameters.QueryDirectory.Length
- Irp->UserBuffer로 지정된 버퍼의 길이





메모장