Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Alexey Alyaev
wine
Commits
3cb5b93d
Commit
3cb5b93d
authored
11 years ago
by
Dmitry Timoshkov
Committed by
Alexandre Julliard
11 years ago
Browse files
Options
Downloads
Patches
Plain Diff
cabinet/tests: Add an FDICopy test which emulates extracting from a memory block.
parent
4f9de6bc
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
dlls/cabinet/tests/fdi.c
+246
-0
246 additions, 0 deletions
dlls/cabinet/tests/fdi.c
with
246 additions
and
0 deletions
dlls/cabinet/tests/fdi.c
+
246
−
0
View file @
3cb5b93d
...
...
@@ -2,6 +2,7 @@
* Unit tests for the File Decompression Interface
*
* Copyright (C) 2006 James Hawkins
* Copyright (C) 2013 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -30,6 +31,105 @@
static
CHAR
CURR_DIR
[
MAX_PATH
];
/* avoid including CRT headers */
#ifndef _O_BINARY
# define _O_BINARY 0x8000
#endif
#ifndef _S_IREAD
# define _S_IREAD 0x0100
# define _S_IWRITE 0x0080
#endif
#include
<pshpack1.h>
struct
CFHEADER
{
UCHAR
signature
[
4
];
/* file signature */
ULONG
reserved1
;
/* reserved */
ULONG
cbCabinet
;
/* size of this cabinet file in bytes */
ULONG
reserved2
;
/* reserved */
ULONG
coffFiles
;
/* offset of the first CFFILE entry */
ULONG
reserved3
;
/* reserved */
UCHAR
versionMinor
;
/* cabinet file format version, minor */
UCHAR
versionMajor
;
/* cabinet file format version, major */
USHORT
cFolders
;
/* number of CFFOLDER entries in this cabinet */
USHORT
cFiles
;
/* number of CFFILE entries in this cabinet */
USHORT
flags
;
/* cabinet file option indicators */
USHORT
setID
;
/* must be the same for all cabinets in a set */
USHORT
iCabinet
;
/* number of this cabinet file in a set */
#if 0
USHORT cbCFHeader; /* (optional) size of per-cabinet reserved area */
UCHAR cbCFFolder; /* (optional) size of per-folder reserved area */
UCHAR cbCFData; /* (optional) size of per-datablock reserved area */
UCHAR abReserve; /* (optional) per-cabinet reserved area */
UCHAR szCabinetPrev; /* (optional) name of previous cabinet file */
UCHAR szDiskPrev; /* (optional) name of previous disk */
UCHAR szCabinetNext; /* (optional) name of next cabinet file */
UCHAR szDiskNext; /* (optional) name of next disk */
#endif
};
struct
CFFOLDER
{
ULONG
coffCabStart
;
/* offset of the first CFDATA block in this folder */
USHORT
cCFData
;
/* number of CFDATA blocks in this folder */
USHORT
typeCompress
;
/* compression type indicator */
#if 0
UCHAR abReserve[]; /* (optional) per-folder reserved area */
#endif
};
struct
CFFILE
{
ULONG
cbFile
;
/* uncompressed size of this file in bytes */
ULONG
uoffFolderStart
;
/* uncompressed offset of this file in the folder */
USHORT
iFolder
;
/* index into the CFFOLDER area */
USHORT
date
;
/* date stamp for this file */
USHORT
time
;
/* time stamp for this file */
USHORT
attribs
;
/* attribute flags for this file */
#if 0
UCHAR szName[]; /* name of this file */
#endif
};
struct
CFDATA
{
ULONG
csum
;
/* checksum of this CFDATA entry */
USHORT
cbData
;
/* number of compressed bytes in this block */
USHORT
cbUncomp
;
/* number of uncompressed bytes in this block */
#if 0
UCHAR abReserve[]; /* (optional) per-datablock reserved area */
UCHAR ab[cbData]; /* compressed data bytes */
#endif
};
static
const
struct
{
struct
CFHEADER
header
;
struct
CFFOLDER
folder
;
struct
CFFILE
file
;
UCHAR
szName
[
sizeof
(
"file.dat"
)];
struct
CFDATA
data
;
UCHAR
ab
[
sizeof
(
"Hello World!"
)
-
1
];
}
cab_data
=
{
{
{
'M'
,
'S'
,
'C'
,
'F'
},
0
,
0x59
,
0
,
sizeof
(
struct
CFHEADER
)
+
sizeof
(
struct
CFFOLDER
),
0
,
3
,
1
,
1
,
1
,
0
,
0x1225
,
0x2013
},
{
sizeof
(
struct
CFHEADER
)
+
sizeof
(
struct
CFFOLDER
)
+
sizeof
(
struct
CFFILE
)
+
sizeof
(
"file.dat"
),
1
,
tcompTYPE_NONE
},
{
sizeof
(
"Hello World!"
)
-
1
,
0
,
0
,
0x1225
,
0x2013
,
0xa114
},
{
'f'
,
'i'
,
'l'
,
'e'
,
'.'
,
'd'
,
'a'
,
't'
,
0
},
{
0
,
sizeof
(
"Hello World!"
)
-
1
,
sizeof
(
"Hello World!"
)
-
1
},
{
'H'
,
'e'
,
'l'
,
'l'
,
'o'
,
' '
,
'W'
,
'o'
,
'r'
,
'l'
,
'd'
,
'!'
}
};
#include
<poppack.h>
struct
mem_data
{
const
char
*
base
;
LONG
size
,
pos
;
};
/* FDI callbacks */
static
void
*
CDECL
fdi_alloc
(
ULONG
cb
)
...
...
@@ -592,6 +692,121 @@ static INT_PTR __cdecl CopyProgress(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION
return
0
;
}
static
INT_PTR
CDECL
fdi_mem_open
(
char
*
name
,
int
oflag
,
int
pmode
)
{
static
const
char
expected
[]
=
"memory
\\
block"
;
struct
mem_data
*
data
;
ok
(
!
strcmp
(
name
,
expected
),
"expected %s, got %s
\n
"
,
expected
,
name
);
ok
(
oflag
==
_O_BINARY
,
"expected _O_BINARY, got %x
\n
"
,
oflag
);
ok
(
pmode
==
(
_S_IREAD
|
_S_IWRITE
),
"expected _S_IREAD | _S_IWRITE, got %x
\n
"
,
pmode
);
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
*
data
));
if
(
!
data
)
return
-
1
;
data
->
base
=
(
const
char
*
)
&
cab_data
;
data
->
size
=
sizeof
(
cab_data
);
data
->
pos
=
0
;
trace
(
"mem_open(%s,%x,%x) => %p
\n
"
,
name
,
oflag
,
pmode
,
data
);
return
(
INT_PTR
)
data
;
}
static
UINT
CDECL
fdi_mem_read
(
INT_PTR
hf
,
void
*
pv
,
UINT
cb
)
{
struct
mem_data
*
data
=
(
struct
mem_data
*
)
hf
;
UINT
available
,
cb_read
;
available
=
data
->
size
-
data
->
pos
;
cb_read
=
(
available
>=
cb
)
?
cb
:
available
;
memcpy
(
pv
,
data
->
base
+
data
->
pos
,
cb_read
);
data
->
pos
+=
cb
;
/*trace("mem_read(%p,%p,%u) => %u\n", hf, pv, cb, cb_read);*/
return
cb_read
;
}
static
UINT
CDECL
fdi_mem_write
(
INT_PTR
hf
,
void
*
pv
,
UINT
cb
)
{
static
const
char
expected
[
12
]
=
"Hello World!"
;
trace
(
"mem_write(%#lx,%p,%u)
\n
"
,
hf
,
pv
,
cb
);
ok
(
hf
==
0x12345678
,
"expected 0x12345678, got %#lx
\n
"
,
hf
);
ok
(
cb
==
12
,
"expected 12, got %u
\n
"
,
cb
);
ok
(
!
memcmp
(
pv
,
expected
,
12
),
"expected %s, got %s
\n
"
,
expected
,
(
const
char
*
)
pv
);
return
cb
;
}
static
int
CDECL
fdi_mem_close
(
INT_PTR
hf
)
{
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
hf
);
return
0
;
}
static
LONG
CDECL
fdi_mem_seek
(
INT_PTR
hf
,
LONG
dist
,
int
seektype
)
{
struct
mem_data
*
data
=
(
struct
mem_data
*
)
hf
;
switch
(
seektype
)
{
case
SEEK_SET
:
data
->
pos
=
dist
;
break
;
case
SEEK_CUR
:
data
->
pos
+=
dist
;
break
;
case
SEEK_END
:
default:
todo_wine
ok
(
0
,
"seek: not expected type %d
\n
"
,
seektype
);
return
-
1
;
}
if
(
data
->
pos
<
0
)
data
->
pos
=
0
;
if
(
data
->
pos
>
data
->
size
)
data
->
pos
=
data
->
size
;
/*mem_seek(%p,%d,%d) => %u\n", hf, dist, seektype, data->pos);*/
return
data
->
pos
;
}
static
INT_PTR
CDECL
fdi_mem_notify
(
FDINOTIFICATIONTYPE
fdint
,
FDINOTIFICATION
*
info
)
{
static
const
char
expected
[
9
]
=
"file.dat
\0
"
;
switch
(
fdint
)
{
case
fdintCLOSE_FILE_INFO
:
trace
(
"mem_notify: CLOSE_FILE_INFO %s, handle %#lx
\n
"
,
info
->
psz1
,
info
->
hf
);
ok
(
!
strcmp
(
info
->
psz1
,
expected
),
"expected %s, got %s
\n
"
,
expected
,
info
->
psz1
);
ok
(
info
->
date
==
0x1225
,
"expected 0x1225, got %#x
\n
"
,
info
->
date
);
ok
(
info
->
time
==
0x2013
,
"expected 0x2013, got %#x
\n
"
,
info
->
time
);
ok
(
info
->
attribs
==
0xa114
,
"expected 0xa114, got %#x
\n
"
,
info
->
attribs
);
ok
(
info
->
iFolder
==
0
,
"expected 0, got %#x
\n
"
,
info
->
iFolder
);
return
1
;
case
fdintCOPY_FILE
:
{
trace
(
"mem_notify: COPY_FILE %s, %d bytes
\n
"
,
info
->
psz1
,
info
->
cb
);
ok
(
info
->
cb
==
12
,
"expected 12, got %u
\n
"
,
info
->
cb
);
ok
(
!
strcmp
(
info
->
psz1
,
expected
),
"expected %s, got %s
\n
"
,
expected
,
info
->
psz1
);
return
0x12345678
;
/* call write() callback */
}
default:
trace
(
"mem_notify(%d,%p)
\n
"
,
fdint
,
info
);
return
0
;
}
return
0
;
}
static
void
test_FDICopy
(
void
)
{
CCAB
cabParams
;
...
...
@@ -601,6 +816,11 @@ static void test_FDICopy(void)
BOOL
ret
;
char
name
[]
=
"extract.cab"
;
char
path
[
MAX_PATH
+
1
];
char
memory_block
[]
=
"memory
\\
block"
;
char
memory
[]
=
"memory
\\
"
;
char
block
[]
=
"block"
;
FDICABINETINFO
info
;
INT_PTR
fd
;
set_cab_parameters
(
&
cabParams
);
...
...
@@ -648,6 +868,32 @@ static void test_FDICopy(void)
FDIDestroy
(
hfdi
);
DeleteFileA
(
name
);
/* test extracting from a memory block */
hfdi
=
FDICreate
(
fdi_alloc
,
fdi_free
,
fdi_mem_open
,
fdi_mem_read
,
fdi_mem_write
,
fdi_mem_close
,
fdi_mem_seek
,
cpuUNKNOWN
,
&
erf
);
ok
(
hfdi
!=
NULL
,
"FDICreate error %d
\n
"
,
erf
.
erfOper
);
fd
=
fdi_mem_open
(
memory_block
,
_O_BINARY
,
_S_IREAD
|
_S_IWRITE
);
ok
(
fd
!=
-
1
,
"fdi_open failed
\n
"
);
memset
(
&
info
,
0
,
sizeof
(
info
));
ret
=
FDIIsCabinet
(
hfdi
,
fd
,
&
info
);
todo_wine
{
ok
(
ret
,
"FDIIsCabinet error %d
\n
"
,
erf
.
erfOper
);
ok
(
info
.
cbCabinet
==
0x59
,
"expected 0x59, got %#x
\n
"
,
info
.
cbCabinet
);
ok
(
info
.
cFiles
==
1
,
"expected 1, got %d
\n
"
,
info
.
cFiles
);
ok
(
info
.
cFolders
==
1
,
"expected 1, got %d
\n
"
,
info
.
cFolders
);
ok
(
info
.
setID
==
0x1225
,
"expected 0x1225, got %#x
\n
"
,
info
.
setID
);
ok
(
info
.
iCabinet
==
0x2013
,
"expected 0x2013, got %#x
\n
"
,
info
.
iCabinet
);
}
fdi_mem_close
(
fd
);
ret
=
FDICopy
(
hfdi
,
block
,
memory
,
0
,
fdi_mem_notify
,
NULL
,
0
);
todo_wine
ok
(
ret
,
"FDICopy error %d
\n
"
,
erf
.
erfOper
);
FDIDestroy
(
hfdi
);
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment