Methods to get NTFS times from the extra field
This commit is contained in:
parent
71696d6669
commit
3b85cd7276
2 changed files with 134 additions and 0 deletions
|
@ -24,6 +24,9 @@ see quazip/(un)zip.h files for details. Basically it's the zlib license.
|
|||
|
||||
#include "quazipfileinfo.h"
|
||||
|
||||
#define EXTRA_NTFS_MAGIC 0x000Au
|
||||
#define EXTRA_NTFS_TIME_MAGIC 0x0001u
|
||||
|
||||
static QFile::Permissions permissionsFromExternalAttr(quint32 externalAttr) {
|
||||
quint32 uPerm = (externalAttr & 0xFFFF0000u) >> 16;
|
||||
QFile::Permissions perm = 0;
|
||||
|
@ -88,3 +91,88 @@ bool QuaZipFileInfo64::toQuaZipFileInfo(QuaZipFileInfo &info) const
|
|||
info.extra = extra;
|
||||
return noOverflow;
|
||||
}
|
||||
|
||||
static QDateTime getNTFSTime(const QByteArray &extra, int position,
|
||||
int *fineTicks)
|
||||
{
|
||||
QDateTime dateTime;
|
||||
for (int i = 0; i <= extra.size() - 4; ) {
|
||||
unsigned type = static_cast<unsigned>(static_cast<unsigned char>(
|
||||
extra.at(i)))
|
||||
| (static_cast<unsigned>(static_cast<unsigned char>(
|
||||
extra.at(i + 1))) << 8);
|
||||
i += 2;
|
||||
unsigned length = static_cast<unsigned>(static_cast<unsigned char>(
|
||||
extra.at(i)))
|
||||
| (static_cast<unsigned>(static_cast<unsigned char>(
|
||||
extra.at(i + 1))) << 8);
|
||||
i += 2;
|
||||
if (type == EXTRA_NTFS_MAGIC && length >= 32) {
|
||||
i += 4; // reserved
|
||||
while (i <= extra.size() - 4) {
|
||||
unsigned tag = static_cast<unsigned>(
|
||||
static_cast<unsigned char>(extra.at(i)))
|
||||
| (static_cast<unsigned>(
|
||||
static_cast<unsigned char>(extra.at(i + 1)))
|
||||
<< 8);
|
||||
i += 2;
|
||||
int tagsize = static_cast<unsigned>(
|
||||
static_cast<unsigned char>(extra.at(i)))
|
||||
| (static_cast<unsigned>(
|
||||
static_cast<unsigned char>(extra.at(i + 1)))
|
||||
<< 8);
|
||||
i += 2;
|
||||
if (tag == EXTRA_NTFS_TIME_MAGIC && tagsize >= position + 8) {
|
||||
i += position;
|
||||
quint64 mtime = static_cast<quint64>(
|
||||
static_cast<unsigned char>(extra.at(i)))
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 1))) << 8)
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 2))) << 16)
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 3))) << 24)
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 4))) << 32)
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 5))) << 40)
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 6))) << 48)
|
||||
| (static_cast<quint64>(static_cast<unsigned char>(
|
||||
extra.at(i + 7))) << 56);
|
||||
// the NTFS time is measured from 1601 for whatever reason
|
||||
QDateTime base(QDate(1601, 1, 1), QTime(0, 0), Qt::UTC);
|
||||
dateTime = base.addMSecs(mtime / 10000);
|
||||
if (fineTicks != NULL) {
|
||||
*fineTicks = static_cast<int>(mtime % 10000);
|
||||
}
|
||||
i += tagsize - position;
|
||||
} else {
|
||||
i += tagsize;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
i += length;
|
||||
}
|
||||
}
|
||||
if (fineTicks != NULL && dateTime.isNull()) {
|
||||
*fineTicks = 0;
|
||||
}
|
||||
return dateTime;
|
||||
}
|
||||
|
||||
QDateTime QuaZipFileInfo64::getNTFSmTime(int *fineTicks) const
|
||||
{
|
||||
return getNTFSTime(extra, 0, fineTicks);
|
||||
}
|
||||
|
||||
QDateTime QuaZipFileInfo64::getNTFSaTime(int *fineTicks) const
|
||||
{
|
||||
return getNTFSTime(extra, 8, fineTicks);
|
||||
}
|
||||
|
||||
QDateTime QuaZipFileInfo64::getNTFScTime(int *fineTicks) const
|
||||
{
|
||||
return getNTFSTime(extra, 16, fineTicks);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,13 @@ struct QUAZIP_EXPORT QuaZipFileInfo64 {
|
|||
/// Compression method.
|
||||
quint16 method;
|
||||
/// Last modification date and time.
|
||||
/**
|
||||
* This is the time stored in the standard ZIP header. This format only allows
|
||||
* to store time with 2-second precision, so the seconds will always be even
|
||||
* and the milliseconds will always be zero. If you need more precise
|
||||
* date and time, you can try to call the getNTFSmTime() function or
|
||||
* its siblings, provided that the archive itself contains these NTFS times.
|
||||
*/
|
||||
QDateTime dateTime;
|
||||
/// CRC.
|
||||
quint32 crc;
|
||||
|
@ -121,6 +128,45 @@ struct QUAZIP_EXPORT QuaZipFileInfo64 {
|
|||
occured.
|
||||
*/
|
||||
bool toQuaZipFileInfo(QuaZipFileInfo &info) const;
|
||||
/// Returns the NTFS modification time
|
||||
/**
|
||||
* The getNTFS*Time() functions only work if there is an NTFS extra field
|
||||
* present. Otherwise, they all return invalid null timestamps.
|
||||
* @param fineTicks If not NULL, the fractional part of milliseconds returned
|
||||
* there, measured in 100-nanosecond ticks. Will be set to
|
||||
* zero if there is no NTFS extra field.
|
||||
* @sa dateTime
|
||||
* @sa getNTFSaTime()
|
||||
* @sa getNTFScTime()
|
||||
* @return The NTFS modification time, UTC
|
||||
*/
|
||||
QDateTime getNTFSmTime(int *fineTicks = NULL) const;
|
||||
/// Returns the NTFS access time
|
||||
/**
|
||||
* The getNTFS*Time() functions only work if there is an NTFS extra field
|
||||
* present. Otherwise, they all return invalid null timestamps.
|
||||
* @param fineTicks If not NULL, the fractional part of milliseconds returned
|
||||
* there, measured in 100-nanosecond ticks. Will be set to
|
||||
* zero if there is no NTFS extra field.
|
||||
* @sa dateTime
|
||||
* @sa getNTFSmTime()
|
||||
* @sa getNTFScTime()
|
||||
* @return The NTFS access time, UTC
|
||||
*/
|
||||
QDateTime getNTFSaTime(int *fineTicks = NULL) const;
|
||||
/// Returns the NTFS creation time
|
||||
/**
|
||||
* The getNTFS*Time() functions only work if there is an NTFS extra field
|
||||
* present. Otherwise, they all return invalid null timestamps.
|
||||
* @param fineTicks If not NULL, the fractional part of milliseconds returned
|
||||
* there, measured in 100-nanosecond ticks. Will be set to
|
||||
* zero if there is no NTFS extra field.
|
||||
* @sa dateTime
|
||||
* @sa getNTFSmTime()
|
||||
* @sa getNTFSaTime()
|
||||
* @return The NTFS creation time, UTC
|
||||
*/
|
||||
QDateTime getNTFScTime(int *fineTicks = NULL) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue