Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
d651fbe4
Commit
d651fbe4
authored
Feb 17, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cabinet: Cleanup file loading and add infrastructure for plugging in real compression.
parent
d9d43231
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
113 additions
and
145 deletions
+113
-145
fci.c
dlls/cabinet/fci.c
+113
-145
No files found.
dlls/cabinet/fci.c
View file @
d651fbe4
...
...
@@ -50,6 +50,7 @@ There is still some work to be done:
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
cabinet
);
#ifdef WORDS_BIGENDIAN
#define fci_endian_ulong(x) RtlUlongByteSwap(x)
...
...
@@ -119,7 +120,7 @@ struct folder
struct
temp_file
data
;
cab_ULONG
data_start
;
cab_UWORD
data_count
;
cab_UWORD
compression
;
TCOMP
compression
;
};
struct
file
...
...
@@ -141,7 +142,7 @@ struct data_block
cab_UWORD
uncompressed
;
};
typedef
struct
typedef
struct
FCI_Int
{
unsigned
int
magic
;
PERF
perf
;
...
...
@@ -185,6 +186,8 @@ typedef struct
cab_ULONG
files_size
;
cab_ULONG
placed_files_size
;
cab_ULONG
folders_data_size
;
TCOMP
compression
;
cab_UWORD
(
*
compress
)(
struct
FCI_Int
*
);
}
FCI_Int
;
#define FCI_INT_MAGIC 0xfcfcfc05
...
...
@@ -282,6 +285,7 @@ static struct file *add_file( FCI_Int *fci, const char *filename )
file
->
attribs
=
0
;
strcpy
(
file
->
name
,
filename
);
list_add_tail
(
&
fci
->
files_list
,
&
file
->
entry
);
fci
->
files_size
+=
sizeof
(
CFFILE
)
+
strlen
(
filename
)
+
1
;
return
file
;
}
...
...
@@ -305,21 +309,92 @@ static void free_file( FCI_Int *fci, struct file *file )
fci
->
free
(
file
);
}
static
struct
data_block
*
add_data_block
(
FCI_Int
*
fci
,
cab_UWORD
compressed
,
cab_UWORD
uncompressed
)
/* create a new data block for the data in fci->data_in */
static
BOOL
add_data_block
(
FCI_Int
*
fci
,
PFNFCISTATUS
status_callback
)
{
struct
data_block
*
block
=
fci
->
alloc
(
sizeof
(
*
block
)
);
int
err
;
struct
data_block
*
block
;
if
(
!
block
)
if
(
!
fci
->
cdata_in
)
return
TRUE
;
if
(
!
(
block
=
fci
->
alloc
(
sizeof
(
*
block
)
)))
{
set_error
(
fci
,
FCIERR_ALLOC_FAIL
,
ERROR_NOT_ENOUGH_MEMORY
);
return
NULL
;
return
FALSE
;
}
block
->
compressed
=
compressed
;
block
->
uncompressed
=
uncompressed
;
list_add_tail
(
&
fci
->
blocks_list
,
&
block
->
entry
);
fci
->
data
.
size
+=
sizeof
(
CFDATA
)
+
fci
->
ccab
.
cbReserveCFData
+
compressed
;
block
->
uncompressed
=
fci
->
cdata_in
;
block
->
compressed
=
fci
->
compress
(
fci
);
if
(
fci
->
write
(
fci
->
data
.
handle
,
fci
->
data_out
,
block
->
compressed
,
&
err
,
fci
->
pv
)
!=
block
->
compressed
)
{
set_error
(
fci
,
FCIERR_TEMP_FILE
,
err
);
fci
->
free
(
block
);
return
FALSE
;
}
fci
->
cdata_in
=
0
;
fci
->
data
.
size
+=
sizeof
(
CFDATA
)
+
fci
->
ccab
.
cbReserveCFData
+
block
->
compressed
;
fci
->
cCompressedBytesInFolder
+=
block
->
compressed
;
fci
->
cDataBlocks
++
;
return
block
;
list_add_tail
(
&
fci
->
blocks_list
,
&
block
->
entry
);
if
(
status_callback
(
statusFile
,
block
->
compressed
,
block
->
uncompressed
,
fci
->
pv
)
==
-
1
)
{
set_error
(
fci
,
FCIERR_USER_ABORT
,
0
);
return
FALSE
;
}
return
TRUE
;
}
/* add compressed blocks for all the data that can be read from the file */
static
BOOL
add_file_data
(
FCI_Int
*
fci
,
char
*
sourcefile
,
char
*
filename
,
BOOL
execute
,
PFNFCIGETOPENINFO
get_open_info
,
PFNFCISTATUS
status_callback
)
{
int
err
,
len
;
INT_PTR
handle
;
struct
file
*
file
;
/* make sure we have buffers */
if
(
!
fci
->
data_in
&&
!
(
fci
->
data_in
=
fci
->
alloc
(
CB_MAX_CHUNK
)))
{
set_error
(
fci
,
FCIERR_ALLOC_FAIL
,
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
if
(
!
fci
->
data_out
&&
!
(
fci
->
data_out
=
fci
->
alloc
(
2
*
CB_MAX_CHUNK
)))
{
set_error
(
fci
,
FCIERR_ALLOC_FAIL
,
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
if
(
!
(
file
=
add_file
(
fci
,
filename
)))
return
FALSE
;
handle
=
get_open_info
(
sourcefile
,
&
file
->
date
,
&
file
->
time
,
&
file
->
attribs
,
&
err
,
fci
->
pv
);
if
(
handle
==
-
1
)
{
free_file
(
fci
,
file
);
set_error
(
fci
,
FCIERR_OPEN_SRC
,
err
);
return
FALSE
;
}
if
(
execute
)
file
->
attribs
|=
_A_EXEC
;
for
(;;)
{
len
=
fci
->
read
(
handle
,
fci
->
data_in
+
fci
->
cdata_in
,
CAB_BLOCKMAX
-
fci
->
cdata_in
,
&
err
,
fci
->
pv
);
if
(
!
len
)
break
;
if
(
len
==
-
1
)
{
set_error
(
fci
,
FCIERR_READ_SRC
,
err
);
return
FALSE
;
}
file
->
size
+=
len
;
fci
->
cdata_in
+=
len
;
if
(
fci
->
cdata_in
==
CAB_BLOCKMAX
&&
!
add_data_block
(
fci
,
status_callback
))
return
FALSE
;
}
fci
->
close
(
handle
,
&
err
,
fci
->
pv
);
return
TRUE
;
}
static
void
free_data_block
(
FCI_Int
*
fci
,
struct
data_block
*
block
)
...
...
@@ -340,7 +415,7 @@ static struct folder *add_folder( FCI_Int *fci )
folder
->
data
.
handle
=
-
1
;
folder
->
data_start
=
fci
->
folders_data_size
;
folder
->
data_count
=
0
;
folder
->
compression
=
tcompTYPE_NONE
;
/* FIXME */
folder
->
compression
=
fci
->
compression
;
list_init
(
&
folder
->
files_list
);
list_init
(
&
folder
->
blocks_list
);
list_add_tail
(
&
fci
->
folders_list
,
&
folder
->
entry
);
...
...
@@ -861,6 +936,13 @@ static BOOL add_files_to_folder( FCI_Int *fci, struct folder *folder, cab_ULONG
return
TRUE
;
}
static
cab_UWORD
compress_NONE
(
FCI_Int
*
fci
)
{
memcpy
(
fci
->
data_out
,
fci
->
data_in
,
fci
->
cdata_in
);
return
fci
->
cdata_in
;
}
/***********************************************************************
* FCICreate (CABINET.10)
*
...
...
@@ -981,6 +1063,8 @@ HFCI __cdecl FCICreate(
p_fci_internal
->
files_size
=
0
;
p_fci_internal
->
placed_files_size
=
0
;
p_fci_internal
->
folders_data_size
=
0
;
p_fci_internal
->
compression
=
tcompTYPE_NONE
;
p_fci_internal
->
compress
=
compress_NONE
;
list_init
(
&
p_fci_internal
->
folders_list
);
list_init
(
&
p_fci_internal
->
files_list
);
...
...
@@ -996,48 +1080,6 @@ HFCI __cdecl FCICreate(
static
BOOL
fci_flush_data_block
(
FCI_Int
*
p_fci_internal
,
int
*
err
,
PFNFCISTATUS
pfnfcis
)
{
/* attention no checks if there is data available!!! */
struct
data_block
*
block
;
/* TODO compress the data of p_fci_internal->data_in */
/* and write it to p_fci_internal->data_out */
memcpy
(
p_fci_internal
->
data_out
,
p_fci_internal
->
data_in
,
p_fci_internal
->
cdata_in
/* number of bytes to copy */
);
if
(
!
(
block
=
add_data_block
(
p_fci_internal
,
p_fci_internal
->
cdata_in
,
p_fci_internal
->
cdata_in
)))
return
FALSE
;
/* write p_fci_internal->data_out to p_fci_internal->data.handle */
if
(
p_fci_internal
->
write
(
p_fci_internal
->
data
.
handle
,
/* file handle */
p_fci_internal
->
data_out
,
/* memory buffer */
block
->
compressed
,
/* number of bytes to copy */
err
,
p_fci_internal
->
pv
)
!=
block
->
compressed
)
{
set_error
(
p_fci_internal
,
FCIERR_TEMP_FILE
,
ERROR_WRITE_FAULT
);
return
FALSE
;
}
/* TODO error handling of err */
/* reset the offset */
p_fci_internal
->
cdata_in
=
0
;
p_fci_internal
->
cCompressedBytesInFolder
+=
block
->
compressed
;
/* report status with pfnfcis about uncompressed and compressed file data */
if
(
(
*
pfnfcis
)(
statusFile
,
block
->
compressed
,
block
->
uncompressed
,
p_fci_internal
->
pv
)
==
-
1
)
{
set_error
(
p_fci_internal
,
FCIERR_USER_ABORT
,
0
);
return
FALSE
;
}
return
TRUE
;
}
/* end of fci_flush_data_block */
static
BOOL
fci_flush_folder
(
FCI_Int
*
p_fci_internal
,
BOOL
fGetNextCab
,
PFNFCIGETNEXTCABINET
pfnfcignc
,
...
...
@@ -1087,12 +1129,8 @@ static BOOL fci_flush_folder( FCI_Int *p_fci_internal,
p_fci_internal
->
fSplitFolder
=
FALSE
;
/* START of COPY */
/* if there is data in p_fci_internal->data_in */
if
(
p_fci_internal
->
cdata_in
!=
0
)
{
if
(
!
add_data_block
(
p_fci_internal
,
pfnfcis
))
return
FALSE
;
if
(
!
fci_flush_data_block
(
p_fci_internal
,
&
err
,
pfnfcis
)
)
return
FALSE
;
}
/* reset to get the number of data blocks of this folder which are */
/* actually in this cabinet ( at least partially ) */
p_fci_internal
->
cDataBlocks
=
0
;
...
...
@@ -1395,10 +1433,7 @@ BOOL __cdecl FCIAddFile(
PFNFCIGETOPENINFO
pfnfcigoi
,
TCOMP
typeCompress
)
{
int
err
;
cab_ULONG
read_result
;
int
file_handle
;
struct
file
*
file
;
FCI_Int
*
p_fci_internal
=
get_fci_ptr
(
hfci
);
if
(
!
p_fci_internal
)
return
FALSE
;
...
...
@@ -1409,6 +1444,21 @@ BOOL __cdecl FCIAddFile(
return
FALSE
;
}
if
(
typeCompress
!=
p_fci_internal
->
compression
)
{
if
(
!
FCIFlushFolder
(
hfci
,
pfnfcignc
,
pfnfcis
))
return
FALSE
;
switch
(
typeCompress
)
{
default:
FIXME
(
"compression %x not supported, defaulting to none
\n
"
,
typeCompress
);
/* fall through */
case
tcompTYPE_NONE
:
p_fci_internal
->
compression
=
tcompTYPE_NONE
;
p_fci_internal
->
compress
=
compress_NONE
;
break
;
}
}
/* TODO check if pszSourceFile??? */
if
(
p_fci_internal
->
fGetNextCabInVain
&&
p_fci_internal
->
fNextCab
)
{
...
...
@@ -1423,51 +1473,6 @@ BOOL __cdecl FCIAddFile(
return
FALSE
;
}
if
(
!
(
file
=
add_file
(
p_fci_internal
,
pszFileName
)))
return
FALSE
;
/* allocation of memory */
if
(
p_fci_internal
->
data_in
==
NULL
)
{
if
(
p_fci_internal
->
cdata_in
!=
0
)
{
/* error handling */
set_error
(
p_fci_internal
,
FCIERR_NONE
,
ERROR_GEN_FAILURE
);
return
FALSE
;
}
if
(
p_fci_internal
->
data_out
!=
NULL
)
{
/* error handling */
set_error
(
p_fci_internal
,
FCIERR_NONE
,
ERROR_GEN_FAILURE
);
return
FALSE
;
}
if
(
!
(
p_fci_internal
->
data_in
=
p_fci_internal
->
alloc
(
CB_MAX_CHUNK
)))
{
set_error
(
p_fci_internal
,
FCIERR_ALLOC_FAIL
,
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
if
(
p_fci_internal
->
data_out
==
NULL
)
{
if
(
!
(
p_fci_internal
->
data_out
=
p_fci_internal
->
alloc
(
2
*
CB_MAX_CHUNK
))){
set_error
(
p_fci_internal
,
FCIERR_ALLOC_FAIL
,
ERROR_NOT_ENOUGH_MEMORY
);
return
FALSE
;
}
}
}
if
(
p_fci_internal
->
data_out
==
NULL
)
{
p_fci_internal
->
free
(
p_fci_internal
->
data_in
);
/* error handling */
set_error
(
p_fci_internal
,
FCIERR_NONE
,
ERROR_GEN_FAILURE
);
return
FALSE
;
}
/* get information about the file */
/* set defaults in case callback doesn't set one or more fields */
file_handle
=
pfnfcigoi
(
pszSourceFile
,
&
file
->
date
,
&
file
->
time
,
&
file
->
attribs
,
&
err
,
p_fci_internal
->
pv
);
/* check file_handle */
if
(
file_handle
==
0
){
set_error
(
p_fci_internal
,
FCIERR_OPEN_SRC
,
ERROR_OPEN_FAILED
);
}
/* TODO error handling of err */
if
(
fExecute
)
{
file
->
attribs
|=
_A_EXEC
;
}
/* REUSE the variable read_result */
read_result
=
get_header_size
(
p_fci_internal
)
+
p_fci_internal
->
ccab
.
cbReserveCFFolder
;
...
...
@@ -1531,45 +1536,8 @@ BOOL __cdecl FCIAddFile(
return
FALSE
;
}
/* read the contents of the file blockwise */
while
(
!
FALSE
)
{
if
(
p_fci_internal
->
cdata_in
>
CAB_BLOCKMAX
)
{
/* internal error */
set_error
(
p_fci_internal
,
FCIERR_NONE
,
ERROR_GEN_FAILURE
);
return
FALSE
;
}
read_result
=
p_fci_internal
->
read
(
file_handle
/* file handle */
,
(
p_fci_internal
->
data_in
+
p_fci_internal
->
cdata_in
)
/* memory buffer */
,
(
CAB_BLOCKMAX
-
p_fci_internal
->
cdata_in
)
/* number of bytes to copy */
,
&
err
,
p_fci_internal
->
pv
);
/* TODO error handling of err */
if
(
read_result
==
0
)
break
;
/* increment the block size */
p_fci_internal
->
cdata_in
+=
read_result
;
/* increment the file size */
file
->
size
+=
read_result
;
if
(
p_fci_internal
->
cdata_in
>
CAB_BLOCKMAX
)
{
/* report internal error */
set_error
(
p_fci_internal
,
FCIERR_NONE
,
ERROR_GEN_FAILURE
);
if
(
!
add_file_data
(
p_fci_internal
,
pszSourceFile
,
pszFileName
,
fExecute
,
pfnfcigoi
,
pfnfcis
))
return
FALSE
;
}
/* write a whole block */
if
(
p_fci_internal
->
cdata_in
==
CAB_BLOCKMAX
)
{
if
(
!
fci_flush_data_block
(
p_fci_internal
,
&
err
,
pfnfcis
)
)
return
FALSE
;
}
}
/* close the file from FCIAddFile */
p_fci_internal
->
close
(
file_handle
,
&
err
,
p_fci_internal
->
pv
);
/* TODO error handling of err */
p_fci_internal
->
files_size
+=
sizeof
(
CFFILE
)
+
strlen
(
pszFileName
)
+
1
;
/* REUSE the variable read_result */
read_result
=
get_header_size
(
p_fci_internal
)
+
p_fci_internal
->
ccab
.
cbReserveCFFolder
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment