diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/7zip/UI/FileManager/FSFolder.cpp | 105 |
1 files changed, 97 insertions, 8 deletions
diff --git a/CPP/7zip/UI/FileManager/FSFolder.cpp b/CPP/7zip/UI/FileManager/FSFolder.cpp index f3e04b3..72cb0ce 100644 --- a/CPP/7zip/UI/FileManager/FSFolder.cpp +++ b/CPP/7zip/UI/FileManager/FSFolder.cpp | |||
@@ -2,11 +2,19 @@ | |||
2 | 2 | ||
3 | #include "StdAfx.h" | 3 | #include "StdAfx.h" |
4 | 4 | ||
5 | #if defined(_MSC_VER) | ||
6 | #include <winternl.h> | ||
7 | #else | ||
8 | // mingw | ||
9 | #include <ddk/winddk.h> | ||
10 | #endif | ||
11 | |||
5 | #include "../../../Common/ComTry.h" | 12 | #include "../../../Common/ComTry.h" |
6 | #include "../../../Common/Defs.h" | 13 | #include "../../../Common/Defs.h" |
7 | #include "../../../Common/StringConvert.h" | 14 | #include "../../../Common/StringConvert.h" |
8 | #include "../../../Common/UTFConvert.h" | 15 | #include "../../../Common/UTFConvert.h" |
9 | 16 | ||
17 | #include "../../../Windows/DLL.h" | ||
10 | #include "../../../Windows/FileDir.h" | 18 | #include "../../../Windows/FileDir.h" |
11 | #include "../../../Windows/FileIO.h" | 19 | #include "../../../Windows/FileIO.h" |
12 | #include "../../../Windows/FileName.h" | 20 | #include "../../../Windows/FileName.h" |
@@ -56,12 +64,15 @@ static const Byte kProps[] = | |||
56 | kpidMTime, | 64 | kpidMTime, |
57 | kpidCTime, | 65 | kpidCTime, |
58 | kpidATime, | 66 | kpidATime, |
67 | #ifdef FS_SHOW_LINKS_INFO | ||
68 | kpidChangeTime, | ||
69 | #endif | ||
59 | kpidAttrib, | 70 | kpidAttrib, |
60 | kpidPackSize, | 71 | kpidPackSize, |
61 | #ifdef FS_SHOW_LINKS_INFO | 72 | #ifdef FS_SHOW_LINKS_INFO |
62 | kpidINode, | 73 | kpidINode, |
63 | kpidLinks, | 74 | kpidLinks, |
64 | #endif | 75 | #endif |
65 | kpidComment, | 76 | kpidComment, |
66 | kpidNumSubDirs, | 77 | kpidNumSubDirs, |
67 | kpidNumSubFiles, | 78 | kpidNumSubFiles, |
@@ -199,19 +210,23 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix) | |||
199 | */ | 210 | */ |
200 | } | 211 | } |
201 | 212 | ||
202 | #ifndef UNDER_CE | 213 | #ifndef UNDER_CE |
203 | 214 | ||
204 | fi.Reparse.Free(); | 215 | fi.Reparse.Free(); |
205 | fi.PackSize_Defined = false; | 216 | fi.PackSize_Defined = false; |
206 | 217 | ||
207 | #ifdef FS_SHOW_LINKS_INFO | 218 | #ifdef FS_SHOW_LINKS_INFO |
208 | fi.FileInfo_Defined = false; | 219 | fi.FileInfo_Defined = false; |
209 | fi.FileInfo_WasRequested = false; | 220 | fi.FileInfo_WasRequested = false; |
210 | fi.FileIndex = 0; | 221 | fi.FileIndex = 0; |
211 | fi.NumLinks = 0; | 222 | fi.NumLinks = 0; |
212 | #endif | 223 | fi.ChangeTime_Defined = false; |
224 | fi.ChangeTime_WasRequested = false; | ||
225 | #endif | ||
213 | 226 | ||
214 | fi.PackSize = fi.Size; | 227 | fi.PackSize = fi.Size; |
228 | |||
229 | #ifdef FS_SHOW_LINKS_INFO | ||
215 | if (fi.HasReparsePoint()) | 230 | if (fi.HasReparsePoint()) |
216 | { | 231 | { |
217 | fi.FileInfo_WasRequested = true; | 232 | fi.FileInfo_WasRequested = true; |
@@ -221,8 +236,9 @@ HRESULT CFSFolder::LoadSubItems(int dirItem, const FString &relPrefix) | |||
221 | fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; | 236 | fi.FileIndex = (((UInt64)info.nFileIndexHigh) << 32) + info.nFileIndexLow; |
222 | fi.FileInfo_Defined = true; | 237 | fi.FileInfo_Defined = true; |
223 | } | 238 | } |
239 | #endif | ||
224 | 240 | ||
225 | #endif | 241 | #endif // UNDER_CE |
226 | 242 | ||
227 | /* unsigned fileIndex = */ Files.Add(fi); | 243 | /* unsigned fileIndex = */ Files.Add(fi); |
228 | 244 | ||
@@ -396,7 +412,9 @@ STDMETHODIMP_(UInt64) CFSFolder::GetItemSize(UInt32 index) | |||
396 | 412 | ||
397 | #endif | 413 | #endif |
398 | 414 | ||
415 | |||
399 | #ifdef FS_SHOW_LINKS_INFO | 416 | #ifdef FS_SHOW_LINKS_INFO |
417 | |||
400 | bool CFSFolder::ReadFileInfo(CDirItem &di) | 418 | bool CFSFolder::ReadFileInfo(CDirItem &di) |
401 | { | 419 | { |
402 | di.FileInfo_WasRequested = true; | 420 | di.FileInfo_WasRequested = true; |
@@ -409,7 +427,71 @@ bool CFSFolder::ReadFileInfo(CDirItem &di) | |||
409 | di.FileInfo_Defined = true; | 427 | di.FileInfo_Defined = true; |
410 | return true; | 428 | return true; |
411 | } | 429 | } |
412 | #endif | 430 | |
431 | |||
432 | typedef struct | ||
433 | { | ||
434 | LARGE_INTEGER CreationTime; | ||
435 | LARGE_INTEGER LastAccessTime; | ||
436 | LARGE_INTEGER LastWriteTime; | ||
437 | LARGE_INTEGER ChangeTime; | ||
438 | ULONG FileAttributes; | ||
439 | UInt32 Reserved; // it's expected for alignment | ||
440 | } | ||
441 | MY__FILE_BASIC_INFORMATION; | ||
442 | |||
443 | |||
444 | typedef enum | ||
445 | { | ||
446 | MY__FileDirectoryInformation = 1, | ||
447 | MY__FileFullDirectoryInformation, | ||
448 | MY__FileBothDirectoryInformation, | ||
449 | MY__FileBasicInformation | ||
450 | } | ||
451 | MY__FILE_INFORMATION_CLASS; | ||
452 | |||
453 | |||
454 | typedef NTSTATUS (WINAPI * Func_NtQueryInformationFile)( | ||
455 | HANDLE handle, IO_STATUS_BLOCK *io, | ||
456 | void *ptr, LONG len, MY__FILE_INFORMATION_CLASS cls); | ||
457 | |||
458 | #define MY__STATUS_SUCCESS 0 | ||
459 | |||
460 | static Func_NtQueryInformationFile f_NtQueryInformationFile; | ||
461 | static bool g_NtQueryInformationFile_WasRequested = false; | ||
462 | |||
463 | void CFSFolder::ReadChangeTime(CDirItem &di) | ||
464 | { | ||
465 | di.ChangeTime_WasRequested = true; | ||
466 | |||
467 | if (!g_NtQueryInformationFile_WasRequested) | ||
468 | { | ||
469 | g_NtQueryInformationFile_WasRequested = true; | ||
470 | f_NtQueryInformationFile = (Func_NtQueryInformationFile) | ||
471 | My_GetProcAddress(::GetModuleHandleW(L"ntdll.dll"), | ||
472 | "NtQueryInformationFile"); | ||
473 | } | ||
474 | if (!f_NtQueryInformationFile) | ||
475 | return; | ||
476 | |||
477 | NIO::CInFile file; | ||
478 | if (!file.Open_for_ReadAttributes(_path + GetRelPath(di))) | ||
479 | return; | ||
480 | MY__FILE_BASIC_INFORMATION fbi; | ||
481 | IO_STATUS_BLOCK IoStatusBlock; | ||
482 | const NTSTATUS status = f_NtQueryInformationFile(file.GetHandle(), &IoStatusBlock, | ||
483 | &fbi, sizeof(fbi), MY__FileBasicInformation); | ||
484 | if (status != MY__STATUS_SUCCESS) | ||
485 | return; | ||
486 | if (IoStatusBlock.Information != sizeof(fbi)) | ||
487 | return; | ||
488 | di.ChangeTime.dwLowDateTime = fbi.ChangeTime.u.LowPart; | ||
489 | di.ChangeTime.dwHighDateTime = fbi.ChangeTime.u.HighPart; | ||
490 | di.ChangeTime_Defined = true; | ||
491 | } | ||
492 | |||
493 | #endif // FS_SHOW_LINKS_INFO | ||
494 | |||
413 | 495 | ||
414 | STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) | 496 | STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) |
415 | { | 497 | { |
@@ -492,7 +574,14 @@ STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va | |||
492 | prop = fi.FileIndex; | 574 | prop = fi.FileIndex; |
493 | #endif | 575 | #endif |
494 | break; | 576 | break; |
495 | 577 | ||
578 | case kpidChangeTime: | ||
579 | if (!fi.ChangeTime_WasRequested) | ||
580 | ReadChangeTime(fi); | ||
581 | if (fi.ChangeTime_Defined) | ||
582 | prop = fi.ChangeTime; | ||
583 | break; | ||
584 | |||
496 | #endif | 585 | #endif |
497 | 586 | ||
498 | case kpidAttrib: prop = (UInt32)fi.Attrib; break; | 587 | case kpidAttrib: prop = (UInt32)fi.Attrib; break; |