Release 970720
[wine/multimedia.git] / loader / module.c
bloba3522c61db8bc29f662eee8b473b3fd878e16443
1 /*
2 * Modules
4 * Copyright 1995 Alexandre Julliard
5 */
7 #include <fcntl.h>
8 #include <stdlib.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 #include "windows.h"
14 #include "class.h"
15 #include "file.h"
16 #include "global.h"
17 #include "heap.h"
18 #include "hook.h"
19 #include "module.h"
20 #include "neexe.h"
21 #include "selectors.h"
22 #include "stackframe.h"
23 #include "task.h"
24 #include "toolhelp.h"
25 #include "stddebug.h"
26 #include "debug.h"
27 #include "callback.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 /***********************************************************************
36 * MODULE_GetPtr
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;
43 return pModule;
47 /***********************************************************************
48 * MODULE_DumpModule
50 void MODULE_DumpModule( HMODULE16 hModule )
52 int i, ordinal;
53 SEGTABLEENTRY *pSeg;
54 BYTE *pstr;
55 WORD *pword;
56 NE_MODULE *pModule;
58 if (!(pModule = MODULE_GetPtr( hModule )))
60 fprintf( stderr, "**** %04x is not a module handle\n", hModule );
61 return;
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++ );
99 while (*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;
116 while (*pstr)
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;
141 ordinal = 1;
142 while (*pstr)
144 printf( "Bundle %d-%d: %02x\n", ordinal, ordinal + *pstr - 1, pstr[1]);
145 if (!pstr[1])
147 ordinal += *pstr;
148 pstr += 2;
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 );
156 pstr = (char *)pe;
158 else /* fixed */
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) );
164 pstr = (char *)pe;
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 );
174 while (*pstr)
176 printf( "%*.*s: %d\n", *pstr, *pstr, pstr + 1,
177 *(WORD *)(pstr + *pstr + 1) );
178 pstr += *pstr + 1 + sizeof(WORD);
181 printf( "\n" );
185 /***********************************************************************
186 * MODULE_WalkModules
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" );
194 while (hModule)
196 NE_MODULE *pModule = MODULE_GetPtr( hModule );
197 if (!pModule)
199 fprintf( stderr, "**** Bad module %04x in list\n", hModule );
200 return;
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 /***********************************************************************
211 * MODULE_OpenFile
213 int MODULE_OpenFile( HMODULE16 hModule )
215 NE_MODULE *pModule;
216 DOS_FULL_NAME full_name;
217 char *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;
226 close( 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",
232 name, hModule );
233 dprintf_module( stddeb, "MODULE_OpenFile: opened '%s' -> %d\n",
234 name, cachedfd );
235 return cachedfd;
239 /***********************************************************************
240 * MODULE_Ne2MemFlags
242 * This function translates NE segment flags to GlobalAlloc flags
244 static WORD MODULE_Ne2MemFlags(WORD flags)
246 WORD memflags = 0;
247 #if 0
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;
258 #else
259 memflags = GMEM_ZEROINIT | GMEM_FIXED;
260 return memflags;
261 #endif
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;
281 NE_MODULE *pModule;
282 int i, minsize;
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),
293 minsize, hModule,
294 !(pSegment->flags & NE_SEGFLAGS_DATA),
295 FALSE,
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;
302 return TRUE;
306 /***********************************************************************
307 * MODULE_GetInstance
309 HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule )
311 SEGTABLEENTRY *pSegment;
312 NE_MODULE *pModule;
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;
329 NE_MODULE *pModule;
330 int minsize;
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 */
340 if (hPrevInstance)
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;
353 return hNewInstance;
357 /***********************************************************************
358 * MODULE_CreateDummyModule
360 * Create a dummy NE module for Win32 or Winelib.
362 HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs )
364 HMODULE16 hModule;
365 NE_MODULE *pModule;
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 */
373 of_size +
374 /* segment table: DS,CS */
375 2 * sizeof(SEGTABLEENTRY) +
376 /* name table */
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;
389 pModule->count = 1;
390 pModule->next = 0;
391 pModule->flags = 0;
392 pModule->dgroup = 1;
393 pModule->ss = 1;
394 pModule->cs = 2;
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;
411 /* Data segment */
412 pSegment->size = 0;
413 pSegment->flags = NE_SEGFLAGS_DATA;
414 pSegment->minsize = 0x1000;
415 pSegment++;
416 /* Code segment */
417 pSegment->flags = 0;
418 pSegment++;
420 /* Module name */
421 pStr = (char *)pSegment;
422 pModule->name_table = (int)pStr - (int)pModule;
423 /* strcpy( pStr, "\x08W32SXXXX" ); */
424 basename = strrchr(ofs->szPathName,'\\');
425 if (!basename)
426 basename=ofs->szPathName;
427 else
428 basename++;
429 basename=strdup(basename);
430 if ((s=strchr(basename,'.')))
431 *s='\0';
432 *pStr = strlen(basename);
433 if (*pStr>8) *pStr=8;
434 strncpy( pStr+1, basename, 8 );
435 free(basename);
436 pStr += 9;
438 /* All tables zero terminated */
439 pModule->res_table = pModule->import_table = pModule->entry_table =
440 (int)pStr - (int)pModule;
442 MODULE_RegisterModule( pModule );
443 return hModule;
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;
454 int size;
455 HMODULE16 hModule;
456 NE_MODULE *pModule;
457 BYTE *pData;
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+
486 /* segment table */
487 ne_header.n_segment_tab * sizeof(SEGTABLEENTRY) +
488 /* resource table */
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) );
504 pModule->count = 0;
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");
529 fastload = NULL;
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;
540 pData += size;
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));
547 if (buffer)
549 int i;
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),
554 buffer ))
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 );
569 else
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,
593 pData ))
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),
608 pData ))
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,
623 pData ))
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,
636 pData ))
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 */
646 #undef READ
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 );
689 return hModule;
693 /***********************************************************************
694 * MODULE_GetOrdinal
696 * Lookup the ordinal for a given name.
698 WORD MODULE_GetOrdinal( HMODULE16 hModule, const char *name )
700 unsigned char buffer[256], *cpnt;
701 BYTE len;
702 NE_MODULE *pModule;
704 if (!(pModule = MODULE_GetPtr( hModule ))) return 0;
706 dprintf_module( stddeb, "MODULE_GetOrdinal(%04x,'%s')\n",
707 hModule, name );
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);
725 while (*cpnt)
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);
743 while (*cpnt)
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);
753 return 0;
757 /***********************************************************************
758 * MODULE_GetEntryPoint
760 * Return the entry point for a given ordinal.
762 FARPROC16 MODULE_GetEntryPoint( HMODULE16 hModule, WORD ordinal )
764 NE_MODULE *pModule;
765 WORD curOrdinal = 1;
766 BYTE *p;
767 WORD sel, offset;
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 */
775 curOrdinal += *p;
776 switch(p[1])
778 case 0: p += 2; break; /* unused */
779 case 0xff: p += 2 + *p * 6; break; /* moveable */
780 default: p += 2 + *p * 3; break; /* fixed */
783 if (!*p) return 0;
785 switch(p[1])
787 case 0: /* unused */
788 return 0;
789 case 0xff: /* moveable */
790 p += 2 + 6 * (ordinal - curOrdinal);
791 sel = p[3];
792 offset = *(WORD *)(p + 4);
793 break;
794 default: /* fixed */
795 sel = p[1];
796 p += 2 + 3 * (ordinal - curOrdinal);
797 offset = *(WORD *)(p + 1);
798 break;
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 )
815 NE_MODULE *pModule;
816 WORD curOrdinal = 1;
817 BYTE *p;
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 */
825 curOrdinal += *p;
826 switch(p[1])
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;
835 switch(p[1])
837 case 0: /* unused */
838 return FALSE;
839 case 0xff: /* moveable */
840 p += 2 + 6 * (ordinal - curOrdinal);
841 *(WORD *)(p + 4) = offset;
842 break;
843 default: /* fixed */
844 p += 2 + 3 * (ordinal - curOrdinal);
845 *(WORD *)(p + 1) = offset;
846 break;
848 return TRUE;
852 /***********************************************************************
853 * MODULE_GetWndProcEntry16 (not a Windows API function)
855 * Return an entry point from the WPROCS dll.
857 #ifndef WINELIB
858 FARPROC16 MODULE_GetWndProcEntry16( const char *name )
860 WORD ordinal;
861 FARPROC16 ret;
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 );
868 return ret;
870 #endif
873 /***********************************************************************
874 * MODULE_GetModuleName
876 LPSTR MODULE_GetModuleName( HMODULE16 hModule )
878 NE_MODULE *pModule;
879 BYTE *p, len;
880 static char buffer[10];
882 if (!(pModule = MODULE_GetPtr( hModule ))) return NULL;
883 p = (BYTE *)pModule + pModule->name_table;
884 len = MIN( *p, 8 );
885 memcpy( buffer, p + 1, len );
886 buffer[len] = '\0';
887 return buffer;
891 /**********************************************************************
892 * MODULE_RegisterModule
894 void MODULE_RegisterModule( NE_MODULE *pModule )
896 pModule->next = hFirstModule;
897 hFirstModule = pModule->self;
901 /**********************************************************************
902 * MODULE_FindModule
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;
913 else filename++;
914 if ((dotptr = strrchr( filename, '.' )) != NULL)
915 len = (BYTE)(dotptr - filename);
916 else len = strlen( filename );
918 while(hModule)
920 NE_MODULE *pModule = MODULE_GetPtr( hModule );
921 if (!pModule) break;
922 modulepath = NE_MODULE_NAME(pModule);
923 if (!(modulename = strrchr( modulepath, '\\' )))
924 modulename = modulepath;
925 else modulename++;
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))
930 return hModule;
931 hModule = pModule->next;
933 return 0;
937 /**********************************************************************
938 * MODULE_CallWEP
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 );
949 if (!WEP)
951 dprintf_module( stddeb, "module %04x doesn't have a WEP\n", hModule );
952 return FALSE;
954 return CallWindowsExitProc( WEP, WEP_FREE_DLL );
958 /**********************************************************************
959 * MODULE_FreeModule
961 * Remove a module from memory.
963 static void MODULE_FreeModule( HMODULE16 hModule )
965 HMODULE16 *hPrevModule;
966 NE_MODULE *pModule;
967 SEGTABLEENTRY *pSegment;
968 HMODULE16 *pModRef;
969 int i;
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 /**********************************************************************
1024 * MODULE_Load
1026 * Implementation of LoadModule()
1028 HINSTANCE16 MODULE_Load( LPCSTR name, LPVOID paramBlock, BOOL32 first )
1030 HMODULE16 hModule;
1031 HINSTANCE16 hInstance, hPrevInstance;
1032 NE_MODULE *pModule;
1033 LOADPARAMS *params = (LOADPARAMS *)paramBlock;
1034 OFSTRUCT ofs;
1035 #ifndef WINELIB
1036 WORD *pModRef, *pDLLs;
1037 HFILE32 hFile;
1038 int i;
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 );
1054 return hModule;
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 );
1068 if (hModule < 32)
1070 /* Note: PE_LoadModule closes the file */
1071 if (hModule == 21)
1072 hModule = PE_LoadModule( hFile, &ofs, paramBlock );
1073 else _lclose32( hFile );
1075 if (hModule < 32)
1076 fprintf( stderr, "LoadModule: can't load '%s', error=%d\n",
1077 name, hModule );
1078 return hModule;
1080 _lclose32( hFile );
1081 pModule = MODULE_GetPtr( hModule );
1083 /* Allocate the segments for this module */
1085 MODULE_CreateSegments( hModule );
1087 hPrevInstance = 0;
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++)
1096 char buffer[256];
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. */
1105 HMODULE16 hDLL;
1107 if ((hDLL = MODULE_Load( buffer, (LPVOID)-1, FALSE )) == 2)
1109 /* file not found */
1110 char *p;
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 );
1119 if (hDLL < 32)
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)
1139 HFILE32 hf;
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");
1146 DWORD oldstack;
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;
1174 stack16Top->bp = 0;
1175 stack16Top->ip = 0;
1176 stack16Top->cs = 0;
1178 if (!IF1632_Saved32_esp)
1180 STACK32FRAME* frame32;
1181 char *stack32Top;
1182 /* Setup an initial 32 bit stack frame */
1183 hInitialStack32 = GLOBAL_Alloc( GMEM_FIXED, 0x10000,
1184 hModule, FALSE, FALSE,
1185 FALSE );
1187 /* Create the 32-bit stack frame */
1189 stack32Top = (char*)GlobalLock16(hInitialStack32) +
1190 0x10000;
1191 frame32 = (STACK32FRAME *)stack32Top - 1;
1192 frame32->saved_esp = (DWORD)stack32Top;
1193 frame32->edi = 0;
1194 frame32->esi = 0;
1195 frame32->edx = 0;
1196 frame32->ecx = 0;
1197 frame32->ebx = 0;
1198 frame32->ebp = 0;
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 );
1205 _lclose32(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;
1216 else
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 */
1229 pModule->count = 1;
1231 if (first && (pModule->flags & NE_FFLAGS_LIBMODULE))
1232 NE_InitializeDLLs( hModule );
1234 else
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 );
1241 pModule->count++;
1243 #else
1244 lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) );
1245 if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule;
1246 pModule = (NE_MODULE *)GlobalLock16( hModule );
1247 hPrevInstance = 0;
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))
1255 HTASK16 hTask;
1256 WORD showcmd;
1258 /* PowerPoint passes NULL as showCmd */
1259 if (params->showCmd)
1260 showcmd = *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1);
1261 else
1262 showcmd = 0; /* FIXME: correct */
1264 hTask = TASK_CreateTask( hModule, hInstance, hPrevInstance,
1265 params->hEnvironment,
1266 (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
1267 showcmd );
1269 if( hTask && TASK_GetNextTask(hTask)) Yield();
1272 return hInstance;
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 )
1290 NE_MODULE *pModule;
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 );
1298 return TRUE;
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 )
1322 NE_MODULE *pModule;
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 )
1337 NE_MODULE *pModule;
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 )
1353 NE_MODULE *pModule;
1355 if (!hModule)
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 );
1377 return res;
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 );
1390 return TRUE;
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);
1400 if (!flags && !hf)
1401 return LoadLibrary32A(libname);
1402 return 0;
1405 /***********************************************************************
1406 * LoadLibrary (KERNEL.95)
1408 HINSTANCE16 LoadLibrary16( LPCSTR libname )
1410 HINSTANCE16 handle;
1412 if (__winelib)
1414 fprintf( stderr, "LoadLibrary not supported in Winelib\n" );
1415 return 0;
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 */
1426 char buffer[256];
1427 lstrcpyn32A( buffer, libname, 252 );
1428 strcat( buffer, ".dll" );
1429 handle = MODULE_Load( buffer, (LPVOID)-1, TRUE );
1431 return handle;
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 )
1459 LOADPARAMS params;
1460 HGLOBAL16 cmdShowHandle, cmdLineHandle;
1461 HINSTANCE16 handle;
1462 WORD *cmdShowPtr;
1463 char *p, *cmdline, filename[256];
1464 static int use_load_module = 1;
1466 if (!lpCmdLine)
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 );
1479 cmdShowPtr[0] = 2;
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;
1490 *p = '\0';
1492 /* Now load the executable file */
1494 if (use_load_module)
1496 #ifdef WINELIB
1497 /* WINELIB: Use LoadModule() only for the program itself */
1498 use_load_module = 0;
1499 params.hEnvironment = (HGLOBAL16)GetDOSEnvironment();
1500 #else
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, &params );
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, &params );
1517 *p = '\0'; /* Remove extension */
1521 else handle = 2;
1523 if (handle < 32)
1525 /* Try to start it as a unix program */
1526 if (!fork())
1528 /* Child process */
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;
1545 if (unixfilename)
1547 /* build argv */
1548 argptr = argv;
1549 if (iconic) *argptr++ = "-iconic";
1550 *argptr++ = unixfilename;
1551 p = cmdline;
1552 while (1)
1554 while (*p && (*p == ' ' || *p == '\t')) *p++ = '\0';
1555 if (!*p) break;
1556 *argptr++ = p;
1557 while (*p && *p != ' ' && *p != '\t') p++;
1559 *argptr++ = 0;
1561 /* Execute */
1562 execvp(argv[0], (char**)argv);
1565 /* Failed ! */
1567 if (__winelib)
1569 /* build argv */
1570 argptr = argv;
1571 *argptr++ = "wine";
1572 if (iconic) *argptr++ = "-iconic";
1573 *argptr++ = lpCmdLine;
1574 *argptr++ = 0;
1576 /* Execute */
1577 execvp(argv[0] , (char**)argv);
1579 /* Failed ! */
1580 fprintf(stderr, "WinExec: can't exec 'wine %s'\n", lpCmdLine);
1582 exit(1);
1586 GlobalFree16( cmdShowHandle );
1587 GlobalFree16( cmdLineHandle );
1588 return handle;
1592 /***********************************************************************
1593 * GetProcAddress16 (KERNEL.50)
1595 FARPROC16 GetProcAddress16( HMODULE16 hModule, SEGPTR name )
1597 WORD ordinal;
1598 FARPROC16 ret;
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) );
1609 else
1611 ordinal = LOWORD(name);
1612 dprintf_module( stddeb, "GetProcAddress: %04x %04x\n",
1613 hModule, ordinal );
1615 if (!ordinal) return (FARPROC16)0;
1617 ret = MODULE_GetEntryPoint( hModule, ordinal );
1619 dprintf_module( stddeb, "GetProcAddress: returning %08x\n", (UINT32)ret );
1620 return ret;
1624 /***********************************************************************
1625 * GetProcAddress32 (KERNEL32.257)
1627 FARPROC32 GetProcAddress32( HMODULE32 hModule, LPCSTR function )
1629 #ifndef WINELIB
1630 NE_MODULE *pModule;
1632 if (HIWORD(function))
1633 dprintf_win32(stddeb,"GetProcAddress32(%08lx,%s)\n",(DWORD)hModule,function);
1634 else
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 );
1644 #else
1645 return NULL;
1646 #endif
1649 /***********************************************************************
1650 * RtlImageNtHeaders (NTDLL)
1652 LPIMAGE_NT_HEADERS
1653 RtlImageNtHeader(HMODULE32 hModule)
1655 #ifndef WINELIB
1656 NE_MODULE *pModule;
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;
1664 #else
1665 return NULL;
1666 #endif
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 )
1707 NE_MODULE *pModule;
1709 if (!lpme->wNext) return FALSE;
1710 if (!(pModule = MODULE_GetPtr( lpme->wNext ))) return FALSE;
1711 strncpy( lpme->szModule, (char *)pModule + pModule->name_table,
1712 MAX_MODULE_NAME );
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;
1719 return TRUE;
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 );