mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 01:03:08 +00:00
Cabman is now a build tool. So we can remove this copy.
svn path=/trunk/; revision=6820
This commit is contained in:
parent
13347e7de3
commit
d9cd4fb435
15 changed files with 0 additions and 5345 deletions
|
@ -1,6 +0,0 @@
|
|||
*.o
|
||||
*.d
|
||||
*.exe
|
||||
*.coff
|
||||
*.sym
|
||||
*.map
|
File diff suppressed because it is too large
Load diff
|
@ -1,431 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/cabinet.h
|
||||
* PURPOSE: Cabinet definitions
|
||||
*/
|
||||
#ifndef __CABINET_H
|
||||
#define __CABINET_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* Debugging */
|
||||
|
||||
#define DBG
|
||||
|
||||
#define NORMAL_MASK 0x000000FF
|
||||
#define SPECIAL_MASK 0xFFFFFF00
|
||||
#define MIN_TRACE 0x00000001
|
||||
#define MID_TRACE 0x00000002
|
||||
#define MAX_TRACE 0x00000003
|
||||
|
||||
#define DEBUG_MEMORY 0x00000100
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
extern DWORD DebugTraceLevel;
|
||||
|
||||
#define DPRINT(_t_, _x_) \
|
||||
if (((DebugTraceLevel & NORMAL_MASK) >= _t_) || \
|
||||
((DebugTraceLevel & _t_) > NORMAL_MASK)) { \
|
||||
printf("(%s:%d)(%s) ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
printf _x_ ; \
|
||||
}
|
||||
|
||||
#define ASSERT(_b_) { \
|
||||
if (!(_b_)) { \
|
||||
printf("(%s:%d)(%s) ASSERTION: ", __FILE__, __LINE__, __FUNCTION__); \
|
||||
printf(#_b_); \
|
||||
ExitProcess(0); \
|
||||
} \
|
||||
}
|
||||
|
||||
#else /* DBG */
|
||||
|
||||
#define DPRINT(_t_, _x_)
|
||||
|
||||
#define ASSERT(_x_)
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
/* Macros */
|
||||
|
||||
#ifndef CopyMemory
|
||||
#define CopyMemory(destination, source, length) memcpy(destination, source, length)
|
||||
#endif /* CopyMemory */
|
||||
|
||||
/* Cabinet constants */
|
||||
|
||||
#define CAB_SIGNATURE 0x4643534D // "MSCF"
|
||||
#define CAB_VERSION 0x0103
|
||||
#define CAB_BLOCKSIZE 32768
|
||||
|
||||
#define CAB_COMP_MASK 0x00FF
|
||||
#define CAB_COMP_NONE 0x0000
|
||||
#define CAB_COMP_MSZIP 0x0001
|
||||
#define CAB_COMP_QUANTUM 0x0002
|
||||
#define CAB_COMP_LZX 0x0003
|
||||
|
||||
#define CAB_FLAG_HASPREV 0x0001
|
||||
#define CAB_FLAG_HASNEXT 0x0002
|
||||
#define CAB_FLAG_RESERVE 0x0004
|
||||
|
||||
#define CAB_ATTRIB_READONLY 0x0001
|
||||
#define CAB_ATTRIB_HIDDEN 0x0002
|
||||
#define CAB_ATTRIB_SYSTEM 0x0004
|
||||
#define CAB_ATTRIB_VOLUME 0x0008
|
||||
#define CAB_ATTRIB_DIRECTORY 0x0010
|
||||
#define CAB_ATTRIB_ARCHIVE 0x0020
|
||||
#define CAB_ATTRIB_EXECUTE 0x0040
|
||||
#define CAB_ATTRIB_UTF_NAME 0x0080
|
||||
|
||||
#define CAB_FILE_MAX_FOLDER 0xFFFC
|
||||
#define CAB_FILE_CONTINUED 0xFFFD
|
||||
#define CAB_FILE_SPLIT 0xFFFE
|
||||
#define CAB_FILE_PREV_NEXT 0xFFFF
|
||||
|
||||
|
||||
/* Cabinet structures */
|
||||
|
||||
typedef struct _CFHEADER
|
||||
{
|
||||
DWORD Signature; // File signature 'MSCF' (CAB_SIGNATURE)
|
||||
DWORD Reserved1; // Reserved field
|
||||
DWORD CabinetSize; // Cabinet file size
|
||||
DWORD Reserved2; // Reserved field
|
||||
DWORD FileTableOffset; // Offset of first CFFILE
|
||||
DWORD Reserved3; // Reserved field
|
||||
WORD Version; // Cabinet version (CAB_VERSION)
|
||||
WORD FolderCount; // Number of folders
|
||||
WORD FileCount; // Number of files
|
||||
WORD Flags; // Cabinet flags (CAB_FLAG_*)
|
||||
WORD SetID; // Cabinet set id
|
||||
WORD CabinetNumber; // Zero-based cabinet number
|
||||
/* Optional fields (depends on Flags)
|
||||
WORD CabinetResSize // Per-cabinet reserved area size
|
||||
CHAR FolderResSize // Per-folder reserved area size
|
||||
CHAR FileResSize // Per-file reserved area size
|
||||
CHAR CabinetReserved[] // Per-cabinet reserved area
|
||||
CHAR CabinetPrev[] // Name of previous cabinet file
|
||||
CHAR DiskPrev[] // Name of previous disk
|
||||
CHAR CabinetNext[] // Name of next cabinet file
|
||||
CHAR DiskNext[] // Name of next disk
|
||||
*/
|
||||
} CFHEADER, *PCFHEADER;
|
||||
|
||||
|
||||
typedef struct _CFFOLDER
|
||||
{
|
||||
DWORD DataOffset; // Absolute offset of first CFDATA block in this folder
|
||||
WORD DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet
|
||||
WORD CompressionType; // Type of compression used for all CFDATA blocks in this folder
|
||||
/* Optional fields (depends on Flags)
|
||||
CHAR FolderReserved[] // Per-folder reserved area
|
||||
*/
|
||||
} CFFOLDER, *PCFFOLDER;
|
||||
|
||||
|
||||
typedef struct _CFFILE
|
||||
{
|
||||
DWORD FileSize; // Uncompressed file size in bytes
|
||||
DWORD FileOffset; // Uncompressed offset of file in the folder
|
||||
WORD FileControlID; // File control ID (CAB_FILE_*)
|
||||
WORD FileDate; // File date stamp, as used by DOS
|
||||
WORD FileTime; // File time stamp, as used by DOS
|
||||
WORD Attributes; // File attributes (CAB_ATTRIB_*)
|
||||
/* After this is the NULL terminated filename */
|
||||
} CFFILE, *PCFFILE;
|
||||
|
||||
|
||||
typedef struct _CFDATA
|
||||
{
|
||||
DWORD Checksum; // Checksum of CFDATA entry
|
||||
WORD CompSize; // Number of compressed bytes in this block
|
||||
WORD UncompSize; // Number of uncompressed bytes in this block
|
||||
/* Optional fields (depends on Flags)
|
||||
CHAR DataReserved[] // Per-datablock reserved area
|
||||
*/
|
||||
} CFDATA, *PCFDATA;
|
||||
|
||||
typedef struct _CFDATA_NODE
|
||||
{
|
||||
struct _CFDATA_NODE *Next;
|
||||
struct _CFDATA_NODE *Prev;
|
||||
DWORD ScratchFilePosition; // Absolute offset in scratch file
|
||||
DWORD AbsoluteOffset; // Absolute offset in cabinet
|
||||
DWORD UncompOffset; // Uncompressed offset in folder
|
||||
CFDATA Data;
|
||||
} CFDATA_NODE, *PCFDATA_NODE;
|
||||
|
||||
typedef struct _CFFOLDER_NODE
|
||||
{
|
||||
struct _CFFOLDER_NODE *Next;
|
||||
struct _CFFOLDER_NODE *Prev;
|
||||
DWORD UncompOffset; // File size accumulator
|
||||
DWORD AbsoluteOffset;
|
||||
DWORD TotalFolderSize; // Total size of folder in current disk
|
||||
PCFDATA_NODE DataListHead;
|
||||
PCFDATA_NODE DataListTail;
|
||||
DWORD Index;
|
||||
BOOL Commit; // TRUE if the folder should be committed
|
||||
BOOL Delete; // TRUE if marked for deletion
|
||||
CFFOLDER Folder;
|
||||
} CFFOLDER_NODE, *PCFFOLDER_NODE;
|
||||
|
||||
typedef struct _CFFILE_NODE
|
||||
{
|
||||
struct _CFFILE_NODE *Next;
|
||||
struct _CFFILE_NODE *Prev;
|
||||
CFFILE File;
|
||||
LPTSTR FileName;
|
||||
PCFDATA_NODE DataBlock; // First data block of file. NULL if not known
|
||||
BOOL Commit; // TRUE if the file data should be committed
|
||||
BOOL Delete; // TRUE if marked for deletion
|
||||
PCFFOLDER_NODE FolderNode; // Folder this file belong to
|
||||
} CFFILE_NODE, *PCFFILE_NODE;
|
||||
|
||||
|
||||
typedef struct _CAB_SEARCH
|
||||
{
|
||||
TCHAR Search[MAX_PATH]; // Search criteria
|
||||
PCFFILE_NODE Next; // Pointer to next node
|
||||
PCFFILE File; // Pointer to current CFFILE
|
||||
LPTSTR FileName; // Current filename
|
||||
} CAB_SEARCH, *PCAB_SEARCH;
|
||||
|
||||
|
||||
/* Constants */
|
||||
|
||||
/* Status codes */
|
||||
#define CAB_STATUS_SUCCESS 0x00000000
|
||||
#define CAB_STATUS_FAILURE 0x00000001
|
||||
#define CAB_STATUS_NOMEMORY 0x00000002
|
||||
#define CAB_STATUS_CANNOT_OPEN 0x00000003
|
||||
#define CAB_STATUS_CANNOT_CREATE 0x00000004
|
||||
#define CAB_STATUS_CANNOT_READ 0x00000005
|
||||
#define CAB_STATUS_CANNOT_WRITE 0x00000006
|
||||
#define CAB_STATUS_FILE_EXISTS 0x00000007
|
||||
#define CAB_STATUS_INVALID_CAB 0x00000008
|
||||
#define CAB_STATUS_NOFILE 0x00000009
|
||||
#define CAB_STATUS_UNSUPPCOMP 0x0000000A
|
||||
|
||||
|
||||
|
||||
/* Codecs */
|
||||
|
||||
class CCABCodec {
|
||||
public:
|
||||
/* Default constructor */
|
||||
CCABCodec() {};
|
||||
/* Default destructor */
|
||||
virtual ~CCABCodec() {};
|
||||
/* Compresses a data block */
|
||||
virtual ULONG Compress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength) = 0;
|
||||
/* Uncompresses a data block */
|
||||
virtual ULONG Uncompress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength) = 0;
|
||||
};
|
||||
|
||||
|
||||
/* Codec status codes */
|
||||
#define CS_SUCCESS 0x0000 /* All data consumed */
|
||||
#define CS_NOMEMORY 0x0001 /* Not enough free memory */
|
||||
#define CS_BADSTREAM 0x0002 /* Bad data stream */
|
||||
|
||||
|
||||
/* Codec indentifiers */
|
||||
#define CAB_CODEC_RAW 0x00
|
||||
#define CAB_CODEC_LZX 0x01
|
||||
#define CAB_CODEC_MSZIP 0x02
|
||||
|
||||
|
||||
|
||||
/* Classes */
|
||||
|
||||
#ifndef CAB_READ_ONLY
|
||||
|
||||
class CCFDATAStorage {
|
||||
public:
|
||||
/* Default constructor */
|
||||
CCFDATAStorage();
|
||||
/* Default destructor */
|
||||
virtual ~CCFDATAStorage();
|
||||
ULONG Create(LPTSTR FileName);
|
||||
ULONG Destroy();
|
||||
ULONG Truncate();
|
||||
ULONG Position();
|
||||
ULONG Seek(LONG Position);
|
||||
ULONG ReadBlock(PCFDATA Data, PVOID Buffer, PDWORD BytesRead);
|
||||
ULONG WriteBlock(PCFDATA Data, PVOID Buffer, PDWORD BytesWritten);
|
||||
private:
|
||||
BOOL FileCreated;
|
||||
HANDLE FileHandle;
|
||||
};
|
||||
|
||||
#endif /* CAB_READ_ONLY */
|
||||
|
||||
class CCabinet {
|
||||
public:
|
||||
/* Default constructor */
|
||||
CCabinet();
|
||||
/* Default destructor */
|
||||
virtual ~CCabinet();
|
||||
/* Returns a pointer to the filename part of a fully qualified filename */
|
||||
LPTSTR GetFileName(LPTSTR Path);
|
||||
/* Removes a filename from a fully qualified filename */
|
||||
VOID RemoveFileName(LPTSTR Path);
|
||||
/* Normalizes a path */
|
||||
BOOL NormalizePath(LPTSTR Path, DWORD Length);
|
||||
/* Returns name of cabinet file */
|
||||
LPTSTR GetCabinetName();
|
||||
/* Sets the name of the cabinet file */
|
||||
VOID SetCabinetName(LPTSTR FileName);
|
||||
/* Sets destination path for extracted files */
|
||||
VOID SetDestinationPath(LPTSTR DestinationPath);
|
||||
/* Returns destination path */
|
||||
LPTSTR GetDestinationPath();
|
||||
/* Returns zero-based current disk number */
|
||||
DWORD GetCurrentDiskNumber();
|
||||
/* Opens the current cabinet file */
|
||||
ULONG Open();
|
||||
/* Closes the current open cabinet file */
|
||||
VOID Close();
|
||||
/* Locates the first file in the current cabinet file that matches a search criteria */
|
||||
ULONG FindFirst(LPTSTR FileName, PCAB_SEARCH Search);
|
||||
/* Locates the next file in the current cabinet file */
|
||||
ULONG FindNext(PCAB_SEARCH Search);
|
||||
/* Extracts a file from the current cabinet file */
|
||||
ULONG ExtractFile(LPTSTR FileName);
|
||||
/* Select codec engine to use */
|
||||
VOID SelectCodec(ULONG Id);
|
||||
#ifndef CAB_READ_ONLY
|
||||
/* Creates a new cabinet file */
|
||||
ULONG NewCabinet();
|
||||
/* Forces a new disk to be created */
|
||||
ULONG NewDisk();
|
||||
/* Forces a new folder to be created */
|
||||
ULONG NewFolder();
|
||||
/* Writes a file to scratch storage */
|
||||
ULONG WriteFileToScratchStorage(PCFFILE_NODE FileNode);
|
||||
/* Forces the current disk to be written */
|
||||
ULONG WriteDisk(DWORD MoreDisks);
|
||||
/* Commits the current disk */
|
||||
ULONG CommitDisk(DWORD MoreDisks);
|
||||
/* Closes the current disk */
|
||||
ULONG CloseDisk();
|
||||
/* Closes the current cabinet */
|
||||
ULONG CloseCabinet();
|
||||
/* Adds a file to the current disk */
|
||||
ULONG AddFile(LPTSTR FileName);
|
||||
/* Sets the maximum size of the current disk */
|
||||
VOID SetMaxDiskSize(DWORD Size);
|
||||
#endif /* CAB_READ_ONLY */
|
||||
|
||||
/* Default event handlers */
|
||||
|
||||
/* Handler called when a file is about to be overridden */
|
||||
virtual BOOL OnOverwrite(PCFFILE Entry, LPTSTR FileName);
|
||||
/* Handler called when a file is about to be extracted */
|
||||
virtual VOID OnExtract(PCFFILE Entry, LPTSTR FileName);
|
||||
/* Handler called when a new disk is to be processed */
|
||||
virtual VOID OnDiskChange(LPTSTR CabinetName, LPTSTR DiskLabel);
|
||||
#ifndef CAB_READ_ONLY
|
||||
/* Handler called when a file is about to be added */
|
||||
virtual VOID OnAdd(PCFFILE Entry, LPTSTR FileName);
|
||||
/* Handler called when a cabinet need a name */
|
||||
virtual BOOL OnCabinetName(ULONG Number, LPTSTR Name);
|
||||
/* Handler called when a disk needs a label */
|
||||
virtual BOOL OnDiskLabel(ULONG Number, LPTSTR Label);
|
||||
#endif /* CAB_READ_ONLY */
|
||||
private:
|
||||
PCFFOLDER_NODE LocateFolderNode(DWORD Index);
|
||||
ULONG GetAbsoluteOffset(PCFFILE_NODE File);
|
||||
ULONG LocateFile(LPTSTR FileName, PCFFILE_NODE *File);
|
||||
ULONG ReadString(LPTSTR String, DWORD MaxLength);
|
||||
ULONG ReadFileTable();
|
||||
ULONG ReadDataBlocks(PCFFOLDER_NODE FolderNode);
|
||||
PCFFOLDER_NODE NewFolderNode();
|
||||
PCFFILE_NODE NewFileNode();
|
||||
PCFDATA_NODE NewDataNode(PCFFOLDER_NODE FolderNode);
|
||||
VOID DestroyDataNodes(PCFFOLDER_NODE FolderNode);
|
||||
VOID DestroyFileNodes();
|
||||
VOID DestroyDeletedFileNodes();
|
||||
VOID DestroyFolderNodes();
|
||||
VOID DestroyDeletedFolderNodes();
|
||||
ULONG ComputeChecksum(PVOID Buffer, UINT Size, ULONG Seed);
|
||||
ULONG ReadBlock(PVOID Buffer, DWORD Size, PDWORD BytesRead);
|
||||
#ifndef CAB_READ_ONLY
|
||||
ULONG InitCabinetHeader();
|
||||
ULONG WriteCabinetHeader(BOOL MoreDisks);
|
||||
ULONG WriteFolderEntries();
|
||||
ULONG WriteFileEntries();
|
||||
ULONG CommitDataBlocks(PCFFOLDER_NODE FolderNode);
|
||||
ULONG WriteDataBlock();
|
||||
ULONG GetAttributesOnFile(PCFFILE_NODE File);
|
||||
ULONG SetAttributesOnFile(PCFFILE_NODE File);
|
||||
#endif /* CAB_READ_ONLY */
|
||||
DWORD CurrentDiskNumber; // Zero based disk number
|
||||
TCHAR CabinetName[256]; // Filename of current cabinet
|
||||
TCHAR CabinetPrev[256]; // Filename of previous cabinet
|
||||
TCHAR DiskPrev[256]; // Label of cabinet in file CabinetPrev
|
||||
TCHAR CabinetNext[256]; // Filename of next cabinet
|
||||
TCHAR DiskNext[256]; // Label of cabinet in file CabinetNext
|
||||
DWORD TotalHeaderSize; // Size of header and optional fields
|
||||
DWORD NextFieldsSize; // Size of next cabinet name and next disk label
|
||||
DWORD TotalFolderSize; // Size of all folder entries
|
||||
DWORD TotalFileSize; // Size of all file entries
|
||||
DWORD FolderUncompSize; // Uncompressed size of folder
|
||||
DWORD BytesLeftInBlock; // Number of bytes left in current block
|
||||
BOOL ReuseBlock;
|
||||
TCHAR DestPath[MAX_PATH];
|
||||
HANDLE FileHandle;
|
||||
BOOL FileOpen;
|
||||
CFHEADER CABHeader;
|
||||
ULONG CabinetReserved;
|
||||
ULONG FolderReserved;
|
||||
ULONG DataReserved;
|
||||
PCFFOLDER_NODE FolderListHead;
|
||||
PCFFOLDER_NODE FolderListTail;
|
||||
PCFFOLDER_NODE CurrentFolderNode;
|
||||
PCFDATA_NODE CurrentDataNode;
|
||||
PCFFILE_NODE FileListHead;
|
||||
PCFFILE_NODE FileListTail;
|
||||
CCABCodec *Codec;
|
||||
ULONG CodecId;
|
||||
BOOL CodecSelected;
|
||||
PVOID InputBuffer;
|
||||
PVOID CurrentIBuffer; // Current offset in input buffer
|
||||
DWORD CurrentIBufferSize; // Bytes left in input buffer
|
||||
PVOID OutputBuffer;
|
||||
DWORD TotalCompSize; // Total size of current CFDATA block
|
||||
PVOID CurrentOBuffer; // Current offset in output buffer
|
||||
DWORD CurrentOBufferSize; // Bytes left in output buffer
|
||||
DWORD BytesLeftInCabinet;
|
||||
BOOL RestartSearch;
|
||||
DWORD LastFileOffset; // Uncompressed offset of last extracted file
|
||||
#ifndef CAB_READ_ONLY
|
||||
DWORD LastBlockStart; // Uncompressed offset of last block in folder
|
||||
DWORD MaxDiskSize;
|
||||
DWORD DiskSize;
|
||||
DWORD PrevCabinetNumber; // Previous cabinet number (where split file starts)
|
||||
BOOL CreateNewDisk;
|
||||
BOOL CreateNewFolder;
|
||||
|
||||
CCFDATAStorage *ScratchFile;
|
||||
HANDLE SourceFile;
|
||||
BOOL ContinueFile;
|
||||
DWORD TotalBytesLeft;
|
||||
BOOL BlockIsSplit; // TRUE if current data block is split
|
||||
ULONG NextFolderNumber; // Zero based folder number
|
||||
#endif /* CAB_READ_ONLY */
|
||||
};
|
||||
|
||||
#endif /* __CABINET_H */
|
||||
|
||||
/* EOF */
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/cabman.h
|
||||
* PURPOSE: Cabinet manager header
|
||||
*/
|
||||
#ifndef __CABMAN_H
|
||||
#define __CABMAN_H
|
||||
|
||||
#include "cabinet.h"
|
||||
#include "dfp.h"
|
||||
|
||||
/* Cabinet manager modes */
|
||||
#define CM_MODE_CREATE 0
|
||||
#define CM_MODE_DISPLAY 1
|
||||
#define CM_MODE_EXTRACT 2
|
||||
|
||||
|
||||
/* Classes */
|
||||
|
||||
class CCABManager : public CDFParser {
|
||||
public:
|
||||
CCABManager();
|
||||
virtual ~CCABManager();
|
||||
BOOL ParseCmdline(INT argc, PCHAR argv[]);
|
||||
VOID Run();
|
||||
private:
|
||||
VOID Usage();
|
||||
VOID CreateCabinet();
|
||||
VOID DisplayCabinet();
|
||||
VOID ExtractFromCabinet();
|
||||
/* Event handlers */
|
||||
virtual BOOL OnOverwrite(PCFFILE File, LPTSTR FileName);
|
||||
virtual VOID OnExtract(PCFFILE File, LPTSTR FileName);
|
||||
virtual VOID OnDiskChange(LPTSTR CabinetName, LPTSTR DiskLabel);
|
||||
virtual VOID OnAdd(PCFFILE Entry, LPTSTR FileName);
|
||||
/* Configuration */
|
||||
BOOL ProcessAll;
|
||||
DWORD Mode;
|
||||
BOOL PromptOnOverwrite;
|
||||
TCHAR Location[MAX_PATH];
|
||||
TCHAR FileName[MAX_PATH];
|
||||
};
|
||||
|
||||
#endif /* __CABMAN_H */
|
||||
|
||||
/* EOF */
|
|
@ -1,55 +0,0 @@
|
|||
Directive File Format for ReactOS Cabinet Manager
|
||||
-------------------------------------------------
|
||||
|
||||
Directives begin with a period ("."), and are followed by a command
|
||||
name, and possibly blank delimited arguments. Commands and variable names are
|
||||
case insensitive.
|
||||
|
||||
Syntax Description
|
||||
-------------------------------------------------------------------------------
|
||||
; Anything on a line after this is a comment
|
||||
<filename> [destination] File copy command
|
||||
.Define variable=[value] Define variable to be equal to value (*)
|
||||
.Delete variable Delete a variable definition (*)
|
||||
.New Disk|Cabinet|Folder Start a new disk, cabinet or folder (* -- new disk will work)
|
||||
.Set variable=[value] Set variable to be equal to value (*)
|
||||
%variable% Substitute value of variable (*)
|
||||
<blank line> Blank lines are ignored
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Standard variable Description
|
||||
-------------------------------------------------------------------------------
|
||||
Cabinet=ON|OFF Turns cabinet mode on or off (* -- currently always on)
|
||||
CabinetFileCountThreshold=count Threshold count of files per cabinet (*)
|
||||
CabinetNamen=filename Cabinet file name for cabinet number n
|
||||
CabinetNameTemplate=template Cabinet file name template
|
||||
* is replaced by cabinet number
|
||||
Compress=ON|OFF Turns compression on or off (* -- currently always on)
|
||||
CompressionType=NONE|MSZIP Compression engine to use (* -- currently always mszip)
|
||||
DiskLabeln=label Printed disk label name for disk n
|
||||
DiskLabelTemplate=template Printed disk label name template
|
||||
* is replaced by disk number
|
||||
FolderFileCountThreshold=count Threshold count of files per folder (*)
|
||||
FolderSizeThreshold=size Threshold folder size for current folder (*)
|
||||
MaxDiskFileCount=count Maximum count of files per disk (*)
|
||||
MaxDiskSize[n]=size Maximum disk size (for disk n)
|
||||
ReservePerCabinetSize=size Amount of space to reserve in each cabinet (*)
|
||||
ReservePerDataBlockSize=size Amount of space to reserve in each data block (*)
|
||||
ReservePerFolderSize=size Amount of space to reserve in each folder (*)
|
||||
SourceDir=path Default path for source files (*)
|
||||
-------------------------------------------------------------------------------
|
||||
(*) = not implemented
|
||||
|
||||
|
||||
MaxDiskSize
|
||||
-----------
|
||||
0 means disk size is unlimited. Standard sizes available are:
|
||||
|
||||
2.88M
|
||||
1.44M
|
||||
1.25M
|
||||
1.2M
|
||||
720K
|
||||
360K
|
||||
CDROM
|
|
@ -1,992 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/dfp.cpp
|
||||
* PURPOSE: Directive file parser
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* NOTES: The directive file format is similar to the
|
||||
* directive file format used by Microsoft's MAKECAB
|
||||
* REVISIONS:
|
||||
* CSH 21/03-2001 Created
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "cabinet.h"
|
||||
#include "dfp.h"
|
||||
|
||||
|
||||
/* CDFParser */
|
||||
|
||||
CDFParser::CDFParser()
|
||||
/*
|
||||
* FUNCTION: Default constructor
|
||||
*/
|
||||
{
|
||||
FileBuffer = NULL;
|
||||
FileLoaded = FALSE;
|
||||
CurrentOffset = 0;
|
||||
CurrentLine = 0;
|
||||
CabinetCreated = FALSE;
|
||||
DiskCreated = FALSE;
|
||||
FolderCreated = FALSE;
|
||||
CabinetName = NULL;
|
||||
DiskLabel = NULL;
|
||||
MaxDiskSize = NULL;
|
||||
|
||||
MaxDiskSizeAllSet = FALSE;
|
||||
CabinetNameTemplateSet = FALSE;
|
||||
DiskLabelTemplateSet = FALSE;
|
||||
}
|
||||
|
||||
|
||||
CDFParser::~CDFParser()
|
||||
/*
|
||||
* FUNCTION: Default destructor
|
||||
*/
|
||||
{
|
||||
PCABINET_NAME CNPrev;
|
||||
PCABINET_NAME CNNext;
|
||||
PDISK_NUMBER DNPrev;
|
||||
PDISK_NUMBER DNNext;
|
||||
|
||||
if (FileBuffer)
|
||||
HeapFree(GetProcessHeap(), 0, FileBuffer);
|
||||
CNNext = CabinetName;
|
||||
while (CNNext != NULL) {
|
||||
CNPrev = CNNext->Next;
|
||||
HeapFree(GetProcessHeap(), 0, CNNext);
|
||||
CNNext = CNPrev;
|
||||
}
|
||||
CNNext = DiskLabel;
|
||||
while (CNNext != NULL) {
|
||||
CNPrev = CNNext->Next;
|
||||
HeapFree(GetProcessHeap(), 0, CNNext);
|
||||
CNNext = CNPrev;
|
||||
}
|
||||
DNNext = MaxDiskSize;
|
||||
while (DNNext != NULL) {
|
||||
DNPrev = DNNext->Next;
|
||||
HeapFree(GetProcessHeap(), 0, DNNext);
|
||||
DNNext = DNPrev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::Load(LPTSTR FileName)
|
||||
/*
|
||||
* FUNCTION: Loads a directive file into memory
|
||||
* ARGUMENTS:
|
||||
* FileName = Pointer to name of directive file
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
DWORD BytesRead;
|
||||
LONG FileSize;
|
||||
|
||||
if (FileLoaded)
|
||||
return CAB_STATUS_SUCCESS;
|
||||
|
||||
/* Create cabinet file, overwrite if it already exists */
|
||||
FileHandle = CreateFile(FileName, // Create this file
|
||||
GENERIC_READ, // Open for reading
|
||||
0, // No sharing
|
||||
NULL, // No security
|
||||
OPEN_EXISTING, // Open the file
|
||||
FILE_ATTRIBUTE_NORMAL, // Normal file
|
||||
NULL); // No attribute template
|
||||
if (FileHandle == INVALID_HANDLE_VALUE)
|
||||
return CAB_STATUS_CANNOT_OPEN;
|
||||
|
||||
FileSize = GetFileSize(FileHandle, NULL);
|
||||
if (FileSize < 0) {
|
||||
CloseHandle(FileHandle);
|
||||
return CAB_STATUS_CANNOT_OPEN;
|
||||
}
|
||||
|
||||
FileBufferSize = (ULONG)FileSize;
|
||||
|
||||
FileBuffer = (PCHAR)HeapAlloc(GetProcessHeap(), 0, FileBufferSize);
|
||||
if (!FileBuffer) {
|
||||
CloseHandle(FileHandle);
|
||||
return CAB_STATUS_NOMEMORY;
|
||||
}
|
||||
|
||||
if (!ReadFile(FileHandle, FileBuffer, FileBufferSize, &BytesRead, NULL)) {
|
||||
CloseHandle(FileHandle);
|
||||
HeapFree(GetProcessHeap(), 0, FileBuffer);
|
||||
FileBuffer = NULL;
|
||||
return CAB_STATUS_CANNOT_READ;
|
||||
}
|
||||
|
||||
CloseHandle(FileHandle);
|
||||
|
||||
FileLoaded = TRUE;
|
||||
|
||||
DPRINT(MAX_TRACE, ("File (%d bytes)\n", FileBufferSize));
|
||||
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::Parse()
|
||||
/*
|
||||
* FUNCTION: Parses a loaded directive file
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
BOOL Command;
|
||||
ULONG Status;
|
||||
|
||||
if (!FileLoaded)
|
||||
return CAB_STATUS_NOFILE;
|
||||
|
||||
while (ReadLine()) {
|
||||
Command = FALSE;
|
||||
|
||||
while (CurrentToken != TokenEnd) {
|
||||
switch (CurrentToken) {
|
||||
case TokenInteger:
|
||||
itoa(CurrentInteger, (LPTSTR)&CurrentString, 10);
|
||||
case TokenIdentifier:
|
||||
if (Command) {
|
||||
/* Command */
|
||||
Status = PerformCommand();
|
||||
|
||||
if (Status == CAB_STATUS_FAILURE) {
|
||||
printf("Directive file contains errors at line %d.\n", (UINT)CurrentLine);
|
||||
DPRINT(MID_TRACE, ("Error while executing command.\n"));
|
||||
}
|
||||
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
return Status;
|
||||
} else {
|
||||
/* File copy */
|
||||
Status = PerformFileCopy();
|
||||
|
||||
if (Status == CAB_STATUS_FAILURE) {
|
||||
printf("Directive file contains errors at line %d.\n", (UINT)CurrentLine);
|
||||
DPRINT(MID_TRACE, ("Error while copying file.\n"));
|
||||
}
|
||||
|
||||
if (Status != CAB_STATUS_SUCCESS)
|
||||
return Status;
|
||||
}
|
||||
break;
|
||||
case TokenSpace:
|
||||
break;
|
||||
case TokenSemi:
|
||||
CurrentToken = TokenEnd;
|
||||
continue;
|
||||
case TokenPeriod:
|
||||
Command = TRUE;
|
||||
break;
|
||||
default:
|
||||
printf("Directive file contains errors at line %d.\n", (UINT)CurrentLine);
|
||||
DPRINT(MIN_TRACE, ("Token is (%d).\n", (UINT)CurrentToken));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
NextToken();
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nWriting cabinet. This may take a while...\n\n");
|
||||
|
||||
if (DiskCreated) {
|
||||
Status = WriteDisk(FALSE);
|
||||
if (Status == CAB_STATUS_SUCCESS)
|
||||
Status = CloseDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot write disk (%d).\n", (UINT)Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
if (CabinetCreated) {
|
||||
Status = CloseCabinet();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot close cabinet (%d).\n", (UINT)Status));
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nDone.\n");
|
||||
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::OnDiskLabel(ULONG Number, LPTSTR Label)
|
||||
/*
|
||||
* FUNCTION: Called when a disk needs a label
|
||||
* ARGUMENTS:
|
||||
* Number = Cabinet number that needs a label
|
||||
* Label = Pointer to buffer to place label of disk
|
||||
* RETURNS:
|
||||
* TRUE if a disk label was returned, FALSE if not
|
||||
*/
|
||||
{
|
||||
TCHAR Buffer[20];
|
||||
INT i, j;
|
||||
TCHAR ch;
|
||||
|
||||
Number += 1;
|
||||
|
||||
DPRINT(MID_TRACE, ("Giving disk (%d) a label...\n", (UINT)Number));
|
||||
|
||||
if (GetDiskName(&DiskLabel, Number, Label))
|
||||
return TRUE;
|
||||
|
||||
if (DiskLabelTemplateSet) {
|
||||
j = 0;
|
||||
lstrcpy(Label, "");
|
||||
for (i = 0; i < lstrlen(DiskLabelTemplate); i++) {
|
||||
ch = DiskLabelTemplate[i];
|
||||
if (ch == '*') {
|
||||
lstrcat(Label, itoa(Number, Buffer, 10));
|
||||
j += lstrlen(Buffer);
|
||||
} else {
|
||||
Label[j] = ch;
|
||||
j++;
|
||||
}
|
||||
Label[j] = '\0';
|
||||
}
|
||||
|
||||
DPRINT(MID_TRACE, ("Giving disk (%s) as a label...\n", Label));
|
||||
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::OnCabinetName(ULONG Number, LPTSTR Name)
|
||||
/*
|
||||
* FUNCTION: Called when a cabinet needs a name
|
||||
* ARGUMENTS:
|
||||
* Number = Disk number that needs a name
|
||||
* Name = Pointer to buffer to place name of cabinet
|
||||
* RETURNS:
|
||||
* TRUE if a cabinet name was returned, FALSE if not
|
||||
*/
|
||||
{
|
||||
TCHAR Buffer[20];
|
||||
INT i, j;
|
||||
TCHAR ch;
|
||||
|
||||
Number += 1;
|
||||
|
||||
DPRINT(MID_TRACE, ("Giving cabinet (%d) a name...\n", (UINT)Number));
|
||||
|
||||
if (GetDiskName(&CabinetName, Number, Name))
|
||||
return TRUE;
|
||||
|
||||
if (CabinetNameTemplateSet) {
|
||||
j = 0;
|
||||
lstrcpy(Name, "");
|
||||
for (i = 0; i < lstrlen(CabinetNameTemplate); i++) {
|
||||
ch = CabinetNameTemplate[i];
|
||||
if (ch == '*') {
|
||||
lstrcat(Name, itoa(Number, Buffer, 10));
|
||||
j += lstrlen(Buffer);
|
||||
} else {
|
||||
Name[j] = ch;
|
||||
j++;
|
||||
}
|
||||
Name[j] = '\0';
|
||||
}
|
||||
|
||||
DPRINT(MID_TRACE, ("Giving cabinet (%s) as a name...\n", Name));
|
||||
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::SetDiskName(PCABINET_NAME *List, ULONG Number, LPTSTR String)
|
||||
/*
|
||||
* FUNCTION: Sets an entry in a list
|
||||
* ARGUMENTS:
|
||||
* List = Address of pointer to list
|
||||
* Number = Disk number
|
||||
* String = Pointer to string
|
||||
* RETURNS:
|
||||
* FALSE if there was not enough free memory available
|
||||
*/
|
||||
{
|
||||
PCABINET_NAME CN;
|
||||
|
||||
CN = *List;
|
||||
while (CN != NULL) {
|
||||
if (CN->DiskNumber == Number) {
|
||||
lstrcpy(CN->Name, String);
|
||||
return TRUE;
|
||||
}
|
||||
CN = CN->Next;
|
||||
}
|
||||
|
||||
CN = (PCABINET_NAME)HeapAlloc(GetProcessHeap(), 0, sizeof(CABINET_NAME));
|
||||
if (!CN)
|
||||
return FALSE;
|
||||
|
||||
CN->DiskNumber = Number;
|
||||
lstrcpy(CN->Name, String);
|
||||
|
||||
CN->Next = *List;
|
||||
*List = CN;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::GetDiskName(PCABINET_NAME *List, ULONG Number, LPTSTR String)
|
||||
/*
|
||||
* FUNCTION: Returns an entry in a list
|
||||
* ARGUMENTS:
|
||||
* List = Address of pointer to list
|
||||
* Number = Disk number
|
||||
* String = Address of buffer to copy string to
|
||||
* RETURNS:
|
||||
* FALSE if there was not enough free memory available
|
||||
*/
|
||||
{
|
||||
PCABINET_NAME CN;
|
||||
|
||||
CN = *List;
|
||||
while (CN != NULL) {
|
||||
if (CN->DiskNumber == Number) {
|
||||
lstrcpy(String, CN->Name);
|
||||
return TRUE;
|
||||
}
|
||||
CN = CN->Next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::SetDiskNumber(PDISK_NUMBER *List, ULONG Number, ULONG Value)
|
||||
/*
|
||||
* FUNCTION: Sets an entry in a list
|
||||
* ARGUMENTS:
|
||||
* List = Address of pointer to list
|
||||
* Number = Disk number
|
||||
* Value = Value to set
|
||||
* RETURNS:
|
||||
* FALSE if there was not enough free memory available
|
||||
*/
|
||||
{
|
||||
PDISK_NUMBER DN;
|
||||
|
||||
DN = *List;
|
||||
while (DN != NULL) {
|
||||
if (DN->DiskNumber == Number) {
|
||||
DN->Number = Value;
|
||||
return TRUE;
|
||||
}
|
||||
DN = DN->Next;
|
||||
}
|
||||
|
||||
DN = (PDISK_NUMBER)HeapAlloc(GetProcessHeap(), 0, sizeof(DISK_NUMBER));
|
||||
if (!DN)
|
||||
return FALSE;
|
||||
|
||||
DN->DiskNumber = Number;
|
||||
DN->Number = Value;
|
||||
|
||||
DN->Next = *List;
|
||||
*List = DN;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::GetDiskNumber(PDISK_NUMBER *List, ULONG Number, PULONG Value)
|
||||
/*
|
||||
* FUNCTION: Returns an entry in a list
|
||||
* ARGUMENTS:
|
||||
* List = Address of pointer to list
|
||||
* Number = Disk number
|
||||
* Value = Address of buffer to place value
|
||||
* RETURNS:
|
||||
* TRUE if the entry was found
|
||||
*/
|
||||
{
|
||||
PDISK_NUMBER DN;
|
||||
|
||||
DN = *List;
|
||||
while (DN != NULL) {
|
||||
if (DN->DiskNumber == Number) {
|
||||
*Value = DN->Number;
|
||||
return TRUE;
|
||||
}
|
||||
DN = DN->Next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::DoDiskLabel(ULONG Number, LPTSTR Label)
|
||||
/*
|
||||
* FUNCTION: Sets the label of a disk
|
||||
* ARGUMENTS:
|
||||
* Number = Disk number
|
||||
* Label = Pointer to label of disk
|
||||
* RETURNS:
|
||||
* FALSE if there was not enough free memory available
|
||||
*/
|
||||
{
|
||||
DPRINT(MID_TRACE, ("Setting label of disk (%d) to '%s'\n", (UINT)Number, Label));
|
||||
|
||||
return SetDiskName(&DiskLabel, Number, Label);
|
||||
}
|
||||
|
||||
|
||||
VOID CDFParser::DoDiskLabelTemplate(LPTSTR Template)
|
||||
/*
|
||||
* FUNCTION: Sets a disk label template to use
|
||||
* ARGUMENTS:
|
||||
* Template = Pointer to disk label template
|
||||
*/
|
||||
{
|
||||
DPRINT(MID_TRACE, ("Setting disk label template to '%s'\n", Template));
|
||||
|
||||
lstrcpy(DiskLabelTemplate, Template);
|
||||
DiskLabelTemplateSet = TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::DoCabinetName(ULONG Number, LPTSTR Name)
|
||||
/*
|
||||
* FUNCTION: Sets the name of a cabinet
|
||||
* ARGUMENTS:
|
||||
* Number = Disk number
|
||||
* Name = Pointer to name of cabinet
|
||||
* RETURNS:
|
||||
* FALSE if there was not enough free memory available
|
||||
*/
|
||||
{
|
||||
DPRINT(MID_TRACE, ("Setting name of cabinet (%d) to '%s'\n", (UINT)Number, Name));
|
||||
|
||||
return SetDiskName(&CabinetName, Number, Name);
|
||||
}
|
||||
|
||||
|
||||
VOID CDFParser::DoCabinetNameTemplate(LPTSTR Template)
|
||||
/*
|
||||
* FUNCTION: Sets a cabinet name template to use
|
||||
* ARGUMENTS:
|
||||
* Template = Pointer to cabinet name template
|
||||
*/
|
||||
{
|
||||
DPRINT(MID_TRACE, ("Setting cabinet name template to '%s'\n", Template));
|
||||
|
||||
lstrcpy(CabinetNameTemplate, Template);
|
||||
CabinetNameTemplateSet = TRUE;
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::DoMaxDiskSize(BOOL NumberValid, ULONG Number)
|
||||
/*
|
||||
* FUNCTION: Sets the maximum disk size
|
||||
* ARGUMENTS:
|
||||
* NumberValid = TRUE if disk number is valid
|
||||
* Number = Disk number
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
* NOTES:
|
||||
* Standard sizes are 2.88M, 1.44M, 1.25M, 1.2M, 720K, 360K, and CDROM
|
||||
*/
|
||||
{
|
||||
ULONG A, B, Value;
|
||||
|
||||
if (IsNextToken(TokenInteger, TRUE)) {
|
||||
|
||||
A = CurrentInteger;
|
||||
|
||||
if (IsNextToken(TokenPeriod, FALSE)) {
|
||||
if (!IsNextToken(TokenInteger, FALSE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
B = CurrentInteger;
|
||||
|
||||
} else
|
||||
B = 0;
|
||||
|
||||
if (CurrentToken == TokenIdentifier) {
|
||||
switch (CurrentString[0]) {
|
||||
case 'K':
|
||||
if (B != 0)
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
if (A == 720)
|
||||
/* 720K disk */
|
||||
Value = 730112;
|
||||
else if (A == 360)
|
||||
/* 360K disk */
|
||||
Value = 362496;
|
||||
else
|
||||
return CAB_STATUS_FAILURE;
|
||||
break;
|
||||
case 'M':
|
||||
if (A == 1) {
|
||||
if (B == 44)
|
||||
/* 1.44M disk */
|
||||
Value = 1457664;
|
||||
else if (B == 25)
|
||||
/* 1.25M disk */
|
||||
Value = 1300000; // FIXME: Value?
|
||||
else if (B == 2)
|
||||
/* 1.2M disk */
|
||||
Value = 1213952;
|
||||
else
|
||||
return CAB_STATUS_FAILURE;
|
||||
} else if (A == 2) {
|
||||
if (B == 88)
|
||||
/* 2.88M disk */
|
||||
Value = 2915328;
|
||||
else
|
||||
return CAB_STATUS_FAILURE;
|
||||
} else
|
||||
return CAB_STATUS_FAILURE;
|
||||
break;
|
||||
default:
|
||||
DPRINT(MID_TRACE, ("Bad suffix (%c)\n", CurrentString[0]));
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
} else
|
||||
Value = A;
|
||||
} else {
|
||||
if ((CurrentToken != TokenString) &&
|
||||
(strcmpi(CurrentString, "CDROM") != 0))
|
||||
return CAB_STATUS_FAILURE;
|
||||
/* CDROM */
|
||||
Value = 640*1024*1024; // FIXME: Correct size for CDROM?
|
||||
}
|
||||
|
||||
if (NumberValid)
|
||||
return (SetDiskNumber(&MaxDiskSize, Number, Value)?
|
||||
CAB_STATUS_SUCCESS : CAB_STATUS_FAILURE);
|
||||
|
||||
MaxDiskSizeAll = Value;
|
||||
MaxDiskSizeAllSet = TRUE;
|
||||
|
||||
SetMaxDiskSize(Value);
|
||||
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::SetupNewDisk()
|
||||
/*
|
||||
* FUNCTION: Sets up parameters for a new disk
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
ULONG Value;
|
||||
|
||||
if (!GetDiskNumber(&MaxDiskSize, GetCurrentDiskNumber(), &Value)) {
|
||||
if (MaxDiskSizeAllSet)
|
||||
Value = MaxDiskSizeAll;
|
||||
else
|
||||
Value = 0;
|
||||
}
|
||||
SetMaxDiskSize(Value);
|
||||
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::PerformSetCommand()
|
||||
/*
|
||||
* FUNCTION: Performs a set variable command
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
SETTYPE SetType;
|
||||
BOOL NumberValid = FALSE;
|
||||
ULONG Number = 0;
|
||||
|
||||
if (!IsNextToken(TokenIdentifier, TRUE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
if (strcmpi(CurrentString, "DiskLabel") == 0)
|
||||
SetType = stDiskLabel;
|
||||
else if (strcmpi(CurrentString, "DiskLabelTemplate") == 0)
|
||||
SetType = stDiskLabelTemplate;
|
||||
else if (strcmpi(CurrentString, "CabinetName") == 0)
|
||||
SetType = stCabinetName;
|
||||
else if (strcmpi(CurrentString, "CabinetNameTemplate") == 0)
|
||||
SetType = stCabinetNameTemplate;
|
||||
else if (strcmpi(CurrentString, "MaxDiskSize") == 0)
|
||||
SetType = stMaxDiskSize;
|
||||
else
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
if ((SetType == stDiskLabel) || (SetType == stCabinetName)) {
|
||||
if (!IsNextToken(TokenInteger, FALSE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
Number = CurrentInteger;
|
||||
|
||||
if (!IsNextToken(TokenEqual, TRUE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
} else if (SetType == stMaxDiskSize) {
|
||||
if (IsNextToken(TokenInteger, FALSE)) {
|
||||
NumberValid = TRUE;
|
||||
Number = CurrentInteger;
|
||||
} else {
|
||||
NumberValid = FALSE;
|
||||
while (CurrentToken == TokenSpace)
|
||||
NextToken();
|
||||
if (CurrentToken != TokenEqual)
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
} else if (!IsNextToken(TokenEqual, TRUE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
if (SetType != stMaxDiskSize) {
|
||||
if (!IsNextToken(TokenString, TRUE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
switch (SetType) {
|
||||
case stDiskLabel:
|
||||
if (!DoDiskLabel(Number, CurrentString))
|
||||
DPRINT(MIN_TRACE, ("Not enough available free memory.\n"));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
case stCabinetName:
|
||||
if (!DoCabinetName(Number, CurrentString))
|
||||
DPRINT(MIN_TRACE, ("Not enough available free memory.\n"));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
case stDiskLabelTemplate:
|
||||
DoDiskLabelTemplate(CurrentString);
|
||||
return CAB_STATUS_SUCCESS;
|
||||
case stCabinetNameTemplate:
|
||||
DoCabinetNameTemplate(CurrentString);
|
||||
return CAB_STATUS_SUCCESS;
|
||||
case stMaxDiskSize:
|
||||
return DoMaxDiskSize(NumberValid, Number);
|
||||
default:
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::PerformNewCommand()
|
||||
/*
|
||||
* FUNCTION: Performs a new disk|cabinet|folder command
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
NEWTYPE NewType;
|
||||
ULONG Status;
|
||||
|
||||
if (!IsNextToken(TokenIdentifier, TRUE))
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
if (strcmpi(CurrentString, "Disk") == 0)
|
||||
NewType = ntDisk;
|
||||
else if (strcmpi(CurrentString, "Cabinet") == 0)
|
||||
NewType = ntCabinet;
|
||||
else if (strcmpi(CurrentString, "Folder") == 0)
|
||||
NewType = ntFolder;
|
||||
else
|
||||
return CAB_STATUS_FAILURE;
|
||||
|
||||
switch (NewType) {
|
||||
case ntDisk:
|
||||
if (DiskCreated) {
|
||||
Status = WriteDisk(TRUE);
|
||||
if (Status == CAB_STATUS_SUCCESS)
|
||||
Status = CloseDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot write disk (%d).\n", (UINT)Status));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
DiskCreated = FALSE;
|
||||
}
|
||||
|
||||
Status = NewDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot create disk (%d).\n", (UINT)Status));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
DiskCreated = TRUE;
|
||||
SetupNewDisk();
|
||||
return CAB_STATUS_SUCCESS;
|
||||
case ntCabinet:
|
||||
if (DiskCreated) {
|
||||
Status = WriteDisk(TRUE);
|
||||
if (Status == CAB_STATUS_SUCCESS)
|
||||
Status = CloseDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot write disk (%d).\n", (UINT)Status));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
DiskCreated = FALSE;
|
||||
}
|
||||
|
||||
Status = NewCabinet();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot create cabinet (%d).\n", (UINT)Status));
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
DiskCreated = TRUE;
|
||||
SetupNewDisk();
|
||||
return CAB_STATUS_SUCCESS;
|
||||
case ntFolder:
|
||||
Status = NewFolder();
|
||||
ASSERT(Status == CAB_STATUS_SUCCESS);
|
||||
return CAB_STATUS_SUCCESS;
|
||||
default:
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::PerformCommand()
|
||||
/*
|
||||
* FUNCTION: Performs a command
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
if (strcmpi(CurrentString, "Set") == 0)
|
||||
return PerformSetCommand();
|
||||
if (strcmpi(CurrentString, "New") == 0)
|
||||
return PerformNewCommand();
|
||||
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
ULONG CDFParser::PerformFileCopy()
|
||||
/*
|
||||
* FUNCTION: Performs a file copy
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
ULONG Status;
|
||||
ULONG i, j;
|
||||
TCHAR ch;
|
||||
TCHAR SrcName[MAX_PATH];
|
||||
TCHAR DstName[MAX_PATH];
|
||||
|
||||
lstrcpy(SrcName, "");
|
||||
lstrcpy(DstName, "");
|
||||
|
||||
i = lstrlen(CurrentString);
|
||||
while ((i < LineLength) &&
|
||||
((ch = Line[i]) != ' ') &&
|
||||
(ch != 0x09) &&
|
||||
(ch != ';')) {
|
||||
CurrentString[i] = ch;
|
||||
i++;
|
||||
}
|
||||
CurrentString[i] = '\0';
|
||||
CurrentToken = TokenString;
|
||||
CurrentChar = i + 1;
|
||||
lstrcpy(SrcName, CurrentString);
|
||||
|
||||
SkipSpaces();
|
||||
|
||||
if (CurrentToken != TokenEnd) {
|
||||
j = lstrlen(CurrentString); i = 0;
|
||||
while ((CurrentChar + i < LineLength) &&
|
||||
((ch = Line[CurrentChar + i]) != ' ') &&
|
||||
(ch != 0x09) &&
|
||||
(ch != ';')) {
|
||||
CurrentString[j + i] = ch;
|
||||
i++;
|
||||
}
|
||||
CurrentString[j + i] = '\0';
|
||||
CurrentToken = TokenString;
|
||||
CurrentChar += i + 1;
|
||||
lstrcpy(DstName, CurrentString);
|
||||
}
|
||||
|
||||
if (!CabinetCreated) {
|
||||
|
||||
DPRINT(MID_TRACE, ("Creating cabinet.\n"));
|
||||
|
||||
Status = NewCabinet();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot create cabinet (%d).\n", (UINT)Status));
|
||||
printf("Cannot create cabinet.\n");
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
CabinetCreated = TRUE;
|
||||
|
||||
DPRINT(MID_TRACE, ("Creating disk.\n"));
|
||||
|
||||
Status = NewDisk();
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
DPRINT(MIN_TRACE, ("Cannot create disk (%d).\n", (UINT)Status));
|
||||
printf("Cannot create disk.\n");
|
||||
return CAB_STATUS_FAILURE;
|
||||
}
|
||||
DiskCreated = TRUE;
|
||||
SetupNewDisk();
|
||||
}
|
||||
|
||||
DPRINT(MID_TRACE, ("Adding file: '%s' destination: '%s'.\n", SrcName, DstName));
|
||||
|
||||
Status = AddFile(SrcName);
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
if (Status == CAB_STATUS_CANNOT_OPEN)
|
||||
printf("File does not exist: %s.\n", SrcName);
|
||||
else if (Status == CAB_STATUS_NOMEMORY)
|
||||
printf("Insufficient memory to add file: %s.\n", SrcName);
|
||||
else
|
||||
printf("Cannot add file: %s (%d).\n", SrcName, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
return CAB_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
VOID CDFParser::SkipSpaces()
|
||||
/*
|
||||
* FUNCTION: Skips any spaces in the current line
|
||||
*/
|
||||
{
|
||||
NextToken();
|
||||
while (CurrentToken == TokenSpace)
|
||||
NextToken();
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::IsNextToken(TOKEN Token, BOOL NoSpaces)
|
||||
/*
|
||||
* FUNCTION: Checks if next token equals Token
|
||||
* ARGUMENTS:
|
||||
* Token = Token to compare with
|
||||
* SkipSp = TRUE if spaces should be skipped
|
||||
* RETURNS:
|
||||
* FALSE if next token is diffrent from Token
|
||||
*/
|
||||
{
|
||||
if (NoSpaces)
|
||||
SkipSpaces();
|
||||
else
|
||||
NextToken();
|
||||
return (CurrentToken == Token);
|
||||
}
|
||||
|
||||
|
||||
BOOL CDFParser::ReadLine()
|
||||
/*
|
||||
* FUNCTION: Reads the next line into the line buffer
|
||||
* RETURNS:
|
||||
* TRUE if there is a new line, FALSE if not
|
||||
*/
|
||||
{
|
||||
ULONG i, j;
|
||||
TCHAR ch;
|
||||
|
||||
if (CurrentOffset >= FileBufferSize)
|
||||
return FALSE;
|
||||
|
||||
i = 0;
|
||||
while (((j = CurrentOffset + i) < FileBufferSize) && (i < 127) &&
|
||||
((ch = FileBuffer[j]) != 0x0D)) {
|
||||
Line[i] = ch;
|
||||
i++;
|
||||
}
|
||||
|
||||
Line[i] = '\0';
|
||||
LineLength = i;
|
||||
|
||||
if (FileBuffer[CurrentOffset + i + 1] == 0x0A)
|
||||
CurrentOffset++;
|
||||
|
||||
CurrentOffset += i + 1;
|
||||
|
||||
CurrentChar = 0;
|
||||
|
||||
CurrentLine++;
|
||||
|
||||
NextToken();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID CDFParser::NextToken()
|
||||
/*
|
||||
* FUNCTION: Reads the next token from the current line
|
||||
*/
|
||||
{
|
||||
ULONG i;
|
||||
TCHAR ch = ' ';
|
||||
|
||||
if (CurrentChar >= LineLength) {
|
||||
CurrentToken = TokenEnd;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Line[CurrentChar]) {
|
||||
case ' ':
|
||||
case 0x09: CurrentToken = TokenSpace;
|
||||
break;
|
||||
case ';': CurrentToken = TokenSemi;
|
||||
break;
|
||||
case '=': CurrentToken = TokenEqual;
|
||||
break;
|
||||
case '.': CurrentToken = TokenPeriod;
|
||||
break;
|
||||
case '\\': CurrentToken = TokenBackslash;
|
||||
break;
|
||||
case '"':
|
||||
i = 0;
|
||||
while ((CurrentChar + i + 1 < LineLength) &&
|
||||
((ch = Line[CurrentChar + i + 1]) != '"')) {
|
||||
CurrentString[i] = ch;
|
||||
i++;
|
||||
}
|
||||
CurrentString[i] = '\0';
|
||||
CurrentToken = TokenString;
|
||||
CurrentChar += i + 2;
|
||||
return;
|
||||
default:
|
||||
i = 0;
|
||||
while ((CurrentChar + i < LineLength) &&
|
||||
((ch = Line[CurrentChar + i]) >= '0') && (ch <= '9')) {
|
||||
CurrentString[i] = ch;
|
||||
i++;
|
||||
}
|
||||
if (i > 0) {
|
||||
CurrentString[i] = '\0';
|
||||
CurrentInteger = atoi((PCHAR)CurrentString);
|
||||
CurrentToken = TokenInteger;
|
||||
CurrentChar += i;
|
||||
return;
|
||||
}
|
||||
i = 0;
|
||||
while (((CurrentChar + i < LineLength) &&
|
||||
(((ch = Line[CurrentChar + i]) >= 'a') && (ch <= 'z')) ||
|
||||
((ch >= 'A') && (ch <= 'Z')) || (ch == '_'))) {
|
||||
CurrentString[i] = ch;
|
||||
i++;
|
||||
}
|
||||
if (i > 0) {
|
||||
CurrentString[i] = '\0';
|
||||
CurrentToken = TokenIdentifier;
|
||||
CurrentChar += i;
|
||||
return;
|
||||
}
|
||||
CurrentToken = TokenUnknown;
|
||||
}
|
||||
CurrentChar++;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,130 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/dfp.h
|
||||
* PURPOSE: Directive file parser header
|
||||
*/
|
||||
#ifndef __DFP_H
|
||||
#define __DFP_H
|
||||
|
||||
#include "cabinet.h"
|
||||
|
||||
typedef struct _CABINET_NAME {
|
||||
struct _CABINET_NAME *Next;
|
||||
ULONG DiskNumber;
|
||||
TCHAR Name[128];
|
||||
} CABINET_NAME, *PCABINET_NAME;
|
||||
|
||||
typedef struct _DISK_NUMBER {
|
||||
struct _DISK_NUMBER *Next;
|
||||
ULONG DiskNumber;
|
||||
ULONG Number;
|
||||
} DISK_NUMBER, *PDISK_NUMBER;
|
||||
|
||||
typedef enum {
|
||||
TokenUnknown,
|
||||
TokenInteger,
|
||||
TokenIdentifier,
|
||||
TokenString,
|
||||
TokenSpace,
|
||||
TokenSemi,
|
||||
TokenEqual,
|
||||
TokenPeriod,
|
||||
TokenBackslash,
|
||||
TokenEnd,
|
||||
} TOKEN;
|
||||
|
||||
|
||||
typedef enum {
|
||||
stCabinetName,
|
||||
stCabinetNameTemplate,
|
||||
stDiskLabel,
|
||||
stDiskLabelTemplate,
|
||||
stMaxDiskSize
|
||||
} SETTYPE;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ntDisk,
|
||||
ntCabinet,
|
||||
ntFolder,
|
||||
} NEWTYPE;
|
||||
|
||||
|
||||
/* Classes */
|
||||
|
||||
class CDFParser : public CCabinet {
|
||||
public:
|
||||
CDFParser();
|
||||
virtual ~CDFParser();
|
||||
ULONG Load(LPTSTR FileName);
|
||||
ULONG Parse();
|
||||
private:
|
||||
/* Event handlers */
|
||||
virtual BOOL OnDiskLabel(ULONG Number, LPTSTR Label);
|
||||
virtual BOOL OnCabinetName(ULONG Number, LPTSTR Name);
|
||||
|
||||
BOOL SetDiskName(PCABINET_NAME *List, ULONG Number, LPTSTR String);
|
||||
BOOL GetDiskName(PCABINET_NAME *List, ULONG Number, LPTSTR String);
|
||||
BOOL SetDiskNumber(PDISK_NUMBER *List, ULONG Number, ULONG Value);
|
||||
BOOL GetDiskNumber(PDISK_NUMBER *List, ULONG Number, PULONG Value);
|
||||
BOOL DoDiskLabel(ULONG Number, LPTSTR Label);
|
||||
VOID DoDiskLabelTemplate(LPTSTR Template);
|
||||
BOOL DoCabinetName(ULONG Number, LPTSTR Name);
|
||||
VOID DoCabinetNameTemplate(LPTSTR Template);
|
||||
ULONG DoMaxDiskSize(BOOL NumberValid, ULONG Number);
|
||||
ULONG SetupNewDisk();
|
||||
ULONG PerformSetCommand();
|
||||
ULONG PerformNewCommand();
|
||||
ULONG PerformCommand();
|
||||
ULONG PerformFileCopy();
|
||||
VOID SkipSpaces();
|
||||
BOOL IsNextToken(TOKEN Token, BOOL NoSpaces);
|
||||
BOOL ReadLine();
|
||||
VOID NextToken();
|
||||
/* Parsing */
|
||||
BOOL FileLoaded;
|
||||
HANDLE FileHandle;
|
||||
PCHAR FileBuffer;
|
||||
DWORD FileBufferSize;
|
||||
ULONG CurrentOffset;
|
||||
TCHAR Line[128];
|
||||
ULONG LineLength;
|
||||
ULONG CurrentLine;
|
||||
ULONG CurrentChar;
|
||||
/* Token */
|
||||
TOKEN CurrentToken;
|
||||
ULONG CurrentInteger;
|
||||
TCHAR CurrentString[256];
|
||||
|
||||
/* State */
|
||||
BOOL CabinetCreated;
|
||||
BOOL DiskCreated;
|
||||
BOOL FolderCreated;
|
||||
/* Standard directive variable */
|
||||
BOOL Cabinet;
|
||||
ULONG CabinetFileCountThreshold;
|
||||
PCABINET_NAME CabinetName;
|
||||
BOOL CabinetNameTemplateSet;
|
||||
TCHAR CabinetNameTemplate[128];
|
||||
BOOL Compress;
|
||||
ULONG CompressionType;
|
||||
PCABINET_NAME DiskLabel;
|
||||
BOOL DiskLabelTemplateSet;
|
||||
TCHAR DiskLabelTemplate[128];
|
||||
ULONG FolderFileCountThreshold;
|
||||
ULONG FolderSizeThreshold;
|
||||
ULONG MaxCabinetSize;
|
||||
ULONG MaxDiskFileCount;
|
||||
PDISK_NUMBER MaxDiskSize;
|
||||
BOOL MaxDiskSizeAllSet;
|
||||
ULONG MaxDiskSizeAll;
|
||||
ULONG ReservePerCabinetSize;
|
||||
ULONG ReservePerDataBlockSize;
|
||||
ULONG ReservePerFolderSize;
|
||||
TCHAR SourceDir[256];
|
||||
};
|
||||
|
||||
#endif /* __DFP_H */
|
||||
|
||||
/* EOF */
|
|
@ -1,493 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/main.cpp
|
||||
* PURPOSE: Main program
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 21/03-2001 Created
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#include <reactos/buildno.h>
|
||||
#include "cabman.h"
|
||||
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
DWORD DebugTraceLevel = MIN_TRACE;
|
||||
//DWORD DebugTraceLevel = MID_TRACE;
|
||||
//DWORD DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
#define CM_VERSION KERNEL_VERSION_STR
|
||||
|
||||
|
||||
LPTSTR Pad(LPTSTR Str, CHAR PadChar, UINT 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
|
||||
*/
|
||||
{
|
||||
UINT Len;
|
||||
|
||||
Len = lstrlen(Str);
|
||||
|
||||
if (Len < Length) {
|
||||
memcpy(&Str[Length - Len], Str, Len + 1);
|
||||
memset(Str, PadChar, Length - Len);
|
||||
}
|
||||
return Str;
|
||||
}
|
||||
|
||||
|
||||
LPTSTR Date2Str(LPTSTR Str, WORD Date)
|
||||
/*
|
||||
* FUNCTION: Converts a DOS style date to a string
|
||||
* ARGUMENTS:
|
||||
* Str = Pointer to destination string
|
||||
* Date = DOS style date
|
||||
* RETURNS:
|
||||
* Pointer to string
|
||||
*/
|
||||
{
|
||||
DWORD 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;
|
||||
}
|
||||
|
||||
|
||||
LPTSTR Time2Str(LPTSTR Str, WORD 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;
|
||||
DWORD Hour;
|
||||
DWORD 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;
|
||||
}
|
||||
|
||||
|
||||
LPTSTR Attr2Str(LPTSTR Str, WORD 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;
|
||||
Mode = CM_MODE_DISPLAY;
|
||||
PromptOnOverwrite = TRUE;
|
||||
}
|
||||
|
||||
|
||||
CCABManager::~CCABManager()
|
||||
/*
|
||||
* FUNCTION: Default destructor
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::Usage()
|
||||
/*
|
||||
* FUNCTION: Display usage information on screen
|
||||
*/
|
||||
{
|
||||
printf("ReactOS Cabinet Manager - Version %s\n\n", CM_VERSION);
|
||||
printf("CABMAN [/D | /E] [/A] [/L dir] [/Y] cabinet [filename ...]\n");
|
||||
printf("CABMAN /C dirfile\n");
|
||||
printf(" cabinet Cabinet file.\n");
|
||||
printf(" filename Name of the file to 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\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(" /L dir Location to place extracted files\n");
|
||||
printf(" (default is current directory).\n");
|
||||
printf(" /Y Do not prompt before overwriting an existing file.\n\n");
|
||||
}
|
||||
|
||||
|
||||
BOOL CCABManager::ParseCmdline(INT argc, PCHAR 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 'l':
|
||||
case 'L':
|
||||
if (argv[i][2] == ' ') {
|
||||
i++;
|
||||
SetDestinationPath((LPTSTR)&argv[i][0]);
|
||||
} else
|
||||
SetDestinationPath((LPTSTR)&argv[i][1]);
|
||||
break;
|
||||
case 'y':
|
||||
case 'Y': PromptOnOverwrite = FALSE; break;
|
||||
default:
|
||||
printf("Bad parameter %s.\n", argv[i]);
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if ((FoundCabinet) || (Mode == CM_MODE_CREATE)) {
|
||||
/* FIXME: There may be many of these if Mode != CM_MODE_CREATE */
|
||||
lstrcpy((LPTSTR)FileName, argv[i]);
|
||||
} else {
|
||||
SetCabinetName(argv[i]);
|
||||
FoundCabinet = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ShowUsage) {
|
||||
Usage();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME */
|
||||
SelectCodec(CAB_CODEC_MSZIP);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::CreateCabinet()
|
||||
/*
|
||||
* FUNCTION: Create cabinet
|
||||
*/
|
||||
{
|
||||
ULONG Status;
|
||||
|
||||
Status = Load((LPTSTR)&FileName);
|
||||
if (Status != CAB_STATUS_SUCCESS) {
|
||||
printf("Specified directive file could not be found: %s.\n", (LPTSTR)&FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
Parse();
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::DisplayCabinet()
|
||||
/*
|
||||
* FUNCTION: Display cabinet contents
|
||||
*/
|
||||
{
|
||||
CAB_SEARCH Search;
|
||||
TCHAR Str[20];
|
||||
DWORD FileCount = 0;
|
||||
DWORD ByteCount = 0;
|
||||
|
||||
if (Open() == CAB_STATUS_SUCCESS) {
|
||||
printf("Cabinet %s\n\n", GetCabinetName());
|
||||
|
||||
if (FindFirst("", &Search) == CAB_STATUS_SUCCESS) {
|
||||
do {
|
||||
if (Search.File->FileControlID != CAB_FILE_CONTINUED) {
|
||||
printf("%s ", Date2Str((LPTSTR)&Str, Search.File->FileDate));
|
||||
printf("%s ", Time2Str((LPTSTR)&Str, Search.File->FileTime));
|
||||
printf("%s ", Attr2Str((LPTSTR)&Str, Search.File->Attributes));
|
||||
printf("%s ", Pad(itoa(Search.File->FileSize, (LPTSTR)&Str, 10), ' ', 13));
|
||||
printf("%s\n", Search.FileName);
|
||||
|
||||
FileCount++;
|
||||
ByteCount += Search.File->FileSize;
|
||||
}
|
||||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
if (FileCount > 0) {
|
||||
if (FileCount == 1)
|
||||
printf(" 1 file ");
|
||||
else
|
||||
printf(" %s files ",
|
||||
Pad(itoa(FileCount, (LPTSTR)&Str, 10), ' ', 12));
|
||||
|
||||
if (ByteCount == 1)
|
||||
printf(" 1 byte\n");
|
||||
else
|
||||
printf("%s bytes\n",
|
||||
Pad(itoa(ByteCount, (LPTSTR)&Str, 10), ' ', 12));
|
||||
} else {
|
||||
/* There should be at least one file in a cabinet */
|
||||
printf("No files in cabinet.");
|
||||
}
|
||||
} else
|
||||
printf("Cannot not open file: %s\n", GetCabinetName());
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::ExtractFromCabinet()
|
||||
/*
|
||||
* FUNCTION: Extract file(s) from cabinet
|
||||
*/
|
||||
{
|
||||
CAB_SEARCH Search;
|
||||
ULONG Status;
|
||||
|
||||
if (Open() == CAB_STATUS_SUCCESS) {
|
||||
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("Cabinet contains errors.\n");
|
||||
return;
|
||||
case CAB_STATUS_UNSUPPCOMP:
|
||||
printf("Cabinet uses unsupported compression type.\n");
|
||||
return;
|
||||
case CAB_STATUS_CANNOT_WRITE:
|
||||
printf("You've run out of free space on the destination volume or the volume is damaged.\n");
|
||||
return;
|
||||
default:
|
||||
printf("Unspecified error code (%d).\n", (UINT)Status);
|
||||
return;
|
||||
}
|
||||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
}
|
||||
} else
|
||||
printf("Cannot not open file: %s.\n", GetCabinetName());
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::Run()
|
||||
/*
|
||||
* FUNCTION: Process cabinet
|
||||
*/
|
||||
{
|
||||
printf("ReactOS Cabinet Manager - Version %s\n\n", CM_VERSION);
|
||||
|
||||
switch (Mode) {
|
||||
case CM_MODE_CREATE: CreateCabinet(); break;
|
||||
case CM_MODE_DISPLAY: DisplayCabinet(); break;
|
||||
case CM_MODE_EXTRACT: ExtractFromCabinet(); break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
/* Event handlers */
|
||||
|
||||
BOOL CCABManager::OnOverwrite(PCFFILE File,
|
||||
LPTSTR 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
|
||||
*/
|
||||
{
|
||||
TCHAR ch;
|
||||
|
||||
if (Mode == CM_MODE_CREATE)
|
||||
return TRUE;
|
||||
|
||||
/* Should we prompt on overwrite? */
|
||||
if (!PromptOnOverwrite)
|
||||
return TRUE;
|
||||
|
||||
/* Ask if file should be overwritten */
|
||||
printf("Overwrite %s (Yes/No/All)? ", GetFileName(FileName));
|
||||
|
||||
for (;;) {
|
||||
ch = _getch();
|
||||
switch (ch) {
|
||||
case 'Y':
|
||||
case 'y': printf("%c\n", ch); return TRUE;
|
||||
case 'N':
|
||||
case 'n': printf("%c\n", ch); return FALSE;
|
||||
case 'A':
|
||||
case 'a': printf("%c\n", ch); PromptOnOverwrite = FALSE; return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::OnExtract(PCFFILE File,
|
||||
LPTSTR 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)
|
||||
*/
|
||||
{
|
||||
printf("Extracting %s\n", GetFileName(FileName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID CCABManager::OnDiskChange(LPTSTR CabinetName,
|
||||
LPTSTR 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
|
||||
*/
|
||||
{
|
||||
printf("\nChanging to cabinet %s - %s\n\n", CabinetName, DiskLabel);
|
||||
}
|
||||
|
||||
|
||||
VOID CCABManager::OnAdd(PCFFILE File,
|
||||
LPTSTR 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)
|
||||
*/
|
||||
{
|
||||
printf("Adding %s\n", GetFileName(FileName));
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
{
|
||||
CCABManager CABMgr;
|
||||
|
||||
if (CABMgr.ParseCmdline(argc, argv))
|
||||
CABMgr.Run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,26 +0,0 @@
|
|||
# $Id: makefile,v 1.8 2003/04/13 03:24:26 hyperion Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
TARGET_TYPE = program
|
||||
|
||||
TARGET_APPTYPE = console
|
||||
|
||||
TARGET_NAME = cabman
|
||||
|
||||
TARGET_OBJECTS = cabinet.o mszip.o raw.o main.o dfp.o
|
||||
|
||||
TARGET_SDKLIBS = zlib.a
|
||||
|
||||
TARGET_CFLAGS = -I$(PATH_TO_TOP)/lib/zlib
|
||||
|
||||
TARGET_CPPFLAGS = $(TARGET_CFLAGS)
|
||||
|
||||
TARGET_GCCLIBS = stdc++
|
||||
|
||||
TARGET_NORC = yes
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
|
@ -1,172 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/mszip.cpp
|
||||
* PURPOSE: CAB codec for MSZIP compressed data
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* NOTES: The ZLIB does the real work. Get the full version
|
||||
* from http://www.cdrom.com/pub/infozip/zlib/
|
||||
* REVISIONS:
|
||||
* CSH 21/03-2001 Created
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "mszip.h"
|
||||
|
||||
|
||||
/* Memory functions */
|
||||
|
||||
voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
DPRINT(DEBUG_MEMORY, ("items = (%d) size = (%d)\n", items, size));
|
||||
return HeapAlloc(GetProcessHeap(), 0, items * size);
|
||||
}
|
||||
|
||||
void MSZipFree (voidpf opaque, voidpf address)
|
||||
{
|
||||
DPRINT(DEBUG_MEMORY, ("\n"));
|
||||
HeapFree(GetProcessHeap(), 0, address);
|
||||
}
|
||||
|
||||
|
||||
/* CMSZipCodec */
|
||||
|
||||
CMSZipCodec::CMSZipCodec()
|
||||
/*
|
||||
* FUNCTION: Default constructor
|
||||
*/
|
||||
{
|
||||
ZStream.zalloc = MSZipAlloc;
|
||||
ZStream.zfree = MSZipFree;
|
||||
ZStream.opaque = (voidpf)0;
|
||||
}
|
||||
|
||||
|
||||
CMSZipCodec::~CMSZipCodec()
|
||||
/*
|
||||
* FUNCTION: Default destructor
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ULONG CMSZipCodec::Compress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength)
|
||||
/*
|
||||
* FUNCTION: Compresses data in a buffer
|
||||
* ARGUMENTS:
|
||||
* OutputBuffer = Pointer to buffer to place compressed data
|
||||
* InputBuffer = Pointer to buffer with data to be compressed
|
||||
* InputLength = Length of input buffer
|
||||
* OutputLength = Address of buffer to place size of compressed data
|
||||
*/
|
||||
{
|
||||
PUSHORT Magic;
|
||||
|
||||
DPRINT(MAX_TRACE, ("InputLength (%d).\n", InputLength));
|
||||
|
||||
Magic = (PUSHORT)OutputBuffer;
|
||||
*Magic = MSZIP_MAGIC;
|
||||
|
||||
ZStream.next_in = (PUCHAR)InputBuffer;
|
||||
ZStream.avail_in = InputLength;
|
||||
ZStream.next_out = (PUCHAR)((ULONG)OutputBuffer + 2);
|
||||
ZStream.avail_out = CAB_BLOCKSIZE + 12;
|
||||
|
||||
/* WindowBits is passed < 0 to tell that there is no zlib header */
|
||||
Status = deflateInit2(&ZStream,
|
||||
Z_BEST_COMPRESSION,
|
||||
Z_DEFLATED,
|
||||
-MAX_WBITS,
|
||||
8, /* memLevel */
|
||||
Z_DEFAULT_STRATEGY);
|
||||
if (Status != Z_OK) {
|
||||
DPRINT(MIN_TRACE, ("deflateInit() returned (%d).\n", Status));
|
||||
return CS_NOMEMORY;
|
||||
}
|
||||
|
||||
Status = deflate(&ZStream, Z_FINISH);
|
||||
if ((Status != Z_OK) && (Status != Z_STREAM_END)) {
|
||||
DPRINT(MIN_TRACE, ("deflate() returned (%d) (%s).\n", Status, ZStream.msg));
|
||||
if (Status == Z_MEM_ERROR)
|
||||
return CS_NOMEMORY;
|
||||
return CS_BADSTREAM;
|
||||
}
|
||||
|
||||
*OutputLength = ZStream.total_out + 2;
|
||||
|
||||
Status = deflateEnd(&ZStream);
|
||||
if (Status != Z_OK) {
|
||||
DPRINT(MIN_TRACE, ("deflateEnd() returned (%d).\n", Status));
|
||||
return CS_BADSTREAM;
|
||||
}
|
||||
|
||||
return CS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ULONG CMSZipCodec::Uncompress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength)
|
||||
/*
|
||||
* FUNCTION: Uncompresses data in a buffer
|
||||
* ARGUMENTS:
|
||||
* OutputBuffer = Pointer to buffer to place uncompressed data
|
||||
* InputBuffer = Pointer to buffer with data to be uncompressed
|
||||
* InputLength = Length of input buffer
|
||||
* OutputLength = Address of buffer to place size of uncompressed data
|
||||
*/
|
||||
{
|
||||
USHORT Magic;
|
||||
|
||||
DPRINT(MAX_TRACE, ("InputLength (%d).\n", InputLength));
|
||||
|
||||
Magic = *((PUSHORT)InputBuffer);
|
||||
|
||||
if (Magic != MSZIP_MAGIC) {
|
||||
DPRINT(MID_TRACE, ("Bad MSZIP block header magic (0x%X)\n", Magic));
|
||||
return CS_BADSTREAM;
|
||||
}
|
||||
|
||||
ZStream.next_in = (PUCHAR)((ULONG)InputBuffer + 2);
|
||||
ZStream.avail_in = InputLength - 2;
|
||||
ZStream.next_out = (PUCHAR)OutputBuffer;
|
||||
ZStream.avail_out = CAB_BLOCKSIZE + 12;
|
||||
|
||||
/* WindowBits is passed < 0 to tell that there is no zlib header.
|
||||
* Note that in this case inflate *requires* an extra "dummy" byte
|
||||
* after the compressed stream in order to complete decompression and
|
||||
* return Z_STREAM_END.
|
||||
*/
|
||||
Status = inflateInit2(&ZStream, -MAX_WBITS);
|
||||
if (Status != Z_OK) {
|
||||
DPRINT(MIN_TRACE, ("inflateInit2() returned (%d).\n", Status));
|
||||
return CS_BADSTREAM;
|
||||
}
|
||||
|
||||
while ((ZStream.total_out < CAB_BLOCKSIZE + 12) &&
|
||||
(ZStream.total_in < InputLength - 2)) {
|
||||
Status = inflate(&ZStream, Z_NO_FLUSH);
|
||||
if (Status == Z_STREAM_END) break;
|
||||
if (Status != Z_OK) {
|
||||
DPRINT(MIN_TRACE, ("inflate() returned (%d) (%s).\n", Status, ZStream.msg));
|
||||
if (Status == Z_MEM_ERROR)
|
||||
return CS_NOMEMORY;
|
||||
return CS_BADSTREAM;
|
||||
}
|
||||
}
|
||||
|
||||
*OutputLength = ZStream.total_out;
|
||||
|
||||
Status = inflateEnd(&ZStream);
|
||||
if (Status != Z_OK) {
|
||||
DPRINT(MIN_TRACE, ("inflateEnd() returned (%d).\n", Status));
|
||||
return CS_BADSTREAM;
|
||||
}
|
||||
return CS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/mszip.h
|
||||
* PURPOSE: CAB codec for MSZIP compressed data
|
||||
*/
|
||||
#ifndef __MSZIP_H
|
||||
#define __MSZIP_H
|
||||
|
||||
#include "cabinet.h"
|
||||
#include <zlib.h>
|
||||
|
||||
#define MSZIP_MAGIC 0x4B43
|
||||
|
||||
|
||||
/* Classes */
|
||||
|
||||
class CMSZipCodec : public CCABCodec {
|
||||
public:
|
||||
/* Default constructor */
|
||||
CMSZipCodec();
|
||||
/* Default destructor */
|
||||
virtual ~CMSZipCodec();
|
||||
/* Compresses a data block */
|
||||
virtual ULONG Compress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength);
|
||||
/* Uncompresses a data block */
|
||||
virtual ULONG Uncompress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength);
|
||||
private:
|
||||
INT Status;
|
||||
z_stream ZStream; /* Zlib stream */
|
||||
};
|
||||
|
||||
#endif /* __MSZIP_H */
|
||||
|
||||
/* EOF */
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/raw.cpp
|
||||
* PURPOSE: CAB codec for uncompressed "raw" data
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 21/03-2001 Created
|
||||
*/
|
||||
#include <windows.h>
|
||||
#include "raw.h"
|
||||
|
||||
|
||||
/* CRawCodec */
|
||||
|
||||
CRawCodec::CRawCodec()
|
||||
/*
|
||||
* FUNCTION: Default constructor
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CRawCodec::~CRawCodec()
|
||||
/*
|
||||
* FUNCTION: Default destructor
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ULONG CRawCodec::Compress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength)
|
||||
/*
|
||||
* FUNCTION: Compresses data in a buffer
|
||||
* ARGUMENTS:
|
||||
* OutputBuffer = Pointer to buffer to place compressed data
|
||||
* InputBuffer = Pointer to buffer with data to be compressed
|
||||
* InputLength = Length of input buffer
|
||||
* OutputLength = Address of buffer to place size of compressed data
|
||||
*/
|
||||
{
|
||||
CopyMemory(OutputBuffer, InputBuffer, InputLength);
|
||||
*OutputLength = InputLength;
|
||||
return CS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ULONG CRawCodec::Uncompress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength)
|
||||
/*
|
||||
* FUNCTION: Uncompresses data in a buffer
|
||||
* ARGUMENTS:
|
||||
* OutputBuffer = Pointer to buffer to place uncompressed data
|
||||
* InputBuffer = Pointer to buffer with data to be uncompressed
|
||||
* InputLength = Length of input buffer
|
||||
* OutputLength = Address of buffer to place size of uncompressed data
|
||||
*/
|
||||
{
|
||||
CopyMemory(OutputBuffer, InputBuffer, InputLength);
|
||||
*OutputLength = InputLength;
|
||||
return CS_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS cabinet manager
|
||||
* FILE: apps/cabman/raw.h
|
||||
* PURPOSE: CAB codec for uncompressed data
|
||||
*/
|
||||
#ifndef __RAW_H
|
||||
#define __RAW_H
|
||||
|
||||
#include "cabinet.h"
|
||||
|
||||
|
||||
/* Classes */
|
||||
|
||||
class CRawCodec : public CCABCodec {
|
||||
public:
|
||||
/* Default constructor */
|
||||
CRawCodec();
|
||||
/* Default destructor */
|
||||
virtual ~CRawCodec();
|
||||
/* Compresses a data block */
|
||||
virtual ULONG Compress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength);
|
||||
/* Uncompresses a data block */
|
||||
virtual ULONG Uncompress(PVOID OutputBuffer,
|
||||
PVOID InputBuffer,
|
||||
DWORD InputLength,
|
||||
PDWORD OutputLength);
|
||||
};
|
||||
|
||||
#endif /* __RAW_H */
|
||||
|
||||
/* EOF */
|
|
@ -1,164 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Test program for cabinet classes
|
||||
* FILE: apps/cabman/test.cpp
|
||||
* PURPOSE: Test program
|
||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||
* REVISIONS:
|
||||
* CSH 21/03-2001 Created
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <conio.h>
|
||||
#include <windows.h>
|
||||
#include "test.h"
|
||||
|
||||
|
||||
#ifdef DBG
|
||||
|
||||
DWORD DebugTraceLevel = MIN_TRACE;
|
||||
//DWORD DebugTraceLevel = MID_TRACE;
|
||||
//DWORD DebugTraceLevel = MAX_TRACE;
|
||||
|
||||
#endif /* DBG */
|
||||
|
||||
|
||||
/* CCABManager */
|
||||
|
||||
CCABTest::CCABTest()
|
||||
/*
|
||||
* FUNCTION: Default constructor
|
||||
*/
|
||||
{
|
||||
PromptOnOverwrite = FALSE;
|
||||
}
|
||||
|
||||
|
||||
CCABTest::~CCABTest()
|
||||
/*
|
||||
* FUNCTION: Default destructor
|
||||
*/
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
VOID CCABTest::ExtractFromCabinet()
|
||||
/*
|
||||
* FUNCTION: Extract file(s) from cabinet
|
||||
*/
|
||||
{
|
||||
CAB_SEARCH Search;
|
||||
ULONG Status;
|
||||
|
||||
if (Open() == CAB_STATUS_SUCCESS) {
|
||||
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("Cabinet contains errors.\n");
|
||||
return;
|
||||
case CAB_STATUS_UNSUPPCOMP:
|
||||
printf("Cabinet uses unsupported compression type.\n");
|
||||
return;
|
||||
case CAB_STATUS_CANNOT_WRITE:
|
||||
printf("You've run out of free space on the destination volume or the volume is damaged.\n");
|
||||
return;
|
||||
default:
|
||||
printf("Unspecified error code (%d).\n", (UINT)Status);
|
||||
return;
|
||||
}
|
||||
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
|
||||
}
|
||||
} else {
|
||||
printf("Cannot not open file: %s.\n", GetCabinetName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Event handlers */
|
||||
|
||||
BOOL CCABTest::OnOverwrite(PCFFILE File,
|
||||
LPTSTR 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
|
||||
*/
|
||||
{
|
||||
TCHAR ch;
|
||||
|
||||
/* Should we prompt on overwrite? */
|
||||
if (!PromptOnOverwrite)
|
||||
return TRUE;
|
||||
|
||||
/* Ask if file should be overwritten */
|
||||
printf("Overwrite %s (Yes/No/All)? ", GetFileName(FileName));
|
||||
|
||||
for (;;) {
|
||||
ch = _getch();
|
||||
switch (ch) {
|
||||
case 'Y':
|
||||
case 'y': printf("%c\n", ch); return TRUE;
|
||||
case 'N':
|
||||
case 'n': printf("%c\n", ch); return FALSE;
|
||||
case 'A':
|
||||
case 'a': printf("%c\n", ch); PromptOnOverwrite = FALSE; return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID CCABTest::OnExtract(PCFFILE File,
|
||||
LPTSTR 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)
|
||||
*/
|
||||
{
|
||||
printf("Extracting %s\n", GetFileName(FileName));
|
||||
}
|
||||
|
||||
|
||||
|
||||
VOID CCABTest::OnDiskChange(LPTSTR CabinetName,
|
||||
LPTSTR 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
|
||||
*/
|
||||
{
|
||||
printf("\nChanging to cabinet %s - %s\n\n", CabinetName, DiskLabel);
|
||||
}
|
||||
|
||||
|
||||
INT main(INT argc, PCHAR argv[])
|
||||
/*
|
||||
* FUNCTION: Main entry point
|
||||
* ARGUMENTS:
|
||||
* argc = Number of arguments on command line
|
||||
* argv = Pointer to list of command line arguments
|
||||
*/
|
||||
{
|
||||
CCABTest CABTest;
|
||||
|
||||
// Specify your cabinet filename here
|
||||
CABTest.SetCabinetName("ros1.cab");
|
||||
CABTest.ExtractFromCabinet();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: Test program for cabinet classes
|
||||
* FILE: apps/cabman/test.h
|
||||
* PURPOSE: Test program header
|
||||
*/
|
||||
#ifndef __TEST_H
|
||||
#define __TEST_H
|
||||
|
||||
#define CAB_READ_ONLY // Define for smaller read only version
|
||||
#include "cabinet.h"
|
||||
|
||||
|
||||
/* Classes */
|
||||
|
||||
class CCABTest : public CCabinet {
|
||||
public:
|
||||
CCABTest();
|
||||
virtual ~CCABTest();
|
||||
VOID ExtractFromCabinet();
|
||||
/* Event handlers */
|
||||
virtual BOOL OnOverwrite(PCFFILE File, LPTSTR FileName);
|
||||
virtual VOID OnExtract(PCFFILE File, LPTSTR FileName);
|
||||
virtual VOID OnDiskChange(LPTSTR CabinetName, LPTSTR DiskLabel);
|
||||
private:
|
||||
/* Configuration */
|
||||
BOOL PromptOnOverwrite;
|
||||
};
|
||||
|
||||
#endif /* __CABMAN_H */
|
||||
|
||||
/* EOF */
|
Loading…
Add table
Add a link
Reference in a new issue