aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/UI/FileManager/FSFolder.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CPP/7zip/UI/FileManager/FSFolder.cpp105
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
400bool CFSFolder::ReadFileInfo(CDirItem &di) 418bool 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
432typedef 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}
441MY__FILE_BASIC_INFORMATION;
442
443
444typedef enum
445{
446 MY__FileDirectoryInformation = 1,
447 MY__FileFullDirectoryInformation,
448 MY__FileBothDirectoryInformation,
449 MY__FileBasicInformation
450}
451MY__FILE_INFORMATION_CLASS;
452
453
454typedef 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
460static Func_NtQueryInformationFile f_NtQueryInformationFile;
461static bool g_NtQueryInformationFile_WasRequested = false;
462
463void 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
414STDMETHODIMP CFSFolder::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) 496STDMETHODIMP 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;