Fixed a bunch of improper timestamp handling, made ZIP timestamping deterministic, added default timestamp

This commit is contained in:
elasota
2020-01-23 02:47:31 -05:00
parent a73d6fe10d
commit a1475d2ee3
11 changed files with 429 additions and 136 deletions

View File

@@ -39,6 +39,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib.vcxproj",
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2gp", "bin2gp\bin2gp.vcxproj", "{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin2gp", "bin2gp\bin2gp.vcxproj", "{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MakeTimestamp", "MakeTimestamp\MakeTimestamp.vcxproj", "{9023DF2F-A33D-485A-B13D-0973348B2F9B}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
@@ -191,6 +193,14 @@ Global
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x64.Build.0 = Release|x64 {D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x64.Build.0 = Release|x64
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x86.ActiveCfg = Release|Win32 {D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x86.ActiveCfg = Release|Win32
{D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x86.Build.0 = Release|Win32 {D7BFE702-0667-4155-9B0B-2A54DF9AE60B}.Release|x86.Build.0 = Release|Win32
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x64.ActiveCfg = Debug|x64
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x64.Build.0 = Debug|x64
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x86.ActiveCfg = Debug|Win32
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Debug|x86.Build.0 = Debug|Win32
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x64.ActiveCfg = Release|x64
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x64.Build.0 = Release|x64
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x86.ActiveCfg = Release|Win32
{9023DF2F-A33D-485A-B13D-0973348B2F9B}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -35,7 +35,7 @@ int64_t GpSystemServices_Win32::GetTime() const
int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32); int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32);
int64_t currentTime64 = (static_cast<int64_t>(currentTime.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(currentTime.dwHighDateTime) << 32); int64_t currentTime64 = (static_cast<int64_t>(currentTime.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(currentTime.dwHighDateTime) << 32);
return currentTime64 - epochStart64; return (currentTime64 - epochStart64) / 10000000;
} }
void GpSystemServices_Win32::GetLocalDateTime(unsigned int &year, unsigned int &month, unsigned int &day, unsigned int &hour, unsigned int &minute, unsigned int &second) const void GpSystemServices_Win32::GetLocalDateTime(unsigned int &year, unsigned int &month, unsigned int &day, unsigned int &hour, unsigned int &minute, unsigned int &second) const

View File

@@ -5,73 +5,79 @@ mkdir ResourceTemp
x64\Release\MiniRez.exe "GliderProData\Glider PRO.r" Packaged\ApplicationResources.gpr x64\Release\MiniRez.exe "GliderProData\Glider PRO.r" Packaged\ApplicationResources.gpr
x64\Release\gpr2gpa.exe Packaged\ApplicationResources.gpr Packaged\ApplicationResources.gpa copy /B /Y NUL Packaged\Empty.txt
x64\Release\FTagData.exe "Packaged\Empty.txt" "DefaultTimestamp.timestamp" "Packaged\ApplicationResources" APPL ozm5 0 0 locked
x64\Release\gpr2gpa.exe Packaged\ApplicationResources Packaged\ApplicationResources.gpa
x64\Release\ConvertColorCursors.exe x64\Release\ConvertColorCursors.exe
x64\Release\hqx2gp.exe "GliderProData\Houses\Art Museum.binhex" "Packaged\Houses\Art Museum" x64\Release\hqx2gp.exe "GliderProData\Houses\Art Museum.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Art Museum"
x64\Release\hqx2gp.exe "GliderProData\Houses\California or Bust!.binhex" "Packaged\Houses\California or Bust!" x64\Release\hqx2gp.exe "GliderProData\Houses\California or Bust!.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\California or Bust!"
x64\Release\hqx2gp.exe "GliderProData\Houses\Castle o' the Air.binhex" "Packaged\Houses\Castle o' the Air" x64\Release\hqx2gp.exe "GliderProData\Houses\Castle o' the Air.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Castle o' the Air"
x64\Release\hqx2gp.exe "GliderProData\Houses\CD Demo House.binhex" "Packaged\Houses\CD Demo House" x64\Release\hqx2gp.exe "GliderProData\Houses\CD Demo House.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\CD Demo House"
x64\Release\hqx2gp.exe "GliderProData\Houses\Davis Station.binhex" "Packaged\Houses\Davis Station" x64\Release\hqx2gp.exe "GliderProData\Houses\Davis Station.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Davis Station"
x64\Release\hqx2gp.exe "GliderProData\Houses\Demo House.binhex" "Packaged\Houses\Demo House" x64\Release\hqx2gp.exe "GliderProData\Houses\Demo House.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Demo House"
x64\Release\hqx2gp.exe "GliderProData\Houses\Empty House.binhex" "Packaged\Houses\Empty House" x64\Release\hqx2gp.exe "GliderProData\Houses\Empty House.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Empty House"
x64\Release\hqx2gp.exe "GliderProData\Houses\Fun House.binhex" "Packaged\Houses\Fun House" x64\Release\hqx2gp.exe "GliderProData\Houses\Fun House.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Fun House"
x64\Release\hqx2gp.exe "GliderProData\Houses\Grand Prix.binhex" "Packaged\Houses\Grand Prix" x64\Release\hqx2gp.exe "GliderProData\Houses\Grand Prix.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Grand Prix"
x64\Release\hqx2gp.exe "GliderProData\Houses\ImagineHouse PRO II.binhex" "Packaged\Houses\ImagineHouse PRO II" x64\Release\hqx2gp.exe "GliderProData\Houses\ImagineHouse PRO II.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\ImagineHouse PRO II"
x64\Release\hqx2gp.exe "GliderProData\Houses\In The Mirror.binhex" "Packaged\Houses\In The Mirror" x64\Release\hqx2gp.exe "GliderProData\Houses\In The Mirror.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\In The Mirror"
x64\Release\hqx2gp.exe "GliderProData\Houses\Land of Illusion.binhex" "Packaged\Houses\Land of Illusion" x64\Release\hqx2gp.exe "GliderProData\Houses\Land of Illusion.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Land of Illusion"
x64\Release\hqx2gp.exe "GliderProData\Houses\Leviathan.binhex" "Packaged\Houses\Leviathan" x64\Release\hqx2gp.exe "GliderProData\Houses\Leviathan.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Leviathan"
x64\Release\hqx2gp.exe "GliderProData\Houses\Metropolis.binhex" "Packaged\Houses\Metropolis" x64\Release\hqx2gp.exe "GliderProData\Houses\Metropolis.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Metropolis"
x64\Release\hqx2gp.exe "GliderProData\Houses\Nemo's Market.binhex" "Packaged\Houses\Nemo's Market" x64\Release\hqx2gp.exe "GliderProData\Houses\Nemo's Market.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Nemo's Market"
x64\Release\hqx2gp.exe "GliderProData\Houses\Rainbow's End.binhex" "Packaged\Houses\Rainbow's End" x64\Release\hqx2gp.exe "GliderProData\Houses\Rainbow's End.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Rainbow's End"
x64\Release\hqx2gp.exe "GliderProData\Houses\Sampler.binhex" "Packaged\Houses\Sampler" x64\Release\hqx2gp.exe "GliderProData\Houses\Sampler.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Sampler"
x64\Release\hqx2gp.exe "GliderProData\Houses\Slumberland.binhex" "Packaged\Houses\Slumberland" x64\Release\hqx2gp.exe "GliderProData\Houses\Slumberland.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Slumberland"
x64\Release\hqx2gp.exe "GliderProData\Houses\SpacePods.binhex" "Packaged\Houses\SpacePods" x64\Release\hqx2gp.exe "GliderProData\Houses\SpacePods.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\SpacePods"
x64\Release\hqx2gp.exe "GliderProData\Houses\Teddy World.binhex" "Packaged\Houses\Teddy World" x64\Release\hqx2gp.exe "GliderProData\Houses\Teddy World.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Teddy World"
x64\Release\hqx2gp.exe "GliderProData\Houses\The Asylum Pro.binhex" "Packaged\Houses\The Asylum Pro" x64\Release\hqx2gp.exe "GliderProData\Houses\The Asylum Pro.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\The Asylum Pro"
x64\Release\hqx2gp.exe "GliderProData\Houses\Titanic.binhex" "Packaged\Houses\Titanic" x64\Release\hqx2gp.exe "GliderProData\Houses\Titanic.binhex" "DefaultTimestamp.timestamp" "Packaged\Houses\Titanic"
x64\Release\gpr2gpa.exe "Packaged\Houses\Art Museum.gpr" "Packaged\Houses\Art Museum.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Art Museum" "Packaged\Houses\Art Museum.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\California or Bust!.gpr" "Packaged\Houses\California or Bust!.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\California or Bust!" "Packaged\Houses\California or Bust!.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Castle o' the Air.gpr" "Packaged\Houses\Castle o' the Air.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Castle o' the Air" "Packaged\Houses\Castle o' the Air.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\CD Demo House.gpr" "Packaged\Houses\CD Demo House.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\CD Demo House" "Packaged\Houses\CD Demo House.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Davis Station.gpr" "Packaged\Houses\Davis Station.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Davis Station" "Packaged\Houses\Davis Station.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Demo House.gpr" "Packaged\Houses\Demo House.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Demo House" "Packaged\Houses\Demo House.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Empty House.gpr" "Packaged\Houses\Empty House.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Empty House" "Packaged\Houses\Empty House.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Fun House.gpr" "Packaged\Houses\Fun House.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Fun House" "Packaged\Houses\Fun House.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Grand Prix.gpr" "Packaged\Houses\Grand Prix.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Grand Prix" "Packaged\Houses\Grand Prix.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\ImagineHouse PRO II.gpr" "Packaged\Houses\ImagineHouse PRO II.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\ImagineHouse PRO II" "Packaged\Houses\ImagineHouse PRO II.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\In The Mirror.gpr" "Packaged\Houses\In The Mirror.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\In The Mirror" "Packaged\Houses\In The Mirror.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Land of Illusion.gpr" "Packaged\Houses\Land of Illusion.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Land of Illusion" "Packaged\Houses\Land of Illusion.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Leviathan.gpr" "Packaged\Houses\Leviathan.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Leviathan" "Packaged\Houses\Leviathan.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Metropolis.gpr" "Packaged\Houses\Metropolis.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Metropolis" "Packaged\Houses\Metropolis.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Nemo's Market.gpr" "Packaged\Houses\Nemo's Market.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Nemo's Market" "Packaged\Houses\Nemo's Market.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Rainbow's End.gpr" "Packaged\Houses\Rainbow's End.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Rainbow's End" "Packaged\Houses\Rainbow's End.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Sampler.gpr" "Packaged\Houses\Sampler.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Sampler" "Packaged\Houses\Sampler.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Slumberland.gpr" "Packaged\Houses\Slumberland.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Slumberland" "Packaged\Houses\Slumberland.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\SpacePods.gpr" "Packaged\Houses\SpacePods.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\SpacePods" "Packaged\Houses\SpacePods.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Teddy World.gpr" "Packaged\Houses\Teddy World.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Teddy World" "Packaged\Houses\Teddy World.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\The Asylum Pro.gpr" "Packaged\Houses\The Asylum Pro.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\The Asylum Pro" "Packaged\Houses\The Asylum Pro.gpa"
x64\Release\gpr2gpa.exe "Packaged\Houses\Titanic.gpr" "Packaged\Houses\Titanic.gpa" x64\Release\gpr2gpa.exe "Packaged\Houses\Titanic" "Packaged\Houses\Titanic.gpa"
x64\Release\FTagData.exe "GliderProData\Houses\Art Museum.mov", "Packaged\Houses\Art Museum.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Art Museum.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Art Museum.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Castle o' the Air.mov", "Packaged\Houses\Castle o' the Air.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Castle o' the Air.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Castle o' the Air.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\CD Demo House.mov", "Packaged\Houses\CD Demo House.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\CD Demo House.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\CD Demo House.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Davis Station.mov", "Packaged\Houses\Davis Station.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Davis Station.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Davis Station.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Demo House.mov", "Packaged\Houses\Demo House.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Demo House.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Demo House.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Grand Prix.mov", "Packaged\Houses\Grand Prix.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Grand Prix.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Grand Prix.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\ImagineHouse PRO II.mov", "Packaged\Houses\ImagineHouse PRO II.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\ImagineHouse PRO II.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\ImagineHouse PRO II.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Land of Illusion.mov", "Packaged\Houses\Land of Illusion.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Land of Illusion.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Land of Illusion.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Leviathan.mov", "Packaged\Houses\Leviathan.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Leviathan.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Leviathan.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Nemo's Market.mov", "Packaged\Houses\Nemo's Market.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Nemo's Market.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Nemo's Market.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Rainbow's End.mov", "Packaged\Houses\Rainbow's End.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Rainbow's End.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Rainbow's End.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Slumberland.mov", "Packaged\Houses\Slumberland.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Slumberland.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Slumberland.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\SpacePods.mov", "Packaged\Houses\SpacePods.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\SpacePods.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\SpacePods.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Teddy World.mov", "Packaged\Houses\Teddy World.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Teddy World.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Teddy World.mov" MooV ozm5 0 0 locked
x64\Release\FTagData.exe "GliderProData\Houses\Titanic.mov", "Packaged\Houses\Titanic.mov" MooV ozm5 0 0 locked x64\Release\FTagData.exe "GliderProData\Houses\Titanic.mov" "DefaultTimestamp.timestamp" "Packaged\Houses\Titanic.mov" MooV ozm5 0 0 locked
del /Q Packaged\Houses\*.gpr del /Q Packaged\Houses\*.gpr
del /Q Packaged\ApplicationResources.gpr del /Q Packaged\ApplicationResources.gpr
del /Q Packaged\ApplicationResources.gpf
del /Q Packaged\ApplicationResources.gpd
del /Q Packaged\Empty.txt
pause pause

BIN
DefaultTimestamp.timestamp Normal file

Binary file not shown.

View File

@@ -5,56 +5,55 @@
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
if (argc < 7) if (argc < 8)
{ {
fprintf(stderr, "FTagData <input> <output> <file type ID> <file creator ID> <x pos> <y pos> [flags]"); fprintf(stderr, "FTagData <input> <timestamp> <output> <file type ID> <file creator ID> <x pos> <y pos> [flags]");
return -1; return -1;
} }
std::string inPath = argv[1]; std::string inPath = argv[1];
std::string outPath = argv[2]; std::string timestampPath = argv[2];
std::string outPath = argv[3];
if (strlen(argv[3]) != 4) if (strlen(argv[4]) != 4)
{ {
fprintf(stderr, "File type ID must be 4 characters"); fprintf(stderr, "File type ID must be 4 characters");
return -2; return -2;
} }
if (strlen(argv[4]) != 4) if (strlen(argv[5]) != 4)
{ {
fprintf(stderr, "File creator ID must be 4 characters"); fprintf(stderr, "File creator ID must be 4 characters");
return -3; return -3;
} }
FILETIME currentTime; FILE *tsF = nullptr;
GetSystemTimeAsFileTime(&currentTime); errno_t ferr = fopen_s(&tsF, timestampPath.c_str(), "rb");
int64_t timestamp = 0;
SYSTEMTIME epochStart; if (!ferr)
epochStart.wYear = 1904; {
epochStart.wMonth = 1; uint8_t encodedTimestamp[8];
epochStart.wDayOfWeek = 5; if (fread(encodedTimestamp, 1, 8, tsF) != 8)
epochStart.wDay = 1; {
epochStart.wHour = 0; fprintf(stderr, "Error reading timestamp file");
epochStart.wMinute = 0; return -1;
epochStart.wSecond = 0; }
epochStart.wMilliseconds = 0;
FILETIME epochStartFT; for (int i = 0; i < 8; i++)
SystemTimeToFileTime(&epochStart, &epochStartFT); timestamp |= static_cast<int64_t>(encodedTimestamp[i]) << (i * 8);
int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32); fclose(tsF);
int64_t currentTime64 = (static_cast<int64_t>(currentTime.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(currentTime.dwHighDateTime) << 32); }
int64_t timeDelta = (currentTime64 - epochStart64) / 10000000;
PortabilityLayer::MacFileProperties mfp; PortabilityLayer::MacFileProperties mfp;
memcpy(mfp.m_fileType, argv[3], 4); memcpy(mfp.m_fileType, argv[4], 4);
memcpy(mfp.m_fileCreator, argv[4], 4); memcpy(mfp.m_fileCreator, argv[5], 4);
mfp.m_xPos = atoi(argv[5]); mfp.m_xPos = atoi(argv[6]);
mfp.m_yPos = atoi(argv[6]); mfp.m_yPos = atoi(argv[7]);
mfp.m_finderFlags = 0; mfp.m_finderFlags = 0;
mfp.m_protected = 0; mfp.m_protected = 0;
mfp.m_modifiedDate = mfp.m_creationDate = static_cast<uint32_t>(timeDelta & 0xffffffff); mfp.m_modifiedDate = mfp.m_creationDate = timestamp;
for (int i = 7; i < argc; i++) for (int i = 7; i < argc; i++)
{ {

View File

@@ -0,0 +1,54 @@
#include <Windows.h>
#include <stdio.h>
#include <stdint.h>
int main(int argc, const char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Usage: MakeTimestamp <output.ts>\n");
fprintf(stderr, "Outputs the current timestamp in 1904 epoch format");
return -1;
}
SYSTEMTIME epochStart;
epochStart.wYear = 1904;
epochStart.wMonth = 1;
epochStart.wDayOfWeek = 5;
epochStart.wDay = 1;
epochStart.wHour = 0;
epochStart.wMinute = 0;
epochStart.wSecond = 0;
epochStart.wMilliseconds = 0;
FILETIME epochStartFT;
if (!SystemTimeToFileTime(&epochStart, &epochStartFT))
return 0;
SYSTEMTIME localTime;
GetLocalTime(&localTime);
FILETIME localTimeFT;
SystemTimeToFileTime(&localTime, &localTimeFT);
int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32);
int64_t currentTime64 = (static_cast<int64_t>(localTimeFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(localTimeFT.dwHighDateTime) << 32);
int64_t timeDelta = (currentTime64 - epochStart64) / 10000000;
FILE *f = nullptr;
if (fopen_s(&f, argv[1], "wb"))
{
fprintf(stderr, "Error opening output file");
return -1;
}
uint8_t encodedTimestamp[8];
for (int i = 0; i < 8; i++)
encodedTimestamp[i] = static_cast<uint8_t>((timeDelta >> (i * 8)) & 0xff);
fwrite(encodedTimestamp, 8, 1, f);
fclose(f);
return 0;
}

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{9023DF2F-A33D-485A-B13D-0973348B2F9B}</ProjectGuid>
<RootNamespace>MakeTimestamp</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="MakeTimestamp.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PortabilityLayer\PortabilityLayer.vcxproj">
<Project>{6ec62b0f-9353-40a4-a510-3788f1368b33}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="MakeTimestamp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@@ -29,9 +29,6 @@ namespace PortabilityLayer
uint8_t m_protected; uint8_t m_protected;
int64_t m_creationDate; int64_t m_creationDate;
int64_t m_modifiedDate; int64_t m_modifiedDate;
void Serialize(void *buffer) const;
void Deserialize(const void *buffer);
}; };
struct MacFilePropertiesSerialized struct MacFilePropertiesSerialized

View File

@@ -5,6 +5,7 @@
#include "QDPictDecoder.h" #include "QDPictDecoder.h"
#include "QDPictEmitContext.h" #include "QDPictEmitContext.h"
#include "QDPictEmitScanlineParameters.h" #include "QDPictEmitScanlineParameters.h"
#include "MacFileInfo.h"
#include "ResourceFile.h" #include "ResourceFile.h"
#include "ResourceCompiledTypeList.h" #include "ResourceCompiledTypeList.h"
#include "SharedTypes.h" #include "SharedTypes.h"
@@ -93,7 +94,59 @@ bool TryDeflate(const std::vector<uint8_t> &uncompressed, std::vector<uint8_t> &
return true; return true;
} }
void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries) void ConvertToMSDOSTimestamp(int64_t timestamp, uint16_t &msdosDate, uint16_t &msdosTime)
{
SYSTEMTIME epochStart;
epochStart.wYear = 1904;
epochStart.wMonth = 1;
epochStart.wDayOfWeek = 5;
epochStart.wDay = 1;
epochStart.wHour = 0;
epochStart.wMinute = 0;
epochStart.wSecond = 0;
epochStart.wMilliseconds = 0;
FILETIME epochStartFT;
SystemTimeToFileTime(&epochStart, &epochStartFT);
int64_t epochStart64 = (static_cast<int64_t>(epochStartFT.dwLowDateTime) & 0xffffffff) | (static_cast<int64_t>(epochStartFT.dwHighDateTime) << 32);
int64_t offsetDate64 = (epochStart64 + timestamp * 10000000);
FILETIME timestampFT;
timestampFT.dwLowDateTime = static_cast<DWORD>(offsetDate64 & 0xffffffff);
timestampFT.dwHighDateTime = static_cast<DWORD>((offsetDate64 >> 32) & 0xffffffff);
// We could use FileTimeToDosDateTime but we want to clamp
SYSTEMTIME timestampST;
FileTimeToSystemTime(&timestampFT, &timestampST);
DWORD yearsSince1980 = timestampST.wYear - 1980;
if (yearsSince1980 < 0)
{
// Time machine
yearsSince1980 = 0;
timestampST.wSecond = 0;
timestampST.wMinute = 0;
timestampST.wHour = 0;
timestampST.wDay = 1;
timestampST.wMonth = 1;
}
else if (yearsSince1980 > 127)
{
// I was promised flying cars, but it's 2107 and you're still flying paper airplanes...
yearsSince1980 = 127;
timestampST.wSecond = 59;
timestampST.wMinute = 59;
timestampST.wHour = 23;
timestampST.wDay = 31;
timestampST.wMonth = 12;
}
msdosTime = (timestampST.wSecond / 2) | (timestampST.wMinute << 5) | (timestampST.wHour << 11);
msdosDate = timestampST.wDay | (timestampST.wMonth << 5) | (yearsSince1980 << 9);
}
void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries, const PortabilityLayer::MacFileProperties &mfp)
{ {
FILE *outF = nullptr; FILE *outF = nullptr;
if (fopen_s(&outF, path, "wb")) if (fopen_s(&outF, path, "wb"))
@@ -102,41 +155,10 @@ void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries)
return; return;
} }
SYSTEMTIME localTime; uint16_t msdosModificationTime = 0;
GetLocalTime(&localTime); uint16_t msdosModificationDate = 0;
DWORD yearsSince1980 = localTime.wYear - 1980; ConvertToMSDOSTimestamp(mfp.m_modifiedDate, msdosModificationDate, msdosModificationTime);
if (yearsSince1980 < 0)
{
// Time machine
yearsSince1980 = 0;
localTime.wSecond = 0;
localTime.wMinute = 0;
localTime.wHour = 0;
localTime.wDay = 1;
localTime.wMonth = 1;
}
else if (yearsSince1980 > 127)
{
// Original author is either dead or cryofrozen
yearsSince1980 = 127;
localTime.wSecond = 59;
localTime.wMinute = 59;
localTime.wHour = 23;
localTime.wDay = 31;
localTime.wMonth = 12;
}
uint16_t msdosTime = 0;
uint16_t msdosDate = 0;
msdosTime |= localTime.wSecond / 2;
msdosTime |= (localTime.wMinute << 5);
msdosTime |= (localTime.wHour << 11);
msdosDate |= localTime.wDay;
msdosDate |= (localTime.wMonth << 5);
msdosDate |= (yearsSince1980 << 9);
std::vector<PortabilityLayer::ZipCentralDirectoryFileHeader> cdirRecords; std::vector<PortabilityLayer::ZipCentralDirectoryFileHeader> cdirRecords;
@@ -162,8 +184,8 @@ void ExportZipFile(const char *path, const std::vector<PlannedEntry> &entries)
cdirHeader.m_versionRequired = PortabilityLayer::ZipConstants::kStoredRequiredVersion; cdirHeader.m_versionRequired = PortabilityLayer::ZipConstants::kStoredRequiredVersion;
cdirHeader.m_flags = 0; cdirHeader.m_flags = 0;
cdirHeader.m_method = isCompressed ? PortabilityLayer::ZipConstants::kDeflatedMethod : PortabilityLayer::ZipConstants::kStoredMethod; cdirHeader.m_method = isCompressed ? PortabilityLayer::ZipConstants::kDeflatedMethod : PortabilityLayer::ZipConstants::kStoredMethod;
cdirHeader.m_modificationTime = msdosTime; cdirHeader.m_modificationTime = msdosModificationTime;
cdirHeader.m_modificationDate = msdosDate; cdirHeader.m_modificationDate = msdosModificationDate;
cdirHeader.m_crc = 0; cdirHeader.m_crc = 0;
if (entry.m_isDirectory) if (entry.m_isDirectory)
@@ -717,17 +739,38 @@ int main(int argc, const char **argv)
{ {
if (argc != 3) if (argc != 3)
{ {
fprintf(stderr, "Usage: gpr2gpa <input.gpr> <output.gpa>"); fprintf(stderr, "Usage: gpr2gpa <prefix> <output.gpa>");
return -1; return -1;
} }
std::string base = argv[1];
std::string metadataPath = base + ".gpf";
std::string resPath = base + ".gpr";
FILE *inF = nullptr; FILE *inF = nullptr;
if (fopen_s(&inF, argv[1], "rb")) if (fopen_s(&inF, resPath.c_str(), "rb"))
{ {
fprintf(stderr, "Error opening input file"); fprintf(stderr, "Error opening input file");
return -1; return -1;
} }
FILE *metaF = nullptr;
if (fopen_s(&metaF, metadataPath.c_str(), "rb"))
{
fprintf(stderr, "Error opening metadata file");
return -1;
}
PortabilityLayer::MacFilePropertiesSerialized mfpSerialized;
if (fread(mfpSerialized.m_data, 1, PortabilityLayer::MacFilePropertiesSerialized::kSize, metaF) != PortabilityLayer::MacFilePropertiesSerialized::kSize)
{
fprintf(stderr, "Error reading metadata");
return -1;
}
PortabilityLayer::MacFileProperties mfp;
mfpSerialized.Deserialize(mfp);
PortabilityLayer::CFileStream cfs(inF); PortabilityLayer::CFileStream cfs(inF);
PortabilityLayer::ResourceFile *resFile = PortabilityLayer::ResourceFile::Create(); PortabilityLayer::ResourceFile *resFile = PortabilityLayer::ResourceFile::Create();
@@ -808,7 +851,7 @@ int main(int argc, const char **argv)
} }
} }
ExportZipFile(argv[2], contents); ExportZipFile(argv[2], contents, mfp);
resFile->Destroy(); resFile->Destroy();

View File

@@ -34,9 +34,9 @@ using namespace PortabilityLayer;
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
if (argc != 3) if (argc != 4)
{ {
fprintf(stderr, "Usage: hqx2gp <input.hqx> <output>"); fprintf(stderr, "Usage: hqx2gp <input.hqx> <input.ts> <output>");
return -1; return -1;
} }
@@ -54,18 +54,52 @@ int main(int argc, const char **argv)
return -1; return -1;
} }
#ifdef _CRT_INSECURE_DEPRECATE
FILE *tsF = nullptr;
if (fopen_s(&tsF, argv[2], "rb"))
tsF = nullptr;
#else
FILE *tsF = fopen(argv[2], "rb");
#endif
if (!tsF)
{
fprintf(stderr, "Could not open timestamp file");
return -1;
}
int64_t timestamp = 0;
{
uint8_t encodedTimestamp[8];
if (fread(encodedTimestamp, 1, 8, tsF) != 8)
{
fprintf(stderr, "Error reading timestamp file");
return -1;
}
for (int i = 0; i < 8; i++)
timestamp |= static_cast<int64_t>(encodedTimestamp[i]) << (i * 8);
}
fclose(tsF);
CFileStream fs(f, true, false, true); CFileStream fs(f, true, false, true);
ScopedPtr<MacFileMem> memFile = BinHex4::LoadHQX(&fs); ScopedPtr<MacFileMem> memFile = BinHex4::LoadHQX(&fs);
fs.Close(); fs.Close();
std::string fname = argv[2]; std::string fname = argv[3];
const char* extensions[] = { ".gpf", ".gpr", ".gpd", ".gpc" }; const char* extensions[] = { ".gpf", ".gpr", ".gpd", ".gpc" };
MacFileProperties mfp = memFile->FileInfo().m_properties;
mfp.m_creationDate = mfp.m_modifiedDate = timestamp;
MacFilePropertiesSerialized sp; MacFilePropertiesSerialized sp;
sp.Serialize(memFile->FileInfo().m_properties); sp.Serialize(mfp);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {