2003-08-24 Casper S. Hornstrup <chorns@users.sourceforge.net>

* Makefile: Support creating compressed bootable CDs.
	* rules.mak (HOST_CXX, HOST_AR, CABMAN): Define.
	* bootdata/txtsetup.sif: Add Cabinets section.
	Remove files that are put in reactos.cab.
	* subsys/system/usetup/filequeue.c (SetupCloseFileQueue): Release
	memory allocated for SourceCabinet.
	(SetupQueueCopy): Support copying files in cabinets.
	(SetupCommitFileQueue): Support copying files in cabinets.
	* subsys/system/usetup/filequeue.h (SetupQueueCopy): Add SourceCabinet
	parameter.
	* subsys/system/usetup/filesup.c (SetupExtractFile): New function.
	* subsys/system/usetup/filesup.h (SetupExtractFile): Prototype.
	* subsys/system/usetup/infcache.c (InfOpenBufferedFile): New function.
	* subsys/system/usetup/infcache.h (InfOpenBufferedFile): Prototype.
	* subsys/system/usetup/makefile (TARGET_SDKLIBS): Add zlib.a.
	(TARGET_CFLAGS): Add zlib to include path.
	(TARGET_OBJECTS): Add cabinet.o.
	* subsys/system/usetup/usetup.c (PrepareCopyPageInfFile): New function.
	(PrepareCopyPage): Process Cabinets section.
	* tools/helper.mk: Support C++ applications.
	* rosbin.txt: Remove.
	* bootdata/packages: New directory.
	* bootdata/packages/reactos.dff: New file.
	* lib/zlib/Makefile.host: New file.
	* subsys/system/usetup/cabinet.c: Ditto.
	* subsys/system/usetup/cabinet.h: Ditto.
	* tools/cabman: New directory.
	* tools/cabman/.cvsignore: New file.
	* tools/cabman/cabinet.cxx: Ditto.
	* tools/cabman/cabinet.h: Ditto.
	* tools/cabman/cabman.h: Ditto.
	* tools/cabman/dff.txt: Ditto.
	* tools/cabman/dfp.cxx: Ditto.
	* tools/cabman/dfp.h: Ditto.
	* tools/cabman/main.cxx: Ditto.
	* tools/cabman/makefile: Ditto.
	* tools/cabman/makefile.win32: Ditto.
	* tools/cabman/mszip.cxx: Ditto.
	* tools/cabman/mszip.h: Ditto.
	* tools/cabman/raw.cxx: Ditto.
	* tools/cabman/raw.h: Ditto.

svn path=/trunk/; revision=5813
This commit is contained in:
Casper Hornstrup 2003-08-24 10:36:07 +00:00
parent a60eb421a7
commit aa6c5c7738
33 changed files with 9086 additions and 246 deletions

View file

@ -1,3 +1,47 @@
2003-08-24 Casper S. Hornstrup <chorns@users.sourceforge.net>
* Makefile: Support creating compressed bootable CDs.
* rules.mak (HOST_CXX, HOST_AR, CABMAN): Define.
* bootdata/txtsetup.sif: Add Cabinets section.
Remove files that are put in reactos.cab.
* subsys/system/usetup/filequeue.c (SetupCloseFileQueue): Release
memory allocated for SourceCabinet.
(SetupQueueCopy): Support copying files in cabinets.
(SetupCommitFileQueue): Support copying files in cabinets.
* subsys/system/usetup/filequeue.h (SetupQueueCopy): Add SourceCabinet
parameter.
* subsys/system/usetup/filesup.c (SetupExtractFile): New function.
* subsys/system/usetup/filesup.h (SetupExtractFile): Prototype.
* subsys/system/usetup/infcache.c (InfOpenBufferedFile): New function.
* subsys/system/usetup/infcache.h (InfOpenBufferedFile): Prototype.
* subsys/system/usetup/makefile (TARGET_SDKLIBS): Add zlib.a.
(TARGET_CFLAGS): Add zlib to include path.
(TARGET_OBJECTS): Add cabinet.o.
* subsys/system/usetup/usetup.c (PrepareCopyPageInfFile): New function.
(PrepareCopyPage): Process Cabinets section.
* tools/helper.mk: Support C++ applications.
* rosbin.txt: Remove.
* bootdata/packages: New directory.
* bootdata/packages/reactos.dff: New file.
* lib/zlib/Makefile.host: New file.
* subsys/system/usetup/cabinet.c: Ditto.
* subsys/system/usetup/cabinet.h: Ditto.
* tools/cabman: New directory.
* tools/cabman/.cvsignore: New file.
* tools/cabman/cabinet.cxx: Ditto.
* tools/cabman/cabinet.h: Ditto.
* tools/cabman/cabman.h: Ditto.
* tools/cabman/dff.txt: Ditto.
* tools/cabman/dfp.cxx: Ditto.
* tools/cabman/dfp.h: Ditto.
* tools/cabman/main.cxx: Ditto.
* tools/cabman/makefile: Ditto.
* tools/cabman/makefile.win32: Ditto.
* tools/cabman/mszip.cxx: Ditto.
* tools/cabman/mszip.h: Ditto.
* tools/cabman/raw.cxx: Ditto.
* tools/cabman/raw.h: Ditto.
2003-08-24 Casper S. Hornstrup <chorns@users.sourceforge.net>
* include/structs.h: Apply packed attribute to the typedef, not the

View file

@ -158,8 +158,23 @@ bootcd_bootstrap_files: $(COMPONENTS:%=%_bootcd) $(HALS:%=%_bootcd) $(BUS:%=%_bo
$(LIB_STATIC:%=%_bootcd) $(LIB_FSLIB:%=%_bootcd) $(DLLS:%=%_bootcd) $(KERNEL_DRIVERS:%=%_bootcd) \
$(SUBSYS:%=%_bootcd) $(SYS_APPS:%=%_bootcd)
bootcd: all bootcd_directory_layout bootcd_bootstrap_files
$(MAKE) install INSTALL_DIR=$(BOOTCD_DIR)/reactos INSTALL_SYMBOLS=no BOOTCD_INSTALL=yes
bootcd_install_before:
$(RLINE) bootdata/autorun.inf $(BOOTCD_DIR)/autorun.inf
$(RLINE) bootdata/readme.txt $(BOOTCD_DIR)/readme.txt
$(RLINE) bootdata/hivecls.inf $(BOOTCD_DIR)/reactos/hivecls.inf
$(RLINE) bootdata/hivedef.inf $(BOOTCD_DIR)/reactos/hivedef.inf
$(RLINE) bootdata/hivesft.inf $(BOOTCD_DIR)/reactos/hivesft.inf
$(RLINE) bootdata/hivesys.inf $(BOOTCD_DIR)/reactos/hivesys.inf
$(RLINE) bootdata/txtsetup.sif $(BOOTCD_DIR)/reactos/txtsetup.sif
$(CP) bootdata/icon.ico $(BOOTCD_DIR)/icon.ico
$(CP) media/nls/c_1252.nls $(BOOTCD_DIR)/reactos/c_1252.nls
$(CP) media/nls/c_437.nls $(BOOTCD_DIR)/reactos/c_437.nls
$(CP) media/nls/l_intl.nls $(BOOTCD_DIR)/reactos/l_intl.nls
bootcd: all bootcd_directory_layout bootcd_bootstrap_files bootcd_install_before
$(CABMAN) /C bootdata/packages/reactos.dff /L $(BOOTCD_DIR)/reactos /I
$(CABMAN) /C bootdata/packages/reactos.dff /RC $(BOOTCD_DIR)/reactos/reactos.inf /L $(BOOTCD_DIR)/reactos /N
- $(RM) $(BOOTCD_DIR)/reactos/reactos.inf
.PHONY: all depends implib clean clean_before install dist bootcd_directory_layout \
bootcd_bootstrap_files bootcd

View file

@ -0,0 +1,134 @@
; Main ReactOS package
.Set DiskLabelTemplate="ReactOS" ; Label of disk
.Set CabinetNameTemplate="reactos.cab" ; reactos.cab
.Set InfFileName="reactos.inf" ; reactos.inf
;.Set Cabinet=on
;.Set Compress=on
.InfBegin
[Version]
Signature = "$ReactOS$"
[Directories]
1 = system32
2 = system32\drivers
3 = media\fonts
.InfEnd
; Contents of disk
.InfBegin
[SourceFiles]
.InfEnd
drivers\bus\acpi\acpi.sys 2
drivers\bus\isapnp\isapnp.sys 2
drivers\bus\pci\pci.sys 2
drivers\dd\beep\beep.sys 2
drivers\dd\null\null.sys 2
drivers\dd\serial\serial.sys 2
drivers\dd\vga\display\vgaddi.dll 1
drivers\dd\vga\miniport\vgamp.sys 2
drivers\dd\videoprt\videoprt.sys 2
drivers\fs\fs_rec\fs_rec.sys 2
drivers\fs\ms\msfs.sys 2
drivers\fs\mup\mup.sys 2
drivers\fs\np\npfs.sys 2
drivers\input\mouclass\mouclass.sys 2
drivers\input\psaux\psaux.sys 2
drivers\input\sermouse\sermouse.sys 2
drivers\net\afd\afd.sys 2
drivers\net\ndis\ndis.sys 2
drivers\net\tcpip\tcpip.sys 2
drivers\net\tdi\tdi.sys 2
drivers\net\wshtcpip\wshtcpip.dll 1
drivers\net\dd\ne2000\ne2000.sys 2
lib\advapi32\advapi32.dll 1
lib\crtdll\crtdll.dll 1
lib\fmifs\fmifs.dll 1
lib\freetype\freetype.dll 1
lib\gdi32\gdi32.dll 1
lib\iphlpapi\iphlpapi.dll 1
lib\kbdus\kbdus.dll 1
lib\kernel32\kernel32.dll 1
lib\lzexpand\lz32.dll 1
lib\msafd\msafd.dll 1
lib\msvcrt\msvcrt.dll 1
lib\ntdll\ntdll.dll 1
lib\secur32\secur32.dll 1
lib\syssetup\syssetup.dll 1
lib\twain\twain_32.dll 1
lib\user32\user32.dll 1
lib\version\version.dll 1
lib\winmm\winmm.dll 1
lib\winspool\winspool.drv 1
lib\ws2_32\ws2_32.dll 1
lib\ws2help\ws2help.dll 1
lib\wshirda\wshirda.dll 1
lib\wsock32\wsock32.dll 1
subsys\csrss\csrss.exe 1
subsys\ntvdm\ntvdm.exe 1
subsys\smss\smss.exe 1
subsys\win32k\win32k.sys 1
subsys\system\autochk\autochk.exe 1
subsys\system\cmd\cmd.exe 1
subsys\system\format\format.exe 1
subsys\system\services\services.exe 1
subsys\system\setup\setup.exe 1
subsys\system\winlogon\winlogon.exe 1
services\eventlog\eventlog.exe 1
services\rpcss\rpcss.exe 1
media\fonts\helb____.ttf 3
media\fonts\timr____.ttf 3
media\nls\c_037.nls 1
media\nls\c_500.nls 1
media\nls\c_737.nls 1
media\nls\c_775.nls 1
media\nls\c_850.nls 1
media\nls\c_852.nls 1
media\nls\c_855.nls 1
media\nls\c_856.nls 1
media\nls\c_857.nls 1
media\nls\c_860.nls 1
media\nls\c_861.nls 1
media\nls\c_862.nls 1
media\nls\c_863.nls 1
media\nls\c_864.nls 1
media\nls\c_865.nls 1
media\nls\c_866.nls 1
media\nls\c_869.nls 1
media\nls\c_874.nls 1
media\nls\c_875.nls 1
media\nls\c_878.nls 1
media\nls\c_932.nls 1
media\nls\c_936.nls 1
media\nls\c_949.nls 1
media\nls\c_950.nls 1
media\nls\c_1006.nls 1
media\nls\c_1026.nls 1
media\nls\c_1250.nls 1
media\nls\c_1251.nls 1
media\nls\c_1253.nls 1
media\nls\c_1254.nls 1
media\nls\c_1255.nls 1
media\nls\c_1256.nls 1
media\nls\c_1257.nls 1
media\nls\c_1258.nls 1
media\nls\c_10000.nls 1
media\nls\c_10006.nls 1
media\nls\c_10007.nls 1
media\nls\c_10029.nls 1
media\nls\c_10079.nls 1
media\nls\c_10081.nls 1
media\nls\c_20866.nls 1
media\nls\c_28591.nls 1
media\nls\c_28592.nls 1
media\nls\c_28593.nls 1
media\nls\c_28594.nls 1
media\nls\c_28595.nls 1
media\nls\c_28596.nls 1
media\nls\c_28597.nls 1
media\nls\c_28598.nls 1
media\nls\c_28599.nls 1

View file

@ -11,112 +11,25 @@ Signature = "$ReactOS$"
7 = bin
[SourceFiles]
ntoskrnl.exe = 2
hal.dll = 2
atapi.sys = 3
blue.sys = 3
c_437.nls = 2
c_1252.nls = 2
cdfs.sys = 3
cdrom.sys = 3
class2.sys = 3
disk.sys = 3
floppy.sys = 3
hal.dll = 2
keyboard.sys = 3
l_intl.nls = 2
ntfs.sys = 3
ntoskrnl.exe = 2
scsiport.sys = 3
vfatfs.sys = 3
acpi.sys = 3
isapnp.sys = 3
beep.sys = 3
blue.sys = 3
debugout.sys = 3
floppy.sys = 3
null.sys = 3
serial.sys = 3
vgaddi.dll = 2
vgamp.sys = 3
videoprt.sys = 3
cdfs.sys = 3
fs_rec.sys = 3
msfs.sys = 3
mup.sys = 3
npfs.sys = 3
ntfs.sys = 3
vfatfs.sys = 3
keyboard.sys = 3
mouclass.sys = 3
psaux.sys = 3
sermouse.sys = 3
unbzip2.sys = 3
afd.sys = 3
ne2000.sys = 3
ndis.sys = 3
npf.sys = 3
;packet.sys = 3
tcpip.sys = 3
tdi.sys = 3
atapi.sys = 3
cdrom.sys = 3
class2.sys = 3
disk.sys = 3
scsiport.sys = 3
advapi32.dll = 2
crtdll.dll = 2
fmifs.dll = 2
freetype.dll = 2
gdi32.dll = 2
kernel32.dll = 2
msafd.dll = 2
msvcrt.dll = 2
ntdll.dll = 2
;ole32.dll = 2
;oleaut32.dll = 2
packet.dll = 2
secur32.dll = 2
;shell32.dll = 2
syssetup.dll = 2
user32.dll = 2
version.dll = 2
winedbgc.dll = 2
winspool.drv = 2
;winmm.dll = 2
ws2_32.dll = 2
ws2help.dll = 2
wshirda.dll = 2
autochk.exe = 2
cmd.exe = 2
csrss.exe = 2
eventlog.exe = 2
;lsass.exe = 2
ntvdm.exe = 2
rpcss.exe = 2
setup.exe = 2
smss.exe = 2
services.exe = 2
winlogon.exe = 2
win32k.sys = 2
helb____.ttf = 6
timr____.ttf = 6
Vera.ttf = 6
VeraBd.ttf = 6
VeraBI.ttf = 6
VeraIt.ttf = 6
VeraMoBd.ttf = 6
VeraMoBI.ttf = 6
VeraMoIt.ttf = 6
VeraMono.ttf = 6
VeraSe.ttf = 6
VeraSeBd.ttf = 6
c_10000.nls = 2
c_1252.nls = 2
c_437.nls = 2
l_intl.nls = 2
winhello.exe = 2
hcalc.exe = 2
mc.exe = 2
winemine.exe = 2
[Cabinets]
Cabinet=reactos.cab
[SetupData]
DefaultPath = \ReactOS

44
reactos/lib/zlib/Makefile.host Executable file
View file

@ -0,0 +1,44 @@
# $Id: Makefile.host,v 1.1 2003/08/24 10:36:06 chorns Exp $
PATH_TO_TOP = ../..
TARGET = zlib.host.a
CFLAGS = \
-MMD -O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
-Wstrict-prototypes -Wmissing-prototypes
OBJECTS = \
adler32.o \
compress.o \
crc32.o \
gzio.o \
uncompr.o \
deflate.o \
trees.o \
zutil.o \
inflate.o \
infblock.o \
inftrees.o \
infcodes.o \
infutil.o \
inffast.o
all: hostobjs $(TARGET)
hostobjs:
- $(RMKDIR) hostobjs
%.o: %.c
$(HOST_CC) $(CFLAGS) -c $< -o hostobjs/$@
$(TARGET): $(OBJECTS)
$(HOST_AR) -r $(TARGET) $(addprefix hostobjs/, $(OBJECTS))
clean:
- $(RM) hostobjs/*
- $(RM) $(TARGET)
- $(RMDIR) hostobjs
.phony: clean
include $(PATH_TO_TOP)/rules.mak

View file

@ -1,67 +0,0 @@
; ReactOS Cabinet Manager Directive File - ReactOS Binary Distribution
;.Set DiskLabel1="ReactOS Setup Disk" ; Label of 1st disk
;.Set DiskLabel2="ReactOS Drivers" ; Label of 2nd disk
;.Set DiskLabel3="ReactOS Subsystems" ; Label of 3rd disk
;.Set DiskLabel4="ReactOS Applications" ; Label of 4th disk
.Set DiskLabelTemplate="ReactOS Disk *" ; Label of all disks
.Set CabinetNameTemplate="ROS*.CAB" ; ROS1.CAB, ROS2.CAB, etc.
.Set MaxDiskSize=500000 ; 500000 bytes disks
;.Set MaxDiskSize=720K ; 720KB disks
;.Set MaxDiskSize=1.44M ; 1.44MB disks
;.Set MaxDiskSize=2.88M ; 2.88MB disks
;.Set Cabinet=on
;.Set Compress=on
; Contents of disk 1
boot.bat
loaders\dos\loadros.com
ntoskrnl\ntoskrnl.exe system32
lib\ntdll\ntdll.dll system32
apps\system\services\services.exe system32
apps\system\winlogon\winlogon.exe system32
; Contents of disk 2
;.New Disk
;services\dd\beep\beep.sys system32\drivers
services\dd\blue\blue.sys system32\drivers
services\dd\floppy\floppy.sys system32\drivers
services\dd\ide\ide.sys system32\drivers
services\dd\null\null.sys system32\drivers
services\dd\parallel\parallel.sys system32\drivers
services\dd\serial\serial.sys system32\drivers
services\dd\vga\display\vgaddi.dll system32\drivers
services\dd\vga\miniport\vgamp.sys system32\drivers
services\dd\vidport\vidport.sys system32\drivers
services\fs\vfat\vfatfs.sys system32\drivers
services\input\keyboard\keyboard.sys system32\drivers
services\net\afd\afd.sys system32
services\net\ndis\ndis.sys system32
services\net\tcpip\tcpip.sys system32
;services\net\tdi\tdi.sys system32
services\net\wshtcpip\wshtcpip.dll system32
services\net\dd\ne2000\ne2000.sys system32\drivers
; Contents of disk 3
;.New Disk
lib\advapi32\advapi32.dll system32
lib\crtdll\crtdll.dll system32
lib\fmifs\fmifs.dll system32
lib\gdi32\gdi32.dll system32
lib\kernel32\kernel32.dll system32
lib\msafd\msafd.dll system32
;lib\msvcrt\msvcrt.dll system32
lib\secur32\secur32.dll system32
;lib\user32\user32.dll system32
lib\ws2_32\ws2_32.dll system32
subsys\csrss\csrss.exe system32
subsys\smss\smss.exe system32
subsys\win32k\win32k.sys system32
; Contents of disk 4
;.New Disk
apps\system\cmd\cmd.exe system32
; EOF

View file

@ -73,6 +73,8 @@ BOOTCD_DIR=$(TOPDIR)/../bootcd/disk
CC = $(PREFIX)gcc
CXX = $(PREFIX)g++
HOST_CC = gcc
HOST_CXX = g++
HOST_AR = ar
HOST_NM = nm
LD = $(PREFIX)ld
NM = $(PREFIX)nm
@ -96,6 +98,7 @@ RSYM = $(TOOLS_PATH)/rsym
RTOUCH = $(TOOLS_PATH)/rtouch
REGTESTS = $(TOOLS_PATH)/regtests
MC = $(TOOLS_PATH)/wmc/wmc
CABMAN = $(TOOLS_PATH)/cabman/cabman
XSLTPROC = xsltproc

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,245 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: apps/cabman/cabinet.h
* PURPOSE: Cabinet definitions
*/
#ifndef __CABINET_H
#define __CABINET_H
#include <string.h>
/* 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
{
ULONG Signature; // File signature 'MSCF' (CAB_SIGNATURE)
ULONG Reserved1; // Reserved field
ULONG CabinetSize; // Cabinet file size
ULONG Reserved2; // Reserved field
ULONG FileTableOffset; // Offset of first CFFILE
ULONG 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
{
ULONG 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
{
ULONG FileSize; // Uncompressed file size in bytes
ULONG 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
{
ULONG 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;
ULONG ScratchFilePosition; // Absolute offset in scratch file
ULONG AbsoluteOffset; // Absolute offset in cabinet
ULONG UncompOffset; // Uncompressed offset in folder
CFDATA Data;
} CFDATA_NODE, *PCFDATA_NODE;
typedef struct _CFFOLDER_NODE
{
struct _CFFOLDER_NODE *Next;
struct _CFFOLDER_NODE *Prev;
ULONG UncompOffset; // File size accumulator
ULONG AbsoluteOffset;
ULONG TotalFolderSize; // Total size of folder in current disk
PCFDATA_NODE DataListHead;
PCFDATA_NODE DataListTail;
ULONG 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;
PWCHAR 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
{
WCHAR Search[MAX_PATH]; // Search criteria
PCFFILE_NODE Next; // Pointer to next node
PCFFILE File; // Pointer to current CFFILE
PWCHAR 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 */
/* Uncompresses a data block */
typedef ULONG (*PCABINET_CODEC_UNCOMPRESS)(PVOID OutputBuffer,
PVOID InputBuffer,
ULONG InputLength,
PULONG OutputLength);
/* 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
#define MSZIP_MAGIC 0x4B43
/* Event handler prototypes */
typedef BOOL (*PCABINET_OVERWRITE)(PCFFILE File,
PWCHAR FileName);
typedef VOID (*PCABINET_EXTRACT)(PCFFILE File,
PWCHAR FileName);
typedef VOID (*PCABINET_DISK_CHANGE)(PWCHAR CabinetName,
PWCHAR DiskLabel);
/* Classes */
/* Default constructor */
VOID CabinetInitialize();
/* Default destructor */
VOID CabinetCleanup();
/* Returns a pointer to the filename part of a fully qualified filename */
PWCHAR CabinetGetFileName(PWCHAR Path);
/* Removes a filename from a fully qualified filename */
VOID CabinetRemoveFileName(PWCHAR Path);
/* Normalizes a path */
BOOL CabinetNormalizePath(PWCHAR Path, ULONG Length);
/* Returns name of cabinet file */
PWCHAR CabinetGetCabinetName();
/* Sets the name of the cabinet file */
VOID CabinetSetCabinetName(PWCHAR FileName);
/* Sets destination path for extracted files */
VOID CabinetSetDestinationPath(PWCHAR DestinationPath);
/* Returns destination path */
PWCHAR CabinetGetDestinationPath();
/* Returns zero-based current disk number */
ULONG CabinetGetCurrentDiskNumber();
/* Opens the current cabinet file */
ULONG CabinetOpen();
/* Closes the current open cabinet file */
VOID CabinetClose();
/* Locates the first file in the current cabinet file that matches a search criteria */
ULONG CabinetFindFirst(PWCHAR FileName, PCAB_SEARCH Search);
/* Locates the next file in the current cabinet file */
ULONG CabinetFindNext(PCAB_SEARCH Search);
/* Extracts a file from the current cabinet file */
ULONG CabinetExtractFile(PWCHAR FileName);
/* Select codec engine to use */
VOID CabinetSelectCodec(ULONG Id);
/* Set event handlers */
VOID CabinetSetEventHandlers(PCABINET_OVERWRITE Overwrite,
PCABINET_EXTRACT Extract,
PCABINET_DISK_CHANGE DiskChange);
/* Get pointer to cabinet reserved area. NULL if none */
PVOID CabinetGetCabinetReservedArea(PULONG Size);
#endif /* __CABINET_H */

View file

@ -16,12 +16,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: filequeue.c,v 1.1 2002/11/23 01:55:27 ekohl Exp $
/* $Id: filequeue.c,v 1.2 2003/08/24 10:36:06 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/filequeue.c
* PURPOSE: File queue functions
* PROGRAMMER: Eric Kohl
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* INCLUDES *****************************************************************/
@ -42,6 +43,7 @@ typedef struct _QUEUEENTRY
struct _QUEUEENTRY *Prev;
struct _QUEUEENTRY *Next;
PWSTR SourceCabinet; /* May be NULL if file is not in a cabinet */
PWSTR SourceRootPath;
PWSTR SourcePath;
PWSTR SourceFilename;
@ -98,6 +100,8 @@ SetupCloseFileQueue(HSPFILEQ QueueHandle)
while (Entry != NULL)
{
/* Delete all strings */
if (Entry->SourceCabinet != NULL)
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
if (Entry->SourceRootPath != NULL)
RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
if (Entry->SourcePath != NULL)
@ -139,6 +143,7 @@ SetupCloseFileQueue(HSPFILEQ QueueHandle)
BOOL
SetupQueueCopy(HSPFILEQ QueueHandle,
PCWSTR SourceCabinet,
PCWSTR SourceRootPath,
PCWSTR SourcePath,
PCWSTR SourceFilename,
@ -149,6 +154,7 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
PQUEUEENTRY Entry;
ULONG Length;
/* SourceCabinet may be NULL */
if (QueueHandle == NULL ||
SourceRootPath == NULL ||
SourceFilename == NULL ||
@ -167,6 +173,26 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
RtlZeroMemory(Entry,
sizeof(QUEUEENTRY));
/* Copy source cabinet if available */
if (SourceCabinet != NULL)
{
Length = wcslen(SourceCabinet);
Entry->SourceCabinet = RtlAllocateHeap(ProcessHeap,
0,
(Length + 1) * sizeof(WCHAR));
if (Entry->SourceCabinet == NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry);
return(FALSE);
}
wcsncpy(Entry->SourceCabinet, SourceCabinet, Length);
Entry->SourceCabinet[Length] = (WCHAR)0;
}
else
{
Entry->SourceCabinet = NULL;
}
/* Copy source root path */
Length = wcslen(SourceRootPath);
Entry->SourceRootPath = RtlAllocateHeap(ProcessHeap,
@ -174,6 +200,10 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
(Length + 1) * sizeof(WCHAR));
if (Entry->SourceRootPath == NULL)
{
if (Entry->SourceCabinet != NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
}
RtlFreeHeap(ProcessHeap, 0, Entry);
return(FALSE);
}
@ -189,6 +219,10 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
(Length + 1) * sizeof(WCHAR));
if (Entry->SourcePath == NULL)
{
if (Entry->SourceCabinet != NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
}
RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
RtlFreeHeap(ProcessHeap, 0, Entry);
return(FALSE);
@ -204,6 +238,10 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
(Length + 1) * sizeof(WCHAR));
if (Entry->SourceFilename == NULL)
{
if (Entry->SourceCabinet != NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
}
RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
RtlFreeHeap(ProcessHeap, 0, Entry);
@ -221,6 +259,10 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
(Length + 1) * sizeof(WCHAR));
if (Entry->TargetDirectory == NULL)
{
if (Entry->SourceCabinet != NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
}
RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename);
@ -239,6 +281,10 @@ SetupQueueCopy(HSPFILEQ QueueHandle,
(Length + 1) * sizeof(WCHAR));
if (Entry->TargetFilename == NULL)
{
if (Entry->SourceCabinet != NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
}
RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename);
@ -278,6 +324,7 @@ SetupCommitFileQueue(HSPFILEQ QueueHandle,
PSP_FILE_CALLBACK MsgHandler,
PVOID Context)
{
WCHAR CabinetName[MAX_PATH];
PFILEQUEUEHEADER QueueHeader;
PQUEUEENTRY Entry;
NTSTATUS Status;
@ -304,7 +351,6 @@ SetupCommitFileQueue(HSPFILEQ QueueHandle,
Entry = QueueHeader->CopyHead;
while (Entry != NULL)
{
/* Build the full source path */
wcscpy(FileSrcPath, Entry->SourceRootPath);
if (Entry->SourcePath != NULL)
wcscat(FileSrcPath, Entry->SourcePath);
@ -328,11 +374,16 @@ SetupCommitFileQueue(HSPFILEQ QueueHandle,
wcscat(FileDstPath, L"\\");
wcscat(FileDstPath, Entry->TargetDirectory);
}
wcscat(FileDstPath, L"\\");
if (Entry->TargetFilename != NULL)
wcscat(FileDstPath, Entry->TargetFilename);
else
wcscat(FileDstPath, Entry->SourceFilename);
/* Use only the destination path if the file is in a cabinet */
if (Entry->SourceCabinet == NULL)
{
wcscat(FileDstPath, L"\\");
if (Entry->TargetFilename != NULL)
wcscat(FileDstPath, Entry->TargetFilename);
else
wcscat(FileDstPath, Entry->SourceFilename);
}
/* FIXME: Do it! */
DPRINT("'%S' ==> '%S'\n",
@ -344,8 +395,21 @@ SetupCommitFileQueue(HSPFILEQ QueueHandle,
(PVOID)Entry->SourceFilename,
(PVOID)FILEOP_COPY);
/* Copy the file */
Status = SetupCopyFile(FileSrcPath, FileDstPath);
if (Entry->SourceCabinet != NULL)
{
/* Extract the file */
wcscpy(CabinetName, Entry->SourceRootPath);
if (Entry->SourcePath != NULL)
wcscat(CabinetName, Entry->SourcePath);
wcscat(CabinetName, L"\\");
wcscat(CabinetName, Entry->SourceCabinet);
Status = SetupExtractFile(CabinetName, Entry->SourceFilename, FileDstPath);
}
else
{
/* Copy the file */
Status = SetupCopyFile(FileSrcPath, FileDstPath);
}
if (!NT_SUCCESS(Status))
{
MsgHandler(Context,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: filequeue.h,v 1.1 2002/11/23 01:55:27 ekohl Exp $
/* $Id: filequeue.h,v 1.2 2003/08/24 10:36:06 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/filequeue.h
@ -69,6 +69,7 @@ SetupCloseFileQueue(HSPFILEQ QueueHandle);
BOOL
SetupQueueCopy(HSPFILEQ QueueHandle,
PCWSTR SourceCabinet,
PCWSTR SourceRootPath,
PCWSTR SourcePath,
PCWSTR SourceFilename,

View file

@ -16,12 +16,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: filesup.c,v 1.6 2003/05/18 12:50:17 ekohl Exp $
/* $Id: filesup.c,v 1.7 2003/08/24 10:36:06 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/filesup.c
* PURPOSE: File support functions
* PROGRAMMER: Eric Kohl
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* INCLUDES *****************************************************************/
@ -31,11 +32,15 @@
#include "usetup.h"
#include "filesup.h"
#include "cabinet.h"
/* FUNCTIONS ****************************************************************/
static BOOLEAN HasCurrentCabinet = FALSE;
static WCHAR CurrentCabinetName[MAX_PATH];
NTSTATUS
CreateDirectory(PWCHAR DirectoryName)
{
@ -274,6 +279,65 @@ SetupCopyFile(PWCHAR SourceFileName,
}
NTSTATUS
SetupExtractFile(PWCHAR CabinetFileName,
PWCHAR SourceFileName,
PWCHAR DestinationPathName)
{
ULONG CabStatus;
DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n",
CabinetFileName, SourceFileName, DestinationPathName);
if (HasCurrentCabinet)
{
DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName);
}
if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) == 0))
{
DPRINT("Using same cabinet as last time\n");
}
else
{
DPRINT("Using new cabinet\n");
if (HasCurrentCabinet)
{
CabinetCleanup();
}
wcscpy(CurrentCabinetName, CabinetFileName);
CabinetInitialize();
CabinetSetEventHandlers(NULL, NULL, NULL);
CabinetSetCabinetName(CabinetFileName);
CabStatus = CabinetOpen();
if (CabStatus == CAB_STATUS_SUCCESS)
{
DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
HasCurrentCabinet = TRUE;
}
else
{
DPRINT("Cannot open cabinet (%d)\n", CabStatus);
return STATUS_UNSUCCESSFUL;
}
}
CabinetSetDestinationPath(DestinationPathName);
CabStatus = CabinetExtractFile(SourceFileName);
if (CabStatus != CAB_STATUS_SUCCESS)
{
DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus);
return STATUS_UNSUCCESSFUL;
}
return STATUS_SUCCESS;
}
BOOLEAN
DoesFileExist(PWSTR PathName,
PWSTR FileName)

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: filesup.h,v 1.3 2003/01/17 13:18:15 ekohl Exp $
/* $Id: filesup.h,v 1.4 2003/08/24 10:36:06 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/filesup.h
@ -34,6 +34,11 @@ NTSTATUS
SetupCopyFile(PWCHAR SourceFileName,
PWCHAR DestinationFileName);
NTSTATUS
SetupExtractFile(PWCHAR CabinetFileName,
PWCHAR SourceFileName,
PWCHAR DestinationFileName);
BOOLEAN
DoesFileExist(PWSTR PathName,
PWSTR FileName);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: infcache.c,v 1.4 2003/05/18 12:50:17 ekohl Exp $
/* $Id: infcache.c,v 1.5 2003/08/24 10:36:06 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/infcache.c
@ -893,6 +893,75 @@ InfpParseBuffer (PINFCACHE file,
/* PUBLIC FUNCTIONS *********************************************************/
NTSTATUS
InfOpenBufferedFile(PHINF InfHandle,
PVOID Buffer,
ULONG BufferSize,
PULONG ErrorLine)
{
NTSTATUS Status;
PINFCACHE Cache;
PCHAR FileBuffer;
*InfHandle = NULL;
*ErrorLine = (ULONG)-1;
/* Allocate file buffer */
FileBuffer = RtlAllocateHeap(ProcessHeap,
0,
BufferSize + 1);
if (FileBuffer == NULL)
{
DPRINT1("RtlAllocateHeap() failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlCopyMemory(FileBuffer, Buffer, BufferSize);
/* Append string terminator */
FileBuffer[BufferSize] = 0;
/* Allocate infcache header */
Cache = (PINFCACHE)RtlAllocateHeap(ProcessHeap,
0,
sizeof(INFCACHE));
if (Cache == NULL)
{
DPRINT("RtlAllocateHeap() failed\n");
RtlFreeHeap(ProcessHeap,
0,
FileBuffer);
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Initialize inicache header */
RtlZeroMemory(Cache,
sizeof(INFCACHE));
/* Parse the inf buffer */
Status = InfpParseBuffer (Cache,
FileBuffer,
FileBuffer + BufferSize,
ErrorLine);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap(ProcessHeap,
0,
Cache);
Cache = NULL;
}
/* Free file buffer */
RtlFreeHeap(ProcessHeap,
0,
FileBuffer);
*InfHandle = (HINF)Cache;
return(Status);
}
NTSTATUS
InfOpenFile(PHINF InfHandle,
PUNICODE_STRING FileName,

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: infcache.h,v 1.3 2003/03/15 19:36:11 ekohl Exp $
/* $Id: infcache.h,v 1.4 2003/08/24 10:36:06 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/infcache.h
@ -49,6 +49,12 @@ typedef struct _INFCONTEXT
/* FUNCTIONS ****************************************************************/
NTSTATUS
InfOpenBufferedFile(PHINF InfHandle,
PVOID Buffer,
ULONG BufferSize,
PULONG ErrorLine);
NTSTATUS
InfOpenFile (PHINF InfHandle,
PUNICODE_STRING FileName,

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.12 2003/08/09 16:32:25 ekohl Exp $
# $Id: makefile,v 1.13 2003/08/24 10:36:06 chorns Exp $
PATH_TO_TOP = ../../..
@ -12,15 +12,15 @@ TARGET_APPTYPE = native
TARGET_NAME = usetup
TARGET_SDKLIBS = vfatlib.a ntdll.a
TARGET_SDKLIBS = zlib.a vfatlib.a ntdll.a
TARGET_INSTALLDIR = system32
TARGET_CFLAGS = -D__NTAPP__
TARGET_CFLAGS = -D__NTAPP__ -I$(PATH_TO_TOP)/lib/zlib
TARGET_OBJECTS = $(TARGET_NAME).o bootsup.o console.o drivesup.o filequeue.o \
filesup.o format.o fslist.o infcache.o inicache.o partlist.o \
progress.o registry.o
TARGET_OBJECTS = $(TARGET_NAME).o bootsup.o cabinet.o console.o drivesup.o \
filequeue.o filesup.o format.o fslist.o infcache.o \
inicache.o partlist.o progress.o registry.o
include $(PATH_TO_TOP)/rules.mak

View file

@ -42,6 +42,7 @@
#include "registry.h"
#include "format.h"
#include "fslist.h"
#include "cabinet.h"
#define NDEBUG
#include <debug.h>
@ -1811,7 +1812,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
PartitionList->CurrentPartition->PartInfo[0].PartitionNumber);
RtlCreateUnicodeString (&DestinationRootPath,
PathBuffer);
DPRINT1 ("DestinationRootPath: %wZ\n", &DestinationRootPath);
DPRINT ("DestinationRootPath: %wZ\n", &DestinationRootPath);
/* Set SystemRootPath */
RtlFreeUnicodeString (&SystemRootPath);
@ -1821,7 +1822,7 @@ CheckFileSystemPage(PINPUT_RECORD Ir)
PartitionList->ActiveBootPartition->PartInfo[0].PartitionNumber);
RtlCreateUnicodeString (&SystemRootPath,
PathBuffer);
DPRINT1 ("SystemRootPath: %wZ\n", &SystemRootPath);
DPRINT ("SystemRootPath: %wZ\n", &SystemRootPath);
while(TRUE)
@ -1977,8 +1978,8 @@ InstallDirectoryPage(PINPUT_RECORD Ir)
}
static PAGE_NUMBER
PrepareCopyPage(PINPUT_RECORD Ir)
static BOOLEAN
PrepareCopyPageInfFile(HINF InfFile, PWCHAR SourceCabinet, PINPUT_RECORD Ir)
{
WCHAR PathBuffer[MAX_PATH];
INFCONTEXT FilesContext;
@ -1987,25 +1988,16 @@ PrepareCopyPage(PINPUT_RECORD Ir)
PWCHAR KeyValue;
ULONG Length;
NTSTATUS Status;
PWCHAR FileKeyName;
PWCHAR FileKeyValue;
PWCHAR DirKeyName;
PWCHAR DirKeyValue;
SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
/*
* Build the file copy list
*/
SetStatusText(" Building the file copy list...");
/* Search for the 'SourceFiles' section */
if (!InfFindFirstLine (SetupInf, L"SourceFiles", NULL, &FilesContext))
if (!InfFindFirstLine (InfFile, L"SourceFiles", NULL, &FilesContext))
{
PopupError("Setup failed to find the 'SourceFiles' section\n"
"in TXTSETUP.SIF.\n",
"in TXTSETUP.SIF.\n", // FIXME
"ENTER = Reboot computer");
while(TRUE)
@ -2014,26 +2006,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
}
}
}
/* Create the file queue */
SetupFileQueue = SetupOpenFileQueue();
if (SetupFileQueue == NULL)
{
PopupError("Setup failed to open the copy file queue.\n",
"ENTER = Reboot computer");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
return(FALSE);
}
}
}
@ -2045,12 +2018,15 @@ PrepareCopyPage(PINPUT_RECORD Ir)
do
{
if (!InfGetData (&FilesContext, &FileKeyName, &FileKeyValue))
break;
{
DPRINT("break\n");
break;
}
DPRINT ("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
if (!InfFindFirstLine (SetupInf, L"Directories", FileKeyValue, &DirContext))
if (!InfFindFirstLine (InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("InfFindFirstLine() failed\n");
@ -2065,6 +2041,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
}
if (!SetupQueueCopy(SetupFileQueue,
SourceCabinet,
SourceRootPath.Buffer,
L"\\reactos",
FileKeyName,
@ -2079,7 +2056,6 @@ PrepareCopyPage(PINPUT_RECORD Ir)
/* Create directories */
SetStatusText(" Creating directories...");
/*
* FIXME:
@ -2110,18 +2086,25 @@ PrepareCopyPage(PINPUT_RECORD Ir)
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
return(FALSE);
}
}
}
/* Search for the 'Directories' section */
if (!InfFindFirstLine(SetupInf, L"Directories", NULL, &DirContext))
if (!InfFindFirstLine(InfFile, L"Directories", NULL, &DirContext))
{
PopupError("Setup failed to find the 'Directories' section\n"
"in TXTSETUP.SIF.\n",
"ENTER = Reboot computer");
if (SourceCabinet)
{
PopupError("Setup failed to find the 'Directories' section\n"
"in the cabinet.\n", "ENTER = Reboot computer");
}
else
{
PopupError("Setup failed to find the 'Directories' section\n"
"in TXTSETUP.SIF.\n", "ENTER = Reboot computer");
}
while(TRUE)
{
@ -2129,7 +2112,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
return(FALSE);
}
}
}
@ -2138,7 +2121,10 @@ PrepareCopyPage(PINPUT_RECORD Ir)
do
{
if (!InfGetData (&DirContext, NULL, &KeyValue))
break;
{
DPRINT1("break\n");
break;
}
if (KeyValue[0] == L'\\' && KeyValue[1] != 0)
{
@ -2171,7 +2157,7 @@ PrepareCopyPage(PINPUT_RECORD Ir)
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
return(FALSE);
}
}
}
@ -2179,6 +2165,159 @@ PrepareCopyPage(PINPUT_RECORD Ir)
}
while (InfFindNextLine (&DirContext, &DirContext));
return(TRUE);
}
static PAGE_NUMBER
PrepareCopyPage(PINPUT_RECORD Ir)
{
INT CabStatus;
HINF InfHandle;
WCHAR PathBuffer[MAX_PATH];
INFCONTEXT CabinetsContext;
ULONG InfFileSize;
PWCHAR KeyValue;
NTSTATUS Status;
ULONG ErrorLine;
PVOID InfFileData;
SetTextXY(6, 8, "Setup prepares your computer for copying the ReactOS files. ");
/*
* Build the file copy list
*/
SetStatusText(" Building the file copy list...");
/* Create the file queue */
SetupFileQueue = SetupOpenFileQueue();
if (SetupFileQueue == NULL)
{
PopupError("Setup failed to open the copy file queue.\n",
"ENTER = Reboot computer");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
}
}
}
if (!PrepareCopyPageInfFile(SetupInf, NULL, Ir))
{
return(QUIT_PAGE);
}
/* Search for the 'Cabinets' section */
if (!InfFindFirstLine (SetupInf, L"Cabinets", NULL, &CabinetsContext))
{
PopupError("Setup failed to find the 'Cabinets' section\n"
"in TXTSETUP.SIF.\n",
"ENTER = Reboot computer");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
}
}
}
/*
* Enumerate the directory values in the 'Cabinets'
* section and parse their inf files.
*/
do
{
if (!InfGetData (&CabinetsContext, NULL, &KeyValue))
break;
wcscpy(PathBuffer, SourcePath.Buffer);
wcscat(PathBuffer, L"\\");
wcscat(PathBuffer, KeyValue);
CabinetInitialize();
CabinetSetEventHandlers(NULL, NULL, NULL);
CabinetSetCabinetName(PathBuffer);
if (CabinetOpen() == CAB_STATUS_SUCCESS)
{
DPRINT("Cabinet %S\n", CabinetGetCabinetName());
InfFileData = CabinetGetCabinetReservedArea(&InfFileSize);
if (InfFileData == NULL)
{
PopupError("Cabinet has no setup script.\n",
"ENTER = Reboot computer");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
}
}
}
}
else
{
DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
PopupError("Cabinet not found.\n", "ENTER = Reboot computer");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
}
}
}
Status = InfOpenBufferedFile(&InfHandle,
InfFileData,
InfFileSize,
&ErrorLine);
if (!NT_SUCCESS(Status))
{
PopupError("Cabinet has no valid inf file.\n",
"ENTER = Reboot computer");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
return(QUIT_PAGE);
}
}
}
CabinetCleanup();
if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir))
{
return(QUIT_PAGE);
}
}
while (InfFindNextLine (&CabinetsContext, &CabinetsContext));
return(FILE_COPY_PAGE);
}
@ -2388,7 +2527,6 @@ BootLoaderPage(PINPUT_RECORD Ir)
SetStatusText(" Please wait...");
if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED)
{
DPRINT1("Error: active partition invalid (unused)\n");
@ -2405,7 +2543,6 @@ BootLoaderPage(PINPUT_RECORD Ir)
}
}
}
if (PartitionList->ActiveBootPartition->PartInfo[0].PartitionType == 0x0A)
{
/* OS/2 boot manager partition */

View file

@ -15,7 +15,7 @@ TOOLS = \
CLEAN_FILES = $(TOOLS)
all: $(TOOLS) wmc_target cdmake_target mkhive_target rgenstat_target
all: $(TOOLS) zlib_target wmc_target cabman_target cdmake_target mkhive_target rgenstat_target
buildno$(EXE_POSTFIX): buildno.c ../include/reactos/version.h
$(HOST_CC) $(CFLAGS) -o buildno$(EXE_POSTFIX) buildno.c
@ -94,9 +94,15 @@ mkflpimg$(EXE_POSTFIX): mkflpimg.c
endif
zlib_target:
$(MAKE) -C ../lib/zlib -f Makefile.host
wmc_target:
$(MAKE) -C wmc wmc$(EXE_POSTFIX)
cabman_target:
$(MAKE) -C cabman cabman$(EXE_POSTFIX)
cdmake_target:
$(MAKE) -C cdmake cdmake$(EXE_POSTFIX)

View file

@ -0,0 +1,7 @@
cabman
*.o
*.d
*.exe
*.coff
*.sym
*.map

3194
reactos/tools/cabman/cabinet.cxx Executable file

File diff suppressed because it is too large Load diff

504
reactos/tools/cabman/cabinet.h Executable file
View file

@ -0,0 +1,504 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/cabman/cabinet.h
* PURPOSE: Cabinet definitions
*/
#ifndef __CABINET_H
#define __CABINET_H
#if defined(WIN32)
#include <windows.h>
#else
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#ifndef MAX_PATH
#define MAX_PATH 260
#endif
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if defined(WIN32)
#define DIR_SEPARATOR_CHAR '\\'
#define DIR_SEPARATOR_STRING "\\"
#define strcasecmp strcmpi
#define AllocateMemory(size) HeapAlloc(GetProcessHeap(), 0, size)
#define FreeMemory(buffer) HeapFree(GetProcessHeap(), 0, buffer)
#define FILEHANDLE HANDLE
#define CloseFile(handle) CloseHandle(handle)
#define GetSizeOfFile(handle) _GetSizeOfFile(handle)
static long _GetSizeOfFile(FILEHANDLE handle)
{
long size = GetFileSize(handle, NULL);
if (size == INVALID_FILE_SIZE)
{
return -1;
}
return size;
}
#define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
static bool _ReadFileData(FILEHANDLE handle, void* buffer, unsigned long size, unsigned long* bytesread)
{
return ReadFile(handle, buffer, size, bytesread, NULL);
}
#else
#define DIR_SEPARATOR_CHAR '/'
#define DIR_SEPARATOR_STRING "/"
#define AllocateMemory(size) malloc(size)
#define FreeMemory(buffer) free(buffer)
#define CloseFile(handle) fclose(handle)
#define FILEHANDLE FILE*
#define GetSizeOfFile(handle) _GetSizeOfFile(handle)
static long _GetSizeOfFile(FILEHANDLE handle)
{
long size;
fseek(handle, 0, SEEK_END);
size = ftell(handle);
fseek(handle, 0, SEEK_SET);
return size;
}
#define ReadFileData(handle, buffer, size, bytesread) _ReadFileData(handle, buffer, size, bytesread)
static bool _ReadFileData(FILEHANDLE handle, void* buffer, unsigned long size, unsigned long* bytesread)
{
*bytesread = fread(buffer, 1, size, handle);
return *bytesread == size;
}
#endif
/* 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 unsigned long 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_); \
exit(0); \
} \
}
#else /* DBG */
#define DPRINT(_t_, _x_)
#define ASSERT(_x_)
#endif /* DBG */
/* 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
{
unsigned long Signature; // File signature 'MSCF' (CAB_SIGNATURE)
unsigned long Reserved1; // Reserved field
unsigned long CabinetSize; // Cabinet file size
unsigned long Reserved2; // Reserved field
unsigned long FileTableOffset; // Offset of first CFFILE
unsigned long Reserved3; // Reserved field
unsigned short Version; // Cabinet version (CAB_VERSION)
unsigned short FolderCount; // Number of folders
unsigned short FileCount; // Number of files
unsigned short Flags; // Cabinet flags (CAB_FLAG_*)
unsigned short SetID; // Cabinet set id
unsigned short CabinetNumber; // Zero-based cabinet number
/* Optional fields (depends on Flags)
unsigned short 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
{
unsigned long DataOffset; // Absolute offset of first CFDATA block in this folder
unsigned short DataBlockCount; // Number of CFDATA blocks in this folder in this cabinet
unsigned short 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
{
unsigned long FileSize; // Uncompressed file size in bytes
unsigned long FileOffset; // Uncompressed offset of file in the folder
unsigned short FileControlID; // File control ID (CAB_FILE_*)
unsigned short FileDate; // File date stamp, as used by DOS
unsigned short FileTime; // File time stamp, as used by DOS
unsigned short Attributes; // File attributes (CAB_ATTRIB_*)
/* After this is the NULL terminated filename */
} CFFILE, *PCFFILE;
typedef struct _CFDATA
{
unsigned long Checksum; // Checksum of CFDATA entry
unsigned short CompSize; // Number of compressed bytes in this block
unsigned short 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;
unsigned long ScratchFilePosition; // Absolute offset in scratch file
unsigned long AbsoluteOffset; // Absolute offset in cabinet
unsigned long UncompOffset; // Uncompressed offset in folder
CFDATA Data;
} CFDATA_NODE, *PCFDATA_NODE;
typedef struct _CFFOLDER_NODE
{
struct _CFFOLDER_NODE *Next;
struct _CFFOLDER_NODE *Prev;
unsigned long UncompOffset; // File size accumulator
unsigned long AbsoluteOffset;
unsigned long TotalFolderSize; // Total size of folder in current disk
PCFDATA_NODE DataListHead;
PCFDATA_NODE DataListTail;
unsigned long 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;
char* 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
{
char Search[MAX_PATH]; // Search criteria
PCFFILE_NODE Next; // Pointer to next node
PCFFILE File; // Pointer to current CFFILE
char* 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 unsigned long Compress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* OutputLength) = 0;
/* Uncompresses a data block */
virtual unsigned long Uncompress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* 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();
unsigned long Create(char* FileName);
unsigned long Destroy();
unsigned long Truncate();
unsigned long Position();
unsigned long Seek(long Position);
unsigned long ReadBlock(PCFDATA Data, void* Buffer, unsigned long* BytesRead);
unsigned long WriteBlock(PCFDATA Data, void* Buffer, unsigned long* BytesWritten);
private:
char FullName[MAX_PATH];
bool FileCreated;
FILEHANDLE FileHandle;
};
#endif /* CAB_READ_ONLY */
class CCabinet {
public:
/* Default constructor */
CCabinet();
/* Default destructor */
virtual ~CCabinet();
/* Determines if a character is a separator */
bool CCabinet::IsSeparator(char Char);
/* Replaces \ or / with the one used be the host environment */
char* CCabinet::ConvertPath(char* Path, bool Allocate);
/* Returns a pointer to the filename part of a fully qualified filename */
char* GetFileName(char* Path);
/* Removes a filename from a fully qualified filename */
void RemoveFileName(char* Path);
/* Normalizes a path */
bool NormalizePath(char* Path, unsigned long Length);
/* Returns name of cabinet file */
char* GetCabinetName();
/* Sets the name of the cabinet file */
void SetCabinetName(char* FileName);
/* Sets destination path for extracted files */
void SetDestinationPath(char* DestinationPath);
/* Sets cabinet reserved file */
bool SetCabinetReservedFile(char* FileName);
/* Returns cabinet reserved file */
char* GetCabinetReservedFile();
/* Returns destination path */
char* GetDestinationPath();
/* Returns zero-based current disk number */
unsigned long GetCurrentDiskNumber();
/* Opens the current cabinet file */
unsigned long Open();
/* Closes the current open cabinet file */
void Close();
/* Locates the first file in the current cabinet file that matches a search criteria */
unsigned long FindFirst(char* FileName, PCAB_SEARCH Search);
/* Locates the next file in the current cabinet file */
unsigned long FindNext(PCAB_SEARCH Search);
/* Extracts a file from the current cabinet file */
unsigned long ExtractFile(char* FileName);
/* Select codec engine to use */
void SelectCodec(unsigned long Id);
#ifndef CAB_READ_ONLY
/* Creates a new cabinet file */
unsigned long NewCabinet();
/* Forces a new disk to be created */
unsigned long NewDisk();
/* Forces a new folder to be created */
unsigned long NewFolder();
/* Writes a file to scratch storage */
unsigned long WriteFileToScratchStorage(PCFFILE_NODE FileNode);
/* Forces the current disk to be written */
unsigned long WriteDisk(unsigned long MoreDisks);
/* Commits the current disk */
unsigned long CommitDisk(unsigned long MoreDisks);
/* Closes the current disk */
unsigned long CloseDisk();
/* Closes the current cabinet */
unsigned long CloseCabinet();
/* Adds a file to the current disk */
unsigned long AddFile(char* FileName);
/* Sets the maximum size of the current disk */
void SetMaxDiskSize(unsigned long Size);
#endif /* CAB_READ_ONLY */
/* Default event handlers */
/* Handler called when a file is about to be overridden */
virtual bool OnOverwrite(PCFFILE Entry, char* FileName);
/* Handler called when a file is about to be extracted */
virtual void OnExtract(PCFFILE Entry, char* FileName);
/* Handler called when a new disk is to be processed */
virtual void OnDiskChange(char* CabinetName, char* DiskLabel);
#ifndef CAB_READ_ONLY
/* Handler called when a file is about to be added */
virtual void OnAdd(PCFFILE Entry, char* FileName);
/* Handler called when a cabinet need a name */
virtual bool OnCabinetName(unsigned long Number, char* Name);
/* Handler called when a disk needs a label */
virtual bool OnDiskLabel(unsigned long Number, char* Label);
#endif /* CAB_READ_ONLY */
private:
PCFFOLDER_NODE LocateFolderNode(unsigned long Index);
unsigned long GetAbsoluteOffset(PCFFILE_NODE File);
unsigned long LocateFile(char* FileName, PCFFILE_NODE *File);
unsigned long ReadString(char* String, unsigned long MaxLength);
unsigned long ReadFileTable();
unsigned long 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();
unsigned long ComputeChecksum(void* Buffer, unsigned int Size, unsigned long Seed);
unsigned long ReadBlock(void* Buffer, unsigned long Size, unsigned long* BytesRead);
#ifndef CAB_READ_ONLY
unsigned long InitCabinetHeader();
unsigned long WriteCabinetHeader(bool MoreDisks);
unsigned long WriteFolderEntries();
unsigned long WriteFileEntries();
unsigned long CommitDataBlocks(PCFFOLDER_NODE FolderNode);
unsigned long WriteDataBlock();
unsigned long GetAttributesOnFile(PCFFILE_NODE File);
unsigned long SetAttributesOnFile(PCFFILE_NODE File);
unsigned long GetFileTimes(FILEHANDLE FileHandle, PCFFILE_NODE File);
#if !defined(WIN32)
void ConvertDateAndTime(time_t* Time, unsigned short* DosDate, unsigned short* DosTime);
#endif
#endif /* CAB_READ_ONLY */
unsigned long CurrentDiskNumber; // Zero based disk number
char CabinetName[256]; // Filename of current cabinet
char CabinetPrev[256]; // Filename of previous cabinet
char DiskPrev[256]; // Label of cabinet in file CabinetPrev
char CabinetNext[256]; // Filename of next cabinet
char DiskNext[256]; // Label of cabinet in file CabinetNext
unsigned long TotalHeaderSize; // Size of header and optional fields
unsigned long NextFieldsSize; // Size of next cabinet name and next disk label
unsigned long TotalFolderSize; // Size of all folder entries
unsigned long TotalFileSize; // Size of all file entries
unsigned long FolderUncompSize; // Uncompressed size of folder
unsigned long BytesLeftInBlock; // Number of bytes left in current block
bool ReuseBlock;
char DestPath[MAX_PATH];
char CabinetReservedFile[MAX_PATH];
void* CabinetReservedFileBuffer;
unsigned long CabinetReservedFileSize;
FILEHANDLE FileHandle;
bool FileOpen;
CFHEADER CABHeader;
unsigned long CabinetReserved;
unsigned long FolderReserved;
unsigned long DataReserved;
PCFFOLDER_NODE FolderListHead;
PCFFOLDER_NODE FolderListTail;
PCFFOLDER_NODE CurrentFolderNode;
PCFDATA_NODE CurrentDataNode;
PCFFILE_NODE FileListHead;
PCFFILE_NODE FileListTail;
CCABCodec *Codec;
unsigned long CodecId;
bool CodecSelected;
void* InputBuffer;
void* CurrentIBuffer; // Current offset in input buffer
unsigned long CurrentIBufferSize; // Bytes left in input buffer
void* OutputBuffer;
unsigned long TotalCompSize; // Total size of current CFDATA block
void* CurrentOBuffer; // Current offset in output buffer
unsigned long CurrentOBufferSize; // Bytes left in output buffer
unsigned long BytesLeftInCabinet;
bool RestartSearch;
unsigned long LastFileOffset; // Uncompressed offset of last extracted file
#ifndef CAB_READ_ONLY
unsigned long LastBlockStart; // Uncompressed offset of last block in folder
unsigned long MaxDiskSize;
unsigned long DiskSize;
unsigned long PrevCabinetNumber; // Previous cabinet number (where split file starts)
bool CreateNewDisk;
bool CreateNewFolder;
CCFDATAStorage *ScratchFile;
FILEHANDLE SourceFile;
bool ContinueFile;
unsigned long TotalBytesLeft;
bool BlockIsSplit; // true if current data block is split
unsigned long NextFolderNumber; // Zero based folder number
#endif /* CAB_READ_ONLY */
};
#endif /* __CABINET_H */
/* EOF */

47
reactos/tools/cabman/cabman.h Executable file
View file

@ -0,0 +1,47 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/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, char* argv[]);
bool Run();
private:
void Usage();
bool CreateCabinet();
bool DisplayCabinet();
bool ExtractFromCabinet();
/* Event handlers */
virtual bool OnOverwrite(PCFFILE File, char* FileName);
virtual void OnExtract(PCFFILE File, char* FileName);
virtual void OnDiskChange(char* CabinetName, char* DiskLabel);
virtual void OnAdd(PCFFILE Entry, char* FileName);
/* Configuration */
bool ProcessAll;
unsigned long Mode;
bool PromptOnOverwrite;
char Location[MAX_PATH];
char FileName[MAX_PATH];
};
#endif /* __CABMAN_H */
/* EOF */

55
reactos/tools/cabman/dff.txt Executable file
View file

@ -0,0 +1,55 @@
Directive File Format for ReactOS Cabinet Manager
-------------------------------------------------
Directives begin with a period ("."), and are followed by a command
name, and possibly blank delimited arguments. Commands and variable names are
case insensitive.
Syntax Description
-------------------------------------------------------------------------------
; Anything on a line after this is a comment
<filename> [destination] File copy command
.Define variable=[value] Define variable to be equal to value (*)
.Delete variable Delete a variable definition (*)
.New Disk|Cabinet|Folder Start a new disk, cabinet or folder (* -- new disk will work)
.Set variable=[value] Set variable to be equal to value (*)
%variable% Substitute value of variable (*)
<blank line> Blank lines are ignored
-------------------------------------------------------------------------------
Standard variable Description
-------------------------------------------------------------------------------
Cabinet=ON|OFF Turns cabinet mode on or off (* -- currently always on)
CabinetFileCountThreshold=count Threshold count of files per cabinet (*)
CabinetNamen=filename Cabinet file name for cabinet number n
CabinetNameTemplate=template Cabinet file name template
* is replaced by cabinet number
Compress=ON|OFF Turns compression on or off (* -- currently always on)
CompressionType=NONE|MSZIP Compression engine to use (* -- currently always mszip)
DiskLabeln=label Printed disk label name for disk n
DiskLabelTemplate=template Printed disk label name template
* is replaced by disk number
FolderFileCountThreshold=count Threshold count of files per folder (*)
FolderSizeThreshold=size Threshold folder size for current folder (*)
MaxDiskFileCount=count Maximum count of files per disk (*)
MaxDiskSize[n]=size Maximum disk size (for disk n)
ReservePerCabinetSize=size Amount of space to reserve in each cabinet (*)
ReservePerDataBlockSize=size Amount of space to reserve in each data block (*)
ReservePerFolderSize=size Amount of space to reserve in each folder (*)
SourceDir=path Default path for source files (*)
-------------------------------------------------------------------------------
(*) = not implemented
MaxDiskSize
-----------
0 means disk size is unlimited. Standard sizes available are:
2.88M
1.44M
1.25M
1.2M
720K
360K
CDROM

1179
reactos/tools/cabman/dfp.cxx Executable file

File diff suppressed because it is too large Load diff

141
reactos/tools/cabman/dfp.h Executable file
View file

@ -0,0 +1,141 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/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;
unsigned long DiskNumber;
char Name[128];
} CABINET_NAME, *PCABINET_NAME;
typedef struct _DISK_NUMBER {
struct _DISK_NUMBER *Next;
unsigned long DiskNumber;
unsigned long 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,
stInfFileName
} SETTYPE;
typedef enum {
ntDisk,
ntCabinet,
ntFolder,
} NEWTYPE;
/* Classes */
class CDFParser : public CCabinet {
public:
CDFParser();
virtual ~CDFParser();
unsigned long Load(char* FileName);
unsigned long Parse();
bool InfFileOnly;
bool DontGenerateInf;
private:
/* Event handlers */
virtual bool OnDiskLabel(unsigned long Number, char* Label);
virtual bool OnCabinetName(unsigned long Number, char* Name);
void WriteInfLine(char* InfLine);
bool SetDiskName(PCABINET_NAME *List, unsigned long Number, char* String);
bool GetDiskName(PCABINET_NAME *List, unsigned long Number, char* String);
bool SetDiskNumber(PDISK_NUMBER *List, unsigned long Number, unsigned long Value);
bool GetDiskNumber(PDISK_NUMBER *List, unsigned long Number, unsigned long* Value);
bool DoDiskLabel(unsigned long Number, char* Label);
void DoDiskLabelTemplate(char* Template);
bool DoCabinetName(unsigned long Number, char* Name);
void DoCabinetNameTemplate(char* Template);
void DoInfFileName(char* InfFileName);
unsigned long DoMaxDiskSize(bool NumberValid, unsigned long Number);
unsigned long SetupNewDisk();
unsigned long PerformSetCommand();
unsigned long PerformNewCommand();
unsigned long PerformInfBeginCommand();
unsigned long PerformInfEndCommand();
unsigned long PerformCommand();
unsigned long PerformFileCopy();
void SkipSpaces();
bool IsNextToken(TOKEN Token, bool NoSpaces);
bool ReadLine();
void NextToken();
/* Parsing */
bool FileLoaded;
FILEHANDLE FileHandle;
char* FileBuffer;
unsigned long FileBufferSize;
unsigned long CurrentOffset;
char Line[128];
unsigned long LineLength;
unsigned long CurrentLine;
unsigned long CurrentChar;
/* Token */
TOKEN CurrentToken;
unsigned long CurrentInteger;
char CurrentString[256];
/* State */
bool CabinetCreated;
bool DiskCreated;
bool FolderCreated;
/* Standard directive variable */
bool Cabinet;
unsigned long CabinetFileCountThreshold;
PCABINET_NAME CabinetName;
bool CabinetNameTemplateSet;
char CabinetNameTemplate[128];
bool InfFileNameSet;
char InfFileName[256];
bool Compress;
unsigned long CompressionType;
PCABINET_NAME DiskLabel;
bool DiskLabelTemplateSet;
char DiskLabelTemplate[128];
unsigned long FolderFileCountThreshold;
unsigned long FolderSizeThreshold;
unsigned long MaxCabinetSize;
unsigned long MaxDiskFileCount;
PDISK_NUMBER MaxDiskSize;
bool MaxDiskSizeAllSet;
unsigned long MaxDiskSizeAll;
unsigned long ReservePerCabinetSize;
unsigned long ReservePerDataBlockSize;
unsigned long ReservePerFolderSize;
char SourceDir[256];
FILEHANDLE InfFileHandle;
bool InfModeEnabled;
};
#endif /* __DFP_H */
/* EOF */

518
reactos/tools/cabman/main.cxx Executable file
View file

@ -0,0 +1,518 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/cabman/main.cpp
* PURPOSE: Main program
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 21/03-2001 Created
* CSH 15/08-2003 Made it portable
*/
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include "cabman.h"
#ifdef DBG
unsigned long DebugTraceLevel = MIN_TRACE;
//unsigned long DebugTraceLevel = MID_TRACE;
//unsigned long DebugTraceLevel = MAX_TRACE;
#endif /* DBG */
#define CM_VERSION "0.9"
char* Pad(char* Str, char PadChar, unsigned int 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
*/
{
unsigned int Len;
Len = strlen(Str);
if (Len < Length) {
memcpy(&Str[Length - Len], Str, Len + 1);
memset(Str, PadChar, Length - Len);
}
return Str;
}
char* Date2Str(char* Str, unsigned short Date)
/*
* FUNCTION: Converts a DOS style date to a string
* ARGUMENTS:
* Str = Pointer to destination string
* Date = DOS style date
* RETURNS:
* Pointer to string
*/
{
unsigned long dw;
/* Month */
Str[0] = (char)('0' + ((Date & 0x01E0) >> 5) / 10);
Str[1] = (char)('0' + ((Date & 0x01E0) >> 5) % 10);
Str[2] = '-';
/* Day */
Str[3] = (char)('0' + (Date & 0x001F) / 10);
Str[4] = (char)('0' + (Date & 0x001F) % 10);
Str[5] = '-';
/* Year */
dw = 1980 + ((Date & 0xFE00) >> 9);
Str[6] = (char)('0' + dw / 1000); dw %= 1000;
Str[7] = (char)('0' + dw / 100); dw %= 100;
Str[8] = (char)('0' + dw / 10); dw %= 10;
Str[9] = (char)('0' + dw % 10);
Str[10] = '\0';
return Str;
}
char* Time2Str(char* Str, unsigned short 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;
unsigned long Hour;
unsigned long dw;
Hour = ((Time & 0xF800) >> 11);
PM = (Hour >= 12);
Hour %= 12;
if (Hour == 0)
Hour = 12;
if (Hour >= 10)
Str[0] = (char)('0' + Hour / 10);
else Str[0] = ' ';
Str[1] = (char)('0' + Hour % 10);
Str[2] = ':';
/* Minute */
Str[3] = (char)('0' + ((Time & 0x07E0) >> 5) / 10);
Str[4] = (char)('0' + ((Time & 0x07E0) >> 5) % 10);
Str[5] = ':';
/* Second */
dw = 2 * (Time & 0x001F);
Str[6] = (char)('0' + dw / 10);
Str[7] = (char)('0' + dw % 10);
Str[8] = PM? 'p' : 'a';
Str[9] = '\0';
return Str;
}
char* Attr2Str(char* Str, unsigned short Attr)
/*
* FUNCTION: Converts attributes to a string
* ARGUMENTS:
* Str = Pointer to destination string
* Attr = Attributes
* RETURNS:
* Pointer to string
*/
{
/* Archive */
if (Attr & CAB_ATTRIB_ARCHIVE)
Str[0] = 'A';
else
Str[0] = '-';
/* Hidden */
if (Attr & CAB_ATTRIB_HIDDEN)
Str[1] = 'H';
else
Str[1] = '-';
/* Read only */
if (Attr & CAB_ATTRIB_READONLY)
Str[2] = 'R';
else
Str[2] = '-';
/* System */
if (Attr & CAB_ATTRIB_SYSTEM)
Str[3] = 'S';
else
Str[3] = '-';
Str[4] = '\0';
return Str;
}
/* CCABManager */
CCABManager::CCABManager()
/*
* FUNCTION: Default constructor
*/
{
ProcessAll = false;
InfFileOnly = false;
Mode = CM_MODE_DISPLAY;
}
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] cabinet [filename ...]\n");
printf("CABMAN /C dirfile [/I] [/RC file]\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");
printf(" /A Process ALL cabinets. Follows cabinet chain\n");
printf(" starting in first cabinet mentioned.\n");
printf(" /C Create cabinet.\n");
printf(" /D Display cabinet directory.\n");
printf(" /E Extract files from cabinet.\n");
printf(" /I Don't create the cabinet, only the .inf file.\n");
printf(" /L dir Location to place extracted or generated files\n");
printf(" (default is current directory).\n");
printf(" /N Don't create the .inf file, only the cabinet.\n");
printf(" /RC Specify file to put in cabinet reserved area\n");
printf(" (size must be less than 64KB).\n");
}
bool CCABManager::ParseCmdline(int argc, char* argv[])
/*
* FUNCTION: Parse command line arguments
* ARGUMENTS:
* argc = Number of arguments on command line
* argv = Pointer to list of command line arguments
* RETURNS:
* true if command line arguments was successfully parsed, false if not
*/
{
int i;
bool ShowUsage;
bool FoundCabinet = false;
ShowUsage = (argc < 2);
for (i = 1; i < argc; i++) {
if (argv[i][0] == '/') {
switch (argv[i][1]) {
case 'a':
case 'A': ProcessAll = true; break;
case 'c':
case 'C': Mode = CM_MODE_CREATE; break;
case 'd':
case 'D': Mode = CM_MODE_DISPLAY; break;
case 'e':
case 'E': Mode = CM_MODE_EXTRACT; break;
case 'i':
case 'I': InfFileOnly = true; break;
case 'l':
case 'L':
if (argv[i][2] == 0) {
i++;
SetDestinationPath((char*)&argv[i][0]);
} else {
SetDestinationPath((char*)&argv[i][1]);
}
break;
case 'n':
case 'N': DontGenerateInf = true; break;
case 'R':
switch (argv[i][2]) {
case 'C': /* File to put in cabinet reserved area */
if (argv[i][3] == 0) {
i++;
if (!SetCabinetReservedFile((char*)&argv[i][0])) {
printf("Cannot open cabinet reserved area file.\n");
return false;
}
} else {
if (!SetCabinetReservedFile((char*)&argv[i][3])) {
printf("Cannot open cabinet reserved area file.\n");
return false;
}
}
break;
default:
printf("Bad parameter %s.\n", argv[i]);
return 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 */
strcpy((char*)FileName, argv[i]);
} else {
SetCabinetName(argv[i]);
FoundCabinet = true;
}
}
}
if (ShowUsage) {
Usage();
return false;
}
/* FIXME */
SelectCodec(CAB_CODEC_MSZIP);
return true;
}
bool CCABManager::CreateCabinet()
/*
* FUNCTION: Create cabinet
*/
{
unsigned long Status;
Status = Load((char*)&FileName);
if (Status != CAB_STATUS_SUCCESS) {
printf("Specified directive file could not be found: %s.\n", (char*)&FileName);
return false;
}
Parse();
return true;
}
bool CCABManager::DisplayCabinet()
/*
* FUNCTION: Display cabinet contents
*/
{
CAB_SEARCH Search;
char Str[20];
unsigned long FileCount = 0;
unsigned long 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((char*)&Str, Search.File->FileDate));
printf("%s ", Time2Str((char*)&Str, Search.File->FileTime));
printf("%s ", Attr2Str((char*)&Str, Search.File->Attributes));
sprintf(Str, "%d", Search.File->FileSize);
printf("%s ", Pad(Str, ' ', 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 {
sprintf(Str, "%d", FileCount);
printf(" %s files ", Pad(Str, ' ', 12));
}
if (ByteCount == 1)
printf(" 1 byte\n");
else {
sprintf(Str, "%d", ByteCount);
printf("%s bytes\n", Pad(Str, ' ', 12));
}
} else {
/* There should be at least one file in a cabinet */
printf("No files in cabinet.");
}
return true;
} else
printf("Cannot not open file: %s\n", GetCabinetName());
return false;
}
bool CCABManager::ExtractFromCabinet()
/*
* FUNCTION: Extract file(s) from cabinet
*/
{
CAB_SEARCH Search;
unsigned long 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 false;
case CAB_STATUS_UNSUPPCOMP:
printf("Cabinet uses unsupported compression type.\n");
return false;
case CAB_STATUS_CANNOT_WRITE:
printf("You've run out of free space on the destination volume or the volume is damaged.\n");
return false;
default:
printf("Unspecified error code (%d).\n", (unsigned int)Status);
return false;
}
} while (FindNext(&Search) == CAB_STATUS_SUCCESS);
}
return true;
} else
printf("Cannot not open file: %s.\n", GetCabinetName());
return false;
}
bool CCABManager::Run()
/*
* FUNCTION: Process cabinet
*/
{
printf("ReactOS Cabinet Manager - Version %s\n\n", CM_VERSION);
switch (Mode) {
case CM_MODE_CREATE: return CreateCabinet(); break;
case CM_MODE_DISPLAY: return DisplayCabinet(); break;
case CM_MODE_EXTRACT: return ExtractFromCabinet(); break;
default:
break;
}
return false;
}
/* Event handlers */
bool CCABManager::OnOverwrite(PCFFILE File,
char* FileName)
/*
* FUNCTION: Called when extracting a file and it already exists
* ARGUMENTS:
* File = Pointer to CFFILE for file being extracted
* Filename = Pointer to buffer with name of file (full path)
* RETURNS
* true if the file should be overwritten, false if not
*/
{
char ch;
if (Mode == CM_MODE_CREATE)
return true;
/* Always overwrite */
return true;
}
void CCABManager::OnExtract(PCFFILE File,
char* FileName)
/*
* FUNCTION: Called just before extracting a file
* ARGUMENTS:
* File = Pointer to CFFILE for file being extracted
* FileName = Pointer to buffer with name of file (full path)
*/
{
printf("Extracting %s\n", GetFileName(FileName));
}
void CCABManager::OnDiskChange(char* CabinetName,
char* DiskLabel)
/*
* FUNCTION: Called when a new disk is to be processed
* ARGUMENTS:
* CabinetName = Pointer to buffer with name of cabinet
* DiskLabel = Pointer to buffer with label of disk
*/
{
printf("\nChanging to cabinet %s - %s\n\n", CabinetName, DiskLabel);
}
void CCABManager::OnAdd(PCFFILE File,
char* FileName)
/*
* FUNCTION: Called just before adding a file to a cabinet
* ARGUMENTS:
* File = Pointer to CFFILE for file being added
* FileName = Pointer to buffer with name of file (full path)
*/
{
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;
bool status = false;
if (CABMgr.ParseCmdline(argc, argv)) {
status = CABMgr.Run();
}
if (status) {
return 0;
} else {
return 1;
}
}
/* EOF */

49
reactos/tools/cabman/makefile Executable file
View file

@ -0,0 +1,49 @@
#
# ReactOS Cabinet Manager
#
PATH_TO_TOP = ../..
TARGET=cabman$(EXE_POSTFIX)
all: $(TARGET)
OBJECTS = cabinet.o mszip.o raw.o main.o dfp.o
CLEAN_FILES = *.o cabman$(EXE_POSTFIX)
HOST_CFLAGS = -g -I. -I $(PATH_TO_TOP)/lib/zlib
HOST_LFLAGS = -g $(PATH_TO_TOP)/lib/zlib/zlib.host.a
cabinet.o: cabinet.cxx
$(HOST_CXX) $(HOST_CFLAGS) -c cabinet.cxx -o cabinet.o
mszip.o: mszip.cxx
$(HOST_CXX) $(HOST_CFLAGS) -c mszip.cxx -o mszip.o
raw.o: raw.cxx
$(HOST_CXX) $(HOST_CFLAGS) -c raw.cxx -o raw.o
main.o: main.cxx
$(HOST_CXX) $(HOST_CFLAGS) -c main.cxx -o main.o
dfp.o: dfp.cxx
$(HOST_CXX) $(HOST_CFLAGS) -c dfp.cxx -o dfp.o
cabman$(EXE_POSTFIX): $(OBJECTS)
$(HOST_CXX) $(OBJECTS) $(HOST_LFLAGS) -o cabman$(EXE_POSTFIX)
ifeq ($(HOST),mingw32-linux)
clean:
rm -f *.o
rm -f cabman$(EXE_POSTFIX)
endif
ifeq ($(HOST),mingw32-windows)
clean:
del *.o
del cabman$(EXE_POSTFIX)
endif
.phony: clean
include $(PATH_TO_TOP)/rules.mak

View file

@ -0,0 +1,29 @@
# $Id: makefile.win32,v 1.1 2003/08/24 10:36:07 chorns Exp $
PATH_TO_TOP = ../..
TARGET_TYPE = program
TARGET_APPTYPE = console
TARGET_NAME = cabman
#TARGET_NAME = test
TARGET_CPPAPP = yes
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

172
reactos/tools/cabman/mszip.cxx Executable file
View file

@ -0,0 +1,172 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/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
* CSH 15/08-2003 Made it portable
*/
#include <stdio.h>
#include "mszip.h"
/* Memory functions */
voidpf MSZipAlloc(voidpf opaque, uInt items, uInt size)
{
DPRINT(DEBUG_MEMORY, ("items = (%d) size = (%d)\n", items, size));
return AllocateMemory(items * size);
}
void MSZipFree (voidpf opaque, voidpf address)
{
DPRINT(DEBUG_MEMORY, ("\n"));
FreeMemory(address);
}
/* CMSZipCodec */
CMSZipCodec::CMSZipCodec()
/*
* FUNCTION: Default constructor
*/
{
ZStream.zalloc = MSZipAlloc;
ZStream.zfree = MSZipFree;
ZStream.opaque = (voidpf)0;
}
CMSZipCodec::~CMSZipCodec()
/*
* FUNCTION: Default destructor
*/
{
}
unsigned long CMSZipCodec::Compress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* 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
*/
{
unsigned short* Magic;
DPRINT(MAX_TRACE, ("InputLength (%d).\n", InputLength));
Magic = (unsigned short*)OutputBuffer;
*Magic = MSZIP_MAGIC;
ZStream.next_in = (unsigned char*)InputBuffer;
ZStream.avail_in = InputLength;
ZStream.next_out = (unsigned char*)((unsigned long)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;
}
unsigned long CMSZipCodec::Uncompress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* 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
*/
{
unsigned short Magic;
DPRINT(MAX_TRACE, ("InputLength (%d).\n", InputLength));
Magic = *((unsigned short*)InputBuffer);
if (Magic != MSZIP_MAGIC) {
DPRINT(MID_TRACE, ("Bad MSZIP block header magic (0x%X)\n", Magic));
return CS_BADSTREAM;
}
ZStream.next_in = (unsigned char*)((unsigned long)InputBuffer + 2);
ZStream.avail_in = InputLength - 2;
ZStream.next_out = (unsigned char*)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 */

41
reactos/tools/cabman/mszip.h Executable file
View file

@ -0,0 +1,41 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/cabman/mszip.h
* PURPOSE: CAB codec for MSZIP compressed data
*/
#ifndef __MSZIP_H
#define __MSZIP_H
#include "cabinet.h"
#include <zlib.h>
#define MSZIP_MAGIC 0x4B43
/* Classes */
class CMSZipCodec : public CCABCodec {
public:
/* Default constructor */
CMSZipCodec();
/* Default destructor */
virtual ~CMSZipCodec();
/* Compresses a data block */
virtual unsigned long Compress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* OutputLength);
/* Uncompresses a data block */
virtual unsigned long Uncompress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* OutputLength);
private:
int Status;
z_stream ZStream; /* Zlib stream */
};
#endif /* __MSZIP_H */
/* EOF */

