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
ccdbcd6e
Commit
ccdbcd6e
authored
Jan 31, 1999
by
Ulrich Weigand
Committed by
Alexandre Julliard
Jan 31, 1999
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed old VER.DLL code.
parent
ce821773
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
0 additions
and
1471 deletions
+0
-1471
Makefile.in
misc/Makefile.in
+0
-1
ver.c
misc/ver.c
+0
-1470
No files found.
misc/Makefile.in
View file @
ccdbcd6e
...
...
@@ -31,7 +31,6 @@ C_SRCS = \
tapi32.c
\
toolhelp.c
\
tweak.c
\
ver.c
\
version.c
\
w32scomb.c
\
w32skrnl.c
\
...
...
misc/ver.c
deleted
100644 → 0
View file @
ce821773
/*
* Implementation of VER.DLL
*
* Copyright 1996,1997 Marcus Meissner
* Copyright 1997 David Cuthbert
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include "windows.h"
#include "win.h"
#include "winerror.h"
#include "heap.h"
#include "ver.h"
#include "lzexpand.h"
#include "module.h"
#include "neexe.h"
#include "debug.h"
#include "xmalloc.h"
#include "winreg.h"
#define LZREAD(what) \
if (sizeof(*what)!=LZRead32(lzfd,what,sizeof(*what))) return 0;
#define LZTELL(lzfd) LZSeek32(lzfd, 0, SEEK_CUR);
/******************************************************************************
*
* void ver_dstring(
* char const * prologue,
* char const * teststring,
* char const * epilogue )
*
* This function will print via dprintf[_]ver to stddeb the prologue string,
* followed by the address of teststring and the string it contains if
* teststring is non-null or "(null)" otherwise, and then the epilogue
* string followed by a new line.
*
* Revision history
* 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
* Original implementation as dprintf[_]ver_string
* 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
* Fixed problem that caused bug with tools/make_debug -- renaming
* this function should fix the problem.
* 15-Feb-1998 Dimitrie Paun (dimi@cs.toronto.edu)
* Modified it to make it print the message using only one
* dprintf[_]ver call.
*
*****************************************************************************/
static
void
ver_dstring
(
char
const
*
prologue
,
char
const
*
teststring
,
char
const
*
epilogue
)
{
TRACE
(
ver
,
"%s %p (
\"
%s
\"
) %s
\n
"
,
prologue
,
(
void
const
*
)
teststring
,
teststring
?
teststring
:
"(null)"
,
epilogue
);
}
/******************************************************************************
*
* This function will print via dprintf[_]ver to stddeb debug info regarding
* the file info structure vffi.
* 15-Feb-1998 Dimitrie Paun (dimi@cs.toronto.edu)
* Added this function to clean up the code.
*
*****************************************************************************/
static
void
print_vffi_debug
(
VS_FIXEDFILEINFO
*
vffi
)
{
dbg_decl_str
(
ver
,
1024
);
TRACE
(
ver
,
" structversion=%u.%u, fileversion=%u.%u.%u.%u, productversion=%u.%u.%u.%u, flagmask=0x%lx, flags=%s%s%s%s%s%s
\n
"
,
HIWORD
(
vffi
->
dwStrucVersion
),
LOWORD
(
vffi
->
dwStrucVersion
),
HIWORD
(
vffi
->
dwFileVersionMS
),
LOWORD
(
vffi
->
dwFileVersionMS
),
HIWORD
(
vffi
->
dwFileVersionLS
),
LOWORD
(
vffi
->
dwFileVersionLS
),
HIWORD
(
vffi
->
dwProductVersionMS
),
LOWORD
(
vffi
->
dwProductVersionMS
),
HIWORD
(
vffi
->
dwProductVersionLS
),
LOWORD
(
vffi
->
dwProductVersionLS
),
vffi
->
dwFileFlagsMask
,
(
vffi
->
dwFileFlags
&
VS_FF_DEBUG
)
?
"DEBUG,"
:
""
,
(
vffi
->
dwFileFlags
&
VS_FF_PRERELEASE
)
?
"PRERELEASE,"
:
""
,
(
vffi
->
dwFileFlags
&
VS_FF_PATCHED
)
?
"PATCHED,"
:
""
,
(
vffi
->
dwFileFlags
&
VS_FF_PRIVATEBUILD
)
?
"PRIVATEBUILD,"
:
""
,
(
vffi
->
dwFileFlags
&
VS_FF_INFOINFERRED
)
?
"INFOINFERRED,"
:
""
,
(
vffi
->
dwFileFlags
&
VS_FF_SPECIALBUILD
)
?
"SPECIALBUILD,"
:
""
);
dsprintf
(
ver
,
" OS=0x%x.0x%x "
,
HIWORD
(
vffi
->
dwFileOS
),
LOWORD
(
vffi
->
dwFileOS
)
);
switch
(
vffi
->
dwFileOS
&
0xFFFF0000
)
{
case
VOS_DOS
:
dsprintf
(
ver
,
"DOS,"
);
break
;
case
VOS_OS216
:
dsprintf
(
ver
,
"OS/2-16,"
);
break
;
case
VOS_OS232
:
dsprintf
(
ver
,
"OS/2-32,"
);
break
;
case
VOS_NT
:
dsprintf
(
ver
,
"NT,"
);
break
;
case
VOS_UNKNOWN
:
default:
dsprintf
(
ver
,
"UNKNOWN(0x%lx),"
,
vffi
->
dwFileOS
&
0xFFFF0000
);
break
;
}
switch
(
LOWORD
(
vffi
->
dwFileOS
))
{
case
VOS__BASE
:
dsprintf
(
ver
,
"BASE"
);
break
;
case
VOS__WINDOWS16
:
dsprintf
(
ver
,
"WIN16"
);
break
;
case
VOS__WINDOWS32
:
dsprintf
(
ver
,
"WIN32"
);
break
;
case
VOS__PM16
:
dsprintf
(
ver
,
"PM16"
);
break
;
case
VOS__PM32
:
dsprintf
(
ver
,
"PM32"
);
break
;
default:
dsprintf
(
ver
,
"UNKNOWN(0x%x)"
,
LOWORD
(
vffi
->
dwFileOS
));
break
;
}
TRACE
(
ver
,
"(%s)
\n
"
,
dbg_str
(
ver
));
dbg_reset_str
(
ver
);
switch
(
vffi
->
dwFileType
)
{
default:
case
VFT_UNKNOWN
:
dsprintf
(
ver
,
"filetype=Unknown(0x%lx)"
,
vffi
->
dwFileType
);
break
;
case
VFT_APP
:
dsprintf
(
ver
,
"filetype=APP,"
);
break
;
case
VFT_DLL
:
dsprintf
(
ver
,
"filetype=DLL,"
);
break
;
case
VFT_DRV
:
dsprintf
(
ver
,
"filetype=DRV,"
);
switch
(
vffi
->
dwFileSubtype
)
{
default:
case
VFT2_UNKNOWN
:
dsprintf
(
ver
,
"UNKNOWN(0x%lx)"
,
vffi
->
dwFileSubtype
);
break
;
case
VFT2_DRV_PRINTER
:
dsprintf
(
ver
,
"PRINTER"
);
break
;
case
VFT2_DRV_KEYBOARD
:
dsprintf
(
ver
,
"KEYBOARD"
);
break
;
case
VFT2_DRV_LANGUAGE
:
dsprintf
(
ver
,
"LANGUAGE"
);
break
;
case
VFT2_DRV_DISPLAY
:
dsprintf
(
ver
,
"DISPLAY"
);
break
;
case
VFT2_DRV_MOUSE
:
dsprintf
(
ver
,
"MOUSE"
);
break
;
case
VFT2_DRV_NETWORK
:
dsprintf
(
ver
,
"NETWORK"
);
break
;
case
VFT2_DRV_SYSTEM
:
dsprintf
(
ver
,
"SYSTEM"
);
break
;
case
VFT2_DRV_INSTALLABLE
:
dsprintf
(
ver
,
"INSTALLABLE"
);
break
;
case
VFT2_DRV_SOUND
:
dsprintf
(
ver
,
"SOUND"
);
break
;
case
VFT2_DRV_COMM
:
dsprintf
(
ver
,
"COMM"
);
break
;
case
VFT2_DRV_INPUTMETHOD
:
dsprintf
(
ver
,
"INPUTMETHOD"
);
break
;
}
break
;
case
VFT_FONT
:
dsprintf
(
ver
,
"filetype=FONT."
);
switch
(
vffi
->
dwFileSubtype
)
{
default:
dsprintf
(
ver
,
"UNKNOWN(0x%lx)"
,
vffi
->
dwFileSubtype
);
break
;
case
VFT2_FONT_RASTER
:
dsprintf
(
ver
,
"RASTER"
);
break
;
case
VFT2_FONT_VECTOR
:
dsprintf
(
ver
,
"VECTOR"
);
break
;
case
VFT2_FONT_TRUETYPE
:
dsprintf
(
ver
,
"TRUETYPE"
);
break
;
}
break
;
case
VFT_VXD
:
dsprintf
(
ver
,
"filetype=VXD"
);
break
;
case
VFT_STATIC_LIB
:
dsprintf
(
ver
,
"filetype=STATIC_LIB"
);
break
;
}
TRACE
(
ver
,
"%s
\n
"
,
dbg_str
(
ver
));
TRACE
(
ver
,
" filedata=0x%lx.0x%lx
\n
"
,
vffi
->
dwFileDateMS
,
vffi
->
dwFileDateLS
);
}
/******************************************************************************
*
* int testFileExistence(
* char const * path,
* char const * file )
*
* Tests whether a given path/file combination exists. If the file does
* not exist, the return value is zero. If it does exist, the return
* value is non-zero.
*
* Revision history
* 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
* Original implementation
*
*****************************************************************************/
static
int
testFileExistence
(
char
const
*
path
,
char
const
*
file
)
{
char
filename
[
1024
];
int
filenamelen
;
OFSTRUCT
fileinfo
;
int
retval
;
fileinfo
.
cBytes
=
sizeof
(
OFSTRUCT
);
strcpy
(
filename
,
path
);
filenamelen
=
strlen
(
filename
);
/* Add a trailing \ if necessary */
if
(
filenamelen
)
{
if
(
filename
[
filenamelen
-
1
]
!=
'\\'
)
strcat
(
filename
,
"
\\
"
);
}
else
/* specify the current directory */
strcpy
(
filename
,
".
\\
"
);
/* Create the full pathname */
strcat
(
filename
,
file
);
if
(
OpenFile32
(
filename
,
&
fileinfo
,
OF_EXIST
)
==
HFILE_ERROR32
)
retval
=
0
;
else
retval
=
1
;
return
retval
;
}
/******************************************************************************
*
* int testFileExclusiveExistence(
* char const * path,
* char const * file )
*
* Tests whether a given path/file combination exists and ensures that no
* other programs have handles to the given file. If the file does not
* exist or is open, the return value is zero. If it does exist, the
* return value is non-zero.
*
* Revision history
* 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
* Original implementation
*
*****************************************************************************/
static
int
testFileExclusiveExistence
(
char
const
*
path
,
char
const
*
file
)
{
char
filename
[
1024
];
int
filenamelen
;
OFSTRUCT
fileinfo
;
int
retval
;
fileinfo
.
cBytes
=
sizeof
(
OFSTRUCT
);
strcpy
(
filename
,
path
);
filenamelen
=
strlen
(
filename
);
/* Add a trailing \ if necessary */
if
(
filenamelen
)
{
if
(
filename
[
filenamelen
-
1
]
!=
'\\'
)
strcat
(
filename
,
"
\\
"
);
}
else
/* specify the current directory */
strcpy
(
filename
,
".
\\
"
);
/* Create the full pathname */
strcat
(
filename
,
file
);
if
(
OpenFile32
(
filename
,
&
fileinfo
,
OF_EXIST
|
OF_SHARE_EXCLUSIVE
)
==
HFILE_ERROR32
)
retval
=
0
;
else
retval
=
1
;
return
retval
;
}
static
int
read_xx_header
(
HFILE32
lzfd
)
{
IMAGE_DOS_HEADER
mzh
;
char
magic
[
3
];
LZSeek32
(
lzfd
,
0
,
SEEK_SET
);
if
(
sizeof
(
mzh
)
!=
LZRead32
(
lzfd
,
&
mzh
,
sizeof
(
mzh
)))
return
0
;
if
(
mzh
.
e_magic
!=
IMAGE_DOS_SIGNATURE
)
return
0
;
LZSeek32
(
lzfd
,
mzh
.
e_lfanew
,
SEEK_SET
);
if
(
2
!=
LZRead32
(
lzfd
,
magic
,
2
))
return
0
;
LZSeek32
(
lzfd
,
mzh
.
e_lfanew
,
SEEK_SET
);
if
(
magic
[
0
]
==
'N'
&&
magic
[
1
]
==
'E'
)
return
IMAGE_OS2_SIGNATURE
;
if
(
magic
[
0
]
==
'P'
&&
magic
[
1
]
==
'E'
)
return
IMAGE_NT_SIGNATURE
;
magic
[
2
]
=
'\0'
;
WARN
(
ver
,
"Can't handle %s files.
\n
"
,
magic
);
return
0
;
}
static
int
find_ne_resource
(
HFILE32
lzfd
,
SEGPTR
typeid
,
SEGPTR
resid
,
BYTE
**
resdata
,
int
*
reslen
,
DWORD
*
off
)
{
IMAGE_OS2_HEADER
nehd
;
NE_TYPEINFO
ti
;
NE_NAMEINFO
ni
;
int
i
;
WORD
shiftcount
;
DWORD
nehdoffset
;
nehdoffset
=
LZTELL
(
lzfd
);
LZREAD
(
&
nehd
);
if
(
nehd
.
resource_tab_offset
==
nehd
.
rname_tab_offset
)
{
TRACE
(
ver
,
"no resources in NE dll
\n
"
);
return
0
;
}
LZSeek32
(
lzfd
,
nehd
.
resource_tab_offset
+
nehdoffset
,
SEEK_SET
);
LZREAD
(
&
shiftcount
);
TRACE
(
ver
,
"shiftcount is %d
\n
"
,
shiftcount
);
TRACE
(
ver
,
"reading resource typeinfo dir.
\n
"
);
if
(
!
HIWORD
(
typeid
))
typeid
=
(
SEGPTR
)(
LOWORD
(
typeid
)
|
0x8000
);
if
(
!
HIWORD
(
resid
))
resid
=
(
SEGPTR
)(
LOWORD
(
resid
)
|
0x8000
);
while
(
1
)
{
int
skipflag
;
LZREAD
(
&
ti
);
if
(
!
ti
.
type_id
)
return
0
;
TRACE
(
ver
,
" ti.typeid =%04x,count=%d
\n
"
,
ti
.
type_id
,
ti
.
count
);
skipflag
=
0
;
if
(
!
HIWORD
(
typeid
))
{
if
((
ti
.
type_id
&
0x8000
)
&&
(
typeid
!=
ti
.
type_id
))
skipflag
=
1
;
}
else
{
if
(
ti
.
type_id
&
0x8000
)
{
skipflag
=
1
;
}
else
{
BYTE
len
;
char
*
str
;
DWORD
whereleft
;
whereleft
=
LZTELL
(
lzfd
);
LZSeek32
(
lzfd
,
nehdoffset
+
nehd
.
resource_tab_offset
+
ti
.
type_id
,
SEEK_SET
);
LZREAD
(
&
len
);
str
=
xmalloc
(
len
);
if
(
len
!=
LZRead32
(
lzfd
,
str
,
len
))
return
0
;
TRACE
(
ver
,
"read %s to compare it with %s
\n
"
,
str
,(
char
*
)
PTR_SEG_TO_LIN
(
typeid
)
);
if
(
lstrcmpi32A
(
str
,(
char
*
)
PTR_SEG_TO_LIN
(
typeid
)))
skipflag
=
1
;
free
(
str
);
LZSeek32
(
lzfd
,
whereleft
,
SEEK_SET
);
}
}
if
(
skipflag
)
{
LZSeek32
(
lzfd
,
ti
.
count
*
sizeof
(
ni
),
SEEK_CUR
);
continue
;
}
for
(
i
=
0
;
i
<
ti
.
count
;
i
++
)
{
WORD
*
rdata
;
int
len
;
LZREAD
(
&
ni
);
TRACE
(
ver
,
" ni.id=%4x,offset=%d,length=%d
\n
"
,
ni
.
id
,
ni
.
offset
,
ni
.
length
);
skipflag
=
1
;
if
(
!
HIWORD
(
resid
))
{
if
(
ni
.
id
==
resid
)
skipflag
=
0
;
}
else
{
if
(
!
(
ni
.
id
&
0x8000
))
{
BYTE
len
;
char
*
str
;
DWORD
whereleft
;
whereleft
=
LZTELL
(
lzfd
);
LZSeek32
(
lzfd
,
nehdoffset
+
nehd
.
resource_tab_offset
+
ni
.
id
,
SEEK_SET
);
LZREAD
(
&
len
);
str
=
xmalloc
(
len
);
if
(
len
!=
LZRead32
(
lzfd
,
str
,
len
))
return
0
;
TRACE
(
ver
,
"read %s to compare it with %s
\n
"
,
str
,(
char
*
)
PTR_SEG_TO_LIN
(
typeid
)
);
if
(
!
lstrcmpi32A
(
str
,(
char
*
)
PTR_SEG_TO_LIN
(
typeid
)))
skipflag
=
0
;
free
(
str
);
LZSeek32
(
lzfd
,
whereleft
,
SEEK_SET
);
}
}
if
(
skipflag
)
continue
;
LZSeek32
(
lzfd
,((
int
)
ni
.
offset
<<
shiftcount
),
SEEK_SET
);
*
off
=
(
int
)
ni
.
offset
<<
shiftcount
;
len
=
ni
.
length
<<
shiftcount
;
rdata
=
(
WORD
*
)
xmalloc
(
len
);
if
(
len
!=
LZRead32
(
lzfd
,
rdata
,
len
))
{
free
(
rdata
);
return
0
;
}
TRACE
(
ver
,
"resource found.
\n
"
);
*
resdata
=
(
BYTE
*
)
rdata
;
*
reslen
=
len
;
return
1
;
}
}
}
/* Loads the specified PE resource.
* FIXME: shouldn't load the whole image
*/
static
int
find_pe_resource
(
HFILE32
lzfd
,
LPWSTR
typeid
,
LPWSTR
resid
,
BYTE
**
resdata
,
int
*
reslen
,
DWORD
*
off
)
{
IMAGE_NT_HEADERS
pehd
;
int
i
;
UINT32
nrofsections
;
DWORD
imagesize
,
pehdoffset
;
BYTE
*
image
;
IMAGE_DATA_DIRECTORY
resdir
;
PIMAGE_RESOURCE_DIRECTORY
resourcedir
,
xresdir
;
PIMAGE_RESOURCE_DATA_ENTRY
xresdata
;
PIMAGE_SECTION_HEADER
sections
;
pehdoffset
=
LZTELL
(
lzfd
);
LZREAD
(
&
pehd
);
resdir
=
pehd
.
OptionalHeader
.
DataDirectory
[
IMAGE_FILE_RESOURCE_DIRECTORY
];
TRACE
(
ver
,
"(.,type=%p, id=%p, len=%u, off=%lu)
\n
"
,
typeid
,
resid
,
*
reslen
,
*
off
);
if
(
!
resdir
.
Size
)
{
WARN
(
ver
,
"No resource directory found in PE file.
\n
"
);
return
0
;
}
imagesize
=
pehd
.
OptionalHeader
.
SizeOfImage
;
image
=
HeapAlloc
(
GetProcessHeap
(),
0
,
imagesize
);
nrofsections
=
pehd
.
FileHeader
.
NumberOfSections
;
sections
=
(
PIMAGE_SECTION_HEADER
)
HeapAlloc
(
GetProcessHeap
(),
0
,
pehd
.
FileHeader
.
NumberOfSections
*
sizeof
(
IMAGE_SECTION_HEADER
));
LZSeek32
(
lzfd
,
pehdoffset
+
sizeof
(
DWORD
)
+
/* Signature */
sizeof
(
IMAGE_FILE_HEADER
)
+
pehd
.
FileHeader
.
SizeOfOptionalHeader
,
SEEK_SET
);
if
(
nrofsections
*
sizeof
(
IMAGE_SECTION_HEADER
)
!=
LZRead32
(
lzfd
,
sections
,
nrofsections
*
sizeof
(
IMAGE_SECTION_HEADER
))
)
{
HeapFree
(
GetProcessHeap
(),
0
,
image
);
return
0
;
}
for
(
i
=
0
;
i
<
nrofsections
;
i
++
)
{
if
(
sections
[
i
].
Characteristics
&
IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
continue
;
LZSeek32
(
lzfd
,
sections
[
i
].
PointerToRawData
,
SEEK_SET
);
if
(
sections
[
i
].
SizeOfRawData
!=
LZRead32
(
lzfd
,
image
+
sections
[
i
].
VirtualAddress
,
sections
[
i
].
SizeOfRawData
)
)
{
HeapFree
(
GetProcessHeap
(),
0
,
image
);
return
0
;
}
}
resourcedir
=
(
PIMAGE_RESOURCE_DIRECTORY
)(
image
+
resdir
.
VirtualAddress
);
xresdir
=
GetResDirEntryW
(
resourcedir
,
typeid
,(
DWORD
)
resourcedir
,
FALSE
);
if
(
!
xresdir
)
{
TRACE
(
ver
,
"...no typeid entry found for %p
\n
"
,
typeid
);
HeapFree
(
GetProcessHeap
(),
0
,
image
);
return
0
;
}
xresdir
=
GetResDirEntryW
(
xresdir
,
resid
,(
DWORD
)
resourcedir
,
FALSE
);
if
(
!
xresdir
)
{
TRACE
(
ver
,
"...no resid entry found for %p
\n
"
,
resid
);
HeapFree
(
GetProcessHeap
(),
0
,
image
);
return
0
;
}
xresdir
=
GetResDirEntryW
(
xresdir
,
0
,(
DWORD
)
resourcedir
,
TRUE
);
if
(
!
xresdir
)
{
TRACE
(
ver
,
"...no 0 (default language) entry found for %p
\n
"
,
resid
);
HeapFree
(
GetProcessHeap
(),
0
,
image
);
return
0
;
}
xresdata
=
(
PIMAGE_RESOURCE_DATA_ENTRY
)
xresdir
;
*
reslen
=
xresdata
->
Size
;
*
resdata
=
(
LPBYTE
)
xmalloc
(
*
reslen
);
memcpy
(
*
resdata
,
image
+
xresdata
->
OffsetToData
,
*
reslen
);
/* find physical address for virtual offset */
for
(
i
=
0
;
i
<
nrofsections
;
i
++
)
{
if
(
sections
[
i
].
Characteristics
&
IMAGE_SCN_CNT_UNINITIALIZED_DATA
)
continue
;
if
(
(
xresdata
->
OffsetToData
>=
sections
[
i
].
VirtualAddress
)
&&
(
xresdata
->
OffsetToData
<
sections
[
i
].
VirtualAddress
+
sections
[
i
].
SizeOfRawData
)
)
{
*
off
=
(
DWORD
)(
xresdata
->
OffsetToData
)
-
(
DWORD
)(
sections
[
i
].
VirtualAddress
)
+
(
DWORD
)(
sections
[
i
].
PointerToRawData
);
break
;
}
}
HeapFree
(
GetProcessHeap
(),
0
,
image
);
HeapFree
(
GetProcessHeap
(),
0
,
sections
);
TRACE
(
ver
,
"-- found at off=%lu
\n
"
,
*
off
);
return
1
;
}
/* GetFileResourceSize [VER.2] */
DWORD
WINAPI
GetFileResourceSize
(
LPCSTR
filename
,
SEGPTR
restype
,
SEGPTR
resid
,
LPDWORD
off
)
{
HFILE32
lzfd
;
OFSTRUCT
ofs
;
BYTE
*
resdata
=
NULL
;
int
reslen
=
0
;
int
res
=
0
;
TRACE
(
ver
,
"(%s,type=0x%lx,id=0x%lx,off=%p)
\n
"
,
filename
,(
LONG
)
restype
,(
LONG
)
resid
,
off
);
lzfd
=
LZOpenFile32A
(
filename
,
&
ofs
,
OF_READ
);
if
(
!
lzfd
)
return
0
;
switch
(
read_xx_header
(
lzfd
))
{
case
0
:
res
=
0
;
break
;
case
IMAGE_OS2_SIGNATURE
:
res
=
find_ne_resource
(
lzfd
,
restype
,
resid
,
&
resdata
,
&
reslen
,
off
);
break
;
case
IMAGE_NT_SIGNATURE
:
res
=
find_pe_resource
(
lzfd
,(
LPWSTR
)
restype
,(
LPWSTR
)
resid
,
&
resdata
,
&
reslen
,
off
);
break
;
}
if
(
!
res
)
{
LZClose32
(
lzfd
);
return
0
;
}
if
(
resdata
)
free
(
resdata
);
LZClose32
(
lzfd
);
return
reslen
;
}
/* GetFileResource [VER.3] */
DWORD
WINAPI
GetFileResource
(
LPCSTR
filename
,
SEGPTR
restype
,
SEGPTR
resid
,
DWORD
off
,
DWORD
datalen
,
LPVOID
data
)
{
HFILE32
lzfd
;
OFSTRUCT
ofs
;
BYTE
*
resdata
=
NULL
;
int
res
=
0
;
int
reslen
=
datalen
;
TRACE
(
ver
,
"(%s,type=0x%lx,id=0x%lx,off=%ld,len=%ld,date=%p)
\n
"
,
filename
,(
LONG
)
restype
,(
LONG
)
resid
,
off
,
datalen
,
data
);
lzfd
=
LZOpenFile32A
(
filename
,
&
ofs
,
OF_READ
);
if
(
lzfd
==
0
)
return
0
;
if
(
!
off
)
{
switch
(
read_xx_header
(
lzfd
))
{
case
0
:
res
=
0
;
break
;
case
IMAGE_OS2_SIGNATURE
:
res
=
find_ne_resource
(
lzfd
,
restype
,
resid
,
&
resdata
,
&
reslen
,
&
off
);
break
;
case
IMAGE_NT_SIGNATURE
:
res
=
find_pe_resource
(
lzfd
,(
LPWSTR
)
restype
,(
LPWSTR
)
resid
,
&
resdata
,
&
reslen
,
&
off
);
break
;
}
LZClose32
(
lzfd
);
if
(
!
res
)
return
0
;
if
(
reslen
>
datalen
)
reslen
=
datalen
;
memcpy
(
data
,
resdata
,
reslen
);
free
(
resdata
);
TRACE
(
ver
,
"--[1] len=%u
\n
"
,
reslen
);
return
reslen
;
}
LZSeek32
(
lzfd
,
off
,
SEEK_SET
);
reslen
=
LZRead32
(
lzfd
,
data
,
datalen
);
LZClose32
(
lzfd
);
TRACE
(
ver
,
"--[2] len=%u
\n
"
,
reslen
);
return
reslen
;
}
/* GetFileVersionInfoSize [VER.6] */
DWORD
WINAPI
GetFileVersionInfoSize16
(
LPCSTR
filename
,
LPDWORD
handle
)
{
DWORD
len
,
ret
,
isuni
=
0
;
BYTE
buf
[
144
];
VS_FIXEDFILEINFO
*
vffi
;
TRACE
(
ver
,
"(%s,%p)
\n
"
,
filename
,
handle
);
len
=
GetFileResourceSize
(
filename
,
VS_FILE_INFO
,
VS_VERSION_INFO
,
handle
);
if
(
!
len
)
return
0
;
ret
=
GetFileResource
(
filename
,
VS_FILE_INFO
,
VS_VERSION_INFO
,
*
handle
,
sizeof
(
buf
),
buf
);
if
(
!
ret
)
return
0
;
vffi
=
(
VS_FIXEDFILEINFO
*
)(
buf
+
0x14
);
if
(
vffi
->
dwSignature
!=
VS_FFI_SIGNATURE
)
{
/* unicode resource */
if
(
vffi
->
dwSignature
==
0x004f0049
)
{
isuni
=
1
;
vffi
=
(
VS_FIXEDFILEINFO
*
)(
buf
+
0x28
);
}
else
{
WARN
(
ver
,
"vffi->dwSignature is 0x%08lx, but not 0x%08lx!
\n
"
,
vffi
->
dwSignature
,
VS_FFI_SIGNATURE
);
return
0
;
}
}
if
(
*
(
WORD
*
)
buf
<
len
)
len
=
*
(
WORD
*
)
buf
;
if
(
TRACE_ON
(
ver
))
print_vffi_debug
(
vffi
);
return
len
;
}
/* GetFileVersionInfoSize32A [VERSION.1] */
DWORD
WINAPI
GetFileVersionInfoSize32A
(
LPCSTR
filename
,
LPDWORD
handle
)
{
TRACE
(
ver
,
"(%s,%p)
\n
"
,
filename
,
handle
);
return
GetFileVersionInfoSize16
(
filename
,
handle
);
}
/* GetFileVersionInfoSize32W [VERSION.2] */
DWORD
WINAPI
GetFileVersionInfoSize32W
(
LPCWSTR
filename
,
LPDWORD
handle
)
{
LPSTR
xfn
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
filename
);
DWORD
ret
=
GetFileVersionInfoSize16
(
xfn
,
handle
);
HeapFree
(
GetProcessHeap
(),
0
,
xfn
);
return
ret
;
}
/* GetFileVersionInfo [VER.7] */
DWORD
WINAPI
GetFileVersionInfo16
(
LPCSTR
filename
,
DWORD
handle
,
DWORD
datasize
,
LPVOID
data
)
{
TRACE
(
ver
,
"(%s,%ld,size=%ld,data=%p)
\n
"
,
filename
,
handle
,
datasize
,
data
);
return
GetFileResource
(
filename
,
VS_FILE_INFO
,
VS_VERSION_INFO
,
handle
,
datasize
,
data
);
}
/* GetFileVersionInfoA [VERSION.0] */
DWORD
WINAPI
GetFileVersionInfo32A
(
LPCSTR
filename
,
DWORD
handle
,
DWORD
datasize
,
LPVOID
data
)
{
return
GetFileVersionInfo16
(
filename
,
handle
,
datasize
,
data
);
}
/* GetFileVersionInfoW [VERSION.3] */
DWORD
WINAPI
GetFileVersionInfo32W
(
LPCWSTR
filename
,
DWORD
handle
,
DWORD
datasize
,
LPVOID
data
)
{
LPSTR
fn
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
filename
);
DWORD
ret
=
GetFileVersionInfo16
(
fn
,
handle
,
datasize
,
data
);
HeapFree
(
GetProcessHeap
(),
0
,
fn
);
return
ret
;
}
/*****************************************************************************
*
* VerFindFile() [VER.8]
* Determines where to install a file based on whether it locates another
* version of the file in the system. The values VerFindFile returns are
* used in a subsequent call to the VerInstallFile function.
*
* Revision history:
* 30-May-1997 Dave Cuthbert (dacut@ece.cmu.edu)
* Reimplementation of VerFindFile from original stub.
*
****************************************************************************/
DWORD
WINAPI
VerFindFile16
(
UINT16
flags
,
LPCSTR
lpszFilename
,
LPCSTR
lpszWinDir
,
LPCSTR
lpszAppDir
,
LPSTR
lpszCurDir
,
UINT16
*
lpuCurDirLen
,
LPSTR
lpszDestDir
,
UINT16
*
lpuDestDirLen
)
{
DWORD
retval
;
char
curDir
[
256
];
char
destDir
[
256
];
unsigned
int
curDirSizeReq
;
unsigned
int
destDirSizeReq
;
retval
=
0
;
/* Print out debugging information */
TRACE
(
ver
,
"called with parameters:
\n
"
"
\t
flags = %x"
,
flags
);
if
(
flags
&
VFFF_ISSHAREDFILE
)
TRACE
(
ver
,
" (VFFF_ISSHAREDFILE)
\n
"
);
else
TRACE
(
ver
,
"
\n
"
);
ver_dstring
(
"
\t
lpszFilename = "
,
lpszFilename
,
""
);
ver_dstring
(
"
\t
lpszWinDir = "
,
lpszWinDir
,
""
);
ver_dstring
(
"
\t
lpszAppDir = "
,
lpszAppDir
,
""
);
TRACE
(
ver
,
"
\t
lpszCurDir = %p
\n
"
,
lpszCurDir
);
if
(
lpuCurDirLen
)
TRACE
(
ver
,
"
\t
lpuCurDirLen = %p (%u)
\n
"
,
lpuCurDirLen
,
*
lpuCurDirLen
);
else
TRACE
(
ver
,
"
\t
lpuCurDirLen = (null)
\n
"
);
TRACE
(
ver
,
"
\t
lpszDestDir = %p
\n
"
,
lpszDestDir
);
if
(
lpuDestDirLen
)
TRACE
(
ver
,
"
\t
lpuDestDirLen = %p (%u)
\n
"
,
lpuDestDirLen
,
*
lpuDestDirLen
);
/* Figure out where the file should go; shared files default to the
system directory */
strcpy
(
curDir
,
""
);
strcpy
(
destDir
,
""
);
if
(
flags
&
VFFF_ISSHAREDFILE
)
{
GetSystemDirectory32A
(
destDir
,
256
);
/* Were we given a filename? If so, try to find the file. */
if
(
lpszFilename
)
{
if
(
testFileExistence
(
destDir
,
lpszFilename
))
{
strcpy
(
curDir
,
destDir
);
if
(
!
testFileExclusiveExistence
(
destDir
,
lpszFilename
))
retval
|=
VFF_FILEINUSE
;
}
else
if
(
lpszAppDir
&&
testFileExistence
(
lpszAppDir
,
lpszFilename
))
{
strcpy
(
curDir
,
lpszAppDir
);
retval
|=
VFF_CURNEDEST
;
if
(
!
testFileExclusiveExistence
(
lpszAppDir
,
lpszFilename
))
retval
|=
VFF_FILEINUSE
;
}
}
}
else
if
(
!
(
flags
&
VFFF_ISSHAREDFILE
))
{
/* not a shared file */
if
(
lpszAppDir
)
{
char
systemDir
[
256
];
GetSystemDirectory32A
(
systemDir
,
256
);
strcpy
(
destDir
,
lpszAppDir
);
if
(
lpszFilename
)
{
if
(
testFileExistence
(
lpszAppDir
,
lpszFilename
))
{
strcpy
(
curDir
,
lpszAppDir
);
if
(
!
testFileExclusiveExistence
(
lpszAppDir
,
lpszFilename
))
retval
|=
VFF_FILEINUSE
;
}
else
if
(
testFileExistence
(
systemDir
,
lpszFilename
))
{
strcpy
(
curDir
,
systemDir
);
retval
|=
VFF_CURNEDEST
;
if
(
!
testFileExclusiveExistence
(
systemDir
,
lpszFilename
))
retval
|=
VFF_FILEINUSE
;
}
}
}
}
curDirSizeReq
=
strlen
(
curDir
)
+
1
;
destDirSizeReq
=
strlen
(
destDir
)
+
1
;
/* Make sure that the pointers to the size of the buffers are
valid; if not, do NOTHING with that buffer. If that pointer
is valid, then make sure that the buffer pointer is valid, too! */
if
(
lpuDestDirLen
&&
lpszDestDir
)
{
if
(
*
lpuDestDirLen
<
destDirSizeReq
)
{
retval
|=
VFF_BUFFTOOSMALL
;
strncpy
(
lpszDestDir
,
destDir
,
*
lpuDestDirLen
-
1
);
lpszDestDir
[
*
lpuDestDirLen
-
1
]
=
'\0'
;
}
else
strcpy
(
lpszDestDir
,
destDir
);
*
lpuDestDirLen
=
destDirSizeReq
;
}
if
(
lpuCurDirLen
&&
lpszCurDir
)
{
if
(
*
lpuCurDirLen
<
curDirSizeReq
)
{
retval
|=
VFF_BUFFTOOSMALL
;
strncpy
(
lpszCurDir
,
curDir
,
*
lpuCurDirLen
-
1
);
lpszCurDir
[
*
lpuCurDirLen
-
1
]
=
'\0'
;
}
else
strcpy
(
lpszCurDir
,
curDir
);
*
lpuCurDirLen
=
curDirSizeReq
;
}
TRACE
(
ver
,
"ret = %lu (%s%s%s)
\n
"
,
retval
,
(
retval
&
VFF_CURNEDEST
)
?
"VFF_CURNEDEST "
:
""
,
(
retval
&
VFF_FILEINUSE
)
?
"VFF_FILEINUSE "
:
""
,
(
retval
&
VFF_BUFFTOOSMALL
)
?
"VFF_BUFFTOOSMALL "
:
""
);
ver_dstring
(
"
\t
(Exit) lpszCurDir = "
,
lpszCurDir
,
""
);
if
(
lpuCurDirLen
)
TRACE
(
ver
,
"
\t
(Exit) lpuCurDirLen = %p (%u)
\n
"
,
lpuCurDirLen
,
*
lpuCurDirLen
);
else
TRACE
(
ver
,
"
\t
(Exit) lpuCurDirLen = (null)
\n
"
);
ver_dstring
(
"
\t
(Exit) lpszDestDir = "
,
lpszDestDir
,
""
);
if
(
lpuDestDirLen
)
TRACE
(
ver
,
"
\t
(Exit) lpuDestDirLen = %p (%u)
\n
"
,
lpuDestDirLen
,
*
lpuDestDirLen
);
return
retval
;
}
/* VerFindFileA [VERSION.5] */
DWORD
WINAPI
VerFindFile32A
(
UINT32
flags
,
LPCSTR
filename
,
LPCSTR
windir
,
LPCSTR
appdir
,
LPSTR
curdir
,
UINT32
*
pcurdirlen
,
LPSTR
destdir
,
UINT32
*
pdestdirlen
)
{
UINT16
curdirlen
,
destdirlen
;
DWORD
ret
;
curdirlen
=
(
UINT16
)
*
pcurdirlen
;
destdirlen
=
(
UINT16
)
*
pdestdirlen
;
ret
=
VerFindFile16
(
flags
,
filename
,
windir
,
appdir
,
curdir
,
&
curdirlen
,
destdir
,
&
destdirlen
);
*
pcurdirlen
=
curdirlen
;
*
pdestdirlen
=
destdirlen
;
return
ret
;
}
/* VerFindFileW [VERSION.6] */
DWORD
WINAPI
VerFindFile32W
(
UINT32
flags
,
LPCWSTR
filename
,
LPCWSTR
windir
,
LPCWSTR
appdir
,
LPWSTR
curdir
,
UINT32
*
pcurdirlen
,
LPWSTR
destdir
,
UINT32
*
pdestdirlen
)
{
UINT16
curdirlen
,
destdirlen
;
LPSTR
wfn
,
wwd
,
wad
,
wdd
,
wcd
;
DWORD
ret
;
wfn
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
filename
);
wwd
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
windir
);
wad
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
appdir
);
wcd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
*
pcurdirlen
);
wdd
=
HeapAlloc
(
GetProcessHeap
(),
0
,
*
pdestdirlen
);
ret
=
VerFindFile16
(
flags
,
wfn
,
wwd
,
wad
,
wcd
,
&
curdirlen
,
wdd
,
&
destdirlen
);
lstrcpynAtoW
(
curdir
,
wcd
,
*
pcurdirlen
);
lstrcpynAtoW
(
destdir
,
wdd
,
*
pdestdirlen
);
*
pcurdirlen
=
strlen
(
wcd
);
*
pdestdirlen
=
strlen
(
wdd
);
HeapFree
(
GetProcessHeap
(),
0
,
wfn
);
HeapFree
(
GetProcessHeap
(),
0
,
wwd
);
HeapFree
(
GetProcessHeap
(),
0
,
wad
);
HeapFree
(
GetProcessHeap
(),
0
,
wcd
);
HeapFree
(
GetProcessHeap
(),
0
,
wdd
);
return
ret
;
}
/* VerInstallFile [VER.9] */
DWORD
WINAPI
VerInstallFile16
(
UINT16
flags
,
LPCSTR
srcfilename
,
LPCSTR
destfilename
,
LPCSTR
srcdir
,
LPCSTR
destdir
,
LPCSTR
curdir
,
LPSTR
tmpfile
,
UINT16
*
tmpfilelen
)
{
UINT32
filelen
;
DWORD
ret
=
VerInstallFile32A
(
flags
,
srcfilename
,
destfilename
,
srcdir
,
destdir
,
curdir
,
tmpfile
,
&
filelen
);
*
tmpfilelen
=
filelen
;
return
ret
;
}
static
LPBYTE
_fetch_versioninfo
(
LPSTR
fn
,
VS_FIXEDFILEINFO
**
vffi
)
{
DWORD
alloclen
;
LPBYTE
buf
;
DWORD
ret
;
alloclen
=
1000
;
buf
=
xmalloc
(
alloclen
);
while
(
1
)
{
ret
=
GetFileVersionInfo32A
(
fn
,
0
,
alloclen
,
buf
);
if
(
!
ret
)
{
free
(
buf
);
return
0
;
}
if
(
alloclen
<*
(
WORD
*
)
buf
)
{
free
(
buf
);
alloclen
=
*
(
WORD
*
)
buf
;
buf
=
xmalloc
(
alloclen
);
}
else
{
*
vffi
=
(
VS_FIXEDFILEINFO
*
)(
buf
+
0x14
);
if
((
*
vffi
)
->
dwSignature
==
0x004f0049
)
/* hack to detect unicode */
*
vffi
=
(
VS_FIXEDFILEINFO
*
)(
buf
+
0x28
);
if
((
*
vffi
)
->
dwSignature
!=
VS_FFI_SIGNATURE
)
WARN
(
ver
,
"Bad VS_FIXEDFILEINFO signature 0x%08lx
\n
"
,(
*
vffi
)
->
dwSignature
);
return
buf
;
}
}
}
static
DWORD
_error2vif
(
DWORD
error
)
{
switch
(
error
)
{
case
ERROR_ACCESS_DENIED
:
return
VIF_ACCESSVIOLATION
;
case
ERROR_SHARING_VIOLATION
:
return
VIF_SHARINGVIOLATION
;
default:
return
0
;
}
}
/******************************************************************************
* VerInstallFile32A [VERSION.7]
*/
DWORD
WINAPI
VerInstallFile32A
(
UINT32
flags
,
LPCSTR
srcfilename
,
LPCSTR
destfilename
,
LPCSTR
srcdir
,
LPCSTR
destdir
,
LPCSTR
curdir
,
LPSTR
tmpfile
,
UINT32
*
tmpfilelen
)
{
LPCSTR
pdest
;
char
destfn
[
260
],
tmpfn
[
260
],
srcfn
[
260
];
HFILE32
hfsrc
,
hfdst
;
DWORD
attr
,
ret
,
xret
,
tmplast
;
LPBYTE
buf1
,
buf2
;
OFSTRUCT
ofs
;
TRACE
(
ver
,
"(%x,%s,%s,%s,%s,%s,%p,%d)
\n
"
,
flags
,
srcfilename
,
destfilename
,
srcdir
,
destdir
,
curdir
,
tmpfile
,
*
tmpfilelen
);
xret
=
0
;
sprintf
(
srcfn
,
"%s
\\
%s"
,
srcdir
,
srcfilename
);
if
(
!
destdir
||
!*
destdir
)
pdest
=
srcdir
;
else
pdest
=
destdir
;
sprintf
(
destfn
,
"%s
\\
%s"
,
pdest
,
destfilename
);
hfsrc
=
LZOpenFile32A
(
srcfn
,
&
ofs
,
OF_READ
);
if
(
hfsrc
==
HFILE_ERROR32
)
return
VIF_CANNOTREADSRC
;
sprintf
(
tmpfn
,
"%s
\\
%s"
,
pdest
,
destfilename
);
tmplast
=
strlen
(
pdest
)
+
1
;
attr
=
GetFileAttributes32A
(
tmpfn
);
if
(
attr
!=-
1
)
{
if
(
attr
&
FILE_ATTRIBUTE_READONLY
)
{
LZClose32
(
hfsrc
);
return
VIF_WRITEPROT
;
}
/* FIXME: check if file currently in use and return VIF_FILEINUSE */
}
attr
=
-
1
;
if
(
flags
&
VIFF_FORCEINSTALL
)
{
if
(
tmpfile
[
0
])
{
sprintf
(
tmpfn
,
"%s
\\
%s"
,
pdest
,
tmpfile
);
tmplast
=
strlen
(
pdest
)
+
1
;
attr
=
GetFileAttributes32A
(
tmpfn
);
/* if it exists, it has been copied by the call before.
* we jump over the copy part...
*/
}
}
if
(
attr
==
-
1
)
{
char
*
s
;
GetTempFileName32A
(
pdest
,
"ver"
,
0
,
tmpfn
);
/* should not fail ... */
s
=
strrchr
(
tmpfn
,
'\\'
);
if
(
s
)
tmplast
=
s
-
tmpfn
;
else
tmplast
=
0
;
hfdst
=
OpenFile32
(
tmpfn
,
&
ofs
,
OF_CREATE
);
if
(
hfdst
==
HFILE_ERROR32
)
{
LZClose32
(
hfsrc
);
return
VIF_CANNOTCREATE
;
/* | translated dos error */
}
ret
=
LZCopy32
(
hfsrc
,
hfdst
);
_lclose32
(
hfdst
);
if
(((
long
)
ret
)
<
0
)
{
/* translate LZ errors into VIF_xxx */
switch
(
ret
)
{
case
LZERROR_BADINHANDLE
:
case
LZERROR_READ
:
case
LZERROR_BADVALUE
:
case
LZERROR_UNKNOWNALG
:
ret
=
VIF_CANNOTREADSRC
;
break
;
case
LZERROR_BADOUTHANDLE
:
case
LZERROR_WRITE
:
ret
=
VIF_OUTOFMEMORY
;
/* FIXME: correct? */
break
;
case
LZERROR_GLOBALLOC
:
case
LZERROR_GLOBLOCK
:
ret
=
VIF_OUTOFSPACE
;
break
;
default:
/* unknown error, should not happen */
ret
=
0
;
break
;
}
if
(
ret
)
{
LZClose32
(
hfsrc
);
return
ret
;
}
}
}
xret
=
0
;
if
(
!
(
flags
&
VIFF_FORCEINSTALL
))
{
VS_FIXEDFILEINFO
*
destvffi
,
*
tmpvffi
;
buf1
=
_fetch_versioninfo
(
destfn
,
&
destvffi
);
if
(
buf1
)
{
buf2
=
_fetch_versioninfo
(
tmpfn
,
&
tmpvffi
);
if
(
buf2
)
{
char
*
tbuf1
,
*
tbuf2
;
UINT32
len1
,
len2
;
len1
=
len2
=
40
;
/* compare file versions */
if
((
destvffi
->
dwFileVersionMS
>
tmpvffi
->
dwFileVersionMS
)
||
((
destvffi
->
dwFileVersionMS
==
tmpvffi
->
dwFileVersionMS
)
&&
(
destvffi
->
dwFileVersionLS
>
tmpvffi
->
dwFileVersionLS
)
)
)
xret
|=
VIF_MISMATCH
|
VIF_SRCOLD
;
/* compare filetypes and filesubtypes */
if
((
destvffi
->
dwFileType
!=
tmpvffi
->
dwFileType
)
||
(
destvffi
->
dwFileSubtype
!=
tmpvffi
->
dwFileSubtype
)
)
xret
|=
VIF_MISMATCH
|
VIF_DIFFTYPE
;
if
(
VerQueryValue32A
(
buf1
,
"
\\
VarFileInfo
\\
Translation"
,(
LPVOID
*
)
&
tbuf1
,
&
len1
)
&&
VerQueryValue32A
(
buf2
,
"
\\
VarFileInfo
\\
Translation"
,(
LPVOID
*
)
&
tbuf2
,
&
len2
)
)
{
/* irgendwas mit tbuf1 und tbuf2 machen
* generiert DIFFLANG|MISMATCH
*/
}
free
(
buf2
);
}
else
xret
=
VIF_MISMATCH
|
VIF_SRCOLD
;
free
(
buf1
);
}
}
if
(
xret
)
{
if
(
*
tmpfilelen
<
strlen
(
tmpfn
+
tmplast
))
{
xret
|=
VIF_BUFFTOOSMALL
;
DeleteFile32A
(
tmpfn
);
}
else
{
strcpy
(
tmpfile
,
tmpfn
+
tmplast
);
*
tmpfilelen
=
strlen
(
tmpfn
+
tmplast
)
+
1
;
xret
|=
VIF_TEMPFILE
;
}
}
else
{
if
(
-
1
!=
GetFileAttributes32A
(
destfn
))
if
(
!
DeleteFile32A
(
destfn
))
{
xret
|=
_error2vif
(
GetLastError
())
|
VIF_CANNOTDELETE
;
DeleteFile32A
(
tmpfn
);
LZClose32
(
hfsrc
);
return
xret
;
}
if
((
!
(
flags
&
VIFF_DONTDELETEOLD
))
&&
curdir
&&
*
curdir
&&
lstrcmpi32A
(
curdir
,
pdest
)
)
{
char
curfn
[
260
];
sprintf
(
curfn
,
"%s
\\
%s"
,
curdir
,
destfilename
);
if
(
-
1
!=
GetFileAttributes32A
(
curfn
))
{
/* FIXME: check if in use ... if it is, VIF_CANNOTDELETECUR */
if
(
!
DeleteFile32A
(
curfn
))
xret
|=
_error2vif
(
GetLastError
())
|
VIF_CANNOTDELETECUR
;
}
}
if
(
!
MoveFile32A
(
tmpfn
,
destfn
))
{
xret
|=
_error2vif
(
GetLastError
())
|
VIF_CANNOTRENAME
;
DeleteFile32A
(
tmpfn
);
}
}
LZClose32
(
hfsrc
);
return
xret
;
}
/* VerInstallFileW [VERSION.8] */
DWORD
WINAPI
VerInstallFile32W
(
UINT32
flags
,
LPCWSTR
srcfilename
,
LPCWSTR
destfilename
,
LPCWSTR
srcdir
,
LPCWSTR
destdir
,
LPCWSTR
curdir
,
LPWSTR
tmpfile
,
UINT32
*
tmpfilelen
)
{
LPSTR
wsrcf
,
wsrcd
,
wdestf
,
wdestd
,
wtmpf
,
wcurd
;
DWORD
ret
;
wsrcf
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
srcfilename
);
wsrcd
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
srcdir
);
wdestf
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
destfilename
);
wdestd
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
destdir
);
wtmpf
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
tmpfile
);
wcurd
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
curdir
);
ret
=
VerInstallFile32A
(
flags
,
wsrcf
,
wdestf
,
wsrcd
,
wdestd
,
wcurd
,
wtmpf
,
tmpfilelen
);
if
(
!
ret
)
lstrcpynAtoW
(
tmpfile
,
wtmpf
,
*
tmpfilelen
);
HeapFree
(
GetProcessHeap
(),
0
,
wsrcf
);
HeapFree
(
GetProcessHeap
(),
0
,
wsrcd
);
HeapFree
(
GetProcessHeap
(),
0
,
wdestf
);
HeapFree
(
GetProcessHeap
(),
0
,
wdestd
);
HeapFree
(
GetProcessHeap
(),
0
,
wtmpf
);
if
(
wcurd
)
HeapFree
(
GetProcessHeap
(),
0
,
wcurd
);
return
ret
;
}
struct
dbA
{
WORD
nextoff
;
WORD
datalen
;
/* in memory structure... */
char
name
[
1
];
/* padded to dword alignment */
/* ....
char data[datalen]; padded to dword alignment
BYTE subdirdata[]; until nextoff
*/
};
#define DATA_OFFSET_A(db) ((4+(strlen((db)->name)+4))&~3)
struct
dbW
{
WORD
nextoff
;
WORD
datalen
;
WORD
btext
;
/* type of data */
/* in memory structure... */
WCHAR
name
[
1
];
/* padded to dword alignment */
/* ....
WCHAR data[datalen]; padded to dword alignment
BYTE subdirdata[]; until nextoff
*/
};
/* WORD nextoffset;
* WORD datalength;
* WORD btype;
* WCHAR szKey[]; (zero terminated)
* PADDING (round up to nearest 32bit boundary)
*/
#define DATA_OFFSET_W(db) ((2+2+2+((lstrlen32W((db)->name)+1)*2+3))&~3)
/* this one used for Win16 resources, which are always in ASCII format */
static
BYTE
*
_find_dataA
(
BYTE
*
block
,
LPCSTR
str
,
int
buff_remain
)
{
char
*
nextslash
;
int
substrlen
,
inc_size
;
struct
dbA
*
db
;
while
(
*
str
&&
*
str
==
'\\'
)
str
++
;
if
(
NULL
!=
(
nextslash
=
strchr
(
str
,
'\\'
)))
substrlen
=
nextslash
-
str
;
else
substrlen
=
strlen
(
str
);
if
(
nextslash
!=
NULL
)
{
while
(
*
nextslash
&&
*
nextslash
==
'\\'
)
nextslash
++
;
if
(
!*
nextslash
)
nextslash
=
NULL
;
}
else
if
(
*
str
==
0
)
return
NULL
;
while
(
1
)
{
db
=
(
struct
dbA
*
)
block
;
TRACE
(
ver
,
"db=%p,db->nextoff=%d,db->datalen=%d,db->name=%s
\n
"
,
db
,
db
->
nextoff
,
db
->
datalen
,
db
->
name
);
if
((
!
db
->
nextoff
)
||
(
buff_remain
<=
0
))
/* no more entries ? */
return
NULL
;
TRACE
(
ver
,
"comparing with %s
\n
"
,
db
->
name
);
if
(
!
lstrncmpi32A
(
db
->
name
,
str
,
substrlen
))
{
if
(
nextslash
)
{
inc_size
=
DATA_OFFSET_A
(
db
)
+
((
db
->
datalen
+
3
)
&~
3
);
return
_find_dataA
(
block
+
inc_size
,
nextslash
,
db
->
nextoff
-
inc_size
);
}
else
return
block
;
}
inc_size
=
((
db
->
nextoff
+
3
)
&~
3
);
block
+=
inc_size
;
buff_remain
-=
inc_size
;
}
}
/* this one used for Win32 resources, which are always in UNICODE format */
extern
LPWSTR
__cdecl
CRTDLL_wcschr
(
LPCWSTR
str
,
WCHAR
xchar
);
static
BYTE
*
_find_dataW
(
BYTE
*
block
,
LPCWSTR
str
,
int
buff_remain
)
{
LPWSTR
nextslash
;
int
substrlen
,
inc_size
;
struct
dbW
*
db
;
while
(
*
str
&&
*
str
==
'\\'
)
str
++
;
if
(
NULL
!=
(
nextslash
=
CRTDLL_wcschr
(
str
,
'\\'
)))
substrlen
=
nextslash
-
str
;
else
substrlen
=
lstrlen32W
(
str
);
if
(
nextslash
!=
NULL
)
{
while
(
*
nextslash
&&
*
nextslash
==
'\\'
)
nextslash
++
;
if
(
!*
nextslash
)
nextslash
=
NULL
;
}
else
if
(
*
str
==
0
)
return
NULL
;
while
(
1
)
{
char
*
xs
,
*
vs
;
db
=
(
struct
dbW
*
)
block
;
xs
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
db
->
name
);
if
(
db
->
datalen
)
{
if
(
db
->
btext
)
vs
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,(
WCHAR
*
)((
block
+
DATA_OFFSET_W
(
db
))));
else
vs
=
HEAP_strdupA
(
GetProcessHeap
(),
0
,
"not a string"
);
}
else
vs
=
HEAP_strdupA
(
GetProcessHeap
(),
0
,
"no data"
);
TRACE
(
ver
,
"db->nextoff=%d,db->name=%s,db->data=
\"
%s
\"\n
"
,
db
->
nextoff
,
xs
,
vs
);
HeapFree
(
GetProcessHeap
(),
0
,
vs
);
HeapFree
(
GetProcessHeap
(),
0
,
xs
);
if
((
!
db
->
nextoff
)
||
(
buff_remain
<=
0
))
/* no more entries ? */
return
NULL
;
if
(
!
lstrncmpi32W
(
db
->
name
,
str
,
substrlen
))
{
if
(
nextslash
)
{
/* DATA_OFFSET_W(db) (padded to 32bit already)
* DATA[datalength]
* PADDING (round up to nearest 32bit boundary)
* --> next level structs
*/
inc_size
=
DATA_OFFSET_W
(
db
)
+
((
db
->
datalen
+
3
)
&~
3
);
return
_find_dataW
(
block
+
inc_size
,
nextslash
,
db
->
nextoff
-
inc_size
);
}
else
return
block
;
}
/* skip over this block, round up to nearest 32bit boundary */
inc_size
=
((
db
->
nextoff
+
3
)
&~
3
);
block
+=
inc_size
;
buff_remain
-=
inc_size
;
}
}
/* VerQueryValue [VER.11] */
/* take care, 'buffer' is NOT a SEGPTR, it just points to one */
DWORD
WINAPI
VerQueryValue16
(
SEGPTR
segblock
,
LPCSTR
subblock
,
SEGPTR
*
buffer
,
UINT16
*
buflen
)
{
LPSTR
s
;
BYTE
*
block
=
PTR_SEG_TO_LIN
(
segblock
),
*
b
;
TRACE
(
ver
,
"(%p,%s,%p,%d)
\n
"
,
block
,
subblock
,
buffer
,
*
buflen
);
s
=
(
char
*
)
xmalloc
(
strlen
(
"VS_VERSION_INFO
\\
"
)
+
strlen
(
subblock
)
+
1
);
strcpy
(
s
,
"VS_VERSION_INFO
\\
"
);
strcat
(
s
,
subblock
);
/* check for UNICODE version */
if
(
(
*
(
DWORD
*
)(
block
+
0x14
)
!=
VS_FFI_SIGNATURE
)
&&
(
*
(
DWORD
*
)(
block
+
0x28
)
==
VS_FFI_SIGNATURE
)
)
{
struct
dbW
*
db
;
LPWSTR
wstr
;
LPSTR
xs
;
wstr
=
HEAP_strdupAtoW
(
GetProcessHeap
(),
0
,
s
);
b
=
_find_dataW
(
block
,
wstr
,
*
(
WORD
*
)
block
);
HeapFree
(
GetProcessHeap
(),
0
,
wstr
);
if
(
!
b
)
{
WARN
(
ver
,
"key %s not found in versionresource.
\n
"
,
s
);
*
buflen
=
0
;
free
(
s
);
return
0
;
}
db
=
(
struct
dbW
*
)
b
;
b
=
b
+
DATA_OFFSET_W
(
db
);
*
buflen
=
db
->
datalen
;
if
(
db
->
btext
)
{
xs
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,(
WCHAR
*
)
b
);
TRACE
(
ver
,
"->%s
\n
"
,
xs
);
HeapFree
(
GetProcessHeap
(),
0
,
xs
);
}
else
TRACE
(
ver
,
"->%p
\n
"
,
b
);
}
else
{
struct
dbA
*
db
;
b
=
_find_dataA
(
block
,
s
,
*
(
WORD
*
)
block
);
if
(
!
b
)
{
WARN
(
ver
,
"key %s not found in versionresource.
\n
"
,
s
);
*
buflen
=
0
;
free
(
s
);
return
0
;
}
db
=
(
struct
dbA
*
)
b
;
b
=
b
+
DATA_OFFSET_A
(
db
);
*
buflen
=
db
->
datalen
;
/* the string is only printable, if it is below \\StringFileInfo*/
if
(
!
lstrncmpi32A
(
"VS_VERSION_INFO
\\
StringFileInfo
\\
"
,
s
,
strlen
(
"VS_VERSION_INFO
\\
StringFileInfo
\\
"
)))
TRACE
(
ver
,
" -> %s=%s
\n
"
,
subblock
,
b
);
else
TRACE
(
ver
,
" -> %s=%p
\n
"
,
subblock
,
b
);
}
*
buffer
=
(
b
-
block
)
+
segblock
;
free
(
s
);
return
1
;
}
DWORD
WINAPI
VER_VerQueryValueA
(
LPVOID
,
LPCSTR
,
LPVOID
*
,
UINT32
*
,
BOOL32
*
);
DWORD
WINAPI
VER_VerQueryValueW
(
LPVOID
vblock
,
LPCWSTR
subblock
,
LPVOID
*
vbuffer
,
UINT32
*
buflen
,
BOOL32
*
bIsString
)
{
BYTE
*
b
,
*
block
=
(
LPBYTE
)
vblock
,
**
buffer
=
(
LPBYTE
*
)
vbuffer
;
TRACE
(
ver
,
"(%p,%s,%p,%d)
\n
"
,
block
,
debugstr_w
(
subblock
),
buffer
,
*
buflen
);
/* check for UNICODE version */
if
(
(
*
(
DWORD
*
)(
block
+
0x14
)
!=
VS_FFI_SIGNATURE
)
&&
(
*
(
DWORD
*
)(
block
+
0x28
)
==
VS_FFI_SIGNATURE
)
)
{
struct
dbW
*
db
;
LPWSTR
s
;
LPWSTR
vs_version_info
=
HEAP_strdupAtoW
(
GetProcessHeap
(),
0
,
"VS_VERSION_INFO
\\
"
);
s
=
(
LPWSTR
)
xmalloc
(
2
*
lstrlen32W
(
vs_version_info
)
+
2
*
lstrlen32W
(
subblock
)
+
2
);
lstrcpy32W
(
s
,
vs_version_info
);
lstrcat32W
(
s
,
subblock
);
b
=
_find_dataW
(
block
,
s
,
*
(
WORD
*
)
block
);
if
(
!
b
)
{
WARN
(
ver
,
"key %s not found in versionresource.
\n
"
,
debugstr_w
(
s
));
*
buflen
=
0
;
free
(
s
);
return
0
;
}
db
=
(
struct
dbW
*
)
b
;
*
buflen
=
db
->
datalen
;
b
=
b
+
DATA_OFFSET_W
(
db
);
if
(
db
->
btext
)
{
TRACE
(
ver
,
"%s->%s
\n
"
,
debugstr_w
(
subblock
),
debugstr_w
((
LPWSTR
)
b
));
if
(
bIsString
)
*
bIsString
=
TRUE
;
}
else
TRACE
(
ver
,
"%s->%p
\n
"
,
debugstr_w
(
subblock
),
b
);
free
(
s
);
*
buffer
=
b
;
}
else
{
BOOL32
bMyIsString
=
FALSE
,
ret
;
LPSTR
subblock_a
;
if
(
!
bIsString
)
return
FALSE
;
subblock_a
=
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,
subblock
);
ret
=
VER_VerQueryValueA
(
vblock
,
subblock_a
,
vbuffer
,
buflen
,
&
bMyIsString
);
free
(
subblock_a
);
if
(
bMyIsString
)
{
/* This is a leak. */
*
buffer
=
(
LPBYTE
)
HEAP_strdupAtoW
(
GetProcessHeap
(),
0
,
*
buffer
);
}
return
ret
;
}
return
1
;
}
DWORD
WINAPI
VER_VerQueryValueA
(
LPVOID
vblock
,
LPCSTR
subblock
,
LPVOID
*
vbuffer
,
UINT32
*
buflen
,
BOOL32
*
bIsString
)
{
BYTE
*
b
,
*
block
=
(
LPBYTE
)
vblock
,
**
buffer
=
(
LPBYTE
*
)
vbuffer
;
TRACE
(
ver
,
"(%p,%s,%p,%d)
\n
"
,
block
,
subblock
,
buffer
,
*
buflen
);
/* check for UNICODE version */
if
(
(
*
(
DWORD
*
)(
block
+
0x14
)
!=
VS_FFI_SIGNATURE
)
&&
(
*
(
DWORD
*
)(
block
+
0x28
)
==
VS_FFI_SIGNATURE
)
)
{
BOOL32
bMyIsString
=
FALSE
,
ret
;
LPWSTR
subblock_w
;
if
(
!
bIsString
)
return
FALSE
;
subblock_w
=
HEAP_strdupAtoW
(
GetProcessHeap
(),
0
,
subblock
);
ret
=
VER_VerQueryValueW
(
vblock
,
subblock_w
,
vbuffer
,
buflen
,
&
bMyIsString
);
free
(
subblock_w
);
if
(
bMyIsString
)
{
/* This is a leak. */
*
buffer
=
(
LPBYTE
)
HEAP_strdupWtoA
(
GetProcessHeap
(),
0
,(
LPWSTR
)
*
buffer
);
}
return
ret
;
}
else
{
struct
dbA
*
db
;
LPSTR
s
;
s
=
(
char
*
)
xmalloc
(
strlen
(
"VS_VERSION_INFO
\\
"
)
+
strlen
(
subblock
)
+
1
);
strcpy
(
s
,
"VS_VERSION_INFO
\\
"
);
strcat
(
s
,
subblock
);
b
=
_find_dataA
(
block
,
s
,
*
(
WORD
*
)
block
);
if
(
!
b
)
{
WARN
(
ver
,
"key %s not found in versionresource.
\n
"
,
subblock
);
*
buflen
=
0
;
free
(
s
);
return
0
;
}
db
=
(
struct
dbA
*
)
b
;
*
buflen
=
db
->
datalen
;
b
=
b
+
DATA_OFFSET_A
(
db
);
/* the string is only printable, if it is below \\StringFileInfo*/
if
(
!
lstrncmpi32A
(
"VS_VERSION_INFO
\\
StringFileInfo
\\
"
,
s
,
strlen
(
"VS_VERSION_INFO
\\
StringFileInfo
\\
"
)))
{
TRACE
(
ver
,
"%s->%s
\n
"
,
subblock
,
b
);
if
(
bIsString
)
*
bIsString
=
TRUE
;
}
else
TRACE
(
ver
,
"%s->%p
\n
"
,
subblock
,
b
);
free
(
s
);
*
buffer
=
b
;
}
return
TRUE
;
}
DWORD
WINAPI
VerQueryValue32A
(
LPVOID
vblock
,
LPCSTR
subblock
,
LPVOID
*
vbuffer
,
UINT32
*
buflen
)
{
return
VER_VerQueryValueA
(
vblock
,
subblock
,
vbuffer
,
buflen
,
NULL
);
}
DWORD
WINAPI
VerQueryValue32W
(
LPVOID
vblock
,
LPCWSTR
subblock
,
LPVOID
*
vbuffer
,
UINT32
*
buflen
)
{
return
VER_VerQueryValueW
(
vblock
,
subblock
,
vbuffer
,
buflen
,
NULL
);
}
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