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
f624b48f
Commit
f624b48f
authored
19 years ago
by
Alexandre Julliard
Browse files
Options
Downloads
Patches
Plain Diff
Split the module building functionality of NE_LoadExeHeader into
separate functions.
parent
d5bfaf78
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/kernel/ne_module.c
+230
-247
230 additions, 247 deletions
dlls/kernel/ne_module.c
with
230 additions
and
247 deletions
dlls/kernel/ne_module.c
+
230
−
247
View file @
f624b48f
...
...
@@ -387,16 +387,20 @@ void NE_WalkModules(void)
*
* Fill in 'resloader' fields in the resource table.
*/
static
void
NE_InitResourceHandler
(
NE_
MODULE
*
p
Module
)
static
void
NE_InitResourceHandler
(
H
MODULE
16
h
Module
)
{
static
FARPROC16
proc
;
NE_TYPEINFO
*
pTypeInfo
=
(
NE_TYPEINFO
*
)((
char
*
)
pModule
+
pModule
->
ne_rsrctab
+
2
);
NE_TYPEINFO
*
pTypeInfo
;
NE_MODULE
*
pModule
;
if
(
!
(
pModule
=
NE_GetPtr
(
hModule
))
||
!
pModule
->
ne_rsrctab
)
return
;
TRACE
(
"InitResourceHandler[%04x]
\n
"
,
p
Module
->
self
);
TRACE
(
"InitResourceHandler[%04x]
\n
"
,
h
Module
);
if
(
!
proc
)
proc
=
GetProcAddress16
(
GetModuleHandle16
(
"KERNEL"
),
"DefResourceHandler"
);
pTypeInfo
=
(
NE_TYPEINFO
*
)((
char
*
)
pModule
+
pModule
->
ne_rsrctab
+
2
);
while
(
pTypeInfo
->
type_id
)
{
memcpy_unaligned
(
&
pTypeInfo
->
resloader
,
&
proc
,
sizeof
(
FARPROC16
)
);
...
...
@@ -602,69 +606,114 @@ static BOOL read_data( HANDLE handle, LONG offset, void *buffer, DWORD size )
return
(
result
==
size
);
}
/***********************************************************************
* NE_LoadExeHeader
* build_bundle_data
*
* Build the entry table bundle data from the on-disk format. Helper for build_module.
*/
static
HMODULE16
NE_LoadExeHeader
(
HANDLE
handle
,
LPCSTR
path
)
static
void
*
build_bundle_data
(
NE_MODULE
*
pModule
,
void
*
dest
,
const
BYTE
*
table
)
{
IMAGE_DOS_HEADER
mz_header
;
IMAGE_OS2_HEADER
ne_header
;
int
size
;
ET_BUNDLE
*
oldbundle
,
*
bundle
=
dest
;
ET_ENTRY
*
entry
;
BYTE
nr_entries
,
type
;
memset
(
bundle
,
0
,
sizeof
(
ET_BUNDLE
));
/* in case no entry table exists */
entry
=
(
ET_ENTRY
*
)((
BYTE
*
)
bundle
+
6
);
while
((
nr_entries
=
*
table
++
))
{
if
((
type
=
*
table
++
))
{
bundle
->
last
+=
nr_entries
;
if
(
type
==
0xff
)
{
while
(
nr_entries
--
)
{
entry
->
type
=
type
;
entry
->
flags
=
*
table
++
;
table
+=
sizeof
(
WORD
);
entry
->
segnum
=
*
table
++
;
entry
->
offs
=
*
(
WORD
*
)
table
;
table
+=
sizeof
(
WORD
);
entry
++
;
}
}
else
{
while
(
nr_entries
--
)
{
entry
->
type
=
type
;
entry
->
flags
=
*
table
++
;
entry
->
segnum
=
type
;
entry
->
offs
=
*
(
WORD
*
)
table
;
table
+=
sizeof
(
WORD
);
entry
++
;
}
}
}
else
{
if
(
bundle
->
first
==
bundle
->
last
)
{
bundle
->
first
+=
nr_entries
;
bundle
->
last
+=
nr_entries
;
}
else
{
oldbundle
=
bundle
;
oldbundle
->
next
=
(
char
*
)
entry
-
(
char
*
)
pModule
;
bundle
=
(
ET_BUNDLE
*
)
entry
;
bundle
->
first
=
bundle
->
last
=
oldbundle
->
last
+
nr_entries
;
bundle
->
next
=
0
;
entry
=
(
ET_ENTRY
*
)(((
BYTE
*
)
entry
)
+
sizeof
(
ET_BUNDLE
));
}
}
}
return
entry
;
}
/***********************************************************************
* build_module
*
* Build the in-memory module from the on-disk data.
*/
static
HMODULE16
build_module
(
const
IMAGE_DOS_HEADER
*
mz_header
,
const
IMAGE_OS2_HEADER
*
ne_header
,
HANDLE
handle
,
LPCSTR
path
,
const
void
*
fastload
,
unsigned
int
fastload_offset
,
unsigned
int
fastload_length
)
{
int
i
;
size_t
size
;
HMODULE16
hModule
;
NE_MODULE
*
pModule
;
BYTE
*
pData
,
*
pTempEntryTable
;
char
*
buffer
,
*
fastload
=
NULL
;
unsigned
int
fastload_offset
=
0
,
fastload_length
=
0
;
ET_ENTRY
*
entry
;
ET_BUNDLE
*
bundle
,
*
oldbundle
;
BYTE
*
buffer
,
*
pData
,
*
ptr
;
OFSTRUCT
*
ofs
;
struct
ne_segment_table_entry_s
*
pSeg
;
/* Read a block from either the file or the fast-load area. */
#define READ(offset,size,buffer) \
((fastload && ((offset) >= fastload_offset) && \
((offset)+(size) <= fastload_offset+fastload_length)) ? \
(memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
read_data( handle, (offset), (buffer), (size)))
if
(
!
read_data
(
handle
,
0
,
&
mz_header
,
sizeof
(
mz_header
))
||
(
mz_header
.
e_magic
!=
IMAGE_DOS_SIGNATURE
))
return
ERROR_BAD_FORMAT
;
if
(
!
read_data
(
handle
,
mz_header
.
e_lfanew
,
&
ne_header
,
sizeof
(
ne_header
)
))
return
ERROR_BAD_FORMAT
;
if
(
ne_header
.
ne_magic
==
IMAGE_NT_SIGNATURE
)
return
(
HMODULE16
)
21
;
/* win32 exe */
if
(
ne_header
.
ne_magic
==
IMAGE_OS2_SIGNATURE_LX
)
{
MESSAGE
(
"Sorry, this is an OS/2 linear executable (LX) file!
\n
"
);
return
(
HMODULE16
)
12
;
}
if
(
ne_header
.
ne_magic
!=
IMAGE_OS2_SIGNATURE
)
return
ERROR_BAD_FORMAT
;
/* We now have a valid NE header */
/* check to be able to fall back to loading OS/2 programs as DOS
* FIXME: should this check be reversed in order to be less strict?
* (only fail for OS/2 ne_exetyp 0x01 here?) */
if
((
ne_header
.
ne_exetyp
!=
0x02
/* Windows */
)
&&
(
ne_header
.
ne_exetyp
!=
0x04
)
/* Windows 386 */
)
return
ERROR_BAD_FORMAT
;
(memcpy( buffer, (const char *)fastload+(offset)-fastload_offset, (size) ), TRUE) : \
(handle && read_data( handle, (offset), (buffer), (size))))
size
=
sizeof
(
NE_MODULE
)
+
/* segment table */
ne_header
.
ne_cseg
*
sizeof
(
SEGTABLEENTRY
)
+
ne_header
->
ne_cseg
*
sizeof
(
SEGTABLEENTRY
)
+
/* resource table */
ne_header
.
ne_restab
-
ne_header
.
ne_rsrctab
+
ne_header
->
ne_restab
-
ne_header
->
ne_rsrctab
+
/* resident names table */
ne_header
.
ne_modtab
-
ne_header
.
ne_restab
+
ne_header
->
ne_modtab
-
ne_header
->
ne_restab
+
/* module ref table */
ne_header
.
ne_cmod
*
sizeof
(
WORD
)
+
ne_header
->
ne_cmod
*
sizeof
(
WORD
)
+
/* imported names table */
ne_header
.
ne_enttab
-
ne_header
.
ne_imptab
+
ne_header
->
ne_enttab
-
ne_header
->
ne_imptab
+
/* entry table length */
ne_header
.
ne_cbenttab
+
ne_header
->
ne_cbenttab
+
/* entry table extra conversion space */
sizeof
(
ET_BUNDLE
)
+
2
*
(
ne_header
.
ne_cbenttab
-
ne_header
.
ne_cmovent
*
6
)
+
2
*
(
ne_header
->
ne_cbenttab
-
ne_header
->
ne_cmovent
*
6
)
+
/* loaded file info */
sizeof
(
OFSTRUCT
)
-
sizeof
(
ofs
->
szPathName
)
+
strlen
(
path
)
+
1
;
...
...
@@ -673,11 +722,10 @@ static HMODULE16 NE_LoadExeHeader( HANDLE handle, LPCSTR path )
FarSetOwner16
(
hModule
,
hModule
);
pModule
=
(
NE_MODULE
*
)
GlobalLock16
(
hModule
);
memcpy
(
pModule
,
&
ne_header
,
sizeof
(
ne_header
)
);
memcpy
(
pModule
,
ne_header
,
sizeof
(
*
ne_header
)
);
pModule
->
count
=
0
;
/* check *programs* for default minimal stack size */
if
(
(
!
(
pModule
->
ne_flags
&
NE_FFLAGS_LIBMODULE
))
&&
(
pModule
->
ne_stack
<
0x1400
)
)
/* check programs for default minimal stack size */
if
(
!
(
pModule
->
ne_flags
&
NE_FFLAGS_LIBMODULE
)
&&
(
pModule
->
ne_stack
<
0x1400
))
pModule
->
ne_stack
=
0x1400
;
pModule
->
module32
=
0
;
pModule
->
self
=
hModule
;
...
...
@@ -688,235 +736,101 @@ static HMODULE16 NE_LoadExeHeader( HANDLE handle, LPCSTR path )
pModule
->
ne_flags
&=
~
(
NE_FFLAGS_BUILTIN
|
NE_FFLAGS_WIN32
);
/*
Read the fast-load area
*/
/*
allocate temporary buffer for segment and entry tables
*/
if
(
ne_header
.
ne_flagsothers
&
NE_AFLAGS_FASTLOAD
)
{
fastload_offset
=
ne_header
.
ne_pretthunks
<<
ne_header
.
ne_align
;
fastload_length
=
ne_header
.
ne_psegrefbytes
<<
ne_header
.
ne_align
;
TRACE
(
"Using fast-load area offset=%x len=%d
\n
"
,
fastload_offset
,
fastload_length
);
if
((
fastload
=
HeapAlloc
(
GetProcessHeap
(),
0
,
fastload_length
))
!=
NULL
)
{
if
(
!
read_data
(
handle
,
fastload_offset
,
fastload
,
fastload_length
))
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
WARN
(
"Error reading fast-load area!
\n
"
);
fastload
=
NULL
;
}
}
}
if
(
!
(
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
max
(
ne_header
->
ne_cseg
*
sizeof
(
*
pSeg
),
ne_header
->
ne_cbenttab
)
)))
goto
failed
;
/* Get the segment table */
pModule
->
ne_segtab
=
pData
-
(
BYTE
*
)
pModule
;
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ne_header
.
ne_cseg
*
sizeof
(
struct
ne_segment_table_entry_s
));
if
(
buffer
)
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_segtab
,
ne_header
->
ne_cseg
*
sizeof
(
struct
ne_segment_table_entry_s
),
buffer
))
goto
failed
;
pSeg
=
(
struct
ne_segment_table_entry_s
*
)
buffer
;
for
(
i
=
ne_header
->
ne_cseg
;
i
>
0
;
i
--
,
pSeg
++
)
{
int
i
;
struct
ne_segment_table_entry_s
*
pSeg
;
if
(
!
READ
(
mz_header
.
e_lfanew
+
ne_header
.
ne_segtab
,
ne_header
.
ne_cseg
*
sizeof
(
struct
ne_segment_table_entry_s
),
buffer
))
{
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
}
pSeg
=
(
struct
ne_segment_table_entry_s
*
)
buffer
;
for
(
i
=
ne_header
.
ne_cseg
;
i
>
0
;
i
--
,
pSeg
++
)
{
memcpy
(
pData
,
pSeg
,
sizeof
(
*
pSeg
)
);
pData
+=
sizeof
(
SEGTABLEENTRY
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
}
else
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
memcpy
(
pData
,
pSeg
,
sizeof
(
*
pSeg
)
);
pData
+=
sizeof
(
SEGTABLEENTRY
);
}
/* Get the resource table */
if
(
ne_header
.
ne_rsrctab
<
ne_header
.
ne_restab
)
if
(
ne_header
->
ne_rsrctab
<
ne_header
->
ne_restab
)
{
pModule
->
ne_rsrctab
=
pData
-
(
BYTE
*
)
pModule
;
if
(
!
READ
(
mz_header
.
e_lfanew
+
ne_header
.
ne_rsrctab
,
ne_header
.
ne_restab
-
ne_header
.
ne_rsrctab
,
pData
))
return
ERROR_BAD_FORMAT
;
pData
+=
ne_header
.
ne_restab
-
ne_header
.
ne_rsrctab
;
NE_InitResourceHandler
(
pModule
);
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_rsrctab
,
ne_header
->
ne_restab
-
ne_header
->
ne_rsrctab
,
pData
))
goto
failed
;
pData
+=
ne_header
->
ne_restab
-
ne_header
->
ne_rsrctab
;
}
else
pModule
->
ne_rsrctab
=
0
;
/* No resource table */
/* Get the resident names table */
pModule
->
ne_restab
=
pData
-
(
BYTE
*
)
pModule
;
if
(
!
READ
(
mz_header
.
e_lfanew
+
ne_header
.
ne_restab
,
ne_header
.
ne_modtab
-
ne_header
.
ne_restab
,
pData
))
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
}
pData
+=
ne_header
.
ne_modtab
-
ne_header
.
ne_restab
;
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_restab
,
ne_header
->
ne_modtab
-
ne_header
->
ne_restab
,
pData
))
goto
failed
;
pData
+=
ne_header
->
ne_modtab
-
ne_header
->
ne_restab
;
/* Get the module references table */
if
(
ne_header
.
ne_cmod
>
0
)
if
(
ne_header
->
ne_cmod
>
0
)
{
pModule
->
ne_modtab
=
pData
-
(
BYTE
*
)
pModule
;
if
(
!
READ
(
mz_header
.
e_lfanew
+
ne_header
.
ne_modtab
,
ne_header
.
ne_cmod
*
sizeof
(
WORD
),
pData
))
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
}
pData
+=
ne_header
.
ne_cmod
*
sizeof
(
WORD
);
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_modtab
,
ne_header
->
ne_cmod
*
sizeof
(
WORD
),
pData
))
goto
failed
;
pData
+=
ne_header
->
ne_cmod
*
sizeof
(
WORD
);
}
else
pModule
->
ne_modtab
=
0
;
/* No module references */
/* Get the imported names table */
pModule
->
ne_imptab
=
pData
-
(
BYTE
*
)
pModule
;
if
(
!
READ
(
mz_header
.
e_lfanew
+
ne_header
.
ne_imptab
,
ne_header
.
ne_enttab
-
ne_header
.
ne_imptab
,
pData
))
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
}
pData
+=
ne_header
.
ne_enttab
-
ne_header
.
ne_imptab
;
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_imptab
,
ne_header
->
ne_enttab
-
ne_header
->
ne_imptab
,
pData
))
goto
failed
;
pData
+=
ne_header
->
ne_enttab
-
ne_header
->
ne_imptab
;
/* Load entry table, convert it to the optimized version used by Windows */
if
((
pTempEntryTable
=
HeapAlloc
(
GetProcessHeap
(),
0
,
ne_header
.
ne_
cb
enttab
))
!=
NULL
)
{
BYTE
nr_entries
,
type
,
*
s
;
pModule
->
ne_enttab
=
pData
-
(
BYTE
*
)
pModule
;
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_enttab
,
ne_header
->
ne_cbenttab
,
buffer
))
goto
failed
;
TRACE
(
"Converting entry table.
\n
"
);
pModule
->
ne_enttab
=
pData
-
(
BYTE
*
)
pModule
;
if
(
!
READ
(
mz_header
.
e_lfanew
+
ne_header
.
ne_enttab
,
ne_header
.
ne_cbenttab
,
pTempEntryTable
))
{
HeapFree
(
GetProcessHeap
(),
0
,
pTempEntryTable
);
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
}
ptr
=
build_bundle_data
(
pModule
,
pData
,
buffer
);
s
=
pTempEntryTable
;
TRACE
(
"entry table: offs %04x, len %04x, entries %d
\n
"
,
ne_header
.
ne_enttab
,
ne_header
.
ne_c
benttab
,
*
s
);
pData
+=
ne_header
->
ne_cbenttab
+
sizeof
(
ET_BUNDLE
)
+
2
*
(
ne_header
->
ne_
cb
enttab
-
ne_header
->
ne_c
movent
*
6
);
bundle
=
(
ET_BUNDLE
*
)
pData
;
TRACE
(
"first bundle: %p
\n
"
,
bundle
);
memset
(
bundle
,
0
,
sizeof
(
ET_BUNDLE
));
/* in case no entry table exists */
entry
=
(
ET_ENTRY
*
)((
BYTE
*
)
bundle
+
6
);
while
((
nr_entries
=
*
s
++
))
{
if
((
type
=
*
s
++
))
{
bundle
->
last
+=
nr_entries
;
if
(
type
==
0xff
)
while
(
nr_entries
--
)
{
entry
->
type
=
type
;
entry
->
flags
=
*
s
++
;
s
+=
2
;
entry
->
segnum
=
*
s
++
;
entry
->
offs
=
*
(
WORD
*
)
s
;
s
+=
2
;
/*TRACE(module, "entry: %p, type: %d, flags: %d, segnum: %d, offs: %04x\n", entry, entry->type, entry->flags, entry->segnum, entry->offs);*/
entry
++
;
}
else
while
(
nr_entries
--
)
{
entry
->
type
=
type
;
entry
->
flags
=
*
s
++
;
entry
->
segnum
=
type
;
entry
->
offs
=
*
(
WORD
*
)
s
;
s
+=
2
;
/*TRACE(module, "entry: %p, type: %d, flags: %d, segnum: %d, offs: %04x\n", entry, entry->type, entry->flags, entry->segnum, entry->offs);*/
entry
++
;
}
}
else
{
if
(
bundle
->
first
==
bundle
->
last
)
{
bundle
->
first
+=
nr_entries
;
bundle
->
last
+=
nr_entries
;
}
else
{
oldbundle
=
bundle
;
oldbundle
->
next
=
((
int
)
entry
-
(
int
)
pModule
);
bundle
=
(
ET_BUNDLE
*
)
entry
;
TRACE
(
"new bundle: %p
\n
"
,
bundle
);
bundle
->
first
=
bundle
->
last
=
oldbundle
->
last
+
nr_entries
;
bundle
->
next
=
0
;
entry
=
(
ET_ENTRY
*
)(((
BYTE
*
)
entry
)
+
sizeof
(
ET_BUNDLE
));
}
}
}
HeapFree
(
GetProcessHeap
(),
0
,
pTempEntryTable
);
}
else
if
(
ptr
>
pData
)
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
FIXME
(
"not enough space for entry table for %s
\n
"
,
debugstr_a
(
path
)
);
goto
failed
;
}
pData
+=
ne_header
.
ne_cbenttab
+
sizeof
(
ET_BUNDLE
)
+
2
*
(
ne_header
.
ne_cbenttab
-
ne_header
.
ne_cmovent
*
6
);
if
((
DWORD
)
entry
>
(
DWORD
)
pData
)
ERR
(
"converted entry table bigger than reserved space !!!
\n
entry: %p, pData: %p. Please report !
\n
"
,
entry
,
pData
);
/* Store the filename information */
pModule
->
fileinfo
=
pData
-
(
BYTE
*
)
pModule
;
size
=
sizeof
(
OFSTRUCT
)
-
sizeof
(
ofs
->
szPathName
)
+
strlen
(
path
)
+
1
;
ofs
=
(
OFSTRUCT
*
)
pData
;
ofs
->
cBytes
=
size
-
1
;
ofs
->
cBytes
=
size
of
(
OFSTRUCT
)
-
sizeof
(
ofs
->
szPathName
)
+
strlen
(
path
)
;
ofs
->
fFixedDisk
=
1
;
strcpy
(
ofs
->
szPathName
,
path
);
pData
+=
size
;
/* Free the fast-load area */
#undef READ
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
pData
+=
ofs
->
cBytes
+
1
;
assert
(
(
BYTE
*
)
pModule
+
size
<=
pData
);
/* Get the non-resident names table */
if
(
ne_header
.
ne_cbnrestab
)
if
(
ne_header
->
ne_cbnrestab
)
{
pModule
->
nrname_handle
=
GlobalAlloc16
(
0
,
ne_header
.
ne_cbnrestab
);
if
(
!
pModule
->
nrname_handle
)
{
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
}
pModule
->
nrname_handle
=
GlobalAlloc16
(
0
,
ne_header
->
ne_cbnrestab
);
if
(
!
pModule
->
nrname_handle
)
goto
failed
;
FarSetOwner16
(
pModule
->
nrname_handle
,
hModule
);
buffe
r
=
GlobalLock16
(
pModule
->
nrname_handle
);
if
(
!
read_data
(
handle
,
ne_header
.
ne_nrestab
,
buffe
r
,
ne_header
.
ne_cbnrestab
))
pt
r
=
GlobalLock16
(
pModule
->
nrname_handle
);
if
(
!
read_data
(
handle
,
ne_header
->
ne_nrestab
,
pt
r
,
ne_header
->
ne_cbnrestab
))
{
GlobalFree16
(
pModule
->
nrname_handle
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
goto
failed
;
}
}
else
pModule
->
nrname_handle
=
0
;
...
...
@@ -930,15 +844,97 @@ static HMODULE16 NE_LoadExeHeader( HANDLE handle, LPCSTR path )
if
(
!
pModule
->
dlls_to_init
)
{
if
(
pModule
->
nrname_handle
)
GlobalFree16
(
pModule
->
nrname_handle
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
goto
failed
;
}
FarSetOwner16
(
pModule
->
dlls_to_init
,
hModule
);
}
else
pModule
->
dlls_to_init
=
0
;
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
NE_RegisterModule
(
pModule
);
SNOOP16_RegisterDLL
(
hModule
,
path
);
if
(
handle
)
{
UINT
drive_type
=
GetDriveTypeA
(
path
);
/* keep the file handle open if not on a removable media */
if
(
drive_type
!=
DRIVE_REMOVABLE
&&
drive_type
!=
DRIVE_CDROM
)
DuplicateHandle
(
GetCurrentProcess
(),
handle
,
GetCurrentProcess
(),
&
pModule
->
fd
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
);
}
return
hModule
;
failed:
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
GlobalFree16
(
hModule
);
return
ERROR_BAD_FORMAT
;
#undef READ
}
/***********************************************************************
* NE_LoadExeHeader
*/
static
HMODULE16
NE_LoadExeHeader
(
HANDLE
handle
,
LPCSTR
path
)
{
IMAGE_DOS_HEADER
mz_header
;
IMAGE_OS2_HEADER
ne_header
;
HMODULE16
hModule
;
char
*
fastload
=
NULL
;
unsigned
int
fastload_offset
=
0
,
fastload_length
=
0
;
if
(
!
read_data
(
handle
,
0
,
&
mz_header
,
sizeof
(
mz_header
))
||
(
mz_header
.
e_magic
!=
IMAGE_DOS_SIGNATURE
))
return
ERROR_BAD_FORMAT
;
if
(
!
read_data
(
handle
,
mz_header
.
e_lfanew
,
&
ne_header
,
sizeof
(
ne_header
)
))
return
ERROR_BAD_FORMAT
;
if
(
ne_header
.
ne_magic
==
IMAGE_NT_SIGNATURE
)
return
(
HMODULE16
)
21
;
/* win32 exe */
if
(
ne_header
.
ne_magic
==
IMAGE_OS2_SIGNATURE_LX
)
{
MESSAGE
(
"Sorry, this is an OS/2 linear executable (LX) file!
\n
"
);
return
(
HMODULE16
)
12
;
}
if
(
ne_header
.
ne_magic
!=
IMAGE_OS2_SIGNATURE
)
return
ERROR_BAD_FORMAT
;
/* We now have a valid NE header */
/* check to be able to fall back to loading OS/2 programs as DOS
* FIXME: should this check be reversed in order to be less strict?
* (only fail for OS/2 ne_exetyp 0x01 here?) */
if
((
ne_header
.
ne_exetyp
!=
0x02
/* Windows */
)
&&
(
ne_header
.
ne_exetyp
!=
0x04
)
/* Windows 386 */
)
return
ERROR_BAD_FORMAT
;
/* Read the fast-load area */
if
(
ne_header
.
ne_flagsothers
&
NE_AFLAGS_FASTLOAD
)
{
fastload_offset
=
ne_header
.
ne_pretthunks
<<
ne_header
.
ne_align
;
fastload_length
=
ne_header
.
ne_psegrefbytes
<<
ne_header
.
ne_align
;
TRACE
(
"Using fast-load area offset=%x len=%d
\n
"
,
fastload_offset
,
fastload_length
);
if
((
fastload
=
HeapAlloc
(
GetProcessHeap
(),
0
,
fastload_length
))
!=
NULL
)
{
if
(
!
read_data
(
handle
,
fastload_offset
,
fastload
,
fastload_length
))
{
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
WARN
(
"Error reading fast-load area!
\n
"
);
fastload
=
NULL
;
}
}
}
hModule
=
build_module
(
&
mz_header
,
&
ne_header
,
handle
,
path
,
fastload
,
fastload_offset
,
fastload_length
);
HeapFree
(
GetProcessHeap
(),
0
,
fastload
);
if
(
hModule
>=
32
)
{
SNOOP16_RegisterDLL
(
hModule
,
path
);
NE_InitResourceHandler
(
hModule
);
}
return
hModule
;
}
...
...
@@ -1049,29 +1045,16 @@ static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only )
HINSTANCE16
hInstance
;
HFILE16
hFile
;
OFSTRUCT
ofs
;
UINT
drive_type
;
/* Open file */
if
((
hFile
=
OpenFile16
(
name
,
&
ofs
,
OF_READ
|
OF_SHARE_DENY_WRITE
))
==
HFILE_ERROR16
)
return
ERROR_FILE_NOT_FOUND
;
hModule
=
NE_LoadExeHeader
(
DosFileHandleToWin32Handle
(
hFile
),
ofs
.
szPathName
);
if
(
hModule
<
32
)
{
_lclose16
(
hFile
);
return
hModule
;
}
pModule
=
NE_GetPtr
(
hModule
);
drive_type
=
GetDriveTypeA
(
ofs
.
szPathName
);
if
(
drive_type
!=
DRIVE_REMOVABLE
&&
drive_type
!=
DRIVE_CDROM
)
{
/* keep the file handle open if not on a removable media */
DuplicateHandle
(
GetCurrentProcess
(),
DosFileHandleToWin32Handle
(
hFile
),
GetCurrentProcess
(),
&
pModule
->
fd
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
);
}
_lclose16
(
hFile
);
if
(
hModule
<
32
)
return
hModule
;
pModule
=
NE_GetPtr
(
hModule
);
if
(
!
lib_only
&&
!
(
pModule
->
ne_flags
&
NE_FFLAGS_LIBMODULE
)
)
return
hModule
;
...
...
@@ -1147,7 +1130,7 @@ static HMODULE16 NE_DoLoadBuiltinModule( const BUILTIN16_DESCRIPTOR *descr )
if
(
pModule
->
ne_heap
)
LocalInit16
(
GlobalHandleToSel16
(
pSegTable
->
hSeg
),
pSegTable
->
minsize
,
minsize
);
if
(
descr
->
rsrc
)
NE_InitResourceHandler
(
p
Module
);
NE_InitResourceHandler
(
h
Module
);
NE_RegisterModule
(
pModule
);
...
...
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