diff --git a/reactos/apps/utils/cabman/.cvsignore b/reactos/apps/utils/cabman/.cvsignore deleted file mode 100644 index d63774a7353..00000000000 --- a/reactos/apps/utils/cabman/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -*.o -*.d -*.exe -*.coff -*.sym -*.map diff --git a/reactos/apps/utils/cabman/cabinet.cpp b/reactos/apps/utils/cabman/cabinet.cpp deleted file mode 100644 index c22cfe57f85..00000000000 --- a/reactos/apps/utils/cabman/cabinet.cpp +++ /dev/null @@ -1,2652 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS cabinet manager - * FILE: apps/cabman/cabinet.cpp - * PURPOSE: Cabinet routines - * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) - * NOTES: Define CAB_READ_ONLY for read only version - * REVISIONS: - * CSH 21/03-2001 Created - * TODO: - * - Checksum of datablocks should be calculated - * - EXTRACT.EXE complains if a disk is created manually - * - Folders that are created manually and span disks will result in a damaged cabinet - */ -#include -#include -#include -#include "cabinet.h" -#include "raw.h" -#include "mszip.h" - - -#ifndef CAB_READ_ONLY - -#ifdef DBG - -VOID DumpBuffer(PVOID Buffer, DWORD Size) -{ - HANDLE FileHandle; - DWORD BytesWritten; - - /* Create file, overwrite if it already exists */ - FileHandle = CreateFile("dump.bin", // Create this file - GENERIC_WRITE, // Open for writing - 0, // No sharing - NULL, // No security - CREATE_ALWAYS, // Create or overwrite - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (FileHandle == INVALID_HANDLE_VALUE) { - DPRINT(MID_TRACE, ("ERROR OPENING '%d'.\n", (UINT)GetLastError())); - return; - } - - if (!WriteFile(FileHandle, Buffer, Size, &BytesWritten, NULL)) { - DPRINT(MID_TRACE, ("ERROR WRITING '%d'.\n", (UINT)GetLastError())); - } - - CloseHandle(FileHandle); -} - -#endif /* DBG */ - - -/* CCFDATAStorage */ - -CCFDATAStorage::CCFDATAStorage() -/* - * FUNCTION: Default constructor - */ -{ - FileCreated = FALSE; -} - - -CCFDATAStorage::~CCFDATAStorage() -/* - * FUNCTION: Default destructor - */ -{ - ASSERT(!FileCreated); -} - - -ULONG CCFDATAStorage::Create(LPTSTR FileName) -/* - * FUNCTION: Creates the file - * ARGUMENTS: - * FileName = Pointer to name of file - * RETURNS: - * Status of operation - */ -{ - TCHAR FullName[MAX_PATH]; - - ASSERT(!FileCreated); - - if (GetTempPath(MAX_PATH, FullName) == 0) - return CAB_STATUS_CANNOT_CREATE; - - lstrcat(FullName, FileName); - - /* Create file, overwrite if it already exists */ - FileHandle = CreateFile(FullName, // Create this file - GENERIC_READ | GENERIC_WRITE, // Open for reading/writing - 0, // No sharing - NULL, // No security - CREATE_ALWAYS, // Create or overwrite - FILE_FLAG_SEQUENTIAL_SCAN | // Optimize for sequential scans - FILE_FLAG_DELETE_ON_CLOSE | // Delete file when closed - FILE_ATTRIBUTE_TEMPORARY, // Temporary file - NULL); // No attribute template - if (FileHandle == INVALID_HANDLE_VALUE) { - DPRINT(MID_TRACE, ("ERROR '%d'.\n", (UINT)GetLastError())); - return CAB_STATUS_CANNOT_CREATE; - } - - FileCreated = TRUE; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCFDATAStorage::Destroy() -/* - * FUNCTION: Destroys the file - * RETURNS: - * Status of operation - */ -{ - ASSERT(FileCreated); - - CloseHandle(FileHandle); - - FileCreated = FALSE; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCFDATAStorage::Truncate() -/* - * FUNCTION: Truncate the scratch file to zero bytes - * RETURNS: - * Status of operation - */ -{ - if (!SetFilePointer(FileHandle, 0, NULL, FILE_BEGIN)) - return CAB_STATUS_FAILURE; - if (!SetEndOfFile(FileHandle)) - return CAB_STATUS_FAILURE; - return CAB_STATUS_SUCCESS; -} - - -ULONG CCFDATAStorage::Position() -/* - * FUNCTION: Returns current position in file - * RETURNS: - * Current position - */ -{ - return SetFilePointer(FileHandle, 0, NULL, FILE_CURRENT); -} - - -ULONG CCFDATAStorage::Seek(LONG Position) -/* - * FUNCTION: Seeks to an absolute position - * ARGUMENTS: - * Position = Absolute position to seek to - * RETURNS: - * Status of operation - */ -{ - if (SetFilePointer(FileHandle, - Position, - NULL, - FILE_BEGIN) == 0xFFFFFFFF) - return CAB_STATUS_FAILURE; - else - return CAB_STATUS_SUCCESS; -} - - -ULONG CCFDATAStorage::ReadBlock(PCFDATA Data, PVOID Buffer, PDWORD BytesRead) -/* - * FUNCTION: Reads a CFDATA block from the file - * ARGUMENTS: - * Data = Pointer to CFDATA block for the buffer - * Buffer = Pointer to buffer to store data read - * BytesWritten = Pointer to buffer to write number of bytes read - * RETURNS: - * Status of operation - */ -{ - if (!ReadFile(FileHandle, Buffer, Data->CompSize, BytesRead, NULL)) - return CAB_STATUS_CANNOT_READ; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCFDATAStorage::WriteBlock(PCFDATA Data, PVOID Buffer, PDWORD BytesWritten) -/* - * FUNCTION: Writes a CFDATA block to the file - * ARGUMENTS: - * Data = Pointer to CFDATA block for the buffer - * Buffer = Pointer to buffer with data to write - * BytesWritten = Pointer to buffer to write number of bytes written - * RETURNS: - * Status of operation - */ -{ - if (!WriteFile(FileHandle, Buffer, Data->CompSize, BytesWritten, NULL)) - return CAB_STATUS_CANNOT_WRITE; - - return CAB_STATUS_SUCCESS; -} - -#endif /* CAB_READ_ONLY */ - - -/* CCabinet */ - -CCabinet::CCabinet() -/* - * FUNCTION: Default constructor - */ -{ - FileOpen = FALSE; - lstrcpy(DestPath, ""); - - FolderListHead = NULL; - FolderListTail = NULL; - FileListHead = NULL; - FileListTail = NULL; - - Codec = new CRawCodec(); - CodecId = CAB_CODEC_RAW; - CodecSelected = TRUE; - - OutputBuffer = NULL; - InputBuffer = NULL; - MaxDiskSize = 0; - BlockIsSplit = FALSE; - ScratchFile = NULL; - - FolderUncompSize = 0; - BytesLeftInBlock = 0; - ReuseBlock = FALSE; - CurrentDataNode = NULL; -} - - -CCabinet::~CCabinet() -/* - * FUNCTION: Default destructor - */ -{ - if (CodecSelected) - delete Codec; -} - - -LPTSTR CCabinet::GetFileName(LPTSTR Path) -/* - * FUNCTION: Returns a pointer to file name - * ARGUMENTS: - * Path = Pointer to string with pathname - * RETURNS: - * Pointer to filename - */ -{ - DWORD i, j; - - j = i = (Path[0] ? (Path[1] == ':' ? 2 : 0) : 0); - - while (Path [i++]) { - if (Path [i - 1] == '\\') j = i; - } - return Path + j; -} - - -VOID CCabinet::RemoveFileName(LPTSTR Path) -/* - * FUNCTION: Removes a file name from a path - * ARGUMENTS: - * Path = Pointer to string with path - */ -{ - LPTSTR FileName; - DWORD i; - - i = (Path [0] ? (Path[1] == ':' ? 2 : 0) : 0); - FileName = GetFileName(Path + i); - - if ((FileName != (Path + i)) && (FileName [-1] == '\\')) - FileName--; - if ((FileName == (Path + i)) && (FileName [0] == '\\')) - FileName++; - FileName[0] = 0; -} - - -BOOL CCabinet::NormalizePath(LPTSTR Path, - DWORD Length) -/* - * FUNCTION: Normalizes a path - * ARGUMENTS: - * Path = Pointer to string with pathname - * Length = Number of bytes in Path - * RETURNS: - * TRUE if there was enough room in Path, or FALSE - */ -{ - DWORD n; - BOOL OK = TRUE; - - if ((n = lstrlen(Path)) && - (Path[n - 1] != '\\') && - (OK = ((n + 1) < Length))) { - Path[n] = '\\'; - Path[n + 1] = 0; - } - return OK; -} - - -LPTSTR CCabinet::GetCabinetName() -/* - * FUNCTION: Returns pointer to cabinet file name - * RETURNS: - * Pointer to string with name of cabinet - */ -{ - return CabinetName; -} - - -VOID CCabinet::SetCabinetName(LPTSTR FileName) -/* - * FUNCTION: Sets cabinet file name - * ARGUMENTS: - * FileName = Pointer to string with name of cabinet - */ -{ - lstrcpy(CabinetName, FileName); -} - - -VOID CCabinet::SetDestinationPath(LPTSTR DestinationPath) -/* - * FUNCTION: Sets destination path - * ARGUMENTS: - * DestinationPath = Pointer to string with name of destination path - */ -{ - lstrcpy(DestPath, DestinationPath); - if (lstrlen(DestPath) > 0) - NormalizePath(DestPath, MAX_PATH); -} - - -LPTSTR CCabinet::GetDestinationPath() -/* - * FUNCTION: Returns destination path - * RETURNS: - * Pointer to string with name of destination path - */ -{ - return DestPath; -} - - -DWORD CCabinet::GetCurrentDiskNumber() -/* - * FUNCTION: Returns current disk number - * RETURNS: - * Current disk number - */ -{ - return CurrentDiskNumber; -} - - -ULONG CCabinet::Open() -/* - * FUNCTION: Opens a cabinet file - * RETURNS: - * Status of operation - */ -{ - PCFFOLDER_NODE FolderNode; - ULONG Status; - DWORD Index; - - if (!FileOpen) { - DWORD BytesRead; - DWORD Size; - - OutputBuffer = HeapAlloc(GetProcessHeap(), - 0, CAB_BLOCKSIZE + 12); // This should be enough - if (!OutputBuffer) - return CAB_STATUS_NOMEMORY; - - FileHandle = CreateFile(CabinetName, // Open this file - GENERIC_READ, // Open for reading - FILE_SHARE_READ, // Share for reading - NULL, // No security - OPEN_EXISTING, // Existing file only - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - - if (FileHandle == INVALID_HANDLE_VALUE) { - DPRINT(MID_TRACE, ("Cannot open file.\n")); - return CAB_STATUS_CANNOT_OPEN; - } - - FileOpen = TRUE; - - /* Load CAB header */ - if ((Status = ReadBlock(&CABHeader, sizeof(CFHEADER), &BytesRead)) - != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - /* Check header */ - if ((BytesRead != sizeof(CFHEADER)) || - (CABHeader.Signature != CAB_SIGNATURE ) || - (CABHeader.Version != CAB_VERSION ) || - (CABHeader.FolderCount == 0 ) || - (CABHeader.FileCount == 0 ) || - (CABHeader.FileTableOffset < sizeof(CFHEADER))) { - CloseCabinet(); - DPRINT(MID_TRACE, ("File has invalid header.\n")); - return CAB_STATUS_INVALID_CAB; - } - - Size = 0; - - /* Read/skip any reserved bytes */ - if (CABHeader.Flags & CAB_FLAG_RESERVE) { - if ((Status = ReadBlock(&Size, sizeof(DWORD), &BytesRead)) - != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - CabinetReserved = Size & 0xFFFF; - FolderReserved = (Size >> 16) & 0xFF; - DataReserved = (Size >> 24) & 0xFF; - - SetFilePointer(FileHandle, CabinetReserved, NULL, FILE_CURRENT); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_NOMEMORY; - } - } - - if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0) { - /* Read name of previous cabinet */ - Status = ReadString(CabinetPrev, 256); - if (Status != CAB_STATUS_SUCCESS) - return Status; - /* Read label of previous disk */ - Status = ReadString(DiskPrev, 256); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } else { - lstrcpy(CabinetPrev, ""); - lstrcpy(DiskPrev, ""); - } - - if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0) { - /* Read name of next cabinet */ - Status = ReadString(CabinetNext, 256); - if (Status != CAB_STATUS_SUCCESS) - return Status; - /* Read label of next disk */ - Status = ReadString(DiskNext, 256); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } else { - lstrcpy(CabinetNext, ""); - lstrcpy(DiskNext, ""); - } - - /* Read all folders */ - for (Index = 0; Index < CABHeader.FolderCount; Index++) { - FolderNode = NewFolderNode(); - if (!FolderNode) { - DPRINT(MIN_TRACE, ("Insufficient resources.\n")); - return CAB_STATUS_NOMEMORY; - } - - if (Index == 0) - FolderNode->UncompOffset = FolderUncompSize; - - FolderNode->Index = Index; - - if ((Status = ReadBlock(&FolderNode->Folder, - sizeof(CFFOLDER), &BytesRead)) != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - } - - /* Read file entries */ - Status = ReadFileTable(); - if (Status != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("ReadFileTable() failed (%d).\n", (UINT)Status)); - return Status; - } - - /* Read data blocks for all folders */ - FolderNode = FolderListHead; - while (FolderNode != NULL) { - Status = ReadDataBlocks(FolderNode); - if (Status != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("ReadDataBlocks() failed (%d).\n", (UINT)Status)); - return Status; - } - FolderNode = FolderNode->Next; - } - } - return CAB_STATUS_SUCCESS; -} - - -VOID CCabinet::Close() -/* - * FUNCTION: Closes the cabinet file - */ -{ - if (FileOpen) { - CloseHandle(FileHandle); - FileOpen = FALSE; - } -} - - -ULONG CCabinet::FindFirst(LPTSTR FileName, - PCAB_SEARCH Search) -/* - * FUNCTION: Finds the first file in the cabinet that matches a search criteria - * ARGUMENTS: - * FileName = Pointer to search criteria - * Search = Pointer to search structure - * RETURNS: - * Status of operation - */ -{ - RestartSearch = FALSE; - strncpy(Search->Search, FileName, MAX_PATH); - Search->Next = FileListHead; - return FindNext(Search); -} - - -ULONG CCabinet::FindNext(PCAB_SEARCH Search) -/* - * FUNCTION: Finds next file in the cabinet that matches a search criteria - * ARGUMENTS: - * Search = Pointer to search structure - * RETURNS: - * Status of operation - */ -{ - ULONG Status; - - if (RestartSearch) { - Search->Next = FileListHead; - - /* Skip split files already extracted */ - while ((Search->Next) && - (Search->Next->File.FileControlID > CAB_FILE_MAX_FOLDER) && - (Search->Next->File.FileOffset <= LastFileOffset)) { - DPRINT(MAX_TRACE, ("Skipping file (%s) FileOffset (0x%X) LastFileOffset (0x%X).\n", - Search->Next->FileName, Search->Next->File.FileOffset, LastFileOffset)); - Search->Next = Search->Next->Next; - } - - RestartSearch = FALSE; - } - - /* FIXME: Check search criteria */ - - if (!Search->Next) { - if (lstrlen(DiskNext) > 0) { - CloseCabinet(); - - SetCabinetName(CabinetNext); - - OnDiskChange(CabinetNext, DiskNext); - - Status = Open(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - - Search->Next = FileListHead; - if (!Search->Next) - return CAB_STATUS_NOFILE; - } else - return CAB_STATUS_NOFILE; - } - - Search->File = &Search->Next->File; - Search->FileName = Search->Next->FileName; - Search->Next = Search->Next->Next; - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::ExtractFile(LPTSTR FileName) -/* - * FUNCTION: Extracts a file from the cabinet - * ARGUMENTS: - * FileName = Pointer to buffer with name of file - * RETURNS - * Status of operation - */ -{ - DWORD Size; - DWORD Offset; - DWORD BytesRead; - DWORD BytesToRead; - DWORD BytesWritten; - DWORD BytesSkipped; - DWORD BytesToWrite; - DWORD TotalBytesRead; - DWORD CurrentOffset; - PUCHAR Buffer; - PUCHAR CurrentBuffer; - HANDLE DestFile; - PCFFILE_NODE File; - CFDATA CFData; - ULONG Status; - BOOL Skip; - FILETIME FileTime; - TCHAR DestName[MAX_PATH]; - TCHAR TempName[MAX_PATH]; - - Status = LocateFile(FileName, &File); - if (Status != CAB_STATUS_SUCCESS) { - DPRINT(MID_TRACE, ("Cannot locate file (%d).\n", (UINT)Status)); - return Status; - } - - LastFileOffset = File->File.FileOffset; - - switch (CurrentFolderNode->Folder.CompressionType & CAB_COMP_MASK) { - case CAB_COMP_NONE: - SelectCodec(CAB_CODEC_RAW); - break; - case CAB_COMP_MSZIP: - SelectCodec(CAB_CODEC_MSZIP); - break; - default: - return CAB_STATUS_UNSUPPCOMP; - } - - DPRINT(MAX_TRACE, ("Extracting file at uncompressed offset (0x%X) Size (%d bytes) AO (0x%X) UO (0x%X).\n", - (UINT)File->File.FileOffset, - (UINT)File->File.FileSize, - (UINT)File->DataBlock->AbsoluteOffset, - (UINT)File->DataBlock->UncompOffset)); - - lstrcpy(DestName, DestPath); - lstrcat(DestName, FileName); - - /* Create destination file, fail if it already exists */ - DestFile = CreateFile(DestName, // Create this file - GENERIC_WRITE, // Open for writing - 0, // No sharing - NULL, // No security - CREATE_NEW, // New file only - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (DestFile == INVALID_HANDLE_VALUE) { - /* If file exists, ask to overwrite file */ - if (((Status = GetLastError()) == ERROR_FILE_EXISTS) && - (OnOverwrite(&File->File, FileName))) { - /* Create destination file, overwrite if it already exists */ - DestFile = CreateFile(DestName, // Create this file - GENERIC_WRITE, // Open for writing - 0, // No sharing - NULL, // No security - TRUNCATE_EXISTING, // Truncate the file - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (DestFile == INVALID_HANDLE_VALUE) - return CAB_STATUS_CANNOT_CREATE; - } else { - if (Status == ERROR_FILE_EXISTS) - return CAB_STATUS_FILE_EXISTS; - else - return CAB_STATUS_CANNOT_CREATE; - } - } - - if (!DosDateTimeToFileTime(File->File.FileDate, File->File.FileTime, &FileTime)) { - CloseHandle(DestFile); - DPRINT(MIN_TRACE, ("DosDateTimeToFileTime() failed (%d).\n", GetLastError())); - return CAB_STATUS_CANNOT_WRITE; - } - - SetFileTime(DestFile, NULL, &FileTime, NULL); - - SetAttributesOnFile(File); - - Buffer = (PUCHAR)HeapAlloc(GetProcessHeap(), - 0, CAB_BLOCKSIZE + 12); // This should be enough - if (!Buffer) { - CloseHandle(DestFile); - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - /* Call OnExtract event handler */ - OnExtract(&File->File, FileName); - - /* Search to start of file */ - Offset = SetFilePointer(FileHandle, - File->DataBlock->AbsoluteOffset, - NULL, - FILE_BEGIN); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_INVALID_CAB; - } - - Size = File->File.FileSize; - Offset = File->File.FileOffset; - CurrentOffset = File->DataBlock->UncompOffset; - - Skip = TRUE; - - ReuseBlock = (CurrentDataNode == File->DataBlock); - if (Size > 0) { - do { - DPRINT(MAX_TRACE, ("CO (0x%X) ReuseBlock (%d) Offset (0x%X) Size (%d) BytesLeftInBlock (%d)\n", - File->DataBlock->UncompOffset, (UINT)ReuseBlock, Offset, Size, - BytesLeftInBlock)); - - if (/*(CurrentDataNode != File->DataBlock) &&*/ (!ReuseBlock) || (BytesLeftInBlock <= 0)) { - - DPRINT(MAX_TRACE, ("Filling buffer. ReuseBlock (%d)\n", (UINT)ReuseBlock)); - - CurrentBuffer = Buffer; - TotalBytesRead = 0; - do { - DPRINT(MAX_TRACE, ("Size (%d bytes).\n", Size)); - - if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) != - CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA))) { - CloseHandle(DestFile); - HeapFree(GetProcessHeap(), 0, Buffer); - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - DPRINT(MAX_TRACE, ("Data block: Checksum (0x%X) CompSize (%d bytes) UncompSize (%d bytes) Offset (0x%X).\n", - (UINT)CFData.Checksum, - (UINT)CFData.CompSize, - (UINT)CFData.UncompSize, - (UINT)SetFilePointer(FileHandle, 0, NULL, FILE_CURRENT))); - - ASSERT(CFData.CompSize <= CAB_BLOCKSIZE + 12); - - BytesToRead = CFData.CompSize; - - DPRINT(MAX_TRACE, ("Read: (0x%X,0x%X).\n", - CurrentBuffer, Buffer)); - - if (((Status = ReadBlock(CurrentBuffer, BytesToRead, &BytesRead)) != - CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead)) { - CloseHandle(DestFile); - HeapFree(GetProcessHeap(), 0, Buffer); - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - /* FIXME: Does not work with files generated by makecab.exe */ -/* - if (CFData.Checksum != 0) { - DWORD Checksum = ComputeChecksum(CurrentBuffer, BytesRead, 0); - if (Checksum != CFData.Checksum) { - CloseHandle(DestFile); - HeapFree(GetProcessHeap(), 0, Buffer); - DPRINT(MIN_TRACE, ("Bad checksum (is 0x%X, should be 0x%X).\n", - Checksum, CFData.Checksum)); - return CAB_STATUS_INVALID_CAB; - } - } -*/ - TotalBytesRead += BytesRead; - - CurrentBuffer += BytesRead; - - if (CFData.UncompSize == 0) { - if (lstrlen(DiskNext) == 0) - return CAB_STATUS_NOFILE; - - /* CloseCabinet() will destroy all file entries so in case - FileName refers to the FileName field of a CFFOLDER_NODE - structure, we have to save a copy of the filename */ - lstrcpy(TempName, FileName); - - CloseCabinet(); - - SetCabinetName(CabinetNext); - - OnDiskChange(CabinetNext, DiskNext); - - Status = Open(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - - /* The first data block of the file will not be - found as it is located in the previous file */ - Status = LocateFile(TempName, &File); - if (Status == CAB_STATUS_NOFILE) { - DPRINT(MID_TRACE, ("Cannot locate file (%d).\n", (UINT)Status)); - return Status; - } - - /* The file is continued in the first data block in the folder */ - File->DataBlock = CurrentFolderNode->DataListHead; - - /* Search to start of file */ - SetFilePointer(FileHandle, - File->DataBlock->AbsoluteOffset, - NULL, - FILE_BEGIN); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_INVALID_CAB; - } - - DPRINT(MAX_TRACE, ("Continuing extraction of file at uncompressed offset (0x%X) Size (%d bytes) AO (0x%X) UO (0x%X).\n", - (UINT)File->File.FileOffset, - (UINT)File->File.FileSize, - (UINT)File->DataBlock->AbsoluteOffset, - (UINT)File->DataBlock->UncompOffset)); - - CurrentDataNode = File->DataBlock; - ReuseBlock = TRUE; - - RestartSearch = TRUE; - } - } while (CFData.UncompSize == 0); - - DPRINT(MAX_TRACE, ("TotalBytesRead (%d).\n", TotalBytesRead)); - - Status = Codec->Uncompress(OutputBuffer, Buffer, TotalBytesRead, &BytesToWrite); - if (Status != CS_SUCCESS) { - CloseHandle(DestFile); - HeapFree(GetProcessHeap(), 0, Buffer); - DPRINT(MID_TRACE, ("Cannot uncompress block.\n")); - if (Status == CS_NOMEMORY) - return CAB_STATUS_NOMEMORY; - return CAB_STATUS_INVALID_CAB; - } - - if (BytesToWrite != CFData.UncompSize) { - DPRINT(MID_TRACE, ("BytesToWrite (%d) != CFData.UncompSize (%d)\n", - BytesToWrite, CFData.UncompSize)); - return CAB_STATUS_INVALID_CAB; - } - - BytesLeftInBlock = BytesToWrite; - } else { - DPRINT(MAX_TRACE, ("Using same buffer. ReuseBlock (%d)\n", (UINT)ReuseBlock)); - - BytesToWrite = BytesLeftInBlock; - - DPRINT(MAX_TRACE, ("Seeking to absolute offset 0x%X.\n", - CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) + - CurrentDataNode->Data.CompSize)); - - if (((Status = ReadBlock(&CFData, sizeof(CFDATA), &BytesRead)) != - CAB_STATUS_SUCCESS) || (BytesRead != sizeof(CFDATA))) { - CloseHandle(DestFile); - HeapFree(GetProcessHeap(), 0, Buffer); - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - DPRINT(MAX_TRACE, ("CFData.CompSize 0x%X CFData.UncompSize 0x%X.\n", - CFData.CompSize, CFData.UncompSize)); - - /* Go to next data block */ - SetFilePointer(FileHandle, - CurrentDataNode->AbsoluteOffset + sizeof(CFDATA) + - CurrentDataNode->Data.CompSize, - NULL, - FILE_BEGIN); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_INVALID_CAB; - } - - ReuseBlock = FALSE; - } - - if (Skip) - BytesSkipped = (Offset - CurrentOffset); - else - BytesSkipped = 0; - - BytesToWrite -= BytesSkipped; - - if (Size < BytesToWrite) - BytesToWrite = Size; - - DPRINT(MAX_TRACE, ("Offset (0x%X) CurrentOffset (0x%X) ToWrite (%d) Skipped (%d)(%d) Size (%d).\n", - (UINT)Offset, - (UINT)CurrentOffset, - (UINT)BytesToWrite, - (UINT)BytesSkipped, (UINT)Skip, - (UINT)Size)); - - if (!WriteFile(DestFile, (PVOID)((ULONG)OutputBuffer + BytesSkipped), - BytesToWrite, &BytesWritten, NULL) || - (BytesToWrite != BytesWritten)) { - - DPRINT(MIN_TRACE, ("Status 0x%X.\n", GetLastError())); - - CloseHandle(DestFile); - HeapFree(GetProcessHeap(), 0, Buffer); - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - Size -= BytesToWrite; - - CurrentOffset += BytesToWrite; - - /* Don't skip any more bytes */ - Skip = FALSE; - } while (Size > 0); - } - - CloseHandle(DestFile); - - HeapFree(GetProcessHeap(), 0, Buffer); - - return CAB_STATUS_SUCCESS; -} - - -VOID CCabinet::SelectCodec(ULONG Id) -/* - * FUNCTION: Selects codec engine to use - * ARGUMENTS: - * Id = Codec identifier - */ -{ - if (CodecSelected) { - if (Id == CodecId) - return; - - CodecSelected = FALSE; - delete Codec; - } - - switch (Id) { - case CAB_CODEC_RAW: - Codec = new CRawCodec(); - break; - case CAB_CODEC_MSZIP: - Codec = new CMSZipCodec(); - break; - default: - return; - } - - CodecId = Id; - CodecSelected = TRUE; -} - - -#ifndef CAB_READ_ONLY - -/* CAB write methods */ - -ULONG CCabinet::NewCabinet() -/* - * FUNCTION: Creates a new cabinet - * RETURNS: - * Status of operation - */ -{ - ULONG Status; - - CurrentDiskNumber = 0; - - OutputBuffer = HeapAlloc(GetProcessHeap(), 0, CAB_BLOCKSIZE + 12); // This should be enough - InputBuffer = HeapAlloc(GetProcessHeap(), 0, CAB_BLOCKSIZE + 12); // This should be enough - if ((!OutputBuffer) || (!InputBuffer)) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - CurrentIBuffer = InputBuffer; - CurrentIBufferSize = 0; - - CABHeader.Signature = CAB_SIGNATURE; - CABHeader.Reserved1 = 0; // Not used - CABHeader.CabinetSize = 0; // Not yet known - CABHeader.Reserved2 = 0; // Not used - CABHeader.Reserved3 = 0; // Not used - CABHeader.Version = CAB_VERSION; - CABHeader.FolderCount = 0; // Not yet known - CABHeader.FileCount = 0; // Not yet known - CABHeader.Flags = 0; // Not yet known - // FIXME: Should be random - CABHeader.SetID = 0x534F; - CABHeader.CabinetNumber = 0; - - - TotalFolderSize = 0; - TotalFileSize = 0; - - DiskSize = sizeof(CFHEADER); - - InitCabinetHeader(); - - // NextFolderNumber is 0-based - NextFolderNumber = 0; - - CurrentFolderNode = NULL; - Status = NewFolder(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - - CurrentFolderNode->Folder.DataOffset = DiskSize - TotalHeaderSize; - - ScratchFile = new CCFDATAStorage; - if (!ScratchFile) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - Status = ScratchFile->Create("~CAB.tmp"); - - CreateNewFolder = FALSE; - - CreateNewDisk = FALSE; - - PrevCabinetNumber = 0; - - return Status; -} - - -ULONG CCabinet::NewDisk() -/* - * FUNCTION: Forces a new disk to be created - * RETURNS: - * Status of operation - */ -{ - // NextFolderNumber is 0-based - NextFolderNumber = 1; - - CreateNewDisk = FALSE; - - DiskSize = sizeof(CFHEADER) + TotalFolderSize + TotalFileSize; - - InitCabinetHeader(); - - CurrentFolderNode->TotalFolderSize = 0; - - CurrentFolderNode->Folder.DataBlockCount = 0; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::NewFolder() -/* - * FUNCTION: Forces a new folder to be created - * RETURNS: - * Status of operation - */ -{ - DPRINT(MAX_TRACE, ("Creating new folder.\n")); - - CurrentFolderNode = NewFolderNode(); - if (!CurrentFolderNode) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - switch (CodecId) { - case CAB_CODEC_RAW: - CurrentFolderNode->Folder.CompressionType = CAB_COMP_NONE; - break; - case CAB_CODEC_MSZIP: - CurrentFolderNode->Folder.CompressionType = CAB_COMP_MSZIP; - break; - default: - return CAB_STATUS_UNSUPPCOMP; - } - - /* FIXME: This won't work if no files are added to the new folder */ - - DiskSize += sizeof(CFFOLDER); - - TotalFolderSize += sizeof(CFFOLDER); - - NextFolderNumber++; - - CABHeader.FolderCount++; - - LastBlockStart = 0; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::WriteFileToScratchStorage(PCFFILE_NODE FileNode) -/* - * FUNCTION: Writes a file to the scratch file - * ARGUMENTS: - * FileNode = Pointer to file node - * RETURNS: - * Status of operation - */ -{ - DWORD BytesToRead; - DWORD BytesRead; - ULONG Status; - DWORD Size; - - if (!ContinueFile) { - /* Try to open file */ - SourceFile = CreateFile( - FileNode->FileName, // Open this file - GENERIC_READ, // Open for reading - FILE_SHARE_READ, // Share for reading - NULL, // No security - OPEN_EXISTING, // File must exist - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (SourceFile == INVALID_HANDLE_VALUE) { - DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileName)); - return CAB_STATUS_NOFILE; - } - - if (CreateNewFolder) { - /* There is always a new folder after - a split file is completely stored */ - Status = NewFolder(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - CreateNewFolder = FALSE; - } - - /* Call OnAdd event handler */ - OnAdd(&FileNode->File, FileNode->FileName); - - TotalBytesLeft = FileNode->File.FileSize; - - FileNode->File.FileOffset = CurrentFolderNode->UncompOffset; - CurrentFolderNode->UncompOffset += TotalBytesLeft; - FileNode->File.FileControlID = NextFolderNumber - 1; - CurrentFolderNode->Commit = TRUE; - PrevCabinetNumber = CurrentDiskNumber; - - Size = sizeof(CFFILE) + lstrlen(GetFileName(FileNode->FileName)) + 1; - CABHeader.FileTableOffset += Size; - TotalFileSize += Size; - DiskSize += Size; - } - - FileNode->Commit = TRUE; - - if (TotalBytesLeft > 0) { - do { - if (TotalBytesLeft > (DWORD)CAB_BLOCKSIZE - CurrentIBufferSize) - BytesToRead = CAB_BLOCKSIZE - CurrentIBufferSize; - else - BytesToRead = TotalBytesLeft; - - if ((!ReadFile(SourceFile, CurrentIBuffer, BytesToRead, &BytesRead, NULL) - != CAB_STATUS_SUCCESS) || (BytesToRead != BytesRead)) { - DPRINT(MIN_TRACE, ("Cannot read from file. BytesToRead (%d) BytesRead (%d) CurrentIBufferSize (%d).\n", - BytesToRead, BytesRead, CurrentIBufferSize)); - return CAB_STATUS_INVALID_CAB; - } - - (PUCHAR)CurrentIBuffer += BytesRead; - - CurrentIBufferSize += (WORD)BytesRead; - - if (CurrentIBufferSize == CAB_BLOCKSIZE) { - Status = WriteDataBlock(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } - TotalBytesLeft -= BytesRead; - } while ((TotalBytesLeft > 0) && (!CreateNewDisk)); - } - - if (TotalBytesLeft == 0) { - CloseHandle(SourceFile); - FileNode->Delete = TRUE; - - if (FileNode->File.FileControlID > CAB_FILE_MAX_FOLDER) { - FileNode->File.FileControlID = CAB_FILE_CONTINUED; - CurrentFolderNode->Delete = TRUE; - - if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) { - Status = WriteDataBlock(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } - - CreateNewFolder = TRUE; - } - } else { - if (FileNode->File.FileControlID <= CAB_FILE_MAX_FOLDER) - FileNode->File.FileControlID = CAB_FILE_SPLIT; - else - FileNode->File.FileControlID = CAB_FILE_PREV_NEXT; - } - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::WriteDisk(DWORD MoreDisks) -/* - * FUNCTION: Forces the current disk to be written - * ARGUMENTS: - * MoreDisks = TRUE if there is one or more disks after this disk - * RETURNS: - * Status of operation - */ -{ - PCFFILE_NODE FileNode; - ULONG Status; - - ContinueFile = FALSE; - FileNode = FileListHead; - while (FileNode != NULL) { - - Status = WriteFileToScratchStorage(FileNode); - if (Status != CAB_STATUS_SUCCESS) - return Status; - if (CreateNewDisk) { - /* A data block could span more than two - disks if MaxDiskSize is very small */ - while (CreateNewDisk) { - DPRINT(MAX_TRACE, ("Creating new disk.\n")); - CommitDisk(TRUE); - CloseDisk(); - NewDisk(); - - ContinueFile = TRUE; - CreateNewDisk = FALSE; - - DPRINT(MAX_TRACE, ("First on new disk. CurrentIBufferSize (%d) CurrentOBufferSize (%d).\n", - CurrentIBufferSize, CurrentOBufferSize)); - - if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) { - Status = WriteDataBlock(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } - } - } else { - ContinueFile = FALSE; - FileNode = FileNode->Next; - } - } - - if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) { - /* A data block could span more than two - disks if MaxDiskSize is very small */ - - ASSERT(CreateNewDisk == FALSE); - - do { - if (CreateNewDisk) { - DPRINT(MID_TRACE, ("Creating new disk 2.\n")); - CommitDisk(TRUE); - CloseDisk(); - NewDisk(); - CreateNewDisk = FALSE; - - ASSERT(FileNode == FileListHead); - } - - if ((CurrentIBufferSize > 0) || (CurrentOBufferSize > 0)) { - Status = WriteDataBlock(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - } - } while (CreateNewDisk); - } - CommitDisk(MoreDisks); - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::CommitDisk(DWORD MoreDisks) -/* - * FUNCTION: Commits the current disk - * ARGUMENTS: - * MoreDisks = TRUE if there is one or more disks after this disk - * RETURNS: - * Status of operation - */ -{ - PCFFOLDER_NODE FolderNode; - ULONG Status; - - OnCabinetName(CurrentDiskNumber, CabinetName); - - /* Create file, fail if it already exists */ - FileHandle = CreateFile(CabinetName, // Create this file - GENERIC_WRITE, // Open for writing - 0, // No sharing - NULL, // No security - CREATE_NEW, // New file only - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (FileHandle == INVALID_HANDLE_VALUE) { - DWORD Status; - /* If file exists, ask to overwrite file */ - if (((Status = GetLastError()) == ERROR_FILE_EXISTS) && - (OnOverwrite(NULL, CabinetName))) { - - /* Create cabinet file, overwrite if it already exists */ - FileHandle = CreateFile(CabinetName, // Create this file - GENERIC_WRITE, // Open for writing - 0, // No sharing - NULL, // No security - TRUNCATE_EXISTING, // Truncate the file - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (FileHandle == INVALID_HANDLE_VALUE) - return CAB_STATUS_CANNOT_CREATE; - } else { - if (Status == ERROR_FILE_EXISTS) - return CAB_STATUS_FILE_EXISTS; - else - return CAB_STATUS_CANNOT_CREATE; - } - } - - WriteCabinetHeader(MoreDisks); - - Status = WriteFolderEntries(); - if (Status != CAB_STATUS_SUCCESS) - return Status; - - /* Write file entries */ - WriteFileEntries(); - - /* Write data blocks */ - FolderNode = FolderListHead; - while (FolderNode != NULL) { - if (FolderNode->Commit) { - Status = CommitDataBlocks(FolderNode); - if (Status != CAB_STATUS_SUCCESS) - return Status; - /* Remove data blocks for folder */ - DestroyDataNodes(FolderNode); - } - FolderNode = FolderNode->Next; - } - - CloseHandle(FileHandle); - - ScratchFile->Truncate(); - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::CloseDisk() -/* - * FUNCTION: Closes the current disk - * RETURNS: - * Status of operation - */ -{ - DestroyDeletedFileNodes(); - - /* Destroy folder nodes that are completely stored */ - DestroyDeletedFolderNodes(); - - CurrentDiskNumber++; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::CloseCabinet() -/* - * FUNCTION: Closes the current cabinet - * RETURNS: - * Status of operation - */ -{ - PCFFOLDER_NODE PrevNode; - PCFFOLDER_NODE NextNode; - ULONG Status; - - DestroyFileNodes(); - - DestroyFolderNodes(); - - if (InputBuffer) { - HeapFree(GetProcessHeap(), 0, InputBuffer); - InputBuffer = NULL; - } - - if (OutputBuffer) { - HeapFree(GetProcessHeap(), 0, OutputBuffer); - OutputBuffer = NULL; - } - - Close(); - - if (ScratchFile) { - Status = ScratchFile->Destroy(); - delete ScratchFile; - return Status; - } - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::AddFile(LPTSTR FileName) -/* - * FUNCTION: Adds a file to the current disk - * ARGUMENTS: - * FileName = Pointer to string with file name (full path) - * RETURNS: - * Status of operation - */ -{ - HANDLE SrcFile; - FILETIME FileTime; - PCFFILE_NODE FileNode; - - FileNode = NewFileNode(); - if (!FileNode) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - FileNode->FolderNode = CurrentFolderNode; - - FileNode->FileName = (LPTSTR)HeapAlloc(GetProcessHeap(), - 0, lstrlen(FileName) + 1); - lstrcpy(FileNode->FileName, FileName); - - /* Try to open file */ - SrcFile = CreateFile( - FileNode->FileName, // Open this file - GENERIC_READ, // Open for reading - FILE_SHARE_READ, // Share for reading - NULL, // No security - OPEN_EXISTING, // File must exist - FILE_ATTRIBUTE_NORMAL, // Normal file - NULL); // No attribute template - if (SrcFile == INVALID_HANDLE_VALUE) { - DPRINT(MID_TRACE, ("File not found (%s).\n", FileNode->FileName)); - return CAB_STATUS_CANNOT_OPEN; - } - - /* FIXME: Check for and handle large files (>= 2GB) */ - FileNode->File.FileSize = GetFileSize(SrcFile, NULL); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("Cannot read from file.\n")); - return CAB_STATUS_CANNOT_READ; - } - - if (GetFileTime(SrcFile, NULL, &FileTime, NULL)) - FileTimeToDosDateTime(&FileTime, - &FileNode->File.FileDate, - &FileNode->File.FileTime); - - GetAttributesOnFile(FileNode); - - CloseHandle(SrcFile); - - return CAB_STATUS_SUCCESS; -} - - -VOID CCabinet::SetMaxDiskSize(DWORD Size) -/* - * FUNCTION: Sets the maximum size of the current disk - * ARGUMENTS: - * Size = Maximum size of current disk (0 means no maximum size) - */ -{ - MaxDiskSize = Size; -} - -#endif /* CAB_READ_ONLY */ - - -/* Default event handlers */ - -BOOL CCabinet::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 - */ -{ - return FALSE; -} - - -VOID CCabinet::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) - */ -{ -} - - -VOID CCabinet::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 - */ -{ -} - - -#ifndef CAB_READ_ONLY - -VOID CCabinet::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) - */ -{ -} - - -BOOL CCabinet::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 - */ -{ - return FALSE; -} - - -BOOL CCabinet::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 - */ -{ - return FALSE; -} - -#endif /* CAB_READ_ONLY */ - -PCFFOLDER_NODE CCabinet::LocateFolderNode(DWORD Index) -/* - * FUNCTION: Locates a folder node - * ARGUMENTS: - * Index = Folder index - * RETURNS: - * Pointer to folder node or NULL if the folder node was not found - */ -{ - PCFFOLDER_NODE Node; - - switch (Index) { - case CAB_FILE_SPLIT: - return FolderListTail; - - case CAB_FILE_CONTINUED: - case CAB_FILE_PREV_NEXT: - return FolderListHead; - } - - Node = FolderListHead; - while (Node != NULL) { - if (Node->Index == Index) - return Node; - Node = Node->Next; - } - return NULL; -} - - -ULONG CCabinet::GetAbsoluteOffset(PCFFILE_NODE File) -/* - * FUNCTION: Returns the absolute offset of a file - * ARGUMENTS: - * File = Pointer to CFFILE_NODE structure for file - * RETURNS: - * Status of operation - */ -{ - PCFDATA_NODE Node; - - DPRINT(MAX_TRACE, ("FileName '%s' FileOffset (0x%X) FileSize (%d).\n", - (LPTSTR)File->FileName, - (UINT)File->File.FileOffset, - (UINT)File->File.FileSize)); - - Node = CurrentFolderNode->DataListHead; - while (Node != NULL) { - - DPRINT(MAX_TRACE, ("GetAbsoluteOffset(): Comparing (0x%X, 0x%X) (%d).\n", - (UINT)Node->UncompOffset, - (UINT)Node->UncompOffset + Node->Data.UncompSize, - (UINT)Node->Data.UncompSize)); - - /* Node->Data.UncompSize will be 0 if the block is split - (ie. it is the last block in this cabinet) */ - if ((Node->Data.UncompSize == 0) || - ((File->File.FileOffset >= Node->UncompOffset) && - (File->File.FileOffset < Node->UncompOffset + - Node->Data.UncompSize))) { - File->DataBlock = Node; - return CAB_STATUS_SUCCESS; - } - - Node = Node->Next; - } - return CAB_STATUS_INVALID_CAB; -} - - -ULONG CCabinet::LocateFile(LPTSTR FileName, - PCFFILE_NODE *File) -/* - * FUNCTION: Locates a file in the cabinet - * ARGUMENTS: - * FileName = Pointer to string with name of file to locate - * File = Address of pointer to CFFILE_NODE structure to fill - * RETURNS: - * Status of operation - * NOTES: - * Current folder is set to the folder of the file - */ -{ - PCFFILE_NODE Node; - ULONG Status; - - DPRINT(MAX_TRACE, ("FileName '%s'\n", FileName)); - - Node = FileListHead; - while (Node != NULL) { - if (lstrcmpi(FileName, Node->FileName) == 0) { - - CurrentFolderNode = LocateFolderNode(Node->File.FileControlID); - if (!CurrentFolderNode) { - DPRINT(MID_TRACE, ("Folder with index number (%d) not found.\n", - (UINT)Node->File.FileControlID)); - return CAB_STATUS_INVALID_CAB; - } - - if (Node->DataBlock == NULL) { - Status = GetAbsoluteOffset(Node); - } else - Status = CAB_STATUS_SUCCESS; - *File = Node; - return Status; - } - Node = Node->Next; - } - return CAB_STATUS_NOFILE; -} - - -ULONG CCabinet::ReadString(LPTSTR String, DWORD MaxLength) -/* - * FUNCTION: Reads a NULL-terminated string from the cabinet - * ARGUMENTS: - * String = Pointer to buffer to place string - * MaxLength = Maximum length of string - * RETURNS: - * Status of operation - */ -{ - DWORD BytesRead; - DWORD Offset; - ULONG Status; - DWORD Size; - BOOL Found; - - Offset = 0; - Found = FALSE; - do { - Size = ((Offset + 32) <= MaxLength)? 32 : MaxLength - Offset; - - if (Size == 0) { - DPRINT(MIN_TRACE, ("Too long a filename.\n")); - return CAB_STATUS_INVALID_CAB; - } - - Status = ReadBlock(&String[Offset], Size, &BytesRead); - if ((Status != CAB_STATUS_SUCCESS) || (BytesRead != Size)) { - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - for (Size = Offset; Size < Offset + BytesRead; Size++) { - if (String[Size] == '\0') { - Found = TRUE; - break; - } - } - - Offset += BytesRead; - - } while (!Found); - - /* Back up some bytes */ - Size = (BytesRead - Size) - 1; - SetFilePointer(FileHandle, -(LONG)Size, NULL, FILE_CURRENT); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_INVALID_CAB; - } - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::ReadFileTable() -/* - * FUNCTION: Reads the file table from the cabinet file - * RETURNS: - * Status of operation - */ -{ - ULONG i; - ULONG Status; - DWORD BytesRead; - PCFFILE_NODE File; - - DPRINT(MAX_TRACE, ("Reading file table at absolute offset (0x%X).\n", - CABHeader.FileTableOffset)); - - /* Seek to file table */ - SetFilePointer(FileHandle, CABHeader.FileTableOffset, NULL, FILE_BEGIN); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_INVALID_CAB; - } - - for (i = 0; i < CABHeader.FileCount; i++) { - File = NewFileNode(); - if (!File) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - if ((Status = ReadBlock(&File->File, sizeof(CFFILE), - &BytesRead)) != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - File->FileName = (LPTSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH); - if (!File->FileName) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - /* Read file name */ - Status = ReadString(File->FileName, MAX_PATH); - if (Status != CAB_STATUS_SUCCESS) - return Status; - - DPRINT(MAX_TRACE, ("Found file '%s' at uncompressed offset (0x%X). Size (%d bytes) ControlId (0x%X).\n", - (LPTSTR)File->FileName, - (UINT)File->File.FileOffset, - (UINT)File->File.FileSize, - (UINT)File->File.FileControlID)); - - } - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::ReadDataBlocks(PCFFOLDER_NODE FolderNode) -/* - * FUNCTION: Reads all CFDATA blocks for a folder from the cabinet file - * ARGUMENTS: - * FolderNode = Pointer to CFFOLDER_NODE structure for folder - * RETURNS: - * Status of operation - */ -{ - DWORD AbsoluteOffset; - DWORD UncompOffset; - PCFDATA_NODE Node; - DWORD BytesRead; - ULONG Status; - ULONG i; - - DPRINT(MAX_TRACE, ("Reading data blocks for folder (%d) at absolute offset (0x%X).\n", - FolderNode->Index, FolderNode->Folder.DataOffset)); - - AbsoluteOffset = FolderNode->Folder.DataOffset; - UncompOffset = FolderNode->UncompOffset; - - for (i = 0; i < FolderNode->Folder.DataBlockCount; i++) { - Node = NewDataNode(FolderNode); - if (!Node) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - /* Seek to data block */ - SetFilePointer(FileHandle, AbsoluteOffset, NULL, FILE_BEGIN); - if (GetLastError() != NO_ERROR) { - DPRINT(MIN_TRACE, ("SetFilePointer() failed.\n")); - return CAB_STATUS_INVALID_CAB; - } - - if ((Status = ReadBlock(&Node->Data, sizeof(CFDATA), - &BytesRead)) != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("Cannot read from file (%d).\n", (UINT)Status)); - return CAB_STATUS_INVALID_CAB; - } - - DPRINT(MAX_TRACE, ("AbsOffset (0x%X) UncompOffset (0x%X) Checksum (0x%X) CompSize (%d) UncompSize (%d).\n", - (UINT)AbsoluteOffset, - (UINT)UncompOffset, - (UINT)Node->Data.Checksum, - (UINT)Node->Data.CompSize, - (UINT)Node->Data.UncompSize)); - - Node->AbsoluteOffset = AbsoluteOffset; - Node->UncompOffset = UncompOffset; - - AbsoluteOffset += sizeof(CFDATA) + Node->Data.CompSize; - UncompOffset += Node->Data.UncompSize; - } - - FolderUncompSize = UncompOffset; - - return CAB_STATUS_SUCCESS; -} - - -PCFFOLDER_NODE CCabinet::NewFolderNode() -/* - * FUNCTION: Creates a new folder node - * RETURNS: - * Pointer to node if there was enough free memory available, otherwise NULL - */ -{ - PCFFOLDER_NODE Node; - - Node = (PCFFOLDER_NODE)HeapAlloc(GetProcessHeap(), - 0, sizeof(CFFOLDER_NODE)); - if (!Node) - return NULL; - - ZeroMemory(Node, sizeof(CFFOLDER_NODE)); - - Node->Folder.CompressionType = CAB_COMP_NONE; - - Node->Prev = FolderListTail; - - if (FolderListTail != NULL) { - FolderListTail->Next = Node; - } else { - FolderListHead = Node; - } - FolderListTail = Node; - - return Node; -} - - -PCFFILE_NODE CCabinet::NewFileNode() -/* - * FUNCTION: Creates a new file node - * ARGUMENTS: - * FolderNode = Pointer to folder node to bind file to - * RETURNS: - * Pointer to node if there was enough free memory available, otherwise NULL - */ -{ - PCFFILE_NODE Node; - - Node = (PCFFILE_NODE)HeapAlloc(GetProcessHeap(), - 0, sizeof(CFFILE_NODE)); - if (!Node) - return NULL; - - ZeroMemory(Node, sizeof(CFFILE_NODE)); - - Node->Prev = FileListTail; - - if (FileListTail != NULL) { - FileListTail->Next = Node; - } else { - FileListHead = Node; - } - FileListTail = Node; - - return Node; -} - - -PCFDATA_NODE CCabinet::NewDataNode(PCFFOLDER_NODE FolderNode) -/* - * FUNCTION: Creates a new data block node - * ARGUMENTS: - * FolderNode = Pointer to folder node to bind data block to - * RETURNS: - * Pointer to node if there was enough free memory available, otherwise NULL - */ -{ - PCFDATA_NODE Node; - - Node = (PCFDATA_NODE)HeapAlloc(GetProcessHeap(), - 0, sizeof(CFDATA_NODE)); - if (!Node) - return NULL; - - ZeroMemory(Node, sizeof(CFDATA_NODE)); - - Node->Prev = FolderNode->DataListTail; - - if (FolderNode->DataListTail != NULL) { - FolderNode->DataListTail->Next = Node; - } else { - FolderNode->DataListHead = Node; - } - FolderNode->DataListTail = Node; - - return Node; -} - - -VOID CCabinet::DestroyDataNodes(PCFFOLDER_NODE FolderNode) -/* - * FUNCTION: Destroys data block nodes bound to a folder node - * ARGUMENTS: - * FolderNode = Pointer to folder node - */ -{ - PCFDATA_NODE PrevNode; - PCFDATA_NODE NextNode; - - NextNode = FolderNode->DataListHead; - while (NextNode != NULL) { - PrevNode = NextNode->Next; - HeapFree(GetProcessHeap(), 0, NextNode); - NextNode = PrevNode; - } - FolderNode->DataListHead = NULL; - FolderNode->DataListTail = NULL; -} - - -VOID CCabinet::DestroyFileNodes() -/* - * FUNCTION: Destroys file nodes - * ARGUMENTS: - * FolderNode = Pointer to folder node - */ -{ - PCFFILE_NODE PrevNode; - PCFFILE_NODE NextNode; - - NextNode = FileListHead; - while (NextNode != NULL) { - PrevNode = NextNode->Next; - if (NextNode->FileName) - HeapFree(GetProcessHeap(), 0, NextNode->FileName); - HeapFree(GetProcessHeap(), 0, NextNode); - NextNode = PrevNode; - } - FileListHead = NULL; - FileListTail = NULL; -} - - -VOID CCabinet::DestroyDeletedFileNodes() -/* - * FUNCTION: Destroys file nodes that are marked for deletion - */ -{ - PCFFILE_NODE CurNode; - PCFFILE_NODE NextNode; - - CurNode = FileListHead; - while (CurNode != NULL) { - NextNode = CurNode->Next; - - if (CurNode->Delete) { - if (CurNode->Prev != NULL) { - CurNode->Prev->Next = CurNode->Next; - } else { - FileListHead = CurNode->Next; - if (FileListHead) - FileListHead->Prev = NULL; - } - - if (CurNode->Next != NULL) { - CurNode->Next->Prev = CurNode->Prev; - } else { - FileListTail = CurNode->Prev; - if (FileListTail) - FileListTail->Next = NULL; - } - - DPRINT(MAX_TRACE, ("Deleting file: '%s'\n", CurNode->FileName)); - - TotalFileSize -= (sizeof(CFFILE) + lstrlen(GetFileName(CurNode->FileName)) + 1); - - if (CurNode->FileName) - HeapFree(GetProcessHeap(), 0, CurNode->FileName); - HeapFree(GetProcessHeap(), 0, CurNode); - } - CurNode = NextNode; - } -} - - -VOID CCabinet::DestroyFolderNodes() -/* - * FUNCTION: Destroys folder nodes - */ -{ - PCFFOLDER_NODE PrevNode; - PCFFOLDER_NODE NextNode; - - NextNode = FolderListHead; - while (NextNode != NULL) { - PrevNode = NextNode->Next; - DestroyDataNodes(NextNode); - HeapFree(GetProcessHeap(), 0, NextNode); - NextNode = PrevNode; - } - FolderListHead = NULL; - FolderListTail = NULL; -} - - -VOID CCabinet::DestroyDeletedFolderNodes() -/* - * FUNCTION: Destroys folder nodes that are marked for deletion - */ -{ - PCFFOLDER_NODE CurNode; - PCFFOLDER_NODE NextNode; - - CurNode = FolderListHead; - while (CurNode != NULL) { - NextNode = CurNode->Next; - - if (CurNode->Delete) { - if (CurNode->Prev != NULL) { - CurNode->Prev->Next = CurNode->Next; - } else { - FolderListHead = CurNode->Next; - if (FolderListHead) - FolderListHead->Prev = NULL; - } - - if (CurNode->Next != NULL) { - CurNode->Next->Prev = CurNode->Prev; - } else { - FolderListTail = CurNode->Prev; - if (FolderListTail) - FolderListTail->Next = NULL; - } - - DestroyDataNodes(CurNode); - HeapFree(GetProcessHeap(), 0, CurNode); - - TotalFolderSize -= sizeof(CFFOLDER); - } - CurNode = NextNode; - } -} - - -ULONG CCabinet::ComputeChecksum(PVOID Buffer, - UINT Size, - ULONG Seed) -/* - * FUNCTION: Computes checksum for data block - * ARGUMENTS: - * Buffer = Pointer to data buffer - * Size = Length of data buffer - * Seed = Previously computed checksum - * RETURNS: - * Checksum of buffer - */ -{ - INT UlongCount; // Number of ULONGs in block - ULONG Checksum; // Checksum accumulator - PBYTE pb; - ULONG ul; - - /* FIXME: Doesn't seem to be correct. EXTRACT.EXE - won't accept checksums computed by this routine */ - - DPRINT(MIN_TRACE, ("Checksumming buffer (0x%X) Size (%d)\n", (UINT)Buffer, Size)); - - UlongCount = Size / 4; // Number of ULONGs - Checksum = Seed; // Init checksum - pb = (PBYTE)Buffer; // Start at front of data block - - /* Checksum integral multiple of ULONGs */ - while (UlongCount-- > 0) { - /* NOTE: Build ULONG in big/little-endian independent manner */ - ul = *pb++; // Get low-order byte - ul |= (((ULONG)(*pb++)) << 8); // Add 2nd byte - ul |= (((ULONG)(*pb++)) << 16); // Add 3nd byte - ul |= (((ULONG)(*pb++)) << 24); // Add 4th byte - - Checksum ^= ul; // Update checksum - } - - /* Checksum remainder bytes */ - ul = 0; - switch (Size % 4) { - case 3: - ul |= (((ULONG)(*pb++)) << 16); // Add 3rd byte - case 2: - ul |= (((ULONG)(*pb++)) << 8); // Add 2nd byte - case 1: - ul |= *pb++; // Get low-order byte - default: - break; - } - Checksum ^= ul; // Update checksum - - /* Return computed checksum */ - return Checksum; -} - - -ULONG CCabinet::ReadBlock(PVOID Buffer, - DWORD Size, - PDWORD BytesRead) -/* - * FUNCTION: Read a block of data from file - * ARGUMENTS: - * Buffer = Pointer to data buffer - * Size = Length of data buffer - * BytesRead = Pointer to DWORD that on return will contain - * number of bytes read - * RETURNS: - * Status of operation - */ -{ - if (!ReadFile(FileHandle, Buffer, Size, BytesRead, NULL)) - return CAB_STATUS_INVALID_CAB; - return CAB_STATUS_SUCCESS; -} - -#ifndef CAB_READ_ONLY - -ULONG CCabinet::InitCabinetHeader() -/* - * FUNCTION: Initializes cabinet header and optional fields - * RETURNS: - * Status of operation - */ -{ - PCFFOLDER_NODE FolderNode; - PCFFILE_NODE FileNode; - DWORD TotalSize; - DWORD Size; - - CABHeader.FileTableOffset = 0; // Not known yet - CABHeader.FolderCount = 0; // Not known yet - CABHeader.FileCount = 0; // Not known yet - CABHeader.Flags = 0; // Not known yet - - CABHeader.CabinetNumber = CurrentDiskNumber; - - if ((CurrentDiskNumber > 0) && (OnCabinetName(PrevCabinetNumber, CabinetPrev))) { - CABHeader.Flags |= CAB_FLAG_HASPREV; - if (!OnDiskLabel(PrevCabinetNumber, DiskPrev)) - lstrcpy(CabinetPrev, ""); - } - - if (OnCabinetName(CurrentDiskNumber + 1, CabinetNext)) { - CABHeader.Flags |= CAB_FLAG_HASNEXT; - if (!OnDiskLabel(CurrentDiskNumber + 1, DiskNext)) - lstrcpy(DiskNext, ""); - } - - TotalSize = 0; - - if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0) { - - DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev)); - - /* Calculate size of name of previous cabinet */ - TotalSize += lstrlen(CabinetPrev) + 1; - - /* Calculate size of label of previous disk */ - TotalSize += lstrlen(DiskPrev) + 1; - } - - if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0) { - - DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext)); - - /* Calculate size of name of next cabinet */ - Size = lstrlen(CabinetNext) + 1; - TotalSize += Size; - NextFieldsSize = Size; - - /* Calculate size of label of next disk */ - Size = lstrlen(DiskNext) + 1; - TotalSize += Size; - NextFieldsSize += Size; - } else - NextFieldsSize = 0; - - DiskSize += TotalSize; - - /* FIXME: Add cabinet reserved area size */ - TotalHeaderSize = sizeof(CFHEADER) + TotalSize; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::WriteCabinetHeader(BOOL MoreDisks) -/* - * FUNCTION: Writes the cabinet header and optional fields - * ARGUMENTS: - * MoreDisks = TRUE if next cabinet name should be included - * RETURNS: - * Status of operation - */ -{ - PCFFOLDER_NODE FolderNode; - PCFFILE_NODE FileNode; - DWORD BytesWritten; - DWORD Size; - - if (MoreDisks) { - CABHeader.Flags |= CAB_FLAG_HASNEXT; - Size = TotalHeaderSize; - } else { - CABHeader.Flags &= ~CAB_FLAG_HASNEXT; - DiskSize -= NextFieldsSize; - Size = TotalHeaderSize - NextFieldsSize; - } - - /* Set absolute folder offsets */ - BytesWritten = Size + TotalFolderSize + TotalFileSize; - CABHeader.FolderCount = 0; - FolderNode = FolderListHead; - while (FolderNode != NULL) { - FolderNode->Folder.DataOffset = BytesWritten; - - BytesWritten += FolderNode->TotalFolderSize; - - CABHeader.FolderCount++; - - FolderNode = FolderNode->Next; - } - - /* Set absolute offset of file table */ - CABHeader.FileTableOffset = Size + TotalFolderSize; - - /* Count number of files to be committed */ - CABHeader.FileCount = 0; - FileNode = FileListHead; - while (FileNode != NULL) { - if (FileNode->Commit) - CABHeader.FileCount++; - FileNode = FileNode->Next; - } - - CABHeader.CabinetSize = DiskSize; - - /* Write header */ - if (!WriteFile(FileHandle, &CABHeader, sizeof(CFHEADER), &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - - if ((CABHeader.Flags & CAB_FLAG_HASPREV) > 0) { - - DPRINT(MAX_TRACE, ("CabinetPrev '%s'.\n", CabinetPrev)); - - /* Write name of previous cabinet */ - Size = lstrlen(CabinetPrev) + 1; - if (!WriteFile(FileHandle, CabinetPrev, Size, &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - - DPRINT(MAX_TRACE, ("DiskPrev '%s'.\n", DiskPrev)); - - /* Write label of previous disk */ - Size = lstrlen(DiskPrev) + 1; - if (!WriteFile(FileHandle, DiskPrev, Size, &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - } - - if ((CABHeader.Flags & CAB_FLAG_HASNEXT) > 0) { - - DPRINT(MAX_TRACE, ("CabinetNext '%s'.\n", CabinetNext)); - - /* Write name of next cabinet */ - Size = lstrlen(CabinetNext) + 1; - if (!WriteFile(FileHandle, CabinetNext, Size, &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - - DPRINT(MAX_TRACE, ("DiskNext '%s'.\n", DiskNext)); - - /* Write label of next disk */ - Size = lstrlen(DiskNext) + 1; - if (!WriteFile(FileHandle, DiskNext, Size, &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - } - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::WriteFolderEntries() -/* - * FUNCTION: Writes folder entries - * RETURNS: - * Status of operation - */ -{ - PCFFOLDER_NODE FolderNode; - DWORD BytesWritten; - - DPRINT(MAX_TRACE, ("Writing folder table.\n")); - - FolderNode = FolderListHead; - while (FolderNode != NULL) { - if (FolderNode->Commit) { - - DPRINT(MAX_TRACE, ("Writing folder entry. CompressionType (0x%X) DataBlockCount (%d) DataOffset (0x%X).\n", - FolderNode->Folder.CompressionType, FolderNode->Folder.DataBlockCount, FolderNode->Folder.DataOffset)); - - if (!WriteFile(FileHandle, - &FolderNode->Folder, - sizeof(CFFOLDER), - &BytesWritten, - NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - } - FolderNode = FolderNode->Next; - } - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::WriteFileEntries() -/* - * FUNCTION: Writes file entries for all files - * RETURNS: - * Status of operation - */ -{ - PCFFILE_NODE File; - DWORD BytesWritten; - BOOL SetCont; - - DPRINT(MAX_TRACE, ("Writing file table.\n")); - - File = FileListHead; - while (File != NULL) { - if (File->Commit) { - /* Remove any continued files that ends in this disk */ - if (File->File.FileControlID == CAB_FILE_CONTINUED) - File->Delete = TRUE; - - /* The file could end in the last (split) block and should therefore - appear in the next disk too */ - - if ((File->File.FileOffset + File->File.FileSize >= LastBlockStart) && - (File->File.FileControlID <= CAB_FILE_MAX_FOLDER) && (BlockIsSplit)) { - File->File.FileControlID = CAB_FILE_SPLIT; - File->Delete = FALSE; - SetCont = TRUE; - } - - DPRINT(MAX_TRACE, ("Writing file entry. FileControlID (0x%X) FileOffset (0x%X) FileSize (%d) FileName (%s).\n", - File->File.FileControlID, File->File.FileOffset, File->File.FileSize, File->FileName)); - - if (!WriteFile(FileHandle, - &File->File, - sizeof(CFFILE), - &BytesWritten, - NULL)) - return CAB_STATUS_CANNOT_WRITE; - - if (!WriteFile(FileHandle, - GetFileName(File->FileName), - lstrlen(GetFileName(File->FileName)) + 1, &BytesWritten, NULL)) - return CAB_STATUS_CANNOT_WRITE; - - if (SetCont) { - File->File.FileControlID = CAB_FILE_CONTINUED; - SetCont = FALSE; - } - } - - File = File->Next; - } - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::CommitDataBlocks(PCFFOLDER_NODE FolderNode) -/* - * FUNCTION: Writes data blocks to the cabinet - * ARGUMENTS: - * FolderNode = Pointer to folder node containing the data blocks - * RETURNS: - * Status of operation - */ -{ - PCFDATA_NODE DataNode; - DWORD BytesWritten; - DWORD BytesRead; - ULONG Status; - - DataNode = FolderNode->DataListHead; - if (DataNode != NULL) - Status = ScratchFile->Seek(DataNode->ScratchFilePosition); - - while (DataNode != NULL) { - DPRINT(MAX_TRACE, ("Reading block at (0x%X) CompSize (%d) UncompSize (%d).\n", - DataNode->ScratchFilePosition, - DataNode->Data.CompSize, - DataNode->Data.UncompSize)); - - /* InputBuffer is free for us to use here, so we use it and avoid a - memory allocation. OutputBuffer can't be used here because it may - still contain valid data (if a data block spans two or more disks) */ - Status = ScratchFile->ReadBlock(&DataNode->Data, InputBuffer, &BytesRead); - if (Status != CAB_STATUS_SUCCESS) { - DPRINT(MIN_TRACE, ("Cannot read from scratch file (%d).\n", (UINT)Status)); - return Status; - } - - if (!WriteFile(FileHandle, &DataNode->Data, - sizeof(CFDATA), &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - - if (!WriteFile(FileHandle, InputBuffer, - DataNode->Data.CompSize, &BytesWritten, NULL)) { - DPRINT(MIN_TRACE, ("Cannot write to file.\n")); - return CAB_STATUS_CANNOT_WRITE; - } - - DataNode = DataNode->Next; - } - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::WriteDataBlock() -/* - * FUNCTION: Writes the current data block to the scratch file - * RETURNS: - * Status of operation - */ -{ - ULONG Status; - DWORD BytesWritten; - PCFDATA_NODE DataNode; - - if (!BlockIsSplit) { - Status = Codec->Compress(OutputBuffer, - InputBuffer, - CurrentIBufferSize, - &TotalCompSize); - - DPRINT(MAX_TRACE, ("Block compressed. CurrentIBufferSize (%d) TotalCompSize(%d).\n", - CurrentIBufferSize, TotalCompSize)); - - CurrentOBuffer = OutputBuffer; - CurrentOBufferSize = TotalCompSize; - } - - DataNode = NewDataNode(CurrentFolderNode); - if (!DataNode) { - DPRINT(MIN_TRACE, ("Insufficient memory.\n")); - return CAB_STATUS_NOMEMORY; - } - - DiskSize += sizeof(CFDATA); - - if (MaxDiskSize > 0) - /* Disk size is limited */ - BlockIsSplit = (DiskSize + CurrentOBufferSize > MaxDiskSize); - else - BlockIsSplit = FALSE; - - if (BlockIsSplit) { - DataNode->Data.CompSize = (WORD)(MaxDiskSize - DiskSize); - DataNode->Data.UncompSize = 0; - CreateNewDisk = TRUE; - } else { - DataNode->Data.CompSize = (WORD)CurrentOBufferSize; - DataNode->Data.UncompSize = (WORD)CurrentIBufferSize; - } - - DataNode->Data.Checksum = 0; - DataNode->ScratchFilePosition = ScratchFile->Position(); - - // FIXME: MAKECAB.EXE does not like this checksum algorithm - //DataNode->Data.Checksum = ComputeChecksum(CurrentOBuffer, DataNode->Data.CompSize, 0); - - DPRINT(MAX_TRACE, ("Writing block. Checksum (0x%X) CompSize (%d) UncompSize (%d).\n", - (UINT)DataNode->Data.Checksum, - (UINT)DataNode->Data.CompSize, - (UINT)DataNode->Data.UncompSize)); - - Status = ScratchFile->WriteBlock(&DataNode->Data, - CurrentOBuffer, &BytesWritten); - if (Status != CAB_STATUS_SUCCESS) - return Status; - - DiskSize += BytesWritten; - - CurrentFolderNode->TotalFolderSize += (BytesWritten + sizeof(CFDATA)); - CurrentFolderNode->Folder.DataBlockCount++; - - (PUCHAR)CurrentOBuffer += DataNode->Data.CompSize; - CurrentOBufferSize -= DataNode->Data.CompSize; - - LastBlockStart += DataNode->Data.UncompSize; - - if (!BlockIsSplit) { - CurrentIBufferSize = 0; - CurrentIBuffer = InputBuffer; - } - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::GetAttributesOnFile(PCFFILE_NODE File) -/* - * FUNCTION: Returns attributes on a file - * ARGUMENTS: - * File = Pointer to CFFILE node for file - * RETURNS: - * Status of operation - */ -{ - DWORD Attributes; - - Attributes = GetFileAttributes(File->FileName); - if (Attributes == -1) - return CAB_STATUS_CANNOT_READ; - - if (Attributes & FILE_ATTRIBUTE_READONLY) - File->File.Attributes |= CAB_ATTRIB_READONLY; - - if (Attributes & FILE_ATTRIBUTE_HIDDEN) - File->File.Attributes |= CAB_ATTRIB_HIDDEN; - - if (Attributes & FILE_ATTRIBUTE_SYSTEM) - File->File.Attributes |= CAB_ATTRIB_SYSTEM; - - if (Attributes & FILE_ATTRIBUTE_DIRECTORY) - File->File.Attributes |= CAB_ATTRIB_DIRECTORY; - - if (Attributes & FILE_ATTRIBUTE_ARCHIVE) - File->File.Attributes |= CAB_ATTRIB_ARCHIVE; - - return CAB_STATUS_SUCCESS; -} - - -ULONG CCabinet::SetAttributesOnFile(PCFFILE_NODE File) -/* - * FUNCTION: Sets attributes on a file - * ARGUMENTS: - * File = Pointer to CFFILE node for file - * RETURNS: - * Status of operation - */ -{ - DWORD Attributes = 0; - - if (File->File.Attributes & CAB_ATTRIB_READONLY) - Attributes |= FILE_ATTRIBUTE_READONLY; - - if (File->File.Attributes & CAB_ATTRIB_HIDDEN) - Attributes |= FILE_ATTRIBUTE_HIDDEN; - - if (File->File.Attributes & CAB_ATTRIB_SYSTEM) - Attributes |= FILE_ATTRIBUTE_SYSTEM; - - if (File->File.Attributes & CAB_ATTRIB_DIRECTORY) - Attributes |= FILE_ATTRIBUTE_DIRECTORY; - - if (File->File.Attributes & CAB_ATTRIB_ARCHIVE) - Attributes |= FILE_ATTRIBUTE_ARCHIVE; - - SetFileAttributes(File->FileName, Attributes); - - return CAB_STATUS_SUCCESS; -} - -#endif /* CAB_READ_ONLY */ - -/* EOF */ diff --git a/reactos/apps/utils/cabman/cabinet.h b/reactos/apps/utils/cabman/cabinet.h deleted file mode 100644 index 2011bd844d8..00000000000 --- a/reactos/apps/utils/cabman/cabinet.h +++ /dev/null @@ -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 - -/* 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 */ diff --git a/reactos/apps/utils/cabman/cabman.h b/reactos/apps/utils/cabman/cabman.h deleted file mode 100644 index 01348bf5828..00000000000 --- a/reactos/apps/utils/cabman/cabman.h +++ /dev/null @@ -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 */ diff --git a/reactos/apps/utils/cabman/dff.txt b/reactos/apps/utils/cabman/dff.txt deleted file mode 100644 index cea6981b9e4..00000000000 --- a/reactos/apps/utils/cabman/dff.txt +++ /dev/null @@ -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 - [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 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 diff --git a/reactos/apps/utils/cabman/dfp.cpp b/reactos/apps/utils/cabman/dfp.cpp deleted file mode 100644 index be84349b41f..00000000000 --- a/reactos/apps/utils/cabman/dfp.cpp +++ /dev/null @@ -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 -#include -#include -#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 */ diff --git a/reactos/apps/utils/cabman/dfp.h b/reactos/apps/utils/cabman/dfp.h deleted file mode 100644 index 559348df2ab..00000000000 --- a/reactos/apps/utils/cabman/dfp.h +++ /dev/null @@ -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 */ diff --git a/reactos/apps/utils/cabman/main.cpp b/reactos/apps/utils/cabman/main.cpp deleted file mode 100644 index 055926eea7d..00000000000 --- a/reactos/apps/utils/cabman/main.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#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 */ diff --git a/reactos/apps/utils/cabman/makefile b/reactos/apps/utils/cabman/makefile deleted file mode 100644 index 3f14c83cbbe..00000000000 --- a/reactos/apps/utils/cabman/makefile +++ /dev/null @@ -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 - diff --git a/reactos/apps/utils/cabman/mszip.cpp b/reactos/apps/utils/cabman/mszip.cpp deleted file mode 100644 index ec35e921ce1..00000000000 --- a/reactos/apps/utils/cabman/mszip.cpp +++ /dev/null @@ -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 -#include -#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 */ diff --git a/reactos/apps/utils/cabman/mszip.h b/reactos/apps/utils/cabman/mszip.h deleted file mode 100644 index 4d787c7b342..00000000000 --- a/reactos/apps/utils/cabman/mszip.h +++ /dev/null @@ -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 - -#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 */ diff --git a/reactos/apps/utils/cabman/raw.cpp b/reactos/apps/utils/cabman/raw.cpp deleted file mode 100644 index 9014b1622d8..00000000000 --- a/reactos/apps/utils/cabman/raw.cpp +++ /dev/null @@ -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 -#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 */ diff --git a/reactos/apps/utils/cabman/raw.h b/reactos/apps/utils/cabman/raw.h deleted file mode 100644 index 35848a0d242..00000000000 --- a/reactos/apps/utils/cabman/raw.h +++ /dev/null @@ -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 */ diff --git a/reactos/apps/utils/cabman/test.cpp b/reactos/apps/utils/cabman/test.cpp deleted file mode 100644 index 0354ec10764..00000000000 --- a/reactos/apps/utils/cabman/test.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#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 */ diff --git a/reactos/apps/utils/cabman/test.h b/reactos/apps/utils/cabman/test.h deleted file mode 100644 index ad9a18bcb58..00000000000 --- a/reactos/apps/utils/cabman/test.h +++ /dev/null @@ -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 */