4 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
22 #include "registers.h"
23 #include "stackframe.h"
31 extern HINSTANCE16
PE_LoadModule( int fd
, OFSTRUCT
*ofs
, LOADPARAMS
* params
);
33 static HMODULE16 hFirstModule
= 0;
34 static HMODULE16 hCachedModule
= 0; /* Module cached by MODULE_OpenFile */
37 static HGLOBAL16 hInitialStack32
= 0;
41 /***********************************************************************
44 NE_MODULE
*MODULE_GetPtr( HMODULE16 hModule
)
46 NE_MODULE
*pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
47 if (!pModule
|| (pModule
->magic
!= NE_SIGNATURE
) ||
48 (pModule
->self
!= hModule
)) return NULL
;
53 /***********************************************************************
56 void MODULE_DumpModule( HMODULE16 hmodule
)
64 if (!(pModule
= MODULE_GetPtr( hmodule
)))
66 fprintf( stderr
, "**** %04x is not a module handle\n", hmodule
);
70 /* Dump the module info */
72 printf( "Module %04x:\n", hmodule
);
73 printf( "count=%d flags=%04x heap=%d stack=%d\n",
74 pModule
->count
, pModule
->flags
,
75 pModule
->heap_size
, pModule
->stack_size
);
76 printf( "cs:ip=%04x:%04x ss:sp=%04x:%04x ds=%04x nb seg=%d modrefs=%d\n",
77 pModule
->cs
, pModule
->ip
, pModule
->ss
, pModule
->sp
, pModule
->dgroup
,
78 pModule
->seg_count
, pModule
->modref_count
);
79 printf( "os_flags=%d swap_area=%d version=%04x\n",
80 pModule
->os_flags
, pModule
->min_swap_area
,
81 pModule
->expected_version
);
82 if (pModule
->flags
& NE_FFLAGS_WIN32
)
83 printf( "PE module=%08x\n", (unsigned int)pModule
->pe_module
);
85 /* Dump the file info */
87 printf( "Filename: '%s'\n", NE_MODULE_NAME(pModule
) );
89 /* Dump the segment table */
91 printf( "\nSegment table:\n" );
92 pSeg
= NE_SEG_TABLE( pModule
);
93 for (i
= 0; i
< pModule
->seg_count
; i
++, pSeg
++)
94 printf( "%02x: pos=%d size=%d flags=%04x minsize=%d sel=%04x\n",
95 i
+ 1, pSeg
->filepos
, pSeg
->size
, pSeg
->flags
,
96 pSeg
->minsize
, pSeg
->selector
);
98 /* Dump the resource table */
100 printf( "\nResource table:\n" );
101 if (pModule
->res_table
)
103 pword
= (WORD
*)((BYTE
*)pModule
+ pModule
->res_table
);
104 printf( "Alignment: %d\n", *pword
++ );
107 struct resource_typeinfo_s
*ptr
= (struct resource_typeinfo_s
*)pword
;
108 struct resource_nameinfo_s
*pname
= (struct resource_nameinfo_s
*)(ptr
+ 1);
109 printf( "id=%04x count=%d\n", ptr
->type_id
, ptr
->count
);
110 for (i
= 0; i
< ptr
->count
; i
++, pname
++)
111 printf( "offset=%d len=%d id=%04x\n",
112 pname
->offset
, pname
->length
, pname
->id
);
113 pword
= (WORD
*)pname
;
116 else printf( "None\n" );
118 /* Dump the resident name table */
120 printf( "\nResident-name table:\n" );
121 pstr
= (char *)pModule
+ pModule
->name_table
;
124 printf( "%*.*s: %d\n", *pstr
, *pstr
, pstr
+ 1,
125 *(WORD
*)(pstr
+ *pstr
+ 1) );
126 pstr
+= *pstr
+ 1 + sizeof(WORD
);
129 /* Dump the module reference table */
131 printf( "\nModule ref table:\n" );
132 if (pModule
->modref_table
)
134 pword
= (WORD
*)((BYTE
*)pModule
+ pModule
->modref_table
);
135 for (i
= 0; i
< pModule
->modref_count
; i
++, pword
++)
137 printf( "%d: %04x -> '%s'\n", i
, *pword
,
138 MODULE_GetModuleName(*pword
));
141 else printf( "None\n" );
143 /* Dump the entry table */
145 printf( "\nEntry table:\n" );
146 pstr
= (char *)pModule
+ pModule
->entry_table
;
150 printf( "Bundle %d-%d: %02x\n", ordinal
, ordinal
+ *pstr
- 1, pstr
[1]);
156 else if ((BYTE
)pstr
[1] == 0xff) /* moveable */
158 struct entry_tab_movable_s
*pe
= (struct entry_tab_movable_s
*)(pstr
+2);
159 for (i
= 0; i
< *pstr
; i
++, pe
++)
160 printf( "%d: %02x:%04x (moveable)\n",
161 ordinal
++, pe
->seg_number
, pe
->offset
);
166 struct entry_tab_fixed_s
*pe
= (struct entry_tab_fixed_s
*)(pstr
+2);
167 for (i
= 0; i
< *pstr
; i
++, pe
++)
168 printf( "%d: %04x (fixed)\n",
169 ordinal
++, pe
->offset
[0] + (pe
->offset
[1] << 8) );
174 /* Dump the non-resident names table */
176 printf( "\nNon-resident names table:\n" );
177 if (pModule
->nrname_handle
)
179 pstr
= (char *)GlobalLock16( pModule
->nrname_handle
);
182 printf( "%*.*s: %d\n", *pstr
, *pstr
, pstr
+ 1,
183 *(WORD
*)(pstr
+ *pstr
+ 1) );
184 pstr
+= *pstr
+ 1 + sizeof(WORD
);
191 /***********************************************************************
194 * Walk the module list and print the modules.
196 void MODULE_WalkModules(void)
198 HMODULE16 hModule
= hFirstModule
;
199 fprintf( stderr
, "Module Flags Name\n" );
202 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
205 fprintf( stderr
, "**** Bad module %04x in list\n", hModule
);
208 fprintf( stderr
, " %04x %04x %.*s\n", hModule
, pModule
->flags
,
209 *((char *)pModule
+ pModule
->name_table
),
210 (char *)pModule
+ pModule
->name_table
+ 1 );
211 hModule
= pModule
->next
;
216 /***********************************************************************
219 int MODULE_OpenFile( HMODULE16 hModule
)
223 const char *unixName
;
225 static int cachedfd
= -1;
227 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
228 dprintf_module( stddeb
, "MODULE_OpenFile(%04x) cache: mod=%04x fd=%d\n",
229 hModule
, hCachedModule
, cachedfd
);
230 if (!(pModule
= MODULE_GetPtr( hModule
))) return -1;
231 if (hCachedModule
== hModule
) return cachedfd
;
233 hCachedModule
= hModule
;
234 name
= NE_MODULE_NAME( pModule
);
235 if (!(unixName
= DOSFS_GetUnixFileName( name
, TRUE
)) ||
236 (cachedfd
= open( unixName
, O_RDONLY
)) == -1)
237 fprintf( stderr
, "MODULE_OpenFile: can't open file '%s' for module %04x\n",
239 dprintf_module( stddeb
, "MODULE_OpenFile: opened '%s' -> %d\n",
245 /***********************************************************************
248 * This function translates NE segment flags to GlobalAlloc flags
250 static WORD
MODULE_Ne2MemFlags(WORD flags
)
254 if (flags
& NE_SEGFLAGS_DISCARDABLE
)
255 memflags
|= GMEM_DISCARDABLE
;
256 if (flags
& NE_SEGFLAGS_MOVEABLE
||
257 ( ! (flags
& NE_SEGFLAGS_DATA
) &&
258 ! (flags
& NE_SEGFLAGS_LOADED
) &&
259 ! (flags
& NE_SEGFLAGS_ALLOCATED
)
262 memflags
|= GMEM_MOVEABLE
;
263 memflags
|= GMEM_ZEROINIT
;
265 memflags
= GMEM_ZEROINIT
| GMEM_FIXED
;
270 /***********************************************************************
271 * MODULE_AllocateSegment (WPROCS.26)
274 DWORD
MODULE_AllocateSegment(WORD wFlags
, WORD wSize
, WORD wElem
)
276 WORD size
= wSize
<< wElem
;
277 HANDLE16 hMem
= GlobalAlloc16( MODULE_Ne2MemFlags(wFlags
), size
);
278 return MAKELONG( hMem
, GlobalHandleToSel(hMem
) );
281 /***********************************************************************
282 * MODULE_CreateSegments
285 static BOOL
MODULE_CreateSegments( HMODULE16 hModule
)
287 SEGTABLEENTRY
*pSegment
;
291 if (!(pModule
= MODULE_GetPtr( hModule
))) return FALSE
;
292 pSegment
= NE_SEG_TABLE( pModule
);
293 for (i
= 1; i
<= pModule
->seg_count
; i
++, pSegment
++)
295 minsize
= pSegment
->minsize
? pSegment
->minsize
: 0x10000;
296 if (i
== pModule
->ss
) minsize
+= pModule
->stack_size
;
297 /* The DGROUP is allocated by MODULE_CreateInstance */
298 if (i
== pModule
->dgroup
) continue;
299 pSegment
->selector
= GLOBAL_Alloc( MODULE_Ne2MemFlags(pSegment
->flags
),
301 !(pSegment
->flags
& NE_SEGFLAGS_DATA
),
303 FALSE
/*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
304 if (!pSegment
->selector
) return FALSE
;
307 pModule
->dgroup_entry
= pModule
->dgroup
? pModule
->seg_table
+
308 (pModule
->dgroup
- 1) * sizeof(SEGTABLEENTRY
) : 0;
314 /***********************************************************************
317 HINSTANCE16
MODULE_GetInstance( HMODULE16 hModule
)
319 SEGTABLEENTRY
*pSegment
;
322 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
323 if (pModule
->dgroup
== 0) return hModule
;
325 pSegment
= NE_SEG_TABLE( pModule
) + pModule
->dgroup
- 1;
327 return pSegment
->selector
;
331 /***********************************************************************
332 * MODULE_CreateInstance
334 HINSTANCE16
MODULE_CreateInstance( HMODULE16 hModule
, LOADPARAMS
*params
)
336 SEGTABLEENTRY
*pSegment
;
339 HINSTANCE16 hNewInstance
, hPrevInstance
;
341 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
342 if (pModule
->dgroup
== 0) return hModule
;
344 pSegment
= NE_SEG_TABLE( pModule
) + pModule
->dgroup
- 1;
345 hPrevInstance
= pSegment
->selector
;
347 /* if it's a library, create a new instance only the first time */
350 if (pModule
->flags
& NE_FFLAGS_LIBMODULE
) return hPrevInstance
;
351 if (params
== (LOADPARAMS
*)-1) return hPrevInstance
;
354 minsize
= pSegment
->minsize
? pSegment
->minsize
: 0x10000;
355 if (pModule
->ss
== pModule
->dgroup
) minsize
+= pModule
->stack_size
;
356 minsize
+= pModule
->heap_size
;
357 hNewInstance
= GLOBAL_Alloc( GMEM_ZEROINIT
| GMEM_FIXED
,
358 minsize
, hModule
, FALSE
, FALSE
, FALSE
);
359 if (!hNewInstance
) return 0;
360 pSegment
->selector
= hNewInstance
;
365 /***********************************************************************
366 * MODULE_CreateDummyModule
368 * Create a dummy NE module for Win32 or Winelib.
370 HMODULE16
MODULE_CreateDummyModule( const OFSTRUCT
*ofs
)
374 SEGTABLEENTRY
*pSegment
;
377 INT32 of_size
= sizeof(OFSTRUCT
) - sizeof(ofs
->szPathName
)
378 + strlen(ofs
->szPathName
) + 1;
379 INT32 size
= sizeof(NE_MODULE
) +
380 /* loaded file info */
382 /* segment table: DS,CS */
383 2 * sizeof(SEGTABLEENTRY
) +
386 /* several empty tables */
389 hModule
= GlobalAlloc16( GMEM_MOVEABLE
| GMEM_ZEROINIT
, size
);
390 if (!hModule
) return (HMODULE16
)11; /* invalid exe */
392 FarSetOwner( hModule
, hModule
);
393 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
395 /* Set all used entries */
396 pModule
->magic
= NE_SIGNATURE
;
403 pModule
->heap_size
= 0xe000;
404 pModule
->stack_size
= 0x1000;
405 pModule
->seg_count
= 2;
406 pModule
->modref_count
= 0;
407 pModule
->nrname_size
= 0;
408 pModule
->fileinfo
= sizeof(NE_MODULE
);
409 pModule
->os_flags
= NE_OSFLAGS_WINDOWS
;
410 pModule
->expected_version
= 0x030a;
411 pModule
->self
= hModule
;
413 /* Set loaded file information */
414 memcpy( pModule
+ 1, ofs
, of_size
);
415 ((OFSTRUCT
*)(pModule
+1))->cBytes
= of_size
- 1;
417 pSegment
= (SEGTABLEENTRY
*)((char*)(pModule
+ 1) + of_size
);
418 pModule
->seg_table
= pModule
->dgroup_entry
= (int)pSegment
- (int)pModule
;
421 pSegment
->flags
= NE_SEGFLAGS_DATA
;
422 pSegment
->minsize
= 0x1000;
429 pStr
= (char *)pSegment
;
430 pModule
->name_table
= (int)pStr
- (int)pModule
;
431 strcpy( pStr
, "\x08W32SXXXX" );
434 /* All tables zero terminated */
435 pModule
->res_table
= pModule
->import_table
= pModule
->entry_table
=
436 (int)pStr
- (int)pModule
;
438 MODULE_RegisterModule( pModule
);
443 /***********************************************************************
444 * MODULE_LoadExeHeader
446 static HMODULE16
MODULE_LoadExeHeader( HFILE hFile
, OFSTRUCT
*ofs
)
448 struct mz_header_s mz_header
;
449 struct ne_header_s ne_header
;
454 char *buffer
, *fastload
= NULL
;
455 int fastload_offset
= 0, fastload_length
= 0;
457 /* Read a block from either the file or the fast-load area. */
458 #define READ(offset,size,buffer) \
459 ((fastload && ((offset) >= fastload_offset) && \
460 ((offset)+(size) <= fastload_offset+fastload_length)) ? \
461 (memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
462 (_llseek( hFile, mz_header.ne_offset+(offset), SEEK_SET), \
463 _lread32( hFile, (buffer), (size) ) == (size)))
465 _llseek( hFile
, 0, SEEK_SET
);
466 if ((_lread32(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) ||
467 (mz_header
.mz_magic
!= MZ_SIGNATURE
))
468 return (HMODULE16
)11; /* invalid exe */
470 _llseek( hFile
, mz_header
.ne_offset
, SEEK_SET
);
471 if (_lread32( hFile
, &ne_header
, sizeof(ne_header
) ) != sizeof(ne_header
))
472 return (HMODULE16
)11; /* invalid exe */
474 if (ne_header
.ne_magic
== PE_SIGNATURE
) return (HMODULE16
)21; /* win32 exe */
475 if (ne_header
.ne_magic
!= NE_SIGNATURE
) return (HMODULE16
)11; /* invalid exe */
477 /* We now have a valid NE header */
479 size
= sizeof(NE_MODULE
) +
480 /* loaded file info */
481 sizeof(OFSTRUCT
)-sizeof(ofs
->szPathName
)+strlen(ofs
->szPathName
)+1+
483 ne_header
.n_segment_tab
* sizeof(SEGTABLEENTRY
) +
485 ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
+
486 /* resident names table */
487 ne_header
.moduleref_tab_offset
- ne_header
.rname_tab_offset
+
488 /* module ref table */
489 ne_header
.n_mod_ref_tab
* sizeof(WORD
) +
490 /* imported names table */
491 ne_header
.entry_tab_offset
- ne_header
.iname_tab_offset
+
492 /* entry table length */
493 ne_header
.entry_tab_length
;
495 hModule
= GlobalAlloc16( GMEM_MOVEABLE
| GMEM_ZEROINIT
, size
);
496 if (!hModule
) return (HMODULE16
)11; /* invalid exe */
497 FarSetOwner( hModule
, hModule
);
498 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
499 memcpy( pModule
, &ne_header
, sizeof(ne_header
) );
501 pModule
->pe_module
= NULL
;
502 pModule
->self
= hModule
;
503 pModule
->self_loading_sel
= 0;
504 pData
= (BYTE
*)(pModule
+ 1);
506 /* Clear internal Wine flags in case they are set in the EXE file */
508 pModule
->flags
&= ~(NE_FFLAGS_BUILTIN
| NE_FFLAGS_WIN32
);
510 /* Read the fast-load area */
512 if (ne_header
.additional_flags
& NE_AFLAGS_FASTLOAD
)
514 fastload_offset
=ne_header
.fastload_offset
<<ne_header
.align_shift_count
;
515 fastload_length
=ne_header
.fastload_length
<<ne_header
.align_shift_count
;
516 dprintf_module( stddeb
, "Using fast-load area offset=%x len=%d\n",
517 fastload_offset
, fastload_length
);
518 if ((fastload
= (char *)xmalloc( fastload_length
)) != NULL
)
520 _llseek( hFile
, mz_header
.ne_offset
+ fastload_offset
, SEEK_SET
);
521 if (_lread32(hFile
, fastload
, fastload_length
) != fastload_length
)
529 /* Store the filename information */
531 pModule
->fileinfo
= (int)pData
- (int)pModule
;
532 size
= sizeof(OFSTRUCT
)-sizeof(ofs
->szPathName
)+strlen(ofs
->szPathName
)+1;
533 memcpy( pData
, ofs
, size
);
534 ((OFSTRUCT
*)pData
)->cBytes
= size
- 1;
537 /* Get the segment table */
539 pModule
->seg_table
= (int)pData
- (int)pModule
;
540 buffer
= xmalloc( ne_header
.n_segment_tab
* sizeof(struct ne_segment_table_entry_s
) );
544 struct ne_segment_table_entry_s
*pSeg
;
546 if (!READ( ne_header
.segment_tab_offset
,
547 ne_header
.n_segment_tab
* sizeof(struct ne_segment_table_entry_s
),
548 buffer
)) return (HMODULE16
)11; /* invalid exe */
549 pSeg
= (struct ne_segment_table_entry_s
*)buffer
;
550 for (i
= ne_header
.n_segment_tab
; i
> 0; i
--, pSeg
++)
552 memcpy( pData
, pSeg
, sizeof(*pSeg
) );
553 pData
+= sizeof(SEGTABLEENTRY
);
559 GlobalFree16( hModule
);
560 return (HMODULE16
)11; /* invalid exe */
563 /* Get the resource table */
565 if (ne_header
.resource_tab_offset
< ne_header
.rname_tab_offset
)
567 pModule
->res_table
= (int)pData
- (int)pModule
;
568 if (!READ(ne_header
.resource_tab_offset
,
569 ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
,
570 pData
)) return (HMODULE16
)11; /* invalid exe */
571 pData
+= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
573 else pModule
->res_table
= 0; /* No resource table */
575 /* Get the resident names table */
577 pModule
->name_table
= (int)pData
- (int)pModule
;
578 if (!READ( ne_header
.rname_tab_offset
,
579 ne_header
.moduleref_tab_offset
- ne_header
.rname_tab_offset
,
582 GlobalFree16( hModule
);
583 return (HMODULE16
)11; /* invalid exe */
585 pData
+= ne_header
.moduleref_tab_offset
- ne_header
.rname_tab_offset
;
587 /* Get the module references table */
589 if (ne_header
.n_mod_ref_tab
> 0)
591 pModule
->modref_table
= (int)pData
- (int)pModule
;
592 if (!READ( ne_header
.moduleref_tab_offset
,
593 ne_header
.n_mod_ref_tab
* sizeof(WORD
),
594 pData
)) return (HMODULE16
)11; /* invalid exe */
595 pData
+= ne_header
.n_mod_ref_tab
* sizeof(WORD
);
597 else pModule
->modref_table
= 0; /* No module references */
599 /* Get the imported names table */
601 pModule
->import_table
= (int)pData
- (int)pModule
;
602 if (!READ( ne_header
.iname_tab_offset
,
603 ne_header
.entry_tab_offset
- ne_header
.iname_tab_offset
,
606 GlobalFree16( hModule
);
607 return (HMODULE16
)11; /* invalid exe */
609 pData
+= ne_header
.entry_tab_offset
- ne_header
.iname_tab_offset
;
611 /* Get the entry table */
613 pModule
->entry_table
= (int)pData
- (int)pModule
;
614 if (!READ( ne_header
.entry_tab_offset
,
615 ne_header
.entry_tab_length
,
618 GlobalFree16( hModule
);
619 return (HMODULE16
)11; /* invalid exe */
621 pData
+= ne_header
.entry_tab_length
;
623 /* Get the non-resident names table */
625 if (ne_header
.nrname_tab_length
)
627 pModule
->nrname_handle
= GLOBAL_Alloc( 0, ne_header
.nrname_tab_length
,
628 hModule
, FALSE
, FALSE
, FALSE
);
629 if (!pModule
->nrname_handle
)
631 GlobalFree16( hModule
);
632 return (HMODULE16
)11; /* invalid exe */
634 buffer
= GlobalLock16( pModule
->nrname_handle
);
635 _llseek( hFile
, ne_header
.nrname_tab_offset
, SEEK_SET
);
636 if (_lread32( hFile
, buffer
, ne_header
.nrname_tab_length
)
637 != ne_header
.nrname_tab_length
)
639 GlobalFree16( pModule
->nrname_handle
);
640 GlobalFree16( hModule
);
641 return (HMODULE16
)11; /* invalid exe */
644 else pModule
->nrname_handle
= 0;
646 /* Allocate a segment for the implicitly-loaded DLLs */
648 if (pModule
->modref_count
)
650 pModule
->dlls_to_init
= GLOBAL_Alloc(GMEM_ZEROINIT
,
651 (pModule
->modref_count
+1)*sizeof(HMODULE16
),
652 hModule
, FALSE
, FALSE
, FALSE
);
653 if (!pModule
->dlls_to_init
)
655 if (pModule
->nrname_handle
) GlobalFree16( pModule
->nrname_handle
);
656 GlobalFree16( hModule
);
657 return (HMODULE16
)11; /* invalid exe */
660 else pModule
->dlls_to_init
= 0;
662 MODULE_RegisterModule( pModule
);
668 /***********************************************************************
671 * Lookup the ordinal for a given name.
673 WORD
MODULE_GetOrdinal( HMODULE16 hModule
, const char *name
)
675 char buffer
[256], *cpnt
;
679 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
681 dprintf_module( stddeb
, "MODULE_GetOrdinal(%04x,'%s')\n",
684 /* First handle names of the form '#xxxx' */
686 if (name
[0] == '#') return atoi( name
+ 1 );
688 /* Now copy and uppercase the string */
690 strcpy( buffer
, name
);
692 len
= strlen( buffer
);
694 /* First search the resident names */
696 cpnt
= (char *)pModule
+ pModule
->name_table
;
698 /* Skip the first entry (module name) */
699 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
702 if (((BYTE
)*cpnt
== len
) && !memcmp( cpnt
+1, buffer
, len
))
704 dprintf_module( stddeb
, " Found: ordinal=%d\n",
705 *(WORD
*)(cpnt
+ *cpnt
+ 1) );
706 return *(WORD
*)(cpnt
+ *cpnt
+ 1);
708 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
711 /* Now search the non-resident names table */
713 if (!pModule
->nrname_handle
) return 0; /* No non-resident table */
714 cpnt
= (char *)GlobalLock16( pModule
->nrname_handle
);
716 /* Skip the first entry (module description string) */
717 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
720 if (((BYTE
)*cpnt
== len
) && !memcmp( cpnt
+1, buffer
, len
))
722 dprintf_module( stddeb
, " Found: ordinal=%d\n",
723 *(WORD
*)(cpnt
+ *cpnt
+ 1) );
724 return *(WORD
*)(cpnt
+ *cpnt
+ 1);
726 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
732 /***********************************************************************
733 * MODULE_GetEntryPoint
735 * Return the entry point for a given ordinal.
737 FARPROC16
MODULE_GetEntryPoint( HMODULE16 hModule
, WORD ordinal
)
744 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
746 p
= (BYTE
*)pModule
+ pModule
->entry_table
;
747 while (*p
&& (curOrdinal
+ *p
<= ordinal
))
749 /* Skipping this bundle */
753 case 0: p
+= 2; break; /* unused */
754 case 0xff: p
+= 2 + *p
* 6; break; /* moveable */
755 default: p
+= 2 + *p
* 3; break; /* fixed */
764 case 0xff: /* moveable */
765 p
+= 2 + 6 * (ordinal
- curOrdinal
);
767 offset
= *(WORD
*)(p
+ 4);
771 p
+= 2 + 3 * (ordinal
- curOrdinal
);
772 offset
= *(WORD
*)(p
+ 1);
776 if (sel
== 0xfe) sel
= 0xffff; /* constant entry */
777 else sel
= (WORD
)(DWORD
)NE_SEG_TABLE(pModule
)[sel
-1].selector
;
778 return (FARPROC16
)PTR_SEG_OFF_TO_SEGPTR( sel
, offset
);
782 /***********************************************************************
783 * MODULE_SetEntryPoint
785 * Change the value of an entry point. Use with caution!
786 * It can only change the offset value, not the selector.
788 BOOL16
MODULE_SetEntryPoint( HMODULE16 hModule
, WORD ordinal
, WORD offset
)
794 if (!(pModule
= MODULE_GetPtr( hModule
))) return FALSE
;
796 p
= (BYTE
*)pModule
+ pModule
->entry_table
;
797 while (*p
&& (curOrdinal
+ *p
<= ordinal
))
799 /* Skipping this bundle */
803 case 0: p
+= 2; break; /* unused */
804 case 0xff: p
+= 2 + *p
* 6; break; /* moveable */
805 default: p
+= 2 + *p
* 3; break; /* fixed */
808 if (!*p
) return FALSE
;
814 case 0xff: /* moveable */
815 p
+= 2 + 6 * (ordinal
- curOrdinal
);
816 *(WORD
*)(p
+ 4) = offset
;
819 p
+= 2 + 3 * (ordinal
- curOrdinal
);
820 *(WORD
*)(p
+ 1) = offset
;
827 /***********************************************************************
828 * MODULE_GetWndProcEntry16 (not a Windows API function)
830 * Return an entry point from the WPROCS dll.
833 FARPROC16
MODULE_GetWndProcEntry16( const char *name
)
837 static HMODULE16 hModule
= 0;
839 if (!hModule
) hModule
= GetModuleHandle( "WPROCS" );
840 ordinal
= MODULE_GetOrdinal( hModule
, name
);
841 if (!(ret
= MODULE_GetEntryPoint( hModule
, ordinal
)))
842 fprintf( stderr
, "GetWndProc16: %s not found, please report\n", name
);
848 /***********************************************************************
849 * MODULE_GetModuleName
851 LPSTR
MODULE_GetModuleName( HMODULE16 hModule
)
855 static char buffer
[10];
857 if (!(pModule
= MODULE_GetPtr( hModule
))) return NULL
;
858 p
= (BYTE
*)pModule
+ pModule
->name_table
;
860 memcpy( buffer
, p
+ 1, len
);
866 /**********************************************************************
867 * MODULE_RegisterModule
869 void MODULE_RegisterModule( NE_MODULE
*pModule
)
871 pModule
->next
= hFirstModule
;
872 hFirstModule
= pModule
->self
;
876 /**********************************************************************
879 * Find a module from a path name.
881 HMODULE16
MODULE_FindModule( LPCSTR path
)
883 HMODULE16 hModule
= hFirstModule
;
884 LPCSTR filename
, dotptr
, modulepath
, modulename
;
885 BYTE len
, *name_table
;
887 if (!(filename
= strrchr( path
, '\\' ))) filename
= path
;
889 if ((dotptr
= strrchr( filename
, '.' )) != NULL
)
890 len
= (BYTE
)(dotptr
- filename
);
891 else len
= strlen( filename
);
895 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
897 modulepath
= NE_MODULE_NAME(pModule
);
898 if (!(modulename
= strrchr( modulepath
, '\\' )))
899 modulename
= modulepath
;
901 if (!lstrcmpi32A( modulename
, filename
)) return hModule
;
903 name_table
= (BYTE
*)pModule
+ pModule
->name_table
;
904 if ((*name_table
== len
) && !lstrncmpi32A(filename
, name_table
+1, len
))
906 hModule
= pModule
->next
;
912 /**********************************************************************
915 * Call a DLL's WEP, allowing it to shut down.
916 * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
918 static BOOL16
MODULE_CallWEP( HMODULE16 hModule
)
920 FARPROC16 WEP
= (FARPROC16
)0;
921 WORD ordinal
= MODULE_GetOrdinal( hModule
, "WEP" );
923 if (ordinal
) WEP
= MODULE_GetEntryPoint( hModule
, ordinal
);
926 dprintf_module( stddeb
, "module %04x doesn't have a WEP\n", hModule
);
929 return CallWindowsExitProc( WEP
, WEP_FREE_DLL
);
933 /**********************************************************************
936 * Remove a module from memory.
938 static void MODULE_FreeModule( HMODULE16 hModule
)
940 HMODULE16
*hPrevModule
;
942 SEGTABLEENTRY
*pSegment
;
946 if (!(pModule
= MODULE_GetPtr( hModule
))) return;
947 if (pModule
->flags
& NE_FFLAGS_BUILTIN
)
948 return; /* Can't free built-in module */
950 if (pModule
->flags
& NE_FFLAGS_LIBMODULE
) MODULE_CallWEP( hModule
);
952 /* Free the objects owned by the module */
954 HOOK_FreeModuleHooks( hModule
);
955 CLASS_FreeModuleClasses( hModule
);
957 /* Clear magic number just in case */
959 pModule
->magic
= pModule
->self
= 0;
961 /* Remove it from the linked list */
963 hPrevModule
= &hFirstModule
;
964 while (*hPrevModule
&& (*hPrevModule
!= hModule
))
966 hPrevModule
= &(MODULE_GetPtr( *hPrevModule
))->next
;
968 if (*hPrevModule
) *hPrevModule
= pModule
->next
;
970 /* Free all the segments */
972 pSegment
= NE_SEG_TABLE( pModule
);
973 for (i
= 1; i
<= pModule
->seg_count
; i
++, pSegment
++)
975 GlobalFree16( pSegment
->selector
);
978 /* Free the referenced modules */
980 pModRef
= (HMODULE16
*)NE_MODULE_TABLE( pModule
);
981 for (i
= 0; i
< pModule
->modref_count
; i
++, pModRef
++)
983 FreeModule16( *pModRef
);
986 /* Free the module storage */
988 if (pModule
->nrname_handle
) GlobalFree16( pModule
->nrname_handle
);
989 if (pModule
->dlls_to_init
) GlobalFree16( pModule
->dlls_to_init
);
990 GlobalFree16( hModule
);
992 /* Remove module from cache */
994 if (hCachedModule
== hModule
) hCachedModule
= 0;
998 /**********************************************************************
999 * LoadModule (KERNEL.45)
1001 HINSTANCE16
LoadModule( LPCSTR name
, LPVOID paramBlock
)
1004 HINSTANCE16 hInstance
, hPrevInstance
;
1006 LOADPARAMS
*params
= (LOADPARAMS
*)paramBlock
;
1009 WORD
*pModRef
, *pDLLs
;
1013 hModule
= MODULE_FindModule( name
);
1015 if (!hModule
) /* We have to load the module */
1017 /* Try to load the built-in first if not disabled */
1018 if ((hModule
= BUILTIN_LoadModule( name
, FALSE
))) return hModule
;
1020 if ((hFile
= OpenFile( name
, &ofs
, OF_READ
)) == HFILE_ERROR
)
1022 /* Now try the built-in even if disabled */
1023 if ((hModule
= BUILTIN_LoadModule( name
, TRUE
)))
1025 fprintf( stderr
, "Warning: could not load Windows DLL '%s', using built-in module.\n", name
);
1028 return 2; /* File not found */
1031 /* Create the module structure */
1033 hModule
= MODULE_LoadExeHeader( hFile
, &ofs
);
1036 /* FIXME: Hack because PE_LoadModule is recursive */
1037 int fd
= dup( FILE_GetUnixHandle(hFile
) );
1039 if (hModule
== 21) hModule
= PE_LoadModule( fd
, &ofs
, paramBlock
);
1042 fprintf( stderr
, "LoadModule: can't load '%s', error=%d\n",
1047 pModule
= MODULE_GetPtr( hModule
);
1049 /* Allocate the segments for this module */
1051 MODULE_CreateSegments( hModule
);
1054 hInstance
= MODULE_CreateInstance( hModule
, (LOADPARAMS
*)paramBlock
);
1056 /* Load the referenced DLLs */
1058 pModRef
= (WORD
*)((char *)pModule
+ pModule
->modref_table
);
1059 pDLLs
= (WORD
*)GlobalLock16( pModule
->dlls_to_init
);
1060 for (i
= 0; i
< pModule
->modref_count
; i
++, pModRef
++)
1063 BYTE
*pstr
= (BYTE
*)pModule
+ pModule
->import_table
+ *pModRef
;
1064 memcpy( buffer
, pstr
+ 1, *pstr
);
1065 strcpy( buffer
+ *pstr
, ".dll" );
1066 dprintf_module( stddeb
, "Loading '%s'\n", buffer
);
1067 if (!(*pModRef
= MODULE_FindModule( buffer
)))
1069 /* If the DLL is not loaded yet, load it and store */
1070 /* its handle in the list of DLLs to initialize. */
1073 if ((hDLL
= LoadModule( buffer
, (LPVOID
)-1 )) == 2) /* file not found */
1077 /* Try with prepending the path of the current module */
1078 GetModuleFileName16( hModule
, buffer
, sizeof(buffer
) );
1079 if (!(p
= strrchr( buffer
, '\\' ))) p
= buffer
;
1080 memcpy( p
+ 1, pstr
+ 1, *pstr
);
1081 strcpy( p
+ 1 + *pstr
, ".dll" );
1082 hDLL
= LoadModule( buffer
, (LPVOID
)-1 );
1086 fprintf( stderr
, "Could not load '%s' required by '%s', error = %d\n",
1087 buffer
, name
, hDLL
);
1088 return 2; /* file not found */
1090 *pModRef
= GetExePtr( hDLL
);
1091 *pDLLs
++ = *pModRef
;
1093 else /* Increment the reference count of the DLL */
1095 NE_MODULE
*pOldDLL
= MODULE_GetPtr( *pModRef
);
1096 if (pOldDLL
) pOldDLL
->count
++;
1100 /* Load the segments */
1102 if (pModule
->flags
& NE_FFLAGS_SELFLOAD
)
1105 /* Handle self loading modules */
1106 SEGTABLEENTRY
* pSegTable
= (SEGTABLEENTRY
*) NE_SEG_TABLE(pModule
);
1107 SELFLOADHEADER
*selfloadheader
;
1108 STACK16FRAME
*stack16Top
;
1109 HMODULE16 hselfload
= GetModuleHandle("WPROCS");
1110 WORD oldss
, oldsp
, saved_dgroup
= pSegTable
[pModule
->dgroup
- 1].selector
;
1111 fprintf (stderr
, "Warning: %*.*s is a self-loading module\n"
1112 "Support for self-loading modules is very experimental\n",
1113 *((BYTE
*)pModule
+ pModule
->name_table
),
1114 *((BYTE
*)pModule
+ pModule
->name_table
),
1115 (char *)pModule
+ pModule
->name_table
+ 1);
1116 NE_LoadSegment( hModule
, 1 );
1117 selfloadheader
= (SELFLOADHEADER
*)
1118 PTR_SEG_OFF_TO_LIN(pSegTable
->selector
, 0);
1119 selfloadheader
->EntryAddrProc
=
1120 MODULE_GetEntryPoint(hselfload
,27);
1121 selfloadheader
->MyAlloc
= MODULE_GetEntryPoint(hselfload
,28);
1122 selfloadheader
->SetOwner
= MODULE_GetEntryPoint(GetModuleHandle("KERNEL"),403);
1123 pModule
->self_loading_sel
= GlobalHandleToSel(
1124 GLOBAL_Alloc (GMEM_ZEROINIT
,
1125 0xFF00, hModule
, FALSE
, FALSE
, FALSE
)
1127 oldss
= IF1632_Saved16_ss
;
1128 oldsp
= IF1632_Saved16_sp
;
1129 IF1632_Saved16_ss
= pModule
->self_loading_sel
;
1130 IF1632_Saved16_sp
= 0xFF00 - sizeof(*stack16Top
);
1131 stack16Top
= CURRENT_STACK16
;
1132 stack16Top
->saved_ss
= 0;
1133 stack16Top
->saved_sp
= 0;
1134 stack16Top
->ds
= stack16Top
->es
= pModule
->self_loading_sel
;
1135 stack16Top
->entry_point
= 0;
1136 stack16Top
->entry_ip
= 0;
1137 stack16Top
->entry_cs
= 0;
1142 if (!IF1632_Stack32_base
) {
1143 STACK32FRAME
* frame32
;
1145 /* Setup an initial 32 bit stack frame */
1146 hInitialStack32
= GLOBAL_Alloc( GMEM_FIXED
, 0x10000,
1147 hModule
, FALSE
, FALSE
,
1150 /* Create the 32-bit stack frame */
1152 *(DWORD
*)GlobalLock16(hInitialStack32
) = 0xDEADBEEF;
1153 stack32Top
= (char*)GlobalLock16(hInitialStack32
) +
1155 frame32
= (STACK32FRAME
*)stack32Top
- 1;
1156 frame32
->saved_esp
= (DWORD
)stack32Top
;
1163 frame32
->retaddr
= 0;
1164 frame32
->codeselector
= WINE_CODE_SELECTOR
;
1165 /* pTask->esp = (DWORD)frame32; */
1166 IF1632_Stack32_base
= WIN16_GlobalLock16(hInitialStack32
);
1169 hf
= FILE_DupUnixHandle( MODULE_OpenFile( hModule
) );
1170 CallTo16_word_ww( selfloadheader
->BootApp
, hModule
, hf
);
1172 /* some BootApp procs overwrite the selector of dgroup */
1173 pSegTable
[pModule
->dgroup
- 1].selector
= saved_dgroup
;
1174 IF1632_Saved16_ss
= oldss
;
1175 IF1632_Saved16_sp
= oldsp
;
1176 for (i
= 2; i
<= pModule
->seg_count
; i
++) NE_LoadSegment( hModule
, i
);
1177 if (hInitialStack32
){
1178 GlobalFree16(hInitialStack32
);
1179 IF1632_Stack32_base
= hInitialStack32
= 0;
1184 for (i
= 1; i
<= pModule
->seg_count
; i
++)
1185 NE_LoadSegment( hModule
, i
);
1188 /* Fixup the functions prologs */
1190 NE_FixupPrologs( pModule
);
1192 /* Make sure the usage count is 1 on the first loading of */
1193 /* the module, even if it contains circular DLL references */
1199 pModule
= MODULE_GetPtr( hModule
);
1200 hPrevInstance
= MODULE_GetInstance( hModule
);
1201 hInstance
= MODULE_CreateInstance( hModule
, params
);
1202 if (hInstance
!= hPrevInstance
) /* not a library */
1203 NE_LoadSegment( hModule
, pModule
->dgroup
);
1207 lstrcpyn32A( ofs
.szPathName
, name
, sizeof(ofs
.szPathName
) );
1208 if ((hModule
= MODULE_CreateDummyModule( &ofs
)) < 32) return hModule
;
1209 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
1211 hInstance
= MODULE_CreateInstance( hModule
, params
);
1212 #endif /* WINELIB */
1214 /* Create a task for this instance */
1216 if (!(pModule
->flags
& NE_FFLAGS_LIBMODULE
) && (paramBlock
!= (LPVOID
)-1))
1221 /* PowerPoint passes NULL as showCmd */
1222 if (params
->showCmd
)
1223 showcmd
= *((WORD
*)PTR_SEG_TO_LIN(params
->showCmd
)+1);
1225 showcmd
= 0; /* FIXME: correct */
1227 hTask
= TASK_CreateTask( hModule
, hInstance
, hPrevInstance
,
1228 params
->hEnvironment
,
1229 (LPSTR
)PTR_SEG_TO_LIN( params
->cmdLine
),
1232 if( hTask
&& TASK_GetNextTask(hTask
)) Yield();
1239 /**********************************************************************
1240 * FreeModule16 (KERNEL.46)
1242 BOOL16
FreeModule16( HMODULE16 hModule
)
1246 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1247 if (!(pModule
= MODULE_GetPtr( hModule
))) return FALSE
;
1249 dprintf_module( stddeb
, "FreeModule16: %s count %d\n",
1250 MODULE_GetModuleName(hModule
), pModule
->count
);
1251 if (--pModule
->count
== 0) MODULE_FreeModule( hModule
);
1256 /**********************************************************************
1257 * GetModuleHandle (KERNEL.47)
1259 HMODULE16
WIN16_GetModuleHandle( SEGPTR name
)
1261 if (HIWORD(name
) == 0) return GetExePtr( (HINSTANCE16
)name
);
1262 return MODULE_FindModule( PTR_SEG_TO_LIN(name
) );
1265 HMODULE16
GetModuleHandle( LPCSTR name
)
1267 return MODULE_FindModule( name
);
1271 /**********************************************************************
1272 * GetModuleUsage (KERNEL.48)
1274 INT16
GetModuleUsage( HINSTANCE16 hModule
)
1278 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1279 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
1280 dprintf_module( stddeb
, "GetModuleUsage(%04x): returning %d\n",
1281 hModule
, pModule
->count
);
1282 return pModule
->count
;
1286 /**********************************************************************
1287 * GetModuleFileName16 (KERNEL.49)
1289 INT16
GetModuleFileName16( HINSTANCE16 hModule
, LPSTR lpFileName
, INT16 nSize
)
1293 if (!hModule
) hModule
= GetCurrentTask();
1294 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1295 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
1296 lstrcpyn32A( lpFileName
, NE_MODULE_NAME(pModule
), nSize
);
1297 dprintf_module( stddeb
, "GetModuleFileName16: %s\n", lpFileName
);
1298 return strlen(lpFileName
);
1302 /***********************************************************************
1303 * GetModuleFileName32A (KERNEL32.235)
1305 DWORD
GetModuleFileName32A( HMODULE32 hModule
, LPSTR lpFileName
, DWORD size
)
1311 TDB
*pTask
= (TDB
*)GlobalLock16( GetCurrentTask() );
1312 hModule
= pTask
->hInstance
;
1314 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1315 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
1316 lstrcpyn32A( lpFileName
, NE_MODULE_NAME(pModule
), size
);
1317 dprintf_module( stddeb
, "GetModuleFileName32A: %s\n", lpFileName
);
1318 return strlen(lpFileName
);
1322 /***********************************************************************
1323 * GetModuleFileName32W (KERNEL32.236)
1325 DWORD
GetModuleFileName32W( HMODULE32 hModule
, LPWSTR lpFileName
, DWORD size
)
1327 LPSTR fnA
= (char*)HeapAlloc( GetProcessHeap(), 0, size
);
1328 DWORD res
= GetModuleFileName32A( hModule
, fnA
, size
);
1329 lstrcpynAtoW( lpFileName
, fnA
, size
);
1330 HeapFree( GetProcessHeap(), 0, fnA
);
1335 /**********************************************************************
1336 * GetModuleName (KERNEL.27)
1338 BOOL16
GetModuleName( HINSTANCE16 hinst
, LPSTR buf
, INT16 nSize
)
1340 LPSTR name
= MODULE_GetModuleName(hinst
);
1342 if (!name
) return FALSE
;
1343 lstrcpyn32A( buf
, name
, nSize
);
1348 /***********************************************************************
1349 * LoadLibrary (KERNEL.95)
1351 HINSTANCE16
LoadLibrary16( LPCSTR libname
)
1357 fprintf( stderr
, "LoadLibrary not supported in Winelib\n" );
1360 dprintf_module( stddeb
, "LoadLibrary: (%08x) %s\n", (int)libname
, libname
);
1362 /* This does not increment the module reference count, and will
1363 * therefore cause crashes on FreeLibrary calls.
1364 if ((handle = MODULE_FindModule( libname )) != 0) return handle;
1366 handle
= LoadModule( libname
, (LPVOID
)-1 );
1367 if (handle
== (HINSTANCE16
)2) /* file not found */
1370 lstrcpyn32A( buffer
, libname
, 252 );
1371 strcat( buffer
, ".dll" );
1372 handle
= LoadModule( buffer
, (LPVOID
)-1 );
1375 if (handle
>= (HINSTANCE16
)32) NE_InitializeDLLs( GetExePtr(handle
) );
1381 /***********************************************************************
1382 * FreeLibrary (KERNEL.96)
1384 void FreeLibrary( HINSTANCE16 handle
)
1386 dprintf_module( stddeb
,"FreeLibrary: %04x\n", handle
);
1387 FreeModule16( handle
);
1391 /***********************************************************************
1392 * WinExec (KERNEL.166)
1394 HINSTANCE16
WinExec( LPSTR lpCmdLine
, WORD nCmdShow
)
1397 HGLOBAL16 cmdShowHandle
, cmdLineHandle
;
1400 char *p
, *cmdline
, filename
[256];
1401 static int use_load_module
= 1;
1403 if (!(cmdShowHandle
= GlobalAlloc16( 0, 2 * sizeof(WORD
) )))
1404 return 8; /* Out of memory */
1405 if (!(cmdLineHandle
= GlobalAlloc16( 0, 256 )))
1407 GlobalFree16( cmdShowHandle
);
1408 return 8; /* Out of memory */
1411 /* Store nCmdShow */
1413 cmdShowPtr
= (WORD
*)GlobalLock16( cmdShowHandle
);
1415 cmdShowPtr
[1] = nCmdShow
;
1417 /* Build the filename and command-line */
1419 cmdline
= (char *)GlobalLock16( cmdLineHandle
);
1420 lstrcpyn32A(filename
, lpCmdLine
, sizeof(filename
) - 4 /* for extension */);
1421 for (p
= filename
; *p
&& (*p
!= ' ') && (*p
!= '\t'); p
++);
1422 if (*p
) lstrcpyn32A( cmdline
, p
+ 1, 128 );
1423 else cmdline
[0] = '\0';
1426 /* Now load the executable file */
1428 if (use_load_module
)
1431 /* WINELIB: Use LoadModule() only for the program itself */
1432 use_load_module
= 0;
1433 params
.hEnvironment
= (HGLOBAL16
)GetDOSEnvironment();
1435 params
.hEnvironment
= (HGLOBAL16
)SELECTOROF( GetDOSEnvironment() );
1436 #endif /* WINELIB */
1437 params
.cmdLine
= (SEGPTR
)WIN16_GlobalLock16( cmdLineHandle
);
1438 params
.showCmd
= (SEGPTR
)WIN16_GlobalLock16( cmdShowHandle
);
1439 params
.reserved
= 0;
1440 handle
= LoadModule( filename
, ¶ms
);
1441 if (handle
== 2) /* file not found */
1443 /* Check that the original file name did not have a suffix */
1444 p
= strrchr(filename
, '.');
1445 /* if there is a '.', check if either \ OR / follow */
1446 if (!p
|| strchr(p
, '/') || strchr(p
, '\\'))
1448 p
= filename
+ strlen(filename
);
1449 strcpy( p
, ".exe" );
1450 handle
= LoadModule( filename
, ¶ms
);
1451 *p
= '\0'; /* Remove extension */
1459 /* Try to start it as a unix program */
1463 const char *unixfilename
;
1464 const char *argv
[256], **argptr
;
1465 int iconic
= (nCmdShow
== SW_SHOWMINIMIZED
||
1466 nCmdShow
== SW_SHOWMINNOACTIVE
);
1468 /* get unixfilename */
1469 if (strchr(filename
, '/') ||
1470 strchr(filename
, ':') ||
1471 strchr(filename
, '\\'))
1472 unixfilename
= DOSFS_GetUnixFileName(filename
, 1);
1473 else unixfilename
= filename
;
1479 if (iconic
) *argptr
++ = "-iconic";
1480 *argptr
++ = unixfilename
;
1484 while (*p
&& (*p
== ' ' || *p
== '\t')) *p
++ = '\0';
1487 while (*p
&& *p
!= ' ' && *p
!= '\t') p
++;
1492 execvp(argv
[0], (char**)argv
);
1502 if (iconic
) *argptr
++ = "-iconic";
1503 *argptr
++ = lpCmdLine
;
1507 execvp(argv
[0] , (char**)argv
);
1510 fprintf(stderr
, "WinExec: can't exec 'wine %s'\n", lpCmdLine
);
1516 GlobalFree16( cmdShowHandle
);
1517 GlobalFree16( cmdLineHandle
);
1522 /***********************************************************************
1523 * GetProcAddress16 (KERNEL.50)
1525 FARPROC16
GetProcAddress16( HMODULE16 hModule
, SEGPTR name
)
1530 if (!hModule
) hModule
= GetCurrentTask();
1531 hModule
= GetExePtr( hModule
);
1533 if (HIWORD(name
) != 0)
1535 ordinal
= MODULE_GetOrdinal( hModule
, (LPSTR
)PTR_SEG_TO_LIN(name
) );
1536 dprintf_module( stddeb
, "GetProcAddress: %04x '%s'\n",
1537 hModule
, (LPSTR
)PTR_SEG_TO_LIN(name
) );
1541 ordinal
= LOWORD(name
);
1542 dprintf_module( stddeb
, "GetProcAddress: %04x %04x\n",
1545 if (!ordinal
) return (FARPROC16
)0;
1547 ret
= MODULE_GetEntryPoint( hModule
, ordinal
);
1549 dprintf_module( stddeb
, "GetProcAddress: returning %08x\n", (UINT32
)ret
);
1554 /***********************************************************************
1555 * GetProcAddress32 (KERNEL32.257)
1557 FARPROC32
GetProcAddress32( HMODULE32 hModule
, LPCSTR function
)
1562 hModule
= GetExePtr( hModule
);
1563 if (!(pModule
= MODULE_GetPtr( hModule
)))
1564 return (FARPROC32
)0;
1565 if (!(pModule
->flags
& NE_FFLAGS_WIN32
) || !pModule
->pe_module
)
1566 return (FARPROC32
)0;
1567 if (pModule
->flags
& NE_FFLAGS_BUILTIN
)
1568 return BUILTIN_GetProcAddress32( pModule
, function
);
1569 return PE_FindExportedFunction( pModule
->pe_module
, function
);
1576 /**********************************************************************
1577 * GetExpWinVer (KERNEL.167)
1579 WORD
GetExpWinVer( HMODULE16 hModule
)
1581 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
1582 return pModule
? pModule
->expected_version
: 0;
1586 /**********************************************************************
1587 * IsSharedSelector (KERNEL.345)
1589 BOOL16
IsSharedSelector( HANDLE16 selector
)
1591 /* Check whether the selector belongs to a DLL */
1592 NE_MODULE
*pModule
= MODULE_GetPtr( GetExePtr( selector
));
1593 if (!pModule
) return FALSE
;
1594 return (pModule
->flags
& NE_FFLAGS_LIBMODULE
) != 0;
1598 /**********************************************************************
1599 * ModuleFirst (TOOLHELP.59)
1601 BOOL16
ModuleFirst( MODULEENTRY
*lpme
)
1603 lpme
->wNext
= hFirstModule
;
1604 return ModuleNext( lpme
);
1608 /**********************************************************************
1609 * ModuleNext (TOOLHELP.60)
1611 BOOL16
ModuleNext( MODULEENTRY
*lpme
)
1615 if (!lpme
->wNext
) return FALSE
;
1616 if (!(pModule
= MODULE_GetPtr( lpme
->wNext
))) return FALSE
;
1617 strncpy( lpme
->szModule
, (char *)pModule
+ pModule
->name_table
,
1619 lpme
->szModule
[MAX_MODULE_NAME
] = '\0';
1620 lpme
->hModule
= lpme
->wNext
;
1621 lpme
->wcUsage
= pModule
->count
;
1622 strncpy( lpme
->szExePath
, NE_MODULE_NAME(pModule
), MAX_PATH
);
1623 lpme
->szExePath
[MAX_PATH
] = '\0';
1624 lpme
->wNext
= pModule
->next
;
1629 /**********************************************************************
1630 * ModuleFindName (TOOLHELP.61)
1632 BOOL16
ModuleFindName( MODULEENTRY
*lpme
, LPCSTR name
)
1634 lpme
->wNext
= GetModuleHandle( name
);
1635 return ModuleNext( lpme
);
1639 /**********************************************************************
1640 * ModuleFindHandle (TOOLHELP.62)
1642 BOOL16
ModuleFindHandle( MODULEENTRY
*lpme
, HMODULE16 hModule
)
1644 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1645 lpme
->wNext
= hModule
;
1646 return ModuleNext( lpme
);