68
reactos/tools/cabman/raw.cxx Executable file
View file

@ -0,0 +1,68 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/cabman/raw.cpp
* PURPOSE: CAB codec for uncompressed "raw" data
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* REVISIONS:
* CSH 21/03-2001 Created
* CSH 15/08-2003 Made it portable
*/
#include "raw.h"
/* CRawCodec */
CRawCodec::CRawCodec()
/*
* FUNCTION: Default constructor
*/
{
}
CRawCodec::~CRawCodec()
/*
* FUNCTION: Default destructor
*/
{
}
unsigned long CRawCodec::Compress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* 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
*/
{
memcpy(OutputBuffer, InputBuffer, InputLength);
*OutputLength = InputLength;
return CS_SUCCESS;
}
unsigned long CRawCodec::Uncompress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* 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
*/
{
memcpy(OutputBuffer, InputBuffer, InputLength);
*OutputLength = InputLength;
return CS_SUCCESS;
}
/* EOF */

35
reactos/tools/cabman/raw.h Executable file
View file

@ -0,0 +1,35 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS cabinet manager
* FILE: tools/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 unsigned long Compress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* OutputLength);
/* Uncompresses a data block */
virtual unsigned long Uncompress(void* OutputBuffer,
void* InputBuffer,
unsigned long InputLength,
unsigned long* OutputLength);
};
#endif /* __RAW_H */
/* EOF */

View file

@ -1,4 +1,4 @@
# $Id: helper.mk,v 1.42 2003/08/09 17:08:14 mf Exp $
# $Id: helper.mk,v 1.43 2003/08/24 10:36:07 chorns Exp $
#
# Helper makefile for ReactOS modules
# Variables this makefile accepts:
@ -19,6 +19,7 @@
# $TARGET_APPTYPE = Application type (windows,native,console)
# $TARGET_NAME = Base name of output file and .rc, .def, and .edf files
# $TARGET_OBJECTS = Object files that compose the module
# $TARGET_CPPAPP = C++ application (no,yes) (optional)
# $TARGET_HEADERS = Header files that the object files depend on (optional)
# $TARGET_DEFNAME = Base name of .def and .edf files (optional)
# $TARGET_BASENAME = Base name of output file (overrides $TARGET_NAME if it exists) (optional)
@ -42,7 +43,7 @@
# $TARGET_LIBPATH = Destination path for import libraries (optional)
# $TARGET_INSTALLDIR = Destination path when installed (optional)
# $TARGET_PCH = Filename of header to use to generate a PCH if supported by the compiler (optional)
# $TARGET_BOOTSTRAP = Wether this file is needed to bootstrap the installation (no,yes) (optional)
# $TARGET_BOOTSTRAP = Wether this file is needed to bootstrap the installation (no,yes) (optional)
# $TARGET_BOOTSTRAP_NAME = Name on the installation medium (optional)
# $TARGET_GENREGTESTS = Generate regression test registrations (optional)
# $WINE_MODE = Compile using WINE headers (no,yes) (optional)
@ -530,7 +531,14 @@ MK_NOSTRIPNAME := $(MK_BASENAME).nostrip$(MK_EXT)
# We don't want to link header files
MK_OBJECTS := $(filter-out %.h,$(TARGET_OBJECTS))
MK_STRIPPED_OBJECT := $(MK_BASENAME).stripped.o
# There is problems with C++ applications and ld -r. Ld can cause errors like:
# reloc refers to symbol `.text$_ZN9CCABCodecC2Ev' which is not being output
ifeq ($(TARGET_CPPAPP),yes)
MK_STRIPPED_OBJECT := $(MK_OBJECTS)
else
MK_STRIPPED_OBJECT := $(MK_BASENAME).stripped.o
endif
ifeq ($(MK_IMPLIBONLY),yes)
@ -620,8 +628,11 @@ else
endif
$(MK_FULLNAME): $(MK_NOSTRIPNAME) $(MK_EXTRADEP)
-
ifneq ($(TARGET_CPPAPP),yes)
$(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS)
$(STRIP) --strip-debug $(MK_STRIPPED_OBJECT)
endif
ifeq ($(MK_EXETYPE),dll)
$(LD_CC) -Wl,--base-file,base.tmp \
-Wl,--entry,$(TARGET_ENTRY) \
@ -653,7 +664,11 @@ endif
$(MK_EXTRACMD2) \
-o $(MK_FULLNAME) \
$(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
ifneq ($(TARGET_CPPAPP),yes)
- $(RM) temp.exp $(MK_STRIPPED_OBJECT)
else
- $(RM) temp.exp
endif
endif # KM_MODE
@ -699,8 +714,11 @@ else
endif
$(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) $(MK_NOSTRIPNAME)
-
ifneq ($(TARGET_CPPAPP),yes)
$(LD) -r -o $(MK_STRIPPED_OBJECT) $(MK_OBJECTS)
$(STRIP) --strip-debug $(MK_STRIPPED_OBJECT)
endif
$(LD_CC) -Wl,--base-file,base.tmp \
-Wl,--entry,$(TARGET_ENTRY) \
$(TARGET_LFLAGS) \
@ -722,7 +740,11 @@ $(MK_FULLNAME): $(MK_FULLRES) $(TARGET_OBJECTS) $(MK_EXTRADEP) $(MK_LIBS) $(MK_N
-mdll -nostartfiles -nostdlib \
-o $(MK_FULLNAME) \
$(MK_FULLRES) $(MK_STRIPPED_OBJECT) $(MK_LIBS) $(MK_GCCLIBS)
ifneq ($(TARGET_CPPAPP),yes)
- $(RM) temp.exp $(MK_STRIPPED_OBJECT)
else
- $(RM) temp.exp
endif
endif # MK_MODE
@ -884,6 +906,8 @@ endif # ROS_USE_PCH
$(CC) $(TARGET_CFLAGS) -c $< -o $@
%.o: %.cc
$(CXX) $(TARGET_CPPFLAGS) -c $< -o $@
%.o: %.cxx
$(CXX) $(TARGET_CPPFLAGS) -c $< -o $@
%.o: %.cpp
$(CXX) $(TARGET_CPPFLAGS) -c $< -o $@
%.o: %.S