mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 18:02:56 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
675
sdk/tools/cabman/main.cxx
Normal file
675
sdk/tools/cabman/main.cxx
Normal file
|
@ -0,0 +1,675 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: tools/cabman/main.cxx
|
||||
* PURPOSE: Main program
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* Colin Finck <mail@colinfinck.de>
|
||||
* REVISIONS:
|
||||
* CSH 21/03-2001 Created
|
||||
* CSH 15/08-2003 Made it portable
|
||||
* CF 04/05-2007 Made it compatible with 64-bit operating systems
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "cabman.h"
|
||||
|
||||
|
||||
#if DBG
|
||||
|
||||
ULONG DebugTraceLevel = MIN_TRACE;
|
||||
//ULONG DebugTraceLevel = MID_TRACE;
|
||||
//ULONG DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
char* Pad(char* Str, char PadChar, ULONG Length)
|
||||
/*
|
||||
* FUNCTION: Pads a string with a character to make a given length
|
||||
* ARGUMENTS:
|
||||
* Str = Pointer to string to pad
|
||||
* PadChar = Character to pad with
|
||||
* Length = Disired length of string
|
||||
* RETURNS:
|
||||
* Pointer to string
|
||||
* NOTES:
|
||||
* Str must be at least Length + 1 bytes
|
||||
*/
|
||||
{
|
||||
ULONG Len;
|
||||
|
||||
Len = (ULONG)strlen(Str);
|
||||
|
||||
if (Len < Length)
|
||||
{
|
||||
memcpy(&Str[Length - Len], Str, Len + 1);
|
||||
memset(Str, PadChar, Length - Len);
|
||||
}
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
char* Date2Str(char* Str, USHORT Date)
|
||||
/*
|
||||
* FUNCTION: Converts a DOS style date to a string
|
||||
* ARGUMENTS:
|
||||
* Str = Pointer to destination string
|
||||
* Date = DOS style date
|
||||
* RETURNS:
|
||||
* Pointer to string
|
||||
*/
|
||||
{
|
||||
ULONG dw;
|
||||
|
||||
/* Month */
|
||||
Str[0] = (char)('0' + ((Date & 0x01E0) >> 5) / 10);
|
||||
Str[1] = (char)('0' + ((Date & 0x01E0) >> 5) % 10);
|
||||
Str[2] = '-';
|
||||
/* Day */
|
||||
Str[3] = (char)('0' + (Date & 0x001F) / 10);
|
||||
Str[4] = (char)('0' + (Date & 0x001F) % 10);
|
||||
Str[5] = '-';
|
||||
/* Year */
|
||||
dw = 1980 + ((Date & 0xFE00) >> 9);
|
||||
Str[6] = (char)('0' + dw / 1000); dw %= 1000;
|
||||
Str[7] = (char)('0' + dw / 100); dw %= 100;
|
||||
Str[8] = (char)('0' + dw / 10); dw %= 10;
|
||||
Str[9] = (char)('0' + dw % 10);
|
||||
Str[10] = '\0';
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
char* Time2Str(char* Str, USHORT Time)
|
||||
/*
|
||||
* FUNCTION: Converts a DOS style time to a string
|
||||
* ARGUMENTS:
|
||||
* Str = Pointer to destination string
|
||||
* Time = DOS style time
|
||||
* RETURNS:
|
||||
* Pointer to string
|
||||
*/
|
||||
{
|
||||
bool PM;
|
||||
ULONG Hour;
|
||||
ULONG dw;
|
||||
|
||||
Hour = ((Time & 0xF800) >> 11);
|
||||
PM = (Hour >= 12);
|
||||
Hour %= 12;
|
||||
if (Hour == 0)
|
||||
Hour = 12;
|
||||
|
||||
if (Hour >= 10)
|
||||
Str[0] = (char)('0' + Hour / 10);
|
||||
else Str[0] = ' ';
|
||||
Str[1] = (char)('0' + Hour % 10);
|
||||
Str[2] = ':';
|
||||
/* Minute */
|
||||
Str[3] = (char)('0' + ((Time & 0x07E0) >> 5) / 10);
|
||||
Str[4] = (char)('0' + ((Time & 0x07E0) >> 5) % 10);
|
||||
Str[5] = ':';
|
||||
/* Second */
|
||||
dw = 2 * (Time & 0x001F);
|
||||
Str[6] = (char)('0' + dw / 10);
|
||||
Str[7] = (char)('0' + dw % 10);
|
||||
|
||||
Str[8] = PM? 'p' : 'a';
|
||||
Str[9] = '\0';
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
char* Attr2Str(char* Str, USHORT Attr)
|
||||
/*
|
||||
* FUNCTION: Converts attributes to a string
|
||||
* ARGUMENTS:
|
||||
* Str = Pointer to destination string
|
||||
* Attr = Attributes
|
||||
* RETURNS:
|
||||
* Pointer to string
|
||||
*/
|
||||
{
|
||||
/* Archive */
|
||||
if (Attr & CAB_ATTRIB_ARCHIVE)
|
||||
Str[0] = 'A';
|
||||
else
|
||||
Str[0] = '-';
|
||||
|
||||
/* Hidden */
|
||||
if (Attr & CAB_ATTRIB_HIDDEN)
|
||||
Str[1] = 'H';
|
||||
else
|
||||
Str[1] = '-';
|
||||
|
||||
/* Read only */
|
||||
if (Attr & CAB_ATTRIB_READONLY)
|
||||
Str[2] = 'R';
|
||||
else
|
||||
Str[2] = '-';
|
||||
|
||||
/* System */
|
||||
if (Attr & CAB_ATTRIB_SYSTEM)
|
||||
Str[3] = 'S';
|
||||
else
|
||||
Str[3] = '-';
|
||||
|
||||
Str[4] = '\0';
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
/* CCABManager */
|
||||
|
||||
CCABManager::CCABManager()
|
||||
/*
|
||||
* FUNCTION: Default constructor
|
||||
*/
|
||||
{
|
||||
ProcessAll = false;
|
||||
InfFileOnly = false;
|
||||
Mode = CM_MODE_DISPLAY;
|
||||
FileName[0] = 0;
|
||||
Verbose = false;
|
||||
}
|
||||
|
||||
|
||||
CCABManager::~CCABManager()
|
||||
/*
|
||||
* FUNCTION: Default destructor
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void CCABManager::Usage()
|
||||
/*
|
||||
* FUNCTION: Display usage information on screen
|
||||
*/
|
||||
{
|
||||
printf("ReactOS Cabinet Manager\n\n");
|
||||
printf("CABMAN [-D | -E] [-A] [-L dir] cabinet [filename ...]\n");
|
||||
printf("CABMAN [-M mode] -C dirfile [-I] [-RC file] [-P dir]\n");
|
||||
printf("CABMAN [-M mode] -S cabinet filename [...]\n");
|
||||
printf(" cabinet Cabinet file.\n");
|
||||
printf(" filename Name of the file to add to or extract from the cabinet.\n");
|
||||
printf(" Wild cards and multiple filenames\n");
|
||||
printf(" (separated by blanks) may be used.\n\n");
|
||||
|
||||
printf(" dirfile Name of the directive file to use.\n");
|
||||
|
||||
printf(" -A Process ALL cabinets. Follows cabinet chain\n");
|
||||
printf(" starting in first cabinet mentioned.\n");
|
||||
printf(" -C Create cabinet.\n");
|
||||
printf(" -D Display cabinet directory.\n");
|
||||
printf(" -E Extract files from cabinet.\n");
|
||||
printf(" -I Don't create the cabinet, only the .inf file.\n");
|
||||
printf(" -L dir Location to place extracted or generated files\n");
|
||||
printf(" (default is current directory).\n");
|
||||
printf(" -M mode Specify the compression method to use:\n");
|
||||
printf(" raw - No compression\n");
|
||||
printf(" mszip - MsZip compression (default)\n");
|
||||
printf(" -N Don't create the .inf file, only the cabinet.\n");
|
||||
printf(" -RC Specify file to put in cabinet reserved area\n");
|
||||
printf(" (size must be less than 64KB).\n");
|
||||
printf(" -S Create simple cabinet.\n");
|
||||
printf(" -P dir Files in the .dff are relative to this directory.\n");
|
||||
printf(" -V Verbose mode (prints more messages).\n");
|
||||
}
|
||||
|
||||
bool CCABManager::ParseCmdline(int argc, char* argv[])
|
||||
/*
|
||||
* FUNCTION: Parse command line arguments
|
||||
* ARGUMENTS:
|
||||
* argc = Number of arguments on command line
|
||||
* argv = Pointer to list of command line arguments
|
||||
* RETURNS:
|
||||
* true if command line arguments was successfully parsed, false if not
|
||||
*/
|
||||
{
|
||||
int i;
|
||||
bool ShowUsage;
|
||||
bool FoundCabinet = false;
|
||||
|
||||
ShowUsage = (argc < 2);
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
ProcessAll = true;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
case 'C':
|
||||
Mode = CM_MODE_CREATE;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'D':
|
||||
Mode = CM_MODE_DISPLAY;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
case 'E':
|
||||
Mode = CM_MODE_EXTRACT;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
case 'I':
|
||||
InfFileOnly = true;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'L':
|
||||
if (argv[i][2] == 0)
|
||||
{
|
||||
i++;
|
||||
SetDestinationPath(&argv[i][0]);
|
||||
}
|
||||
else
|
||||
SetDestinationPath(&argv[i][2]);
|
||||
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
// Set the compression codec (only affects compression, not decompression)
|
||||
if(argv[i][2] == 0)
|
||||
{
|
||||
i++;
|
||||
|
||||
if( !SetCompressionCodec(&argv[i][0]) )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !SetCompressionCodec(&argv[i][2]) )
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'N':
|
||||
DontGenerateInf = true;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
switch (argv[i][2])
|
||||
{
|
||||
case 'C': /* File to put in cabinet reserved area */
|
||||
if (argv[i][3] == 0)
|
||||
{
|
||||
i++;
|
||||
if (!SetCabinetReservedFile(&argv[i][0]))
|
||||
{
|
||||
printf("ERROR: Cannot open cabinet reserved area file.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SetCabinetReservedFile(&argv[i][3]))
|
||||
{
|
||||
printf("ERROR: Cannot open cabinet reserved area file.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: Bad parameter %s.\n", argv[i]);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'S':
|
||||
Mode = CM_MODE_CREATE_SIMPLE;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
if (argv[i][2] == 0)
|
||||
{
|
||||
i++;
|
||||
SetFileRelativePath(&argv[i][0]);
|
||||
}
|
||||
else
|
||||
SetFileRelativePath(&argv[i][2]);
|
||||
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
Verbose = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: Bad parameter %s.\n", argv[i]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Mode == CM_MODE_CREATE)
|
||||
{
|
||||
if(FileName[0])
|
||||
{
|
||||
printf("ERROR: You may only specify one directive file!\n");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For creating cabinets, this argument is the path to the directive file
|
||||
strcpy(FileName, argv[i]);
|
||||
}
|
||||
}
|
||||
else if(FoundCabinet)
|
||||
{
|
||||
// For creating simple cabinets, displaying or extracting them, add the argument as a search criteria
|
||||
AddSearchCriteria(argv[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCabinetName(argv[i]);
|
||||
FoundCabinet = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowUsage)
|
||||
{
|
||||
Usage();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Select MsZip by default for creating cabinets
|
||||
if( (Mode == CM_MODE_CREATE || Mode == CM_MODE_CREATE_SIMPLE) && !IsCodecSelected() )
|
||||
SelectCodec(CAB_CODEC_MSZIP);
|
||||
|
||||
// Search criteria (= the filename argument) is necessary for creating a simple cabinet
|
||||
if( Mode == CM_MODE_CREATE_SIMPLE && !HasSearchCriteria())
|
||||
{
|
||||
printf("ERROR: You have to enter input file names!\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CCABManager::CreateCabinet()
|
||||
/*
|
||||
* FUNCTION: Create cabinet
|
||||
*/
|
||||
{
|
||||
ULONG Status;
|
||||
|
||||
Status = Load(FileName);
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
{
|
||||
printf("ERROR: Specified directive file could not be found: %s.\n", FileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
Status = Parse();
|
||||
|
||||
return (Status == CAB_STATUS_SUCCESS ? true : false);
|
||||
}
|
||||
|
||||
bool CCABManager::DisplayCabinet()
|
||||
/*
|
||||
* FUNCTION: Display cabinet contents
|
||||
*/
|
||||
{
|
||||
CAB_SEARCH Search;
|
||||
char Str[20];
|
||||
ULONG FileCount = 0;
|
||||
ULONG ByteCount = 0;
|
||||
|
||||
if (Open() == CAB_STATUS_SUCCESS)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
printf("Cabinet %s\n\n", GetCabinetName());
|
||||
}
|
||||
|
||||
if (FindFirst(&Search) == CAB_STATUS_SUCCESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (Search.File->FileControlID != CAB_FILE_CONTINUED)
|
||||
{
|
||||
printf("%s ", Date2Str(Str, Search.File->FileDate));
|
||||
printf("%s ", Time2Str(Str, Search.File->FileTime));
|
||||
printf("%s ", Attr2Str(Str, Search.File->Attributes));
|
||||
sprintf(Str, "%u", (UINT)Search.File->FileSize);
|
||||
printf("%s ", Pad(Str, ' ', 13));
|
||||
printf("%s\n", Search.FileName);
|
||||
|
||||
FileCount++;
|
||||
ByteCount += Search.File->FileSize;
|
||||
}
|
||||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
DestroySearchCriteria();
|
||||
|
||||
if (FileCount > 0) {
|
||||
if (FileCount == 1)
|
||||
printf(" 1 file ");
|
||||
else
|
||||
{
|
||||
sprintf(Str, "%u", (UINT)FileCount);
|
||||
printf(" %s files ", Pad(Str, ' ', 12));
|
||||
}
|
||||
|
||||
if (ByteCount == 1)
|
||||
printf(" 1 byte\n");
|
||||
else
|
||||
{
|
||||
sprintf(Str, "%u", (UINT)ByteCount);
|
||||
printf("%s bytes\n", Pad(Str, ' ', 12));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There should be at least one file in a cabinet */
|
||||
printf("WARNING: No files in cabinet.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
printf("ERROR: Cannot open file: %s\n", GetCabinetName());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CCABManager::ExtractFromCabinet()
|
||||
/*
|
||||
* FUNCTION: Extract file(s) from cabinet
|
||||
*/
|
||||
{
|
||||
bool bRet = true;
|
||||
CAB_SEARCH Search;
|
||||
ULONG Status;
|
||||
|
||||
if (Open() == CAB_STATUS_SUCCESS)
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
printf("Cabinet %s\n\n", GetCabinetName());
|
||||
}
|
||||
|
||||
if (FindFirst(&Search) == CAB_STATUS_SUCCESS)
|
||||
{
|
||||
do
|
||||
{
|
||||
switch (Status = ExtractFile(Search.FileName))
|
||||
{
|
||||
case CAB_STATUS_SUCCESS:
|
||||
break;
|
||||
|
||||
case CAB_STATUS_INVALID_CAB:
|
||||
printf("ERROR: Cabinet contains errors.\n");
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
case CAB_STATUS_UNSUPPCOMP:
|
||||
printf("ERROR: Cabinet uses unsupported compression type.\n");
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
case CAB_STATUS_CANNOT_WRITE:
|
||||
printf("ERROR: You've run out of free space on the destination volume or the volume is damaged.\n");
|
||||
bRet = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("ERROR: Unspecified error code (%u).\n", (UINT)Status);
|
||||
bRet = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!bRet)
|
||||
break;
|
||||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
|
||||
DestroySearchCriteria();
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
else
|
||||
printf("ERROR: Cannot open file: %s.\n", GetCabinetName());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool CCABManager::Run()
|
||||
/*
|
||||
* FUNCTION: Process cabinet
|
||||
*/
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
printf("ReactOS Cabinet Manager\n\n");
|
||||
}
|
||||
|
||||
switch (Mode)
|
||||
{
|
||||
case CM_MODE_CREATE:
|
||||
return CreateCabinet();
|
||||
|
||||
case CM_MODE_DISPLAY:
|
||||
return DisplayCabinet();
|
||||
|
||||
case CM_MODE_EXTRACT:
|
||||
return ExtractFromCabinet();
|
||||
|
||||
case CM_MODE_CREATE_SIMPLE:
|
||||
return CreateSimpleCabinet();
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Event handlers */
|
||||
|
||||
bool CCABManager::OnOverwrite(PCFFILE File,
|
||||
char* FileName)
|
||||
/*
|
||||
* FUNCTION: Called when extracting a file and it already exists
|
||||
* ARGUMENTS:
|
||||
* File = Pointer to CFFILE for file being extracted
|
||||
* Filename = Pointer to buffer with name of file (full path)
|
||||
* RETURNS
|
||||
* true if the file should be overwritten, false if not
|
||||
*/
|
||||
{
|
||||
if (Mode == CM_MODE_CREATE)
|
||||
return true;
|
||||
|
||||
/* Always overwrite */
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CCABManager::OnExtract(PCFFILE File,
|
||||
char* FileName)
|
||||
/*
|
||||
* FUNCTION: Called just before extracting a file
|
||||
* ARGUMENTS:
|
||||
* File = Pointer to CFFILE for file being extracted
|
||||
* FileName = Pointer to buffer with name of file (full path)
|
||||
*/
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
printf("Extracting %s\n", GetFileName(FileName));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CCABManager::OnDiskChange(char* CabinetName,
|
||||
char* DiskLabel)
|
||||
/*
|
||||
* FUNCTION: Called when a new disk is to be processed
|
||||
* ARGUMENTS:
|
||||
* CabinetName = Pointer to buffer with name of cabinet
|
||||
* DiskLabel = Pointer to buffer with label of disk
|
||||
*/
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
printf("\nChanging to cabinet %s - %s\n\n", CabinetName, DiskLabel);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CCABManager::OnAdd(PCFFILE File,
|
||||
char* FileName)
|
||||
/*
|
||||
* FUNCTION: Called just before adding a file to a cabinet
|
||||
* ARGUMENTS:
|
||||
* File = Pointer to CFFILE for file being added
|
||||
* FileName = Pointer to buffer with name of file (full path)
|
||||
*/
|
||||
{
|
||||
if (Verbose)
|
||||
{
|
||||
printf("Adding %s\n", GetFileName(FileName));
|
||||
}
|
||||
}
|
||||
|
||||
CCABManager CABMgr;
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
/*
|
||||
* FUNCTION: Main entry point
|
||||
* ARGUMENTS:
|
||||
* argc = Number of arguments on command line
|
||||
* argv = Pointer to list of command line arguments
|
||||
*/
|
||||
{
|
||||
bool status = false;
|
||||
|
||||
if (CABMgr.ParseCmdline(argc, argv)) status = CABMgr.Run();
|
||||
|
||||
return (status ? 0 : 1);
|
||||
}
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue