4 * Copyright 1995 Alexandre Julliard
12 #include <sys/types.h>
25 #include "selectors.h"
26 #include "stackframe.h"
32 extern BOOL32 THREAD_InitDone
;
34 extern HMODULE16 hFirstModule
; /* FIXME */
35 static HMODULE16 hCachedModule
= 0; /* Module cached by MODULE_OpenFile */
37 static HMODULE32
MODULE_LoadModule(LPCSTR name
,BOOL32 force
) { return 0; }
38 HMODULE32 (*fnBUILTIN_LoadModule
)(LPCSTR name
,BOOL32 force
) = MODULE_LoadModule
;
41 /*************************************************************************
42 * MODULE32_LookupHMODULE
43 * looks for the referenced HMODULE in the current process
46 MODULE32_LookupHMODULE(PDB32
*process
,HMODULE32 hmod
) {
50 return process
->exe_modref
;
52 ERR(module
,"tried to lookup 0x%04x in win32 module handler!\n",hmod
);
55 for (wm
= process
->modref_list
;wm
;wm
=wm
->next
)
56 if (wm
->module
== hmod
)
61 /***********************************************************************
64 NE_MODULE
*MODULE_GetPtr16( HMODULE16 hModule
)
66 return (NE_MODULE
*)GlobalLock16( GetExePtr(hModule
) );
70 /***********************************************************************
73 NE_MODULE
*MODULE_GetPtr32( HMODULE32 hModule
)
75 return (NE_MODULE
*)GlobalLock16( MODULE_HANDLEtoHMODULE16(hModule
) );
78 /***********************************************************************
79 * MODULE_HANDLEtoHMODULE16
82 MODULE_HANDLEtoHMODULE16(HANDLE32 handle
) {
87 WARN(module
,"looking up 0x%08x in win16 function!\n",handle
);
88 /* this is a HMODULE32 */
90 /* walk the list looking for the correct startaddress */
91 pModule
= (NE_MODULE
*)GlobalLock16( hFirstModule
);
94 if (pModule
->module32
== handle
) return pModule
->self
;
95 pModule
= (NE_MODULE
*)GlobalLock16(pModule
->next
);
99 return GetExePtr(handle
);
102 /***********************************************************************
105 int MODULE_OpenFile( HMODULE32 hModule
)
108 DOS_FULL_NAME full_name
;
111 static int cachedfd
= -1;
113 hModule
= MODULE_HANDLEtoHMODULE16(hModule
);
114 TRACE(module
, "(%04x) cache: mod=%04x fd=%d\n",
115 hModule
, hCachedModule
, cachedfd
);
116 if (!(pModule
= MODULE_GetPtr32( hModule
))) return -1;
117 if (hCachedModule
== hModule
) return cachedfd
;
119 hCachedModule
= hModule
;
120 name
= NE_MODULE_NAME( pModule
);
121 if (!DOSFS_GetFullName( name
, TRUE
, &full_name
) ||
122 (cachedfd
= open( full_name
.long_name
, O_RDONLY
)) == -1)
123 WARN( module
, "Can't open file '%s' for module %04x\n",
125 TRACE(module
, "opened '%s' -> %d\n",
131 /***********************************************************************
132 * MODULE_CreateInstance
134 * If lib_only is TRUE, handle the module like a library even if it is a .EXE
136 HINSTANCE16
MODULE_CreateInstance( HMODULE16 hModule
, HINSTANCE16
*prev
,
139 SEGTABLEENTRY
*pSegment
;
142 HINSTANCE16 hNewInstance
;
144 if (!(pModule
= MODULE_GetPtr16( hModule
))) return 0;
145 if (pModule
->dgroup
== 0)
147 if (prev
) *prev
= hModule
;
151 pSegment
= NE_SEG_TABLE( pModule
) + pModule
->dgroup
- 1;
152 if (prev
) *prev
= pSegment
->selector
;
154 /* if it's a library, create a new instance only the first time */
155 if (pSegment
->selector
)
157 if (pModule
->flags
& NE_FFLAGS_LIBMODULE
) return pSegment
->selector
;
158 if (lib_only
) return pSegment
->selector
;
161 minsize
= pSegment
->minsize
? pSegment
->minsize
: 0x10000;
162 if (pModule
->ss
== pModule
->dgroup
) minsize
+= pModule
->stack_size
;
163 minsize
+= pModule
->heap_size
;
164 hNewInstance
= GLOBAL_Alloc( GMEM_ZEROINIT
| GMEM_FIXED
,
165 minsize
, hModule
, FALSE
, FALSE
, FALSE
);
166 if (!hNewInstance
) return 0;
167 pSegment
->selector
= hNewInstance
;
172 /***********************************************************************
173 * MODULE_CreateDummyModule
175 * Create a dummy NE module for Win32 or Winelib.
177 HMODULE32
MODULE_CreateDummyModule( const OFSTRUCT
*ofs
)
181 SEGTABLEENTRY
*pSegment
;
184 const char* basename
;
186 INT32 of_size
= sizeof(OFSTRUCT
) - sizeof(ofs
->szPathName
)
187 + strlen(ofs
->szPathName
) + 1;
188 INT32 size
= sizeof(NE_MODULE
) +
189 /* loaded file info */
191 /* segment table: DS,CS */
192 2 * sizeof(SEGTABLEENTRY
) +
195 /* several empty tables */
198 hModule
= GlobalAlloc16( GMEM_MOVEABLE
| GMEM_ZEROINIT
, size
);
199 if (!hModule
) return (HMODULE32
)11; /* invalid exe */
201 FarSetOwner( hModule
, hModule
);
202 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
204 /* Set all used entries */
205 pModule
->magic
= IMAGE_OS2_SIGNATURE
;
212 pModule
->heap_size
= 0xe000;
213 pModule
->stack_size
= 0x1000;
214 pModule
->seg_count
= 2;
215 pModule
->modref_count
= 0;
216 pModule
->nrname_size
= 0;
217 pModule
->fileinfo
= sizeof(NE_MODULE
);
218 pModule
->os_flags
= NE_OSFLAGS_WINDOWS
;
219 pModule
->expected_version
= 0x030a;
220 pModule
->self
= hModule
;
222 /* Set loaded file information */
223 memcpy( pModule
+ 1, ofs
, of_size
);
224 ((OFSTRUCT
*)(pModule
+1))->cBytes
= of_size
- 1;
226 pSegment
= (SEGTABLEENTRY
*)((char*)(pModule
+ 1) + of_size
);
227 pModule
->seg_table
= pModule
->dgroup_entry
= (int)pSegment
- (int)pModule
;
230 pSegment
->flags
= NE_SEGFLAGS_DATA
;
231 pSegment
->minsize
= 0x1000;
238 pStr
= (char *)pSegment
;
239 pModule
->name_table
= (int)pStr
- (int)pModule
;
240 basename
= strrchr(ofs
->szPathName
,'\\');
241 if (!basename
) basename
= ofs
->szPathName
;
243 len
= strlen(basename
);
244 if ((s
= strchr(basename
,'.'))) len
= s
- basename
;
245 if (len
> 8) len
= 8;
247 strncpy( pStr
+1, basename
, len
);
248 if (len
< 8) pStr
[len
+1] = 0;
251 /* All tables zero terminated */
252 pModule
->res_table
= pModule
->import_table
= pModule
->entry_table
=
253 (int)pStr
- (int)pModule
;
255 NE_RegisterModule( pModule
);
260 /***********************************************************************
261 * MODULE_GetWndProcEntry16 (not a Windows API function)
263 * Return an entry point from the WPROCS dll.
265 FARPROC16
MODULE_GetWndProcEntry16( LPCSTR name
)
267 FARPROC16 ret
= NULL
;
271 /* FIXME: hack for Winelib */
272 extern LRESULT
ColorDlgProc(HWND16
,UINT16
,WPARAM16
,LPARAM
);
273 extern LRESULT
FileOpenDlgProc(HWND16
,UINT16
,WPARAM16
,LPARAM
);
274 extern LRESULT
FileSaveDlgProc(HWND16
,UINT16
,WPARAM16
,LPARAM
);
275 extern LRESULT
FindTextDlgProc16(HWND16
,UINT16
,WPARAM16
,LPARAM
);
276 extern LRESULT
PrintDlgProc(HWND16
,UINT16
,WPARAM16
,LPARAM
);
277 extern LRESULT
PrintSetupDlgProc(HWND16
,UINT16
,WPARAM16
,LPARAM
);
278 extern LRESULT
ReplaceTextDlgProc16(HWND16
,UINT16
,WPARAM16
,LPARAM
);
280 if (!strcmp(name
,"ColorDlgProc"))
281 return (FARPROC16
)ColorDlgProc
;
282 if (!strcmp(name
,"FileOpenDlgProc"))
283 return (FARPROC16
)FileOpenDlgProc
;
284 if (!strcmp(name
,"FileSaveDlgProc"))
285 return (FARPROC16
)FileSaveDlgProc
;
286 if (!strcmp(name
,"FindTextDlgProc"))
287 return (FARPROC16
)FindTextDlgProc16
;
288 if (!strcmp(name
,"PrintDlgProc"))
289 return (FARPROC16
)PrintDlgProc
;
290 if (!strcmp(name
,"PrintSetupDlgProc"))
291 return (FARPROC16
)PrintSetupDlgProc
;
292 if (!strcmp(name
,"ReplaceTextDlgProc"))
293 return (FARPROC16
)ReplaceTextDlgProc16
;
294 WARN(module
,"No mapping for %s(), add one in library/miscstubs.c\n",name
);
301 static HMODULE32 hModule
= 0;
303 if (!hModule
) hModule
= GetModuleHandle16( "WPROCS" );
304 ordinal
= NE_GetOrdinal( hModule
, name
);
305 if (!(ret
= NE_GetEntryPoint( hModule
, ordinal
)))
307 WARN( module
, "%s not found\n", name
);
315 /***********************************************************************
316 * MODULE_GetModuleName
318 LPSTR
MODULE_GetModuleName( HMODULE32 hModule
)
322 static char buffer
[10];
324 if (!(pModule
= MODULE_GetPtr32( hModule
))) return NULL
;
325 p
= (BYTE
*)pModule
+ pModule
->name_table
;
327 memcpy( buffer
, p
+ 1, len
);
333 /**********************************************************************
336 * Find a module from a path name.
338 * the win16 module handle if found
341 HMODULE32
MODULE_FindModule16(
342 LPCSTR path
/* [in] path of the module to be found */
344 HMODULE32 hModule
= hFirstModule
;
345 LPCSTR filename
, dotptr
, modulepath
, modulename
;
346 BYTE len
, *name_table
;
348 if (!(filename
= strrchr( path
, '\\' ))) filename
= path
;
350 if ((dotptr
= strrchr( filename
, '.' )) != NULL
)
351 len
= (BYTE
)(dotptr
- filename
);
352 else len
= strlen( filename
);
356 NE_MODULE
*pModule
= MODULE_GetPtr16( hModule
);
358 modulepath
= NE_MODULE_NAME(pModule
);
359 if (!(modulename
= strrchr( modulepath
, '\\' )))
360 modulename
= modulepath
;
362 if (!lstrcmpi32A( modulename
, filename
)) return hModule
;
364 name_table
= (BYTE
*)pModule
+ pModule
->name_table
;
365 if ((*name_table
== len
) && !lstrncmpi32A(filename
, name_table
+1, len
))
367 hModule
= pModule
->next
;
372 /**********************************************************************
373 * MODULE_FindModule32
375 * Find a (loaded) win32 module depending on path
376 * The handling of '.' is a bit weird, but we need it that way,
377 * for sometimes the programs use '<name>.exe' and '<name>.dll' and
378 * this is the only way to differentiate. (mainly hypertrm.exe)
381 * the module handle if found
384 HMODULE32
MODULE_FindModule32(
385 PDB32
* process
, /* [in] process in which to find the library */
386 LPCSTR path
/* [in] pathname of module/library to be found */
392 if (!(filename
= strrchr( path
, '\\' )))
393 filename
= HEAP_strdupA(process
->heap
,0,path
);
395 filename
= HEAP_strdupA(process
->heap
,0,filename
+1);
396 dotptr
=strrchr(filename
,'.');
399 HeapFree(process
->heap
,0,filename
);
402 for (wm
=process
->modref_list
;wm
;wm
=wm
->next
) {
403 LPSTR xmodname
,xdotptr
;
405 assert (wm
->modname
);
406 xmodname
= HEAP_strdupA(process
->heap
,0,wm
->modname
);
407 xdotptr
=strrchr(xmodname
,'.');
408 if ( (xdotptr
&& !dotptr
) ||
411 if (dotptr
) *dotptr
= '\0';
412 if (xdotptr
) *xdotptr
= '\0';
414 if (!lstrcmpi32A( filename
, xmodname
)) {
415 HeapFree(process
->heap
,0,filename
);
416 HeapFree(process
->heap
,0,xmodname
);
419 if (dotptr
) *dotptr
='.';
420 /* FIXME: add paths, shortname */
421 HeapFree(process
->heap
,0,xmodname
);
423 HeapFree(process
->heap
,0,filename
);
429 /**********************************************************************
432 * Call a DLL's WEP, allowing it to shut down.
433 * FIXME: we always pass the WEP WEP_FREE_DLL, never WEP_SYSTEM_EXIT
435 static BOOL16
MODULE_CallWEP( HMODULE16 hModule
)
437 FARPROC16 WEP
= (FARPROC16
)0;
438 WORD ordinal
= NE_GetOrdinal( hModule
, "WEP" );
440 if (ordinal
) WEP
= NE_GetEntryPoint( hModule
, ordinal
);
443 WARN(module
, "module %04x doesn't have a WEP\n", hModule
);
446 return Callbacks
->CallWindowsExitProc( WEP
, WEP_FREE_DLL
);
450 /**********************************************************************
453 * Remove a module from memory.
455 BOOL16
MODULE_FreeModule( HMODULE32 hModule
, TDB
* pTaskContext
)
457 HMODULE16
*hPrevModule
;
459 SEGTABLEENTRY
*pSegment
;
463 if (!(pModule
= MODULE_GetPtr32( hModule
))) return FALSE
;
464 hModule
= pModule
->self
;
466 if (((INT16
)(--pModule
->count
)) > 0 ) return TRUE
;
467 else pModule
->count
= 0;
469 if (pModule
->flags
& NE_FFLAGS_BUILTIN
)
470 return FALSE
; /* Can't free built-in module */
472 if (pModule
->flags
& NE_FFLAGS_LIBMODULE
)
474 MODULE_CallWEP( hModule
);
476 /* Free the objects owned by the DLL module */
478 if( pTaskContext
&& pTaskContext
->userhandler
)
480 pTaskContext
->userhandler( hModule
, USIG_DLL_UNLOAD
, 0,
481 pTaskContext
->hInstance
,
482 pTaskContext
->hQueue
);
485 /* Clear magic number just in case */
487 pModule
->magic
= pModule
->self
= 0;
489 /* Remove it from the linked list */
491 hPrevModule
= &hFirstModule
;
492 while (*hPrevModule
&& (*hPrevModule
!= hModule
))
494 hPrevModule
= &(MODULE_GetPtr16( *hPrevModule
))->next
;
496 if (*hPrevModule
) *hPrevModule
= pModule
->next
;
498 /* Free all the segments */
500 pSegment
= NE_SEG_TABLE( pModule
);
501 for (i
= 1; i
<= pModule
->seg_count
; i
++, pSegment
++)
503 GlobalFree16( pSegment
->selector
);
506 /* Free the referenced modules */
508 pModRef
= (HMODULE16
*)NE_MODULE_TABLE( pModule
);
509 for (i
= 0; i
< pModule
->modref_count
; i
++, pModRef
++)
511 FreeModule16( *pModRef
);
514 /* Free the module storage */
516 if (pModule
->nrname_handle
) GlobalFree16( pModule
->nrname_handle
);
517 if (pModule
->dlls_to_init
) GlobalFree16( pModule
->dlls_to_init
);
518 GlobalFree16( hModule
);
520 /* Remove module from cache */
522 if (hCachedModule
== hModule
) hCachedModule
= 0;
528 /**********************************************************************
531 * Implementation of LoadModule().
533 * cmd_line must contain the whole command-line, including argv[0] (and
534 * without a preceding length byte).
535 * If cmd_line is NULL, the module is loaded as a library even if it is a .exe
537 HINSTANCE16
MODULE_Load( LPCSTR name
, UINT16 uFlags
,
538 LPCSTR cmd_line
, LPCSTR env
, UINT32 show_cmd
)
541 HINSTANCE16 hInstance
, hPrevInstance
;
548 lstrcpyn32A( ofs
.szPathName
, name
, sizeof(ofs
.szPathName
) );
549 if ((hModule
= MODULE_CreateDummyModule( &ofs
)) < 32) return hModule
;
550 pModule
= (NE_MODULE
*)GlobalLock16( hModule
);
551 hInstance
= MODULE_CreateInstance( hModule
, &hPrevInstance
,
552 (cmd_line
== NULL
) );
556 hModule
= MODULE_FindModule16( name
);
558 if (!hModule
) /* We have to load the module */
560 /* Try to load the built-in first if not disabled */
561 if ((hModule
= fnBUILTIN_LoadModule( name
, FALSE
)))
562 return MODULE_HANDLEtoHMODULE16( hModule
);
564 if ((hFile
= OpenFile32( name
, &ofs
, OF_READ
)) == HFILE_ERROR32
)
566 /* Now try the built-in even if disabled */
567 if ((hModule
= fnBUILTIN_LoadModule( name
, TRUE
)))
569 WARN(module
, "Could not load Windows DLL '%s', using built-in module.\n", name
);
570 return MODULE_HANDLEtoHMODULE16( hModule
);
572 return 2; /* File not found */
575 /* Create the module structure */
577 hModule
= NE_LoadModule( hFile
, &ofs
, uFlags
, cmd_line
,
581 if ((hModule
== 21) && cmd_line
)
582 hModule
= PE_LoadModule( hFile
, &ofs
, cmd_line
,
587 fprintf( stderr
, "LoadModule: can't load '%s', error=%d\n",
592 else /* module is already loaded, just create a new data segment if it's a task */
594 pModule
= MODULE_GetPtr32( hModule
);
595 hInstance
= MODULE_CreateInstance( hModule
, &hPrevInstance
,
596 (cmd_line
== NULL
) );
597 if (hInstance
!= hPrevInstance
) /* not a library */
598 NE_LoadSegment( pModule
, pModule
->dgroup
);
603 /* Create a task for this instance */
605 if (cmd_line
&& !(pModule
->flags
& NE_FFLAGS_LIBMODULE
))
609 pModule
->flags
|= NE_FFLAGS_GUI
;
611 pdb
= PROCESS_Create( pModule
, cmd_line
, env
, hInstance
,
612 hPrevInstance
, show_cmd
);
613 if (pdb
&& (GetNumTasks() > 1)) Yield16();
620 /**********************************************************************
621 * LoadModule16 (KERNEL.45)
623 HINSTANCE16
LoadModule16( LPCSTR name
, LPVOID paramBlock
)
625 LOADPARAMS
*params
= (LOADPARAMS
*)paramBlock
;
626 LPSTR cmd_line
= (LPSTR
)PTR_SEG_TO_LIN( params
->cmdLine
);
630 HINSTANCE16 hInstance
;
632 if (!paramBlock
|| (paramBlock
== (LPVOID
)-1))
633 return LoadLibrary16( name
);
635 params
= (LOADPARAMS
*)paramBlock
;
636 cmd_line
= (LPSTR
)PTR_SEG_TO_LIN( params
->cmdLine
);
637 /* PowerPoint passes NULL as showCmd */
639 show_cmd
= *((UINT16
*)PTR_SEG_TO_LIN(params
->showCmd
)+1);
641 if (!cmd_line
) cmd_line
= "";
642 else if (*cmd_line
) cmd_line
++; /* skip the length byte */
644 if (!(new_cmd_line
= HeapAlloc( GetProcessHeap(), 0,
645 strlen(cmd_line
) + strlen(name
) + 2 )))
647 strcpy( new_cmd_line
, name
);
648 strcat( new_cmd_line
, " " );
649 strcat( new_cmd_line
, cmd_line
);
651 if (params
->hEnvironment
) env
= GlobalLock16( params
->hEnvironment
);
652 hInstance
= MODULE_Load( name
, 0, new_cmd_line
, env
, show_cmd
);
653 if (params
->hEnvironment
) GlobalUnlock16( params
->hEnvironment
);
654 HeapFree( GetProcessHeap(), 0, new_cmd_line
);
658 /**********************************************************************
659 * LoadModule32 (KERNEL32.499)
663 * This should get implemented via CreateProcess -- MODULE_Load
664 * is resolutely 16-bit.
666 DWORD
LoadModule32( LPCSTR name
, LPVOID paramBlock
)
668 LOADPARAMS32
*params
= (LOADPARAMS32
*)paramBlock
;
671 PROCESSINFORMATION pi
;
672 st
.cb
= sizeof(STARTUPINFO
);
673 st
.wShowWindow
= p
->lpCmdShow
[2] ; WRONG
675 BOOL32 ret
= CreateProcess32A( name
, p
->lpCmdLine
,
676 NULL
, NULL
, FALSE
, 0, p
->lpEnvAddress
,
679 /* handle errors appropriately */
681 CloseHandle32(pi
.hProcess
);
682 CloseHandle32(pi
.hThread
);
685 return MODULE_Load( name
, 0, params
->lpCmdLine
, params
->lpEnvAddress
,
686 *((UINT16
*)params
->lpCmdShow
+ 1) );
691 /**********************************************************************
692 * FreeModule16 (KERNEL.46)
694 BOOL16 WINAPI
FreeModule16( HMODULE16 hModule
)
698 if (!(pModule
= MODULE_GetPtr16( hModule
))) return FALSE
;
699 TRACE(module
, "%s count %d\n",
700 MODULE_GetModuleName(hModule
), pModule
->count
);
702 return MODULE_FreeModule( hModule
, GlobalLock16(GetCurrentTask()) );
706 /**********************************************************************
707 * GetModuleHandle16 (KERNEL.47)
709 HMODULE16 WINAPI
WIN16_GetModuleHandle( SEGPTR name
)
711 if (HIWORD(name
) == 0) return GetExePtr( (HINSTANCE16
)name
);
712 return MODULE_FindModule16( PTR_SEG_TO_LIN(name
) );
715 HMODULE16 WINAPI
GetModuleHandle16( LPCSTR name
)
717 return MODULE_FindModule16( name
);
720 /***********************************************************************
721 * GetModuleHandle (KERNEL32.237)
723 HMODULE32 WINAPI
GetModuleHandle32A(LPCSTR module
)
726 TRACE(win32
, "%s\n", module
? module
: "NULL");
728 return PROCESS_Current()->exe_modref
->module
;
730 return MODULE_FindModule32(PROCESS_Current(),module
);
733 HMODULE32 WINAPI
GetModuleHandle32W(LPCWSTR module
)
736 LPSTR modulea
= HEAP_strdupWtoA( GetProcessHeap(), 0, module
);
737 hModule
= GetModuleHandle32A( modulea
);
738 HeapFree( GetProcessHeap(), 0, modulea
);
743 /**********************************************************************
744 * GetModuleUsage (KERNEL.48)
746 INT16 WINAPI
GetModuleUsage( HINSTANCE16 hModule
)
750 if (!(pModule
= MODULE_GetPtr16( hModule
))) return 0;
751 TRACE(module
, "(%04x): returning %d\n",
752 hModule
, pModule
->count
);
753 return pModule
->count
;
757 /**********************************************************************
758 * GetModuleFileName16 (KERNEL.49)
760 INT16 WINAPI
GetModuleFileName16( HINSTANCE16 hModule
, LPSTR lpFileName
,
765 if (!hModule
) hModule
= GetCurrentTask();
766 if (!(pModule
= MODULE_GetPtr16( hModule
))) return 0;
767 lstrcpyn32A( lpFileName
, NE_MODULE_NAME(pModule
), nSize
);
768 TRACE(module
, "%s\n", lpFileName
);
769 return strlen(lpFileName
);
773 /***********************************************************************
774 * GetModuleFileName32A (KERNEL32.235)
777 DWORD WINAPI
GetModuleFileName32A( HMODULE32 hModule
, LPSTR lpFileName
,
784 TDB
*pTask
= (TDB
*)GlobalLock16( GetCurrentTask() );
785 hModule
= pTask
->hInstance
;
787 if (!(pModule
= MODULE_GetPtr32( hModule
))) return 0;
788 lstrcpyn32A( lpFileName
, NE_MODULE_NAME(pModule
), size
);
789 TRACE(module
, "%s\n", lpFileName
);
790 return strlen(lpFileName
);
794 /***********************************************************************
795 * GetModuleFileName32W (KERNEL32.236)
797 DWORD WINAPI
GetModuleFileName32W( HMODULE32 hModule
, LPWSTR lpFileName
,
800 LPSTR fnA
= (char*)HeapAlloc( GetProcessHeap(), 0, size
);
801 DWORD res
= GetModuleFileName32A( hModule
, fnA
, size
);
802 lstrcpynAtoW( lpFileName
, fnA
, size
);
803 HeapFree( GetProcessHeap(), 0, fnA
);
808 /**********************************************************************
809 * GetModuleName (KERNEL.27)
811 BOOL16 WINAPI
GetModuleName( HINSTANCE16 hinst
, LPSTR buf
, INT16 nSize
)
813 LPSTR name
= MODULE_GetModuleName(hinst
);
815 if (!name
) return FALSE
;
816 lstrcpyn32A( buf
, name
, nSize
);
821 /***********************************************************************
822 * LoadLibraryEx32W (KERNEL.513)
825 HMODULE32 WINAPI
LoadLibraryEx32W16( LPCSTR libname
, HANDLE16 hf
,
828 TRACE(module
,"(%s,%d,%08lx)\n",libname
,hf
,flags
);
829 return LoadLibraryEx32A(libname
, hf
,flags
);
832 /***********************************************************************
833 * LoadLibraryEx32A (KERNEL32)
835 HMODULE32 WINAPI
LoadLibraryEx32A(LPCSTR libname
,HFILE32 hfile
,DWORD flags
)
839 hmod
= PE_LoadLibraryEx32A(libname
,PROCESS_Current(),hfile
,flags
);
843 strcpy( buffer
, libname
);
844 strcat( buffer
, ".dll" );
845 hmod
= PE_LoadLibraryEx32A(buffer
,PROCESS_Current(),hfile
,flags
);
847 /* initialize all DLLs, which haven't been initialized yet. */
849 PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH
, NULL
);
853 /***********************************************************************
854 * LoadLibraryA (KERNEL32)
856 HMODULE32 WINAPI
LoadLibrary32A(LPCSTR libname
) {
857 return LoadLibraryEx32A(libname
,0,0);
860 /***********************************************************************
861 * LoadLibraryW (KERNEL32)
863 HMODULE32 WINAPI
LoadLibrary32W(LPCWSTR libnameW
)
865 return LoadLibraryEx32W(libnameW
,0,0);
868 /***********************************************************************
869 * LoadLibraryExW (KERNEL32)
871 HMODULE32 WINAPI
LoadLibraryEx32W(LPCWSTR libnameW
,HFILE32 hfile
,DWORD flags
)
873 LPSTR libnameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, libnameW
);
874 HMODULE32 ret
= LoadLibraryEx32A( libnameA
, hfile
, flags
);
876 HeapFree( GetProcessHeap(), 0, libnameA
);
880 /***********************************************************************
883 BOOL32 WINAPI
FreeLibrary32(HINSTANCE32 hLibModule
)
885 TRACE(module
,"hLibModule=%08x\n", hLibModule
);
886 return MODULE_FreeModule(hLibModule
,GlobalLock16(GetCurrentTask()) );
890 /***********************************************************************
891 * LoadLibrary (KERNEL.95)
893 HINSTANCE16 WINAPI
LoadLibrary16( LPCSTR libname
)
897 TRACE(module
, "(%08x) %s\n", (int)libname
, libname
);
899 handle
= MODULE_Load( libname
, 0, NULL
, NULL
, 0 );
900 if (handle
== (HINSTANCE16
)2) /* file not found */
903 lstrcpyn32A( buffer
, libname
, 252 );
904 strcat( buffer
, ".dll" );
905 handle
= MODULE_Load( buffer
, 0, NULL
, NULL
, 0 );
911 /***********************************************************************
912 * PrivateLoadLibrary (KERNEL32)
914 * FIXME: rough guesswork, don't know what "Private" means
916 HINSTANCE32 WINAPI
PrivateLoadLibrary(LPCSTR libname
)
918 return (HINSTANCE32
)LoadLibrary16(libname
);
922 /***********************************************************************
923 * FreeLibrary16 (KERNEL.96)
925 void WINAPI
FreeLibrary16( HINSTANCE16 handle
)
927 TRACE(module
,"%04x\n", handle
);
928 FreeModule16( handle
);
932 /***********************************************************************
933 * PrivateFreeLibrary (KERNEL32)
935 * FIXME: rough guesswork, don't know what "Private" means
937 void WINAPI
PrivateFreeLibrary(HINSTANCE32 handle
)
939 FreeLibrary16((HINSTANCE16
)handle
);
943 /***********************************************************************
944 * WinExec16 (KERNEL.166)
946 HINSTANCE16 WINAPI
WinExec16( LPCSTR lpCmdLine
, UINT16 nCmdShow
)
948 return WinExec32( lpCmdLine
, nCmdShow
);
952 /***********************************************************************
953 * WinExec32 (KERNEL32.566)
955 HINSTANCE32 WINAPI
WinExec32( LPCSTR lpCmdLine
, UINT32 nCmdShow
)
957 HINSTANCE32 handle
= 2;
958 char *p
, filename
[256];
959 static int use_load_module
= 1;
960 int spacelimit
= 0, exhausted
= 0;
963 return 2; /* File not found */
965 /* Keep trying to load a file by trying different filenames; e.g.,
966 for the cmdline "abcd efg hij", try "abcd" with args "efg hij",
967 then "abcd efg" with arg "hij", and finally "abcd efg hij" with
970 while(!exhausted
&& handle
== 2) {
973 /* Build the filename and command-line */
975 lstrcpyn32A(filename
, lpCmdLine
,
976 sizeof(filename
) - 4 /* for extension */);
978 /* Keep grabbing characters until end-of-string, tab, or until the
979 number of spaces is greater than the spacelimit */
981 for (p
= filename
; ; p
++) {
984 if(spacecount
> spacelimit
) {
990 if(*p
== '\0' || *p
== '\t') {
998 /* Now load the executable file */
1000 if (use_load_module
)
1002 /* Winelib: Use LoadModule() only for the program itself */
1003 if (__winelib
) use_load_module
= 0;
1004 handle
= MODULE_Load( filename
, 0, lpCmdLine
, NULL
, nCmdShow
);
1005 if (handle
== 2) /* file not found */
1007 /* Check that the original file name did not have a suffix */
1008 p
= strrchr(filename
, '.');
1009 /* if there is a '.', check if either \ OR / follow */
1010 if (!p
|| strchr(p
, '/') || strchr(p
, '\\'))
1012 p
= filename
+ strlen(filename
);
1013 strcpy( p
, ".exe" );
1014 handle
= MODULE_Load( filename
, 0, lpCmdLine
,
1016 *p
= '\0'; /* Remove extension */
1021 handle
= 2; /* file not found */
1025 /* Try to start it as a unix program */
1029 DOS_FULL_NAME full_name
;
1030 const char *unixfilename
= NULL
;
1031 const char *argv
[256], **argptr
;
1032 int iconic
= (nCmdShow
== SW_SHOWMINIMIZED
||
1033 nCmdShow
== SW_SHOWMINNOACTIVE
);
1035 THREAD_InitDone
= FALSE
; /* we didn't init this process */
1036 /* get unixfilename */
1037 if (strchr(filename
, '/') ||
1038 strchr(filename
, ':') ||
1039 strchr(filename
, '\\'))
1041 if (DOSFS_GetFullName( filename
, TRUE
, &full_name
))
1042 unixfilename
= full_name
.long_name
;
1044 else unixfilename
= filename
;
1050 if (iconic
) *argptr
++ = "-iconic";
1051 *argptr
++ = unixfilename
;
1052 p
= strdup(lpCmdLine
);
1055 while (*p
&& (*p
== ' ' || *p
== '\t')) *p
++ = '\0';
1058 while (*p
&& *p
!= ' ' && *p
!= '\t') p
++;
1063 execvp(argv
[0], (char**)argv
);
1073 if (iconic
) *argptr
++ = "-iconic";
1074 *argptr
++ = lpCmdLine
;
1078 execvp(argv
[0] , (char**)argv
);
1081 MSG("WinExec: can't exec 'wine %s'\n",
1087 } /* while (!exhausted && handle < 32) */
1093 /***********************************************************************
1094 * WIN32_GetProcAddress16 (KERNEL32.36)
1095 * Get procaddress in 16bit module from win32... (kernel32 undoc. ordinal func)
1097 FARPROC16 WINAPI
WIN32_GetProcAddress16( HMODULE32 hModule
, LPSTR name
)
1103 WARN(module
,"hModule may not be 0!\n");
1104 return (FARPROC16
)0;
1106 hModule
= MODULE_HANDLEtoHMODULE16(hModule
);
1108 ordinal
= NE_GetOrdinal( hModule
, name
);
1109 TRACE(module
, "%04x '%s'\n",
1112 ordinal
= LOWORD(name
);
1113 TRACE(module
, "%04x %04x\n",
1116 if (!ordinal
) return (FARPROC16
)0;
1117 ret
= NE_GetEntryPoint( hModule
, ordinal
);
1118 TRACE(module
,"returning %08x\n",(UINT32
)ret
);
1122 /***********************************************************************
1123 * GetProcAddress16 (KERNEL.50)
1125 FARPROC16 WINAPI
GetProcAddress16( HMODULE16 hModule
, SEGPTR name
)
1130 if (!hModule
) hModule
= GetCurrentTask();
1131 hModule
= GetExePtr( hModule
);
1133 if (HIWORD(name
) != 0)
1135 ordinal
= NE_GetOrdinal( hModule
, (LPSTR
)PTR_SEG_TO_LIN(name
) );
1136 TRACE(module
, "%04x '%s'\n",
1137 hModule
, (LPSTR
)PTR_SEG_TO_LIN(name
) );
1141 ordinal
= LOWORD(name
);
1142 TRACE(module
, "%04x %04x\n",
1145 if (!ordinal
) return (FARPROC16
)0;
1147 ret
= NE_GetEntryPoint( hModule
, ordinal
);
1149 TRACE(module
, "returning %08x\n", (UINT32
)ret
);
1154 /***********************************************************************
1155 * GetProcAddress32 (KERNEL32.257)
1157 FARPROC32 WINAPI
GetProcAddress32( HMODULE32 hModule
, LPCSTR function
)
1159 return MODULE_GetProcAddress32( PROCESS_Current(), hModule
, function
);
1163 /***********************************************************************
1164 * MODULE_GetProcAddress32 (internal)
1166 FARPROC32
MODULE_GetProcAddress32(
1167 PDB32
*process
, /* [in] process context */
1168 HMODULE32 hModule
, /* [in] current module handle */
1169 LPCSTR function
) /* [in] function to be looked up */
1171 WINE_MODREF
*wm
= MODULE32_LookupHMODULE(process
,hModule
);
1173 if (HIWORD(function
))
1174 TRACE(win32
,"(%08lx,%s)\n",(DWORD
)hModule
,function
);
1176 TRACE(win32
,"(%08lx,%p)\n",(DWORD
)hModule
,function
);
1178 return (FARPROC32
)0;
1182 return PE_FindExportedFunction( process
, wm
, function
);
1184 ERR(module
,"wine_modref type %d not handled.\n",wm
->type
);
1185 return (FARPROC32
)0;
1190 /***********************************************************************
1191 * RtlImageNtHeaders (NTDLL)
1193 LPIMAGE_NT_HEADERS WINAPI
RtlImageNtHeader(HMODULE32 hModule
)
1196 * return hModule+(((IMAGE_DOS_HEADER*)hModule)->e_lfanew);
1197 * but we could get HMODULE16 or the like (think builtin modules)
1200 WINE_MODREF
*wm
= MODULE32_LookupHMODULE( PROCESS_Current(), hModule
);
1201 if (!wm
|| (wm
->type
!= MODULE32_PE
)) return (LPIMAGE_NT_HEADERS
)0;
1202 return PE_HEADER(wm
->module
);
1206 /**********************************************************************
1207 * GetExpWinVer (KERNEL.167)
1209 WORD WINAPI
GetExpWinVer( HMODULE16 hModule
)
1211 NE_MODULE
*pModule
= MODULE_GetPtr16( hModule
);
1212 return pModule
? pModule
->expected_version
: 0;
1216 /**********************************************************************
1217 * IsSharedSelector (KERNEL.345)
1219 BOOL16 WINAPI
IsSharedSelector( HANDLE16 selector
)
1221 /* Check whether the selector belongs to a DLL */
1222 NE_MODULE
*pModule
= MODULE_GetPtr16( selector
);
1223 if (!pModule
) return FALSE
;
1224 return (pModule
->flags
& NE_FFLAGS_LIBMODULE
) != 0;
1228 /**********************************************************************
1229 * ModuleFirst (TOOLHELP.59)
1231 BOOL16 WINAPI
ModuleFirst( MODULEENTRY
*lpme
)
1233 lpme
->wNext
= hFirstModule
;
1234 return ModuleNext( lpme
);
1238 /**********************************************************************
1239 * ModuleNext (TOOLHELP.60)
1241 BOOL16 WINAPI
ModuleNext( MODULEENTRY
*lpme
)
1246 if (!lpme
->wNext
) return FALSE
;
1247 if (!(pModule
= MODULE_GetPtr16( lpme
->wNext
))) return FALSE
;
1248 name
= (char *)pModule
+ pModule
->name_table
;
1249 memcpy( lpme
->szModule
, name
+ 1, *name
);
1250 lpme
->szModule
[(BYTE
)*name
] = '\0';
1251 lpme
->hModule
= lpme
->wNext
;
1252 lpme
->wcUsage
= pModule
->count
;
1253 strncpy( lpme
->szExePath
, NE_MODULE_NAME(pModule
), MAX_PATH
);
1254 lpme
->szExePath
[MAX_PATH
] = '\0';
1255 lpme
->wNext
= pModule
->next
;
1260 /**********************************************************************
1261 * ModuleFindName (TOOLHELP.61)
1263 BOOL16 WINAPI
ModuleFindName( MODULEENTRY
*lpme
, LPCSTR name
)
1265 lpme
->wNext
= GetModuleHandle16( name
);
1266 return ModuleNext( lpme
);
1270 /**********************************************************************
1271 * ModuleFindHandle (TOOLHELP.62)
1273 BOOL16 WINAPI
ModuleFindHandle( MODULEENTRY
*lpme
, HMODULE16 hModule
)
1275 hModule
= GetExePtr( hModule
);
1276 lpme
->wNext
= hModule
;
1277 return ModuleNext( lpme
);