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
8ebff12b
Commit
8ebff12b
authored
Feb 02, 2011
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cabarc: Add support for listing and extracting cabinets.
parent
30bdbedc
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
200 additions
and
4 deletions
+200
-4
cabarc.c
programs/cabarc/cabarc.c
+200
-4
No files found.
programs/cabarc/cabarc.c
View file @
8ebff12b
...
...
@@ -69,6 +69,7 @@ static int opt_recurse;
static
int
opt_preserve_paths
;
static
int
opt_reserve_space
;
static
int
opt_verbose
;
static
WCHAR
*
opt_dest_dir
;
static
WCHAR
**
opt_files
;
static
void
*
CDECL
cab_alloc
(
ULONG
size
)
...
...
@@ -258,6 +259,194 @@ static INT_PTR CDECL fci_get_open_info( char *name, USHORT *date, USHORT *time,
return
(
INT_PTR
)
handle
;
}
static
INT_PTR
CDECL
fdi_open
(
char
*
file
,
int
oflag
,
int
pmode
)
{
int
err
;
return
fci_open
(
file
,
oflag
,
pmode
,
&
err
,
NULL
);
}
static
UINT
CDECL
fdi_read
(
INT_PTR
hf
,
void
*
pv
,
UINT
cb
)
{
int
err
;
return
fci_read
(
hf
,
pv
,
cb
,
&
err
,
NULL
);
}
static
UINT
CDECL
fdi_write
(
INT_PTR
hf
,
void
*
pv
,
UINT
cb
)
{
int
err
;
return
fci_write
(
hf
,
pv
,
cb
,
&
err
,
NULL
);
}
static
int
CDECL
fdi_close
(
INT_PTR
hf
)
{
int
err
;
return
fci_close
(
hf
,
&
err
,
NULL
);
}
static
LONG
CDECL
fdi_lseek
(
INT_PTR
hf
,
LONG
dist
,
int
whence
)
{
int
err
;
return
fci_lseek
(
hf
,
dist
,
whence
,
&
err
,
NULL
);
}
/* create directories leading to a given file */
static
void
create_directories
(
const
WCHAR
*
name
)
{
WCHAR
*
path
,
*
p
;
/* create the directory/directories */
path
=
cab_alloc
(
(
strlenW
(
name
)
+
1
)
*
sizeof
(
WCHAR
)
);
strcpyW
(
path
,
name
);
p
=
strchrW
(
path
,
'\\'
);
while
(
p
!=
NULL
)
{
*
p
=
0
;
if
(
!
CreateDirectoryW
(
path
,
NULL
))
WINE_TRACE
(
"Couldn't create directory %s - error: %d
\n
"
,
wine_dbgstr_w
(
path
),
GetLastError
());
*
p
=
'\\'
;
p
=
strchrW
(
p
+
1
,
'\\'
);
}
cab_free
(
path
);
}
/* check if file name matches against one of the files specification */
static
BOOL
match_files
(
const
WCHAR
*
name
)
{
int
i
;
if
(
!*
opt_files
)
return
TRUE
;
for
(
i
=
0
;
opt_files
[
i
];
i
++
)
{
unsigned
int
len
=
strlenW
(
opt_files
[
i
]
);
/* FIXME: do smarter matching, and wildcards */
if
(
!
len
)
continue
;
if
(
strncmpiW
(
name
,
opt_files
[
i
],
len
))
continue
;
if
(
opt_files
[
i
][
len
-
1
]
==
'\\'
||
!
name
[
len
]
||
name
[
len
]
==
'\\'
)
return
TRUE
;
}
return
FALSE
;
}
static
INT_PTR
CDECL
list_notify
(
FDINOTIFICATIONTYPE
fdint
,
PFDINOTIFICATION
pfdin
)
{
WCHAR
*
nameW
;
switch
(
fdint
)
{
case
fdintCABINET_INFO
:
return
0
;
case
fdintCOPY_FILE
:
nameW
=
strdupAtoW
(
(
pfdin
->
attribs
&
_A_NAME_IS_UTF
)
?
CP_UTF8
:
CP_ACP
,
pfdin
->
psz1
);
if
(
match_files
(
nameW
))
{
char
*
nameU
=
strdupWtoA
(
CP_UNIXCP
,
nameW
);
if
(
opt_verbose
)
{
char
attrs
[]
=
"rxash"
;
if
(
!
(
pfdin
->
attribs
&
_A_RDONLY
))
attrs
[
0
]
=
'-'
;
if
(
!
(
pfdin
->
attribs
&
_A_EXEC
))
attrs
[
1
]
=
'-'
;
if
(
!
(
pfdin
->
attribs
&
_A_ARCH
))
attrs
[
2
]
=
'-'
;
if
(
!
(
pfdin
->
attribs
&
_A_SYSTEM
))
attrs
[
3
]
=
'-'
;
if
(
!
(
pfdin
->
attribs
&
_A_HIDDEN
))
attrs
[
4
]
=
'-'
;
printf
(
" %s %9u %04u/%02u/%02u %02u:%02u:%02u "
,
attrs
,
pfdin
->
cb
,
(
pfdin
->
date
>>
9
)
+
1980
,
(
pfdin
->
date
>>
5
)
&
0x0f
,
pfdin
->
date
&
0x1f
,
pfdin
->
time
>>
11
,
(
pfdin
->
time
>>
5
)
&
0x3f
,
(
pfdin
->
time
&
0x1f
)
*
2
);
}
printf
(
"%s
\n
"
,
nameU
);
cab_free
(
nameU
);
}
cab_free
(
nameW
);
return
0
;
default:
WINE_FIXME
(
"Unexpected notification type %d.
\n
"
,
fdint
);
return
0
;
}
}
static
int
list_cabinet
(
char
*
cab_dir
,
char
*
cab_file
)
{
ERF
erf
;
int
ret
=
0
;
HFDI
fdi
=
FDICreate
(
cab_alloc
,
cab_free
,
fdi_open
,
fdi_read
,
fdi_write
,
fdi_close
,
fdi_lseek
,
cpuUNKNOWN
,
&
erf
);
if
(
!
FDICopy
(
fdi
,
cab_file
,
cab_dir
,
0
,
list_notify
,
NULL
,
NULL
))
ret
=
GetLastError
();
FDIDestroy
(
fdi
);
return
ret
;
}
static
INT_PTR
CDECL
extract_notify
(
FDINOTIFICATIONTYPE
fdint
,
PFDINOTIFICATION
pfdin
)
{
WCHAR
*
file
,
*
nameW
,
*
path
=
NULL
;
INT_PTR
ret
;
switch
(
fdint
)
{
case
fdintCABINET_INFO
:
return
0
;
case
fdintCOPY_FILE
:
nameW
=
strdupAtoW
(
(
pfdin
->
attribs
&
_A_NAME_IS_UTF
)
?
CP_UTF8
:
CP_ACP
,
pfdin
->
psz1
);
if
(
opt_preserve_paths
)
{
file
=
nameW
;
while
(
*
file
==
'\\'
)
file
++
;
/* remove leading backslashes */
}
else
{
if
((
file
=
strrchrW
(
nameW
,
'\\'
)))
file
++
;
else
file
=
nameW
;
}
if
(
opt_dest_dir
)
{
path
=
cab_alloc
(
(
strlenW
(
opt_dest_dir
)
+
strlenW
(
file
)
+
1
)
*
sizeof
(
WCHAR
)
);
strcpyW
(
path
,
opt_dest_dir
);
strcatW
(
path
,
file
);
}
else
path
=
file
;
if
(
match_files
(
file
))
{
if
(
opt_verbose
)
{
char
*
nameU
=
strdupWtoA
(
CP_UNIXCP
,
path
);
printf
(
"extracting %s
\n
"
,
nameU
);
cab_free
(
nameU
);
}
create_directories
(
path
);
/* FIXME: check for existing file and overwrite mode */
ret
=
(
INT_PTR
)
CreateFileW
(
path
,
GENERIC_WRITE
,
FILE_SHARE_READ
|
FILE_SHARE_WRITE
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
}
else
ret
=
0
;
cab_free
(
nameW
);
if
(
path
!=
file
)
cab_free
(
path
);
return
ret
;
case
fdintCLOSE_FILE_INFO
:
CloseHandle
(
(
HANDLE
)
pfdin
->
hf
);
return
0
;
default:
WINE_FIXME
(
"Unexpected notification type %d.
\n
"
,
fdint
);
return
0
;
}
}
static
int
extract_cabinet
(
char
*
cab_dir
,
char
*
cab_file
)
{
ERF
erf
;
int
ret
=
0
;
HFDI
fdi
=
FDICreate
(
cab_alloc
,
cab_free
,
fdi_open
,
fdi_read
,
fdi_write
,
fdi_close
,
fdi_lseek
,
cpuUNKNOWN
,
&
erf
);
if
(
!
FDICopy
(
fdi
,
cab_file
,
cab_dir
,
0
,
extract_notify
,
NULL
,
NULL
))
ret
=
GetLastError
();
FDIDestroy
(
fdi
);
return
ret
;
}
static
BOOL
add_file
(
HFCI
fci
,
WCHAR
*
name
)
{
...
...
@@ -468,15 +657,22 @@ int wmain( int argc, WCHAR *argv[] )
{
case
'l'
:
case
'L'
:
WINE_FIXME
(
"list not implemented
\n
"
);
return
1
;
return
list_cabinet
(
buffer
,
file_part
);
case
'n'
:
case
'N'
:
return
new_cabinet
(
buffer
,
file_part
);
case
'x'
:
case
'X'
:
WINE_FIXME
(
"extraction not implemented
\n
"
);
return
1
;
if
(
argc
>
1
)
/* check for destination dir as last argument */
{
WCHAR
*
last
=
argv
[
argc
-
1
];
if
(
last
[
0
]
&&
last
[
strlenW
(
last
)
-
1
]
==
'\\'
)
{
opt_dest_dir
=
last
;
argv
[
--
argc
]
=
NULL
;
}
}
return
extract_cabinet
(
buffer
,
file_part
);
default:
usage
();
return
1
;
...
...
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