4 * Copyright 1995 Alexandre Julliard
11 #include <sys/types.h>
21 #include "selectors.h"
22 #include "stackframe.h"
29 extern HINSTANCE16
PE_LoadModule( int fd
, OFSTRUCT
*ofs
, LOADPARAMS
* params
);
31 static HMODULE16 hFirstModule
= 0;
32 static HMODULE16 hCachedModule
= 0; /* Module cached by MODULE_OpenFile */
35 /***********************************************************************
38 NE_MODULE
*MODULE_GetPtr( HMODULE16 hModule
)
40 NE_MODULE
*pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
41 if (!pModule
|| (pModule
->magic
!= IMAGE_OS2_SIGNATURE
) ||
42 (pModule
->self
!= hModule
)) return NULL
;
47 /***********************************************************************
50 void MODULE_DumpModule( HMODULE16 hModule
)
58 if (!(pModule
= MODULE_GetPtr( hModule
)))
60 fprintf( stderr
, "**** %04x is not a module handle\n", hModule
);
64 /* Dump the module info */
66 printf( "Module %04x:\n", hModule
);
67 printf( "count=%d flags=%04x heap=%d stack=%d\n",
68 pModule
->count
, pModule
->flags
,
69 pModule
->heap_size
, pModule
->stack_size
);
70 printf( "cs:ip=%04x:%04x ss:sp=%04x:%04x ds=%04x nb seg=%d modrefs=%d\n",
71 pModule
->cs
, pModule
->ip
, pModule
->ss
, pModule
->sp
, pModule
->dgroup
,
72 pModule
->seg_count
, pModule
->modref_count
);
73 printf( "os_flags=%d swap_area=%d version=%04x\n",
74 pModule
->os_flags
, pModule
->min_swap_area
,
75 pModule
->expected_version
);
76 if (pModule
->flags
& NE_FFLAGS_WIN32
)
77 printf( "PE module=%08x\n", (unsigned int)pModule
->pe_module
);
79 /* Dump the file info */
81 printf( "Filename: '%s'\n", NE_MODULE_NAME(pModule
) );
83 /* Dump the segment table */
85 printf( "\nSegment table:\n" );
86 pSeg
= NE_SEG_TABLE( pModule
);
87 for (i
= 0; i
< pModule
->seg_count
; i
++, pSeg
++)
88 printf( "%02x: pos=%d size=%d flags=%04x minsize=%d sel=%04x\n",
89 i
+ 1, pSeg
->filepos
, pSeg
->size
, pSeg
->flags
,
90 pSeg
->minsize
, pSeg
->selector
);
92 /* Dump the resource table */
94 printf( "\nResource table:\n" );
95 if (pModule
->res_table
)
97 pword
= (WORD
*)((BYTE
*)pModule
+ pModule
->res_table
);
98 printf( "Alignment: %d\n", *pword
++ );
101 struct resource_typeinfo_s
*ptr
= (struct resource_typeinfo_s
*)pword
;
102 struct resource_nameinfo_s
*pname
= (struct resource_nameinfo_s
*)(ptr
+ 1);
103 printf( "id=%04x count=%d\n", ptr
->type_id
, ptr
->count
);
104 for (i
= 0; i
< ptr
->count
; i
++, pname
++)
105 printf( "offset=%d len=%d id=%04x\n",
106 pname
->offset
, pname
->length
, pname
->id
);
107 pword
= (WORD
*)pname
;
110 else printf( "None\n" );
112 /* Dump the resident name table */
114 printf( "\nResident-name table:\n" );
115 pstr
= (char *)pModule
+ pModule
->name_table
;
118 printf( "%*.*s: %d\n", *pstr
, *pstr
, pstr
+ 1,
119 *(WORD
*)(pstr
+ *pstr
+ 1) );
120 pstr
+= *pstr
+ 1 + sizeof(WORD
);
123 /* Dump the module reference table */
125 printf( "\nModule ref table:\n" );
126 if (pModule
->modref_table
)
128 pword
= (WORD
*)((BYTE
*)pModule
+ pModule
->modref_table
);
129 for (i
= 0; i
< pModule
->modref_count
; i
++, pword
++)
131 printf( "%d: %04x -> '%s'\n", i
, *pword
,
132 MODULE_GetModuleName(*pword
));
135 else printf( "None\n" );
137 /* Dump the entry table */
139 printf( "\nEntry table:\n" );
140 pstr
= (char *)pModule
+ pModule
->entry_table
;
144 printf( "Bundle %d-%d: %02x\n", ordinal
, ordinal
+ *pstr
- 1, pstr
[1]);
150 else if ((BYTE
)pstr
[1] == 0xff) /* moveable */
152 struct entry_tab_movable_s
*pe
= (struct entry_tab_movable_s
*)(pstr
+2);
153 for (i
= 0; i
< *pstr
; i
++, pe
++)
154 printf( "%d: %02x:%04x (moveable)\n",
155 ordinal
++, pe
->seg_number
, pe
->offset
);
160 struct entry_tab_fixed_s
*pe
= (struct entry_tab_fixed_s
*)(pstr
+2);
161 for (i
= 0; i
< *pstr
; i
++, pe
++)
162 printf( "%d: %04x (fixed)\n",
163 ordinal
++, pe
->offset
[0] + (pe
->offset
[1] << 8) );
168 /* Dump the non-resident names table */
170 printf( "\nNon-resident names table:\n" );
171 if (pModule
->nrname_handle
)
173 pstr
= (char *)GlobalLock16( pModule
->nrname_handle
);
176 printf( "%*.*s: %d\n", *pstr
, *pstr
, pstr
+ 1,
177 *(WORD
*)(pstr
+ *pstr
+ 1) );
178 pstr
+= *pstr
+ 1 + sizeof(WORD
);
185 /***********************************************************************
188 * Walk the module list and print the modules.
190 void MODULE_WalkModules(void)
192 HMODULE16 hModule
= hFirstModule
;
193 fprintf( stderr
, "Module Flags Name\n" );
196 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
199 fprintf( stderr
, "**** Bad module %04x in list\n", hModule
);
202 fprintf( stderr
, " %04x %04x %.*s\n", hModule
, pModule
->flags
,
203 *((char *)pModule
+ pModule
->name_table
),
204 (char *)pModule
+ pModule
->name_table
+ 1 );
205 hModule
= pModule
->next
;
210 /***********************************************************************
213 int MODULE_OpenFile( HMODULE16 hModule
)
216 DOS_FULL_NAME full_name
;
219 static int cachedfd
= -1;
221 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
222 dprintf_module( stddeb
, "MODULE_OpenFile(%04x) cache: mod=%04x fd=%d\n",
223 hModule
, hCachedModule
, cachedfd
);
224 if (!(pModule
= MODULE_GetPtr( hModule
))) return -1;
225 if (hCachedModule
== hModule
) return cachedfd
;
227 hCachedModule
= hModule
;
228 name
= NE_MODULE_NAME( pModule
);
229 if (!DOSFS_GetFullName( name
, TRUE
, &full_name
) ||
230 (cachedfd
= open( full_name
.long_name
, O_RDONLY
)) == -1)
231 fprintf( stderr
, "MODULE_OpenFile: can't open file '%s' for module %04x\n",
233 dprintf_module( stddeb
, "MODULE_OpenFile: opened '%s' -> %d\n",
239 /***********************************************************************
242 * This function translates NE segment flags to GlobalAlloc flags
244 static WORD
MODULE_Ne2MemFlags(WORD flags
)
248 if (flags
& NE_SEGFLAGS_DISCARDABLE
)
249 memflags
|= GMEM_DISCARDABLE
;
250 if (flags
& NE_SEGFLAGS_MOVEABLE
||
251 ( ! (flags
& NE_SEGFLAGS_DATA
) &&
252 ! (flags
& NE_SEGFLAGS_LOADED
) &&
253 ! (flags
& NE_SEGFLAGS_ALLOCATED
)
256 memflags
|= GMEM_MOVEABLE
;
257 memflags
|= GMEM_ZEROINIT
;
259 memflags
= GMEM_ZEROINIT
| GMEM_FIXED
;
264 /***********************************************************************
265 * MODULE_AllocateSegment (WPROCS.26)
268 DWORD
MODULE_AllocateSegment(WORD wFlags
, WORD wSize
, WORD wElem
)
270 WORD size
= wSize
<< wElem
;
271 HANDLE16 hMem
= GlobalAlloc16( MODULE_Ne2MemFlags(wFlags
), size
);
272 return MAKELONG( hMem
, GlobalHandleToSel(hMem
) );
275 /***********************************************************************
276 * MODULE_CreateSegments
278 static BOOL32
MODULE_CreateSegments( HMODULE16 hModule
)
280 SEGTABLEENTRY
*pSegment
;
284 if (!(pModule
= MODULE_GetPtr( hModule
))) return FALSE
;
285 pSegment
= NE_SEG_TABLE( pModule
);
286 for (i
= 1; i
<= pModule
->seg_count
; i
++, pSegment
++)
288 minsize
= pSegment
->minsize
? pSegment
->minsize
: 0x10000;
289 if (i
== pModule
->ss
) minsize
+= pModule
->stack_size
;
290 /* The DGROUP is allocated by MODULE_CreateInstance */
291 if (i
== pModule
->dgroup
) continue;
292 pSegment
->selector
= GLOBAL_Alloc( MODULE_Ne2MemFlags(pSegment
->flags
),
294 !(pSegment
->flags
& NE_SEGFLAGS_DATA
),
296 FALSE
/*pSegment->flags & NE_SEGFLAGS_READONLY*/ );
297 if (!pSegment
->selector
) return FALSE
;
300 pModule
->dgroup_entry
= pModule
->dgroup
? pModule
->seg_table
+
301 (pModule
->dgroup
- 1) * sizeof(SEGTABLEENTRY
) : 0;
306 /***********************************************************************
309 HINSTANCE16
MODULE_GetInstance( HMODULE16 hModule
)
311 SEGTABLEENTRY
*pSegment
;
314 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
315 if (pModule
->dgroup
== 0) return hModule
;
317 pSegment
= NE_SEG_TABLE( pModule
) + pModule
->dgroup
- 1;
319 return pSegment
->selector
;
323 /***********************************************************************
324 * MODULE_CreateInstance
326 HINSTANCE16
MODULE_CreateInstance( HMODULE16 hModule
, LOADPARAMS
*params
)
328 SEGTABLEENTRY
*pSegment
;
331 HINSTANCE16 hNewInstance
, hPrevInstance
;
333 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
334 if (pModule
->dgroup
== 0) return hModule
;
336 pSegment
= NE_SEG_TABLE( pModule
) + pModule
->dgroup
- 1;
337 hPrevInstance
= pSegment
->selector
;
339 /* if it's a library, create a new instance only the first time */
342 if (pModule
->flags
& NE_FFLAGS_LIBMODULE
) return hPrevInstance
;
343 if (params
== (LOADPARAMS
*)-1) return hPrevInstance
;
346 minsize
= pSegment
->minsize
? pSegment
->minsize
: 0x10000;
347 if (pModule
->ss
== pModule
->dgroup
) minsize
+= pModule
->stack_size
;
348 minsize
+= pModule
->heap_size
;
349 hNewInstance
= GLOBAL_Alloc( GMEM_ZEROINIT
| GMEM_FIXED
,
350 minsize
, hModule
, FALSE
, FALSE
, FALSE
);
351 if (!hNewInstance
) return 0;
352 pSegment
->selector
= hNewInstance
;
357 /***********************************************************************
358 * MODULE_CreateDummyModule
360 * Create a dummy NE module for Win32 or Winelib.
362 HMODULE16
MODULE_CreateDummyModule( const OFSTRUCT
*ofs
)
366 SEGTABLEENTRY
*pSegment
;
367 char *pStr
,*basename
,*s
;
369 INT32 of_size
= sizeof(OFSTRUCT
) - sizeof(ofs
->szPathName
)
370 + strlen(ofs
->szPathName
) + 1;
371 INT32 size
= sizeof(NE_MODULE
) +
372 /* loaded file info */
374 /* segment table: DS,CS */
375 2 * sizeof(SEGTABLEENTRY
) +
378 /* several empty tables */
381 hModule
= GlobalAlloc16( GMEM_MOVEABLE
| GMEM_ZEROINIT
, size
);
382 if (!hModule
) return (HMODULE16
)11; /* invalid exe */
384 FarSetOwner( hModule
, hModule
);
385 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
387 /* Set all used entries */
388 pModule
->magic
= IMAGE_OS2_SIGNATURE
;
395 pModule
->heap_size
= 0xe000;
396 pModule
->stack_size
= 0x1000;
397 pModule
->seg_count
= 2;
398 pModule
->modref_count
= 0;
399 pModule
->nrname_size
= 0;
400 pModule
->fileinfo
= sizeof(NE_MODULE
);
401 pModule
->os_flags
= NE_OSFLAGS_WINDOWS
;
402 pModule
->expected_version
= 0x030a;
403 pModule
->self
= hModule
;
405 /* Set loaded file information */
406 memcpy( pModule
+ 1, ofs
, of_size
);
407 ((OFSTRUCT
*)(pModule
+1))->cBytes
= of_size
- 1;
409 pSegment
= (SEGTABLEENTRY
*)((char*)(pModule
+ 1) + of_size
);
410 pModule
->seg_table
= pModule
->dgroup_entry
= (int)pSegment
- (int)pModule
;
413 pSegment
->flags
= NE_SEGFLAGS_DATA
;
414 pSegment
->minsize
= 0x1000;
421 pStr
= (char *)pSegment
;
422 pModule
->name_table
= (int)pStr
- (int)pModule
;
423 /* strcpy( pStr, "\x08W32SXXXX" ); */
424 basename
= strrchr(ofs
->szPathName
,'\\');
426 basename
=ofs
->szPathName
;
429 basename
=strdup(basename
);
430 if ((s
=strchr(basename
,'.')))
432 *pStr
= strlen(basename
);
433 if (*pStr
>8) *pStr
=8;
434 strncpy( pStr
+1, basename
, 8 );
438 /* All tables zero terminated */
439 pModule
->res_table
= pModule
->import_table
= pModule
->entry_table
=
440 (int)pStr
- (int)pModule
;
442 MODULE_RegisterModule( pModule
);
447 /***********************************************************************
448 * MODULE_LoadExeHeader
450 static HMODULE16
MODULE_LoadExeHeader( HFILE32 hFile
, OFSTRUCT
*ofs
)
452 IMAGE_DOS_HEADER mz_header
;
453 IMAGE_OS2_HEADER ne_header
;
458 char *buffer
, *fastload
= NULL
;
459 int fastload_offset
= 0, fastload_length
= 0;
461 /* Read a block from either the file or the fast-load area. */
462 #define READ(offset,size,buffer) \
463 ((fastload && ((offset) >= fastload_offset) && \
464 ((offset)+(size) <= fastload_offset+fastload_length)) ? \
465 (memcpy( buffer, fastload+(offset)-fastload_offset, (size) ), TRUE) : \
466 (_llseek32( hFile, (offset), SEEK_SET), \
467 _lread32( hFile, (buffer), (size) ) == (size)))
469 _llseek32( hFile
, 0, SEEK_SET
);
470 if ((_lread32(hFile
,&mz_header
,sizeof(mz_header
)) != sizeof(mz_header
)) ||
471 (mz_header
.e_magic
!= IMAGE_DOS_SIGNATURE
))
472 return (HMODULE16
)11; /* invalid exe */
474 _llseek32( hFile
, mz_header
.e_lfanew
, SEEK_SET
);
475 if (_lread32( hFile
, &ne_header
, sizeof(ne_header
) ) != sizeof(ne_header
))
476 return (HMODULE16
)11; /* invalid exe */
478 if (ne_header
.ne_magic
== IMAGE_NT_SIGNATURE
) return (HMODULE16
)21; /* win32 exe */
479 if (ne_header
.ne_magic
!= IMAGE_OS2_SIGNATURE
) return (HMODULE16
)11; /* invalid exe */
481 /* We now have a valid NE header */
483 size
= sizeof(NE_MODULE
) +
484 /* loaded file info */
485 sizeof(OFSTRUCT
)-sizeof(ofs
->szPathName
)+strlen(ofs
->szPathName
)+1+
487 ne_header
.n_segment_tab
* sizeof(SEGTABLEENTRY
) +
489 ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
+
490 /* resident names table */
491 ne_header
.moduleref_tab_offset
- ne_header
.rname_tab_offset
+
492 /* module ref table */
493 ne_header
.n_mod_ref_tab
* sizeof(WORD
) +
494 /* imported names table */
495 ne_header
.entry_tab_offset
- ne_header
.iname_tab_offset
+
496 /* entry table length */
497 ne_header
.entry_tab_length
;
499 hModule
= GlobalAlloc16( GMEM_MOVEABLE
| GMEM_ZEROINIT
, size
);
500 if (!hModule
) return (HMODULE16
)11; /* invalid exe */
501 FarSetOwner( hModule
, hModule
);
502 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
503 memcpy( pModule
, &ne_header
, sizeof(ne_header
) );
505 pModule
->pe_module
= NULL
;
506 pModule
->self
= hModule
;
507 pModule
->self_loading_sel
= 0;
508 pData
= (BYTE
*)(pModule
+ 1);
510 /* Clear internal Wine flags in case they are set in the EXE file */
512 pModule
->flags
&= ~(NE_FFLAGS_BUILTIN
| NE_FFLAGS_WIN32
);
514 /* Read the fast-load area */
516 if (ne_header
.additional_flags
& NE_AFLAGS_FASTLOAD
)
518 fastload_offset
=ne_header
.fastload_offset
<<ne_header
.align_shift_count
;
519 fastload_length
=ne_header
.fastload_length
<<ne_header
.align_shift_count
;
520 dprintf_module( stddeb
, "Using fast-load area offset=%x len=%d\n",
521 fastload_offset
, fastload_length
);
522 if ((fastload
= HeapAlloc( SystemHeap
, 0, fastload_length
)) != NULL
)
524 _llseek32( hFile
, fastload_offset
, SEEK_SET
);
525 if (_lread32(hFile
, fastload
, fastload_length
) != fastload_length
)
527 HeapFree( SystemHeap
, 0, fastload
);
528 fprintf(stderr
, "Error reading fast-load area !\n");
534 /* Store the filename information */
536 pModule
->fileinfo
= (int)pData
- (int)pModule
;
537 size
= sizeof(OFSTRUCT
)-sizeof(ofs
->szPathName
)+strlen(ofs
->szPathName
)+1;
538 memcpy( pData
, ofs
, size
);
539 ((OFSTRUCT
*)pData
)->cBytes
= size
- 1;
542 /* Get the segment table */
544 pModule
->seg_table
= (int)pData
- (int)pModule
;
545 buffer
= HeapAlloc( SystemHeap
, 0, ne_header
.n_segment_tab
*
546 sizeof(struct ne_segment_table_entry_s
));
550 struct ne_segment_table_entry_s
*pSeg
;
552 if (!READ( mz_header
.e_lfanew
+ ne_header
.segment_tab_offset
,
553 ne_header
.n_segment_tab
* sizeof(struct ne_segment_table_entry_s
),
556 HeapFree( SystemHeap
, 0, buffer
);
557 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
558 GlobalFree16( hModule
);
559 return (HMODULE16
)11; /* invalid exe */
561 pSeg
= (struct ne_segment_table_entry_s
*)buffer
;
562 for (i
= ne_header
.n_segment_tab
; i
> 0; i
--, pSeg
++)
564 memcpy( pData
, pSeg
, sizeof(*pSeg
) );
565 pData
+= sizeof(SEGTABLEENTRY
);
567 HeapFree( SystemHeap
, 0, buffer
);
571 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
572 GlobalFree16( hModule
);
573 return (HMODULE16
)11; /* invalid exe */
576 /* Get the resource table */
578 if (ne_header
.resource_tab_offset
< ne_header
.rname_tab_offset
)
580 pModule
->res_table
= (int)pData
- (int)pModule
;
581 if (!READ(mz_header
.e_lfanew
+ ne_header
.resource_tab_offset
,
582 ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
,
583 pData
)) return (HMODULE16
)11; /* invalid exe */
584 pData
+= ne_header
.rname_tab_offset
- ne_header
.resource_tab_offset
;
586 else pModule
->res_table
= 0; /* No resource table */
588 /* Get the resident names table */
590 pModule
->name_table
= (int)pData
- (int)pModule
;
591 if (!READ( mz_header
.e_lfanew
+ ne_header
.rname_tab_offset
,
592 ne_header
.moduleref_tab_offset
- ne_header
.rname_tab_offset
,
595 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
596 GlobalFree16( hModule
);
597 return (HMODULE16
)11; /* invalid exe */
599 pData
+= ne_header
.moduleref_tab_offset
- ne_header
.rname_tab_offset
;
601 /* Get the module references table */
603 if (ne_header
.n_mod_ref_tab
> 0)
605 pModule
->modref_table
= (int)pData
- (int)pModule
;
606 if (!READ( mz_header
.e_lfanew
+ ne_header
.moduleref_tab_offset
,
607 ne_header
.n_mod_ref_tab
* sizeof(WORD
),
610 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
611 GlobalFree16( hModule
);
612 return (HMODULE16
)11; /* invalid exe */
614 pData
+= ne_header
.n_mod_ref_tab
* sizeof(WORD
);
616 else pModule
->modref_table
= 0; /* No module references */
618 /* Get the imported names table */
620 pModule
->import_table
= (int)pData
- (int)pModule
;
621 if (!READ( mz_header
.e_lfanew
+ ne_header
.iname_tab_offset
,
622 ne_header
.entry_tab_offset
- ne_header
.iname_tab_offset
,
625 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
626 GlobalFree16( hModule
);
627 return (HMODULE16
)11; /* invalid exe */
629 pData
+= ne_header
.entry_tab_offset
- ne_header
.iname_tab_offset
;
631 /* Get the entry table */
633 pModule
->entry_table
= (int)pData
- (int)pModule
;
634 if (!READ( mz_header
.e_lfanew
+ ne_header
.entry_tab_offset
,
635 ne_header
.entry_tab_length
,
638 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
639 GlobalFree16( hModule
);
640 return (HMODULE16
)11; /* invalid exe */
642 pData
+= ne_header
.entry_tab_length
;
644 /* Free the fast-load area */
647 if (fastload
) HeapFree( SystemHeap
, 0, fastload
);
649 /* Get the non-resident names table */
651 if (ne_header
.nrname_tab_length
)
653 pModule
->nrname_handle
= GLOBAL_Alloc( 0, ne_header
.nrname_tab_length
,
654 hModule
, FALSE
, FALSE
, FALSE
);
655 if (!pModule
->nrname_handle
)
657 GlobalFree16( hModule
);
658 return (HMODULE16
)11; /* invalid exe */
660 buffer
= GlobalLock16( pModule
->nrname_handle
);
661 _llseek32( hFile
, ne_header
.nrname_tab_offset
, SEEK_SET
);
662 if (_lread32( hFile
, buffer
, ne_header
.nrname_tab_length
)
663 != ne_header
.nrname_tab_length
)
665 GlobalFree16( pModule
->nrname_handle
);
666 GlobalFree16( hModule
);
667 return (HMODULE16
)11; /* invalid exe */
670 else pModule
->nrname_handle
= 0;
672 /* Allocate a segment for the implicitly-loaded DLLs */
674 if (pModule
->modref_count
)
676 pModule
->dlls_to_init
= GLOBAL_Alloc(GMEM_ZEROINIT
,
677 (pModule
->modref_count
+1)*sizeof(HMODULE16
),
678 hModule
, FALSE
, FALSE
, FALSE
);
679 if (!pModule
->dlls_to_init
)
681 if (pModule
->nrname_handle
) GlobalFree16( pModule
->nrname_handle
);
682 GlobalFree16( hModule
);
683 return (HMODULE16
)11; /* invalid exe */
686 else pModule
->dlls_to_init
= 0;
688 MODULE_RegisterModule( pModule
);
693 /***********************************************************************
696 * Lookup the ordinal for a given name.
698 WORD
MODULE_GetOrdinal( HMODULE16 hModule
, const char *name
)
700 unsigned char buffer
[256], *cpnt
;
704 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
706 dprintf_module( stddeb
, "MODULE_GetOrdinal(%04x,'%s')\n",
709 /* First handle names of the form '#xxxx' */
711 if (name
[0] == '#') return atoi( name
+ 1 );
713 /* Now copy and uppercase the string */
715 strcpy( buffer
, name
);
716 CharUpper32A( buffer
);
717 len
= strlen( buffer
);
719 /* First search the resident names */
721 cpnt
= (char *)pModule
+ pModule
->name_table
;
723 /* Skip the first entry (module name) */
724 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
727 if (((BYTE
)*cpnt
== len
) && !memcmp( cpnt
+1, buffer
, len
))
729 dprintf_module( stddeb
, " Found: ordinal=%d\n",
730 *(WORD
*)(cpnt
+ *cpnt
+ 1) );
731 return *(WORD
*)(cpnt
+ *cpnt
+ 1);
733 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
736 /* Now search the non-resident names table */
738 if (!pModule
->nrname_handle
) return 0; /* No non-resident table */
739 cpnt
= (char *)GlobalLock16( pModule
->nrname_handle
);
741 /* Skip the first entry (module description string) */
742 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
745 if (((BYTE
)*cpnt
== len
) && !memcmp( cpnt
+1, buffer
, len
))
747 dprintf_module( stddeb
, " Found: ordinal=%d\n",
748 *(WORD
*)(cpnt
+ *cpnt
+ 1) );
749 return *(WORD
*)(cpnt
+ *cpnt
+ 1);
751 cpnt
+= *cpnt
+ 1 + sizeof(WORD
);
757 /***********************************************************************
758 * MODULE_GetEntryPoint
760 * Return the entry point for a given ordinal.
762 FARPROC16
MODULE_GetEntryPoint( HMODULE16 hModule
, WORD ordinal
)
769 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
771 p
= (BYTE
*)pModule
+ pModule
->entry_table
;
772 while (*p
&& (curOrdinal
+ *p
<= ordinal
))
774 /* Skipping this bundle */
778 case 0: p
+= 2; break; /* unused */
779 case 0xff: p
+= 2 + *p
* 6; break; /* moveable */
780 default: p
+= 2 + *p
* 3; break; /* fixed */
789 case 0xff: /* moveable */
790 p
+= 2 + 6 * (ordinal
- curOrdinal
);
792 offset
= *(WORD
*)(p
+ 4);
796 p
+= 2 + 3 * (ordinal
- curOrdinal
);
797 offset
= *(WORD
*)(p
+ 1);
801 if (sel
== 0xfe) sel
= 0xffff; /* constant entry */
802 else sel
= (WORD
)(DWORD
)NE_SEG_TABLE(pModule
)[sel
-1].selector
;
803 return (FARPROC16
)PTR_SEG_OFF_TO_SEGPTR( sel
, offset
);
807 /***********************************************************************
808 * MODULE_SetEntryPoint
810 * Change the value of an entry point. Use with caution!
811 * It can only change the offset value, not the selector.
813 BOOL16
MODULE_SetEntryPoint( HMODULE16 hModule
, WORD ordinal
, WORD offset
)
819 if (!(pModule
= MODULE_GetPtr( hModule
))) return FALSE
;
821 p
= (BYTE
*)pModule
+ pModule
->entry_table
;
822 while (*p
&& (curOrdinal
+ *p
<= ordinal
))
824 /* Skipping this bundle */
828 case 0: p
+= 2; break; /* unused */
829 case 0xff: p
+= 2 + *p
* 6; break; /* moveable */
830 default: p
+= 2 + *p
* 3; break; /* fixed */
833 if (!*p
) return FALSE
;
839 case 0xff: /* moveable */
840 p
+= 2 + 6 * (ordinal
- curOrdinal
);
841 *(WORD
*)(p
+ 4) = offset
;
844 p
+= 2 + 3 * (ordinal
- curOrdinal
);
845 *(WORD
*)(p
+ 1) = offset
;
852 /***********************************************************************
853 * MODULE_GetWndProcEntry16 (not a Windows API function)
855 * Return an entry point from the WPROCS dll.
858 FARPROC16
MODULE_GetWndProcEntry16( const char *name
)
862 static HMODULE16 hModule
= 0;
864 if (!hModule
) hModule
= GetModuleHandle16( "WPROCS" );
865 ordinal
= MODULE_GetOrdinal( hModule
, name
);
866 if (!(ret
= MODULE_GetEntryPoint( hModule
, ordinal
)))
867 fprintf( stderr
, "GetWndProc16: %s not found, please report\n", name
);
873 /***********************************************************************
874 * MODULE_GetModuleName
876 LPSTR
MODULE_GetModuleName( HMODULE16 hModule
)
880 static char buffer
[10];
882 if (!(pModule
= MODULE_GetPtr( hModule
))) return NULL
;
883 p
= (BYTE
*)pModule
+ pModule
->name_table
;
885 memcpy( buffer
, p
+ 1, len
);
891 /**********************************************************************
892 * MODULE_RegisterModule
894 void MODULE_RegisterModule( NE_MODULE
*pModule
)
896 pModule
->next
= hFirstModule
;
897 hFirstModule
= pModule
->self
;
901 /**********************************************************************
904 * Find a module from a path name.
906 HMODULE16
MODULE_FindModule( LPCSTR path
)
908 HMODULE16 hModule
= hFirstModule
;
909 LPCSTR filename
, dotptr
, modulepath
, modulename
;
910 BYTE len
, *name_table
;
912 if (!(filename
= strrchr( path
, '\\' ))) filename
= path
;
914 if ((dotptr
= strrchr( filename
, '.' )) != NULL
)
915 len
= (BYTE
)(dotptr
- filename
);
916 else len
= strlen( filename
);
920 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
922 modulepath
= NE_MODULE_NAME(pModule
);
923 if (!(modulename
= strrchr( modulepath
, '\\' )))
924 modulename
= modulepath
;
926 if (!lstrcmpi32A( modulename
, filename
)) return hModule
;
928 name_table
= (BYTE
*)pModule
+ pModule
->name_table
;
929 if ((*name_table
== len
) && !lstrncmpi32A(filename
, name_table
+1, len
))
931 hModule
= pModule
->next
;
937 /**********************************************************************
940 * Call a DLL's WEP, allowing it to shut down.
941 * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
943 static BOOL16
MODULE_CallWEP( HMODULE16 hModule
)
945 FARPROC16 WEP
= (FARPROC16
)0;
946 WORD ordinal
= MODULE_GetOrdinal( hModule
, "WEP" );
948 if (ordinal
) WEP
= MODULE_GetEntryPoint( hModule
, ordinal
);
951 dprintf_module( stddeb
, "module %04x doesn't have a WEP\n", hModule
);
954 return CallWindowsExitProc( WEP
, WEP_FREE_DLL
);
958 /**********************************************************************
961 * Remove a module from memory.
963 static void MODULE_FreeModule( HMODULE16 hModule
)
965 HMODULE16
*hPrevModule
;
967 SEGTABLEENTRY
*pSegment
;
971 if (!(pModule
= MODULE_GetPtr( hModule
))) return;
972 if (pModule
->flags
& NE_FFLAGS_BUILTIN
)
973 return; /* Can't free built-in module */
975 if (pModule
->flags
& NE_FFLAGS_LIBMODULE
) MODULE_CallWEP( hModule
);
977 /* Free the objects owned by the module */
979 HOOK_FreeModuleHooks( hModule
);
980 CLASS_FreeModuleClasses( hModule
);
982 /* Clear magic number just in case */
984 pModule
->magic
= pModule
->self
= 0;
986 /* Remove it from the linked list */
988 hPrevModule
= &hFirstModule
;
989 while (*hPrevModule
&& (*hPrevModule
!= hModule
))
991 hPrevModule
= &(MODULE_GetPtr( *hPrevModule
))->next
;
993 if (*hPrevModule
) *hPrevModule
= pModule
->next
;
995 /* Free all the segments */
997 pSegment
= NE_SEG_TABLE( pModule
);
998 for (i
= 1; i
<= pModule
->seg_count
; i
++, pSegment
++)
1000 GlobalFree16( pSegment
->selector
);
1003 /* Free the referenced modules */
1005 pModRef
= (HMODULE16
*)NE_MODULE_TABLE( pModule
);
1006 for (i
= 0; i
< pModule
->modref_count
; i
++, pModRef
++)
1008 FreeModule16( *pModRef
);
1011 /* Free the module storage */
1013 if (pModule
->nrname_handle
) GlobalFree16( pModule
->nrname_handle
);
1014 if (pModule
->dlls_to_init
) GlobalFree16( pModule
->dlls_to_init
);
1015 GlobalFree16( hModule
);
1017 /* Remove module from cache */
1019 if (hCachedModule
== hModule
) hCachedModule
= 0;
1023 /**********************************************************************
1026 * Implementation of LoadModule()
1028 HINSTANCE16
MODULE_Load( LPCSTR name
, LPVOID paramBlock
, BOOL32 first
)
1031 HINSTANCE16 hInstance
, hPrevInstance
;
1033 LOADPARAMS
*params
= (LOADPARAMS
*)paramBlock
;
1036 WORD
*pModRef
, *pDLLs
;
1039 extern const char * DEBUG_curr_module
;
1041 hModule
= MODULE_FindModule( name
);
1043 if (!hModule
) /* We have to load the module */
1045 /* Try to load the built-in first if not disabled */
1046 if ((hModule
= BUILTIN_LoadModule( name
, FALSE
))) return hModule
;
1048 if ((hFile
= OpenFile32( name
, &ofs
, OF_READ
)) == HFILE_ERROR32
)
1050 /* Now try the built-in even if disabled */
1051 if ((hModule
= BUILTIN_LoadModule( name
, TRUE
)))
1053 fprintf( stderr
, "Warning: could not load Windows DLL '%s', using built-in module.\n", name
);
1056 return 2; /* File not found */
1060 * Record this so that the internal debugger gets some
1061 * record of what it is that we are working with.
1063 DEBUG_curr_module
= name
;
1065 /* Create the module structure */
1067 hModule
= MODULE_LoadExeHeader( hFile
, &ofs
);
1070 /* Note: PE_LoadModule closes the file */
1072 hModule
= PE_LoadModule( hFile
, &ofs
, paramBlock
);
1073 else _lclose32( hFile
);
1076 fprintf( stderr
, "LoadModule: can't load '%s', error=%d\n",
1081 pModule
= MODULE_GetPtr( hModule
);
1083 /* Allocate the segments for this module */
1085 MODULE_CreateSegments( hModule
);
1088 hInstance
= MODULE_CreateInstance( hModule
, (LOADPARAMS
*)paramBlock
);
1090 /* Load the referenced DLLs */
1092 pModRef
= (WORD
*)((char *)pModule
+ pModule
->modref_table
);
1093 pDLLs
= (WORD
*)GlobalLock16( pModule
->dlls_to_init
);
1094 for (i
= 0; i
< pModule
->modref_count
; i
++, pModRef
++)
1097 BYTE
*pstr
= (BYTE
*)pModule
+ pModule
->import_table
+ *pModRef
;
1098 memcpy( buffer
, pstr
+ 1, *pstr
);
1099 strcpy( buffer
+ *pstr
, ".dll" );
1100 dprintf_module( stddeb
, "Loading '%s'\n", buffer
);
1101 if (!(*pModRef
= MODULE_FindModule( buffer
)))
1103 /* If the DLL is not loaded yet, load it and store */
1104 /* its handle in the list of DLLs to initialize. */
1107 if ((hDLL
= MODULE_Load( buffer
, (LPVOID
)-1, FALSE
)) == 2)
1109 /* file not found */
1112 /* Try with prepending the path of the current module */
1113 GetModuleFileName16( hModule
, buffer
, sizeof(buffer
) );
1114 if (!(p
= strrchr( buffer
, '\\' ))) p
= buffer
;
1115 memcpy( p
+ 1, pstr
+ 1, *pstr
);
1116 strcpy( p
+ 1 + *pstr
, ".dll" );
1117 hDLL
= MODULE_Load( buffer
, (LPVOID
)-1, FALSE
);
1121 fprintf( stderr
, "Could not load '%s' required by '%s', error = %d\n",
1122 buffer
, name
, hDLL
);
1123 return 2; /* file not found */
1125 *pModRef
= GetExePtr( hDLL
);
1126 *pDLLs
++ = *pModRef
;
1128 else /* Increment the reference count of the DLL */
1130 NE_MODULE
*pOldDLL
= MODULE_GetPtr( *pModRef
);
1131 if (pOldDLL
) pOldDLL
->count
++;
1135 /* Load the segments */
1137 if (pModule
->flags
& NE_FFLAGS_SELFLOAD
)
1140 HGLOBAL16 hInitialStack32
= 0;
1141 /* Handle self loading modules */
1142 SEGTABLEENTRY
* pSegTable
= (SEGTABLEENTRY
*) NE_SEG_TABLE(pModule
);
1143 SELFLOADHEADER
*selfloadheader
;
1144 STACK16FRAME
*stack16Top
;
1145 HMODULE16 hselfload
= GetModuleHandle16("WPROCS");
1147 WORD saved_dgroup
= pSegTable
[pModule
->dgroup
- 1].selector
;
1148 fprintf (stderr
, "Warning: %*.*s is a self-loading module\n"
1149 "Support for self-loading modules is very experimental\n",
1150 *((BYTE
*)pModule
+ pModule
->name_table
),
1151 *((BYTE
*)pModule
+ pModule
->name_table
),
1152 (char *)pModule
+ pModule
->name_table
+ 1);
1153 NE_LoadSegment( hModule
, 1 );
1154 selfloadheader
= (SELFLOADHEADER
*)
1155 PTR_SEG_OFF_TO_LIN(pSegTable
->selector
, 0);
1156 selfloadheader
->EntryAddrProc
=
1157 MODULE_GetEntryPoint(hselfload
,27);
1158 selfloadheader
->MyAlloc
= MODULE_GetEntryPoint(hselfload
,28);
1159 selfloadheader
->SetOwner
= MODULE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
1160 pModule
->self_loading_sel
= GlobalHandleToSel(
1161 GLOBAL_Alloc (GMEM_ZEROINIT
,
1162 0xFF00, hModule
, FALSE
, FALSE
, FALSE
)
1164 oldstack
= IF1632_Saved16_ss_sp
;
1165 IF1632_Saved16_ss_sp
= MAKELONG( 0xFF00 - sizeof(*stack16Top
),
1166 pModule
->self_loading_sel
);
1167 stack16Top
= CURRENT_STACK16
;
1168 stack16Top
->saved_ss_sp
= 0;
1169 stack16Top
->ebp
= 0;
1170 stack16Top
->ds
= stack16Top
->es
= pModule
->self_loading_sel
;
1171 stack16Top
->entry_point
= 0;
1172 stack16Top
->entry_ip
= 0;
1173 stack16Top
->entry_cs
= 0;
1178 if (!IF1632_Saved32_esp
)
1180 STACK32FRAME
* frame32
;
1182 /* Setup an initial 32 bit stack frame */
1183 hInitialStack32
= GLOBAL_Alloc( GMEM_FIXED
, 0x10000,
1184 hModule
, FALSE
, FALSE
,
1187 /* Create the 32-bit stack frame */
1189 stack32Top
= (char*)GlobalLock16(hInitialStack32
) +
1191 frame32
= (STACK32FRAME
*)stack32Top
- 1;
1192 frame32
->saved_esp
= (DWORD
)stack32Top
;
1199 frame32
->retaddr
= 0;
1200 frame32
->codeselector
= WINE_CODE_SELECTOR
;
1201 /* pTask->esp = (DWORD)frame32; */
1203 hf
= FILE_DupUnixHandle( MODULE_OpenFile( hModule
) );
1204 CallTo16_word_ww( selfloadheader
->BootApp
, hModule
, hf
);
1206 /* some BootApp procs overwrite the selector of dgroup */
1207 pSegTable
[pModule
->dgroup
- 1].selector
= saved_dgroup
;
1208 IF1632_Saved16_ss_sp
= oldstack
;
1209 for (i
= 2; i
<= pModule
->seg_count
; i
++) NE_LoadSegment( hModule
, i
);
1210 if (hInitialStack32
)
1212 GlobalFree16(hInitialStack32
);
1213 hInitialStack32
= 0;
1218 for (i
= 1; i
<= pModule
->seg_count
; i
++)
1219 NE_LoadSegment( hModule
, i
);
1222 /* Fixup the functions prologs */
1224 NE_FixupPrologs( pModule
);
1226 /* Make sure the usage count is 1 on the first loading of */
1227 /* the module, even if it contains circular DLL references */
1231 if (first
&& (pModule
->flags
& NE_FFLAGS_LIBMODULE
))
1232 NE_InitializeDLLs( hModule
);
1236 pModule
= MODULE_GetPtr( hModule
);
1237 hPrevInstance
= MODULE_GetInstance( hModule
);
1238 hInstance
= MODULE_CreateInstance( hModule
, params
);
1239 if (hInstance
!= hPrevInstance
) /* not a library */
1240 NE_LoadSegment( hModule
, pModule
->dgroup
);
1244 lstrcpyn32A( ofs
.szPathName
, name
, sizeof(ofs
.szPathName
) );
1245 if ((hModule
= MODULE_CreateDummyModule( &ofs
)) < 32) return hModule
;
1246 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
1248 hInstance
= MODULE_CreateInstance( hModule
, params
);
1249 #endif /* WINELIB */
1251 /* Create a task for this instance */
1253 if (!(pModule
->flags
& NE_FFLAGS_LIBMODULE
) && (paramBlock
!= (LPVOID
)-1))
1258 /* PowerPoint passes NULL as showCmd */
1259 if (params
->showCmd
)
1260 showcmd
= *((WORD
*)PTR_SEG_TO_LIN(params
->showCmd
)+1);
1262 showcmd
= 0; /* FIXME: correct */
1264 hTask
= TASK_CreateTask( hModule
, hInstance
, hPrevInstance
,
1265 params
->hEnvironment
,
1266 (LPSTR
)PTR_SEG_TO_LIN( params
->cmdLine
),
1269 if( hTask
&& TASK_GetNextTask(hTask
)) Yield();
1276 /**********************************************************************
1277 * LoadModule16 (KERNEL.45)
1279 HINSTANCE16
LoadModule16( LPCSTR name
, LPVOID paramBlock
)
1281 return MODULE_Load( name
, paramBlock
, TRUE
);
1285 /**********************************************************************
1286 * FreeModule16 (KERNEL.46)
1288 BOOL16
FreeModule16( HMODULE16 hModule
)
1292 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1293 if (!(pModule
= MODULE_GetPtr( hModule
))) return FALSE
;
1295 dprintf_module( stddeb
, "FreeModule16: %s count %d\n",
1296 MODULE_GetModuleName(hModule
), pModule
->count
);
1297 if (--pModule
->count
== 0) MODULE_FreeModule( hModule
);
1302 /**********************************************************************
1303 * GetModuleHandle16 (KERNEL.47)
1305 HMODULE16
WIN16_GetModuleHandle( SEGPTR name
)
1307 if (HIWORD(name
) == 0) return GetExePtr( (HINSTANCE16
)name
);
1308 return MODULE_FindModule( PTR_SEG_TO_LIN(name
) );
1311 HMODULE16
GetModuleHandle16( LPCSTR name
)
1313 return MODULE_FindModule( name
);
1317 /**********************************************************************
1318 * GetModuleUsage (KERNEL.48)
1320 INT16
GetModuleUsage( HINSTANCE16 hModule
)
1324 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1325 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
1326 dprintf_module( stddeb
, "GetModuleUsage(%04x): returning %d\n",
1327 hModule
, pModule
->count
);
1328 return pModule
->count
;
1332 /**********************************************************************
1333 * GetModuleFileName16 (KERNEL.49)
1335 INT16
GetModuleFileName16( HINSTANCE16 hModule
, LPSTR lpFileName
, INT16 nSize
)
1339 if (!hModule
) hModule
= GetCurrentTask();
1340 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1341 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
1342 lstrcpyn32A( lpFileName
, NE_MODULE_NAME(pModule
), nSize
);
1343 dprintf_module( stddeb
, "GetModuleFileName16: %s\n", lpFileName
);
1344 return strlen(lpFileName
);
1348 /***********************************************************************
1349 * GetModuleFileName32A (KERNEL32.235)
1351 DWORD
GetModuleFileName32A( HMODULE32 hModule
, LPSTR lpFileName
, DWORD size
)
1357 TDB
*pTask
= (TDB
*)GlobalLock16( GetCurrentTask() );
1358 hModule
= pTask
->hInstance
;
1360 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1361 if (!(pModule
= MODULE_GetPtr( hModule
))) return 0;
1362 lstrcpyn32A( lpFileName
, NE_MODULE_NAME(pModule
), size
);
1363 dprintf_module( stddeb
, "GetModuleFileName32A: %s\n", lpFileName
);
1364 return strlen(lpFileName
);
1368 /***********************************************************************
1369 * GetModuleFileName32W (KERNEL32.236)
1371 DWORD
GetModuleFileName32W( HMODULE32 hModule
, LPWSTR lpFileName
, DWORD size
)
1373 LPSTR fnA
= (char*)HeapAlloc( GetProcessHeap(), 0, size
);
1374 DWORD res
= GetModuleFileName32A( hModule
, fnA
, size
);
1375 lstrcpynAtoW( lpFileName
, fnA
, size
);
1376 HeapFree( GetProcessHeap(), 0, fnA
);
1381 /**********************************************************************
1382 * GetModuleName (KERNEL.27)
1384 BOOL16
GetModuleName( HINSTANCE16 hinst
, LPSTR buf
, INT16 nSize
)
1386 LPSTR name
= MODULE_GetModuleName(hinst
);
1388 if (!name
) return FALSE
;
1389 lstrcpyn32A( buf
, name
, nSize
);
1394 /***********************************************************************
1395 * LoadLibraryEx32W (KERNEL.513)
1397 HINSTANCE16
LoadLibraryEx32W16( LPCSTR libname
, HANDLE16 hf
, DWORD flags
)
1399 fprintf(stderr
,"LoadLibraryEx32W(%s,%d,%08lx)\n",libname
,hf
,flags
);
1401 return LoadLibrary32A(libname
);
1405 /***********************************************************************
1406 * LoadLibrary (KERNEL.95)
1408 HINSTANCE16
LoadLibrary16( LPCSTR libname
)
1414 fprintf( stderr
, "LoadLibrary not supported in Winelib\n" );
1417 dprintf_module( stddeb
, "LoadLibrary: (%08x) %s\n", (int)libname
, libname
);
1419 /* This does not increment the module reference count, and will
1420 * therefore cause crashes on FreeLibrary calls.
1421 if ((handle = MODULE_FindModule( libname )) != 0) return handle;
1423 handle
= MODULE_Load( libname
, (LPVOID
)-1, TRUE
);
1424 if (handle
== (HINSTANCE16
)2) /* file not found */
1427 lstrcpyn32A( buffer
, libname
, 252 );
1428 strcat( buffer
, ".dll" );
1429 handle
= MODULE_Load( buffer
, (LPVOID
)-1, TRUE
);
1435 /***********************************************************************
1436 * FreeLibrary16 (KERNEL.96)
1438 void FreeLibrary16( HINSTANCE16 handle
)
1440 dprintf_module( stddeb
,"FreeLibrary: %04x\n", handle
);
1441 FreeModule16( handle
);
1445 /***********************************************************************
1446 * WinExec16 (KERNEL.166)
1448 HINSTANCE16
WinExec16( LPCSTR lpCmdLine
, UINT16 nCmdShow
)
1450 return WinExec32( lpCmdLine
, nCmdShow
);
1454 /***********************************************************************
1455 * WinExec32 (KERNEL32.566)
1457 HINSTANCE32
WinExec32( LPCSTR lpCmdLine
, UINT32 nCmdShow
)
1460 HGLOBAL16 cmdShowHandle
, cmdLineHandle
;
1463 char *p
, *cmdline
, filename
[256];
1464 static int use_load_module
= 1;
1467 return 2; /* File not found */
1468 if (!(cmdShowHandle
= GlobalAlloc16( 0, 2 * sizeof(WORD
) )))
1469 return 8; /* Out of memory */
1470 if (!(cmdLineHandle
= GlobalAlloc16( 0, 256 )))
1472 GlobalFree16( cmdShowHandle
);
1473 return 8; /* Out of memory */
1476 /* Store nCmdShow */
1478 cmdShowPtr
= (WORD
*)GlobalLock16( cmdShowHandle
);
1480 cmdShowPtr
[1] = nCmdShow
;
1482 /* Build the filename and command-line */
1484 cmdline
= (char *)GlobalLock16( cmdLineHandle
);
1485 lstrcpyn32A(filename
, lpCmdLine
, sizeof(filename
) - 4 /* for extension */);
1486 for (p
= filename
; *p
&& (*p
!= ' ') && (*p
!= '\t'); p
++);
1487 if (*p
) lstrcpyn32A( cmdline
+ 1, p
+ 1, 127 );
1488 else cmdline
[1] = '\0';
1489 cmdline
[0] = strlen( cmdline
+ 1 ) + 1;
1492 /* Now load the executable file */
1494 if (use_load_module
)
1497 /* WINELIB: Use LoadModule() only for the program itself */
1498 use_load_module
= 0;
1499 params
.hEnvironment
= (HGLOBAL16
)GetDOSEnvironment();
1501 params
.hEnvironment
= (HGLOBAL16
)SELECTOROF( GetDOSEnvironment() );
1502 #endif /* WINELIB */
1503 params
.cmdLine
= (SEGPTR
)WIN16_GlobalLock16( cmdLineHandle
);
1504 params
.showCmd
= (SEGPTR
)WIN16_GlobalLock16( cmdShowHandle
);
1505 params
.reserved
= 0;
1506 handle
= LoadModule16( filename
, ¶ms
);
1507 if (handle
== 2) /* file not found */
1509 /* Check that the original file name did not have a suffix */
1510 p
= strrchr(filename
, '.');
1511 /* if there is a '.', check if either \ OR / follow */
1512 if (!p
|| strchr(p
, '/') || strchr(p
, '\\'))
1514 p
= filename
+ strlen(filename
);
1515 strcpy( p
, ".exe" );
1516 handle
= LoadModule16( filename
, ¶ms
);
1517 *p
= '\0'; /* Remove extension */
1525 /* Try to start it as a unix program */
1529 DOS_FULL_NAME full_name
;
1530 const char *unixfilename
= NULL
;
1531 const char *argv
[256], **argptr
;
1532 int iconic
= (nCmdShow
== SW_SHOWMINIMIZED
||
1533 nCmdShow
== SW_SHOWMINNOACTIVE
);
1535 /* get unixfilename */
1536 if (strchr(filename
, '/') ||
1537 strchr(filename
, ':') ||
1538 strchr(filename
, '\\'))
1540 if (DOSFS_GetFullName( filename
, TRUE
, &full_name
))
1541 unixfilename
= full_name
.long_name
;
1543 else unixfilename
= filename
;
1549 if (iconic
) *argptr
++ = "-iconic";
1550 *argptr
++ = unixfilename
;
1554 while (*p
&& (*p
== ' ' || *p
== '\t')) *p
++ = '\0';
1557 while (*p
&& *p
!= ' ' && *p
!= '\t') p
++;
1562 execvp(argv
[0], (char**)argv
);
1572 if (iconic
) *argptr
++ = "-iconic";
1573 *argptr
++ = lpCmdLine
;
1577 execvp(argv
[0] , (char**)argv
);
1580 fprintf(stderr
, "WinExec: can't exec 'wine %s'\n", lpCmdLine
);
1586 GlobalFree16( cmdShowHandle
);
1587 GlobalFree16( cmdLineHandle
);
1592 /***********************************************************************
1593 * GetProcAddress16 (KERNEL.50)
1595 FARPROC16
GetProcAddress16( HMODULE16 hModule
, SEGPTR name
)
1600 if (!hModule
) hModule
= GetCurrentTask();
1601 hModule
= GetExePtr( hModule
);
1603 if (HIWORD(name
) != 0)
1605 ordinal
= MODULE_GetOrdinal( hModule
, (LPSTR
)PTR_SEG_TO_LIN(name
) );
1606 dprintf_module( stddeb
, "GetProcAddress: %04x '%s'\n",
1607 hModule
, (LPSTR
)PTR_SEG_TO_LIN(name
) );
1611 ordinal
= LOWORD(name
);
1612 dprintf_module( stddeb
, "GetProcAddress: %04x %04x\n",
1615 if (!ordinal
) return (FARPROC16
)0;
1617 ret
= MODULE_GetEntryPoint( hModule
, ordinal
);
1619 dprintf_module( stddeb
, "GetProcAddress: returning %08x\n", (UINT32
)ret
);
1624 /***********************************************************************
1625 * GetProcAddress32 (KERNEL32.257)
1627 FARPROC32
GetProcAddress32( HMODULE32 hModule
, LPCSTR function
)
1632 if (HIWORD(function
))
1633 dprintf_win32(stddeb
,"GetProcAddress32(%08lx,%s)\n",(DWORD
)hModule
,function
);
1635 dprintf_win32(stddeb
,"GetProcAddress32(%08lx,%p)\n",(DWORD
)hModule
,function
);
1636 hModule
= GetExePtr( hModule
);
1637 if (!(pModule
= MODULE_GetPtr( hModule
)))
1638 return (FARPROC32
)0;
1639 if (!(pModule
->flags
& NE_FFLAGS_WIN32
) || !pModule
->pe_module
)
1640 return (FARPROC32
)0;
1641 if (pModule
->flags
& NE_FFLAGS_BUILTIN
)
1642 return BUILTIN_GetProcAddress32( pModule
, function
);
1643 return PE_FindExportedFunction( pModule
->pe_module
, function
);
1649 /***********************************************************************
1650 * RtlImageNtHeaders (NTDLL)
1653 RtlImageNtHeader(HMODULE32 hModule
)
1658 hModule
= GetExePtr( hModule
);
1659 if (!(pModule
= MODULE_GetPtr( hModule
)))
1660 return (LPIMAGE_NT_HEADERS
)0;
1661 if (!(pModule
->flags
& NE_FFLAGS_WIN32
) || !pModule
->pe_module
)
1662 return (LPIMAGE_NT_HEADERS
)0;
1663 return pModule
->pe_module
->pe_header
;
1670 /**********************************************************************
1671 * GetExpWinVer (KERNEL.167)
1673 WORD
GetExpWinVer( HMODULE16 hModule
)
1675 NE_MODULE
*pModule
= MODULE_GetPtr( hModule
);
1676 return pModule
? pModule
->expected_version
: 0;
1680 /**********************************************************************
1681 * IsSharedSelector (KERNEL.345)
1683 BOOL16
IsSharedSelector( HANDLE16 selector
)
1685 /* Check whether the selector belongs to a DLL */
1686 NE_MODULE
*pModule
= MODULE_GetPtr( GetExePtr( selector
));
1687 if (!pModule
) return FALSE
;
1688 return (pModule
->flags
& NE_FFLAGS_LIBMODULE
) != 0;
1692 /**********************************************************************
1693 * ModuleFirst (TOOLHELP.59)
1695 BOOL16
ModuleFirst( MODULEENTRY
*lpme
)
1697 lpme
->wNext
= hFirstModule
;
1698 return ModuleNext( lpme
);
1702 /**********************************************************************
1703 * ModuleNext (TOOLHELP.60)
1705 BOOL16
ModuleNext( MODULEENTRY
*lpme
)
1709 if (!lpme
->wNext
) return FALSE
;
1710 if (!(pModule
= MODULE_GetPtr( lpme
->wNext
))) return FALSE
;
1711 strncpy( lpme
->szModule
, (char *)pModule
+ pModule
->name_table
,
1713 lpme
->szModule
[MAX_MODULE_NAME
] = '\0';
1714 lpme
->hModule
= lpme
->wNext
;
1715 lpme
->wcUsage
= pModule
->count
;
1716 strncpy( lpme
->szExePath
, NE_MODULE_NAME(pModule
), MAX_PATH
);
1717 lpme
->szExePath
[MAX_PATH
] = '\0';
1718 lpme
->wNext
= pModule
->next
;
1723 /**********************************************************************
1724 * ModuleFindName (TOOLHELP.61)
1726 BOOL16
ModuleFindName( MODULEENTRY
*lpme
, LPCSTR name
)
1728 lpme
->wNext
= GetModuleHandle16( name
);
1729 return ModuleNext( lpme
);
1733 /**********************************************************************
1734 * ModuleFindHandle (TOOLHELP.62)
1736 BOOL16
ModuleFindHandle( MODULEENTRY
*lpme
, HMODULE16 hModule
)
1738 hModule
= GetExePtr( hModule
); /* In case we were passed an hInstance */
1739 lpme
->wNext
= hModule
;
1740 return ModuleNext( lpme
);