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
f624b48f
Commit
f624b48f
authored
May 18, 2005
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Split the module building functionality of NE_LoadExeHeader into
separate functions.
parent
d5bfaf78
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
225 additions
and
242 deletions
+225
-242
ne_module.c
dlls/kernel/ne_module.c
+225
-242
No files found.
dlls/kernel/ne_module.c
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
(
HMODULE16
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
"
,
pModule
->
self
);
TRACE
(
"InitResourceHandler[%04x]
\n
"
,
hModule
);
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
)
{
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
;
}
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
++
)
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
;
}
/* 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_cbenttab
))
!=
NULL
)
{
BYTE
nr_entries
,
type
,
*
s
;
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
;
}
if
(
!
READ
(
mz_header
->
e_lfanew
+
ne_header
->
ne_enttab
,
ne_header
->
ne_cbenttab
,
buffer
))
goto
failed
;
s
=
pTempEntryTable
;
TRACE
(
"entry table: offs %04x, len %04x, entries %d
\n
"
,
ne_header
.
ne_enttab
,
ne_header
.
ne_cbenttab
,
*
s
);
ptr
=
build_bundle_data
(
pModule
,
pData
,
buffer
);
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
);
pData
+=
ne_header
->
ne_cbenttab
+
sizeof
(
ET_BUNDLE
)
+
2
*
(
ne_header
->
ne_cbenttab
-
ne_header
->
ne_cmovent
*
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
if
(
ptr
>
pData
)
{
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
{
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
)
{
pModule
->
nrname_handle
=
GlobalAlloc16
(
0
,
ne_header
.
ne_cbnrestab
);
if
(
!
pModule
->
nrname_handle
)
if
(
ne_header
->
ne_cbnrestab
)
{
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
,
buffer
,
ne_header
.
ne_cbnrestab
))
pt
r
=
GlobalLock16
(
pModule
->
nrname_handle
);
if
(
!
read_data
(
handle
,
ne_header
->
ne_nrestab
,
ptr
,
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
);
if
(
hModule
<
32
)
return
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
);
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
(
pModule
);
NE_InitResourceHandler
(
hModule
);
NE_RegisterModule
(
pModule
);
...
...
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