2 * Module & Library functions
3 static char Copyright[] = "Copyright 1993, 1994 Martin Ayotte, Robert J. Amstadt, Erik Bos";
23 #include "selectors.h"
26 #include "prototypes.h"
31 struct w_files
*wine_files
= NULL
;
32 static char *DLL_Extensions
[] = { "dll", NULL
};
33 static char *EXE_Extensions
[] = { "exe", NULL
};
35 #define IS_BUILTIN_DLL(handle) ((handle >> 8) == 0xff)
37 /**********************************************************************/
39 void ExtractDLLName(char *libname
, char *temp
)
43 strcpy(temp
, libname
);
44 if (strchr(temp
, '\\') || strchr(temp
, '/'))
45 for (i
= strlen(temp
) - 1; i
; i
--)
46 if (temp
[i
] == '\\' || temp
[i
] == '/') {
47 strcpy(temp
, temp
+ i
+ 1);
50 for (i
= strlen(temp
) - 1; i
; i
--)
57 struct w_files
*GetFileInfo(unsigned short instance
)
59 register struct w_files
*w
= wine_files
;
61 while (w
&& w
->hinstance
!= instance
)
67 int IsDLLLoaded(char *name
)
71 if(FindDLLTable(name
))
74 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
)
75 if(strcmp(wpnt
->name
, name
) == 0)
81 void InitDLL(struct w_files
*wpnt
)
89 void InitializeLoadedDLLs(struct w_files
*wpnt
)
91 static flagReadyToRun
= 0;
92 struct w_files
*final_wpnt
;
94 dprintf_module(stddeb
,"InitializeLoadedDLLs(%p)\n", wpnt
);
99 dprintf_module(stddeb
,"Initializing DLLs\n");
107 dprintf_module(stddeb
,"Initializing %s\n", wpnt
->name
);
111 * Initialize libraries
120 final_wpnt
= wpnt
->next
;
123 for( ; wpnt
!= final_wpnt
; wpnt
= wpnt
->next
)
127 /**********************************************************************
129 * Load one executable into memory
131 HINSTANCE
LoadImage(char *module
, int filetype
, int change_dir
)
134 struct w_files
*wpnt
, *wpnt1
;
135 char buffer
[256], header
[2], modulename
[64], *fullname
;
137 ExtractDLLName(module
, modulename
);
138 dprintf_module(stddeb
,"LoadImage [%s]\n", module
);
140 if (FindDLLTable(modulename
)) {
141 return GetModuleHandle(modulename
);
144 /* already loaded ? */
145 for (wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
)
146 if (strcasecmp(wpnt
->name
, modulename
) == 0)
147 return wpnt
->hinstance
;
152 fullname
= DOS_FindFile(buffer
, sizeof(buffer
), module
,
153 (filetype
== EXE
? EXE_Extensions
: DLL_Extensions
),
155 if (fullname
== NULL
)
157 fprintf(stderr
, "LoadImage: I can't find %s.dll | %s.exe !\n",
162 fullname
= DOS_GetDosFileName(fullname
);
164 dprintf_module(stddeb
,"LoadImage: loading %s (%s)\n [%s]\n",
165 module
, buffer
, fullname
);
167 if (change_dir
&& fullname
)
172 strcpy(dirname
, fullname
);
173 p
= strrchr(dirname
, '\\');
176 DOS_SetDefaultDrive(dirname
[0] - 'A');
177 DOS_ChangeDir(dirname
[0] - 'A', dirname
+ 2);
180 /* First allocate a spot to store the info we collect, and add it to
181 * our linked list if we could load the file.
184 wpnt
= (struct w_files
*) malloc(sizeof(struct w_files
));
187 * Open file for reading.
189 wpnt
->fd
= open(buffer
, O_RDONLY
);
194 * Establish header pointers.
196 wpnt
->filename
= strdup(buffer
);
197 wpnt
->name
= strdup(modulename
);
200 wpnt
->mz_header
= (struct mz_header_s
*) malloc(sizeof(struct mz_header_s
));;
201 lseek(wpnt
->fd
, 0, SEEK_SET
);
202 if (read(wpnt
->fd
, wpnt
->mz_header
, sizeof(struct mz_header_s
)) !=
203 sizeof(struct mz_header_s
))
205 fprintf(stderr
, "Unable to read MZ header from file '%s'\n", buffer
);
209 /* This field is ignored according to "Windows Internals", p.242 */
211 if (wpnt
->mz_header
->must_be_0x40
!= 0x40)
212 myerror("This is not a Windows program");
215 /* read first two bytes to determine filetype */
216 lseek(wpnt
->fd
, wpnt
->mz_header
->ne_offset
, SEEK_SET
);
217 read(wpnt
->fd
, &header
, sizeof(header
));
222 * Stick this file into the list of loaded files so we don't try to reload
223 * it again if another module references this module. Do this before
224 * calling NE_LoadImage because we might get back here before NE_loadImage
227 if(wine_files
== NULL
)
237 if (header
[0] == 'N' && header
[1] == 'E')
238 handle
= NE_LoadImage(wpnt
);
239 if (header
[0] == 'P' && header
[1] == 'E')
240 handle
= PE_LoadImage(wpnt
);
241 wpnt
->hinstance
= handle
;
246 fprintf(stderr
, "wine: (%s) unknown fileformat !\n", wpnt
->filename
);
248 /* Remove this module from the list of loaded modules */
249 if (wine_files
== wpnt
)
254 free(wpnt
->filename
);
262 /**********************************************************************
263 * GetModuleHandle [KERNEL.47]
265 HANDLE
GetModuleHandle(LPSTR lpModuleName
)
267 register struct w_files
*w
= wine_files
;
271 if ((int) lpModuleName
& 0xffff0000)
272 ExtractDLLName(lpModuleName
, dllname
);
274 if ((int) lpModuleName
& 0xffff0000)
275 dprintf_module(stddeb
,"GetModuleHandle('%s');\n", lpModuleName
);
277 dprintf_module(stddeb
,"GetModuleHandle('%p');\n", lpModuleName
);
279 /* dprintf_module(stddeb,"GetModuleHandle // searching in builtin libraries\n");*/
280 for (i
= 0; i
< N_BUILTINS
; i
++) {
281 if (dll_builtin_table
[i
].dll_name
== NULL
) break;
282 if (!dll_builtin_table
[i
].dll_is_used
){
283 dprintf_module(stddeb
,"Skipping builtin %s\n",
284 dll_builtin_table
[i
].dll_name
);
287 if (((int) lpModuleName
& 0xffff0000) == 0) {
288 if (0xFF00 + i
== (int) lpModuleName
) {
289 dprintf_module(stddeb
,"GetModuleHandle('%s') return %04X \n",
290 lpModuleName
, 0xff00 + i
);
294 else if (strcasecmp(dll_builtin_table
[i
].dll_name
, dllname
) == 0) {
295 dprintf_module(stddeb
,"GetModuleHandle('%p') return %04X \n",
296 lpModuleName
, 0xFF00 + i
);
301 dprintf_module(stddeb
,"GetModuleHandle // searching in loaded modules\n");
303 /* dprintf_module(stddeb,"GetModuleHandle // '%x' \n", w->name); */
304 if (((int) lpModuleName
& 0xffff0000) == 0) {
305 if (w
->hinstance
== (int) lpModuleName
) {
306 dprintf_module(stddeb
,"GetModuleHandle('%p') return %04X \n",
307 lpModuleName
, w
->hinstance
);
311 else if (strcasecmp(w
->name
, dllname
) == 0) {
312 dprintf_module(stddeb
,"GetModuleHandle('%s') return %04X \n",
313 lpModuleName
, w
->hinstance
);
318 printf("GetModuleHandle('%p') not found !\n", lpModuleName
);
323 /**********************************************************************
324 * GetModuleUsage [KERNEL.48]
326 int GetModuleUsage(HANDLE hModule
)
330 dprintf_module(stddeb
,"GetModuleUsage(%04X);\n", hModule
);
333 if (IS_BUILTIN_DLL(hModule
))
336 w
= GetFileInfo(hModule
);
337 /* return w->Usage; */
342 /**********************************************************************
343 * GetModuleFilename [KERNEL.49]
345 int GetModuleFileName(HANDLE hModule
, LPSTR lpFileName
, short nSize
)
349 char windir
[256], temp
[256];
351 dprintf_module(stddeb
,"GetModuleFileName(%04X, %p, %d);\n", hModule
, lpFileName
, nSize
);
353 if (lpFileName
== NULL
) return 0;
354 if (nSize
< 1) return 0;
357 if (IS_BUILTIN_DLL(hModule
)) {
358 GetWindowsDirectory(windir
, sizeof(windir
));
359 sprintf(temp
, "%s\\%s.DLL", windir
, dll_builtin_table
[hModule
& 0x00ff].dll_name
);
361 strncpy(lpFileName
, temp
, nSize
);
362 dprintf_module(stddeb
,"GetModuleFileName copied '%s' (internal dll) return %d \n", lpFileName
, nSize
);
363 return strlen(lpFileName
);
366 /* check loaded dlls */
367 if ((w
= GetFileInfo(hModule
)) == NULL
)
369 str
= DOS_GetDosFileName(w
->filename
);
370 if (nSize
> strlen(str
)) nSize
= strlen(str
) + 1;
371 strncpy(lpFileName
, str
, nSize
);
372 dprintf_module(stddeb
,"GetModuleFileName copied '%s' return %d \n", lpFileName
, nSize
);
377 /**********************************************************************
378 * LoadLibrary [KERNEL.95]
380 HANDLE
LoadLibrary(LPSTR libname
)
384 if ((h
= LoadImage(libname
, DLL
, 0)) < 32)
387 if (!IS_BUILTIN_DLL(h
))
388 InitDLL(GetFileInfo(h
));
393 /**********************************************************************
394 * FreeLibrary [KERNEL.96]
396 void FreeLibrary(HANDLE hLib
)
398 dprintf_module(stddeb
,"FreeLibrary(%04X);\n", hLib
);
401 if (IS_BUILTIN_DLL(hLib
) || hLib
== 0 || hLib
== hSysRes
)
405 while (lpMod != NULL) {
406 if (lpMod->hInst == hLib) {
407 if (lpMod->Count == 1) {
408 wpnt = GetFileInfo(hLib);
410 NE_UnloadImage(wpnt);
412 PE_UnloadImage(wpnt);
413 if (hLib != (HANDLE)NULL) GlobalFree(hLib);
414 if (lpMod->ModuleName != NULL) free(lpMod->ModuleName);
415 if (lpMod->FileName != NULL) free(lpMod->FileName);
416 GlobalFree(lpMod->hModule);
417 dprintf_module(stddeb,"FreeLibrary // freed !\n");
421 dprintf_module(stddeb,"FreeLibrary // Count decremented !\n");
424 lpMod = lpMod->lpNextModule;
430 /**********************************************************************
431 * GetProcAddress [KERNEL.50]
433 FARPROC
GetProcAddress(HANDLE hModule
, char *proc_name
)
436 WINELIB_UNIMP ("GetProcAddress");
440 register struct w_files
*w
= wine_files
;
448 if (IS_BUILTIN_DLL(hModule
))
450 if ((int) proc_name
& 0xffff0000)
452 dprintf_module(stddeb
,"GetProcAddress: builtin %#04X, '%s'\n",
454 if (GetEntryDLLName(dll_builtin_table
[hModule
- 0xFF00].dll_name
,
455 proc_name
, &sel
, &addr
))
457 printf("Address not found !\n");
462 dprintf_module(stddeb
,"GetProcAddress: builtin %#04X, %d\n",
463 hModule
, (int)proc_name
);
464 if (GetEntryDLLOrdinal(dll_builtin_table
[hModule
-0xFF00].dll_name
,
465 (int)proc_name
& 0x0000FFFF, &sel
, &addr
))
467 printf("Address not found !\n");
470 ret
= MAKELONG(addr
, sel
);
471 dprintf_module(stddeb
,"GetProcAddress // ret=%08X sel=%04X addr=%04X\n",
477 hTask
= GetCurrentTask();
478 dprintf_module(stddeb
,"GetProcAddress // GetCurrentTask()=%04X\n", hTask
);
479 lpTask
= (LPTASKENTRY
) GlobalLock(hTask
);
482 printf("GetProcAddress: can't find current module handle !\n");
485 hModule
= lpTask
->hInst
;
486 dprintf_module(stddeb
,"GetProcAddress: current module=%04X instance=%04X!\n",
487 lpTask
->hModule
, lpTask
->hInst
);
490 while (w
&& w
->hinstance
!= hModule
)
494 dprintf_module(stddeb
,"GetProcAddress // Module Found ! w->filename='%s'\n", w
->filename
);
495 if ((int)proc_name
& 0xFFFF0000)
497 AnsiUpper(proc_name
);
498 dprintf_module(stddeb
,"GetProcAddress: %04X, '%s'\n", hModule
, proc_name
);
499 cpnt
= w
->ne
->nrname_table
;
502 if (((int) cpnt
) - ((int)w
->ne
->nrname_table
) >
503 w
->ne
->ne_header
->nrname_tab_length
) return NULL
;
505 strncpy(C
, cpnt
, len
);
507 dprintf_module(stddeb
,"pointing Function '%s' ordinal=%d !\n",
508 C
, *((unsigned short *)(cpnt
+ len
)));
509 if (strncmp(cpnt
, proc_name
, len
) == 0)
511 ordinal
= *((unsigned short *)(cpnt
+ len
));
518 printf("GetProcAddress // function '%s' not found !\n", proc_name
);
524 dprintf_module(stddeb
,"GetProcAddress: %#04x, %d\n", hModule
, (int) proc_name
);
525 ordinal
= (int)proc_name
;
527 ret
= GetEntryPointFromOrdinal(w
, ordinal
);
530 printf("GetProcAddress // Function #%d not found !\n", ordinal
);
535 dprintf_module(stddeb
,"GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret
, sel
, addr
);
536 return (FARPROC
) ret
;
542 FillModStructBuiltIn(MODULEENTRY
*lpModule
, struct dll_name_table_entry_s
*dll
)
544 lpModule
->dwSize
= dll
->dll_table_length
* 1024;
545 strcpy(lpModule
->szModule
, dll
->dll_name
);
546 lpModule
->hModule
= 0xff00 + dll
->dll_number
;
547 lpModule
->wcUsage
= GetModuleUsage(lpModule
->hModule
);
548 GetModuleFileName(lpModule
->hModule
, lpModule
->szExePath
, MAX_PATH
+ 1);
554 FillModStructLoaded(MODULEENTRY
*lpModule
, struct w_files
*dll
)
556 lpModule
->dwSize
= 16384;
557 strcpy(lpModule
->szModule
, dll
->name
);
558 lpModule
->hModule
= dll
->hinstance
;
559 lpModule
->wcUsage
= GetModuleUsage(lpModule
->hModule
);
560 GetModuleFileName(lpModule
->hModule
, lpModule
->szExePath
, MAX_PATH
+ 1);
564 /**********************************************************************
565 * ModuleFirst [TOOLHELP.59]
567 BOOL
ModuleFirst(MODULEENTRY
*lpModule
)
569 dprintf_module(stddeb
,"ModuleFirst(%08X)\n", (int) lpModule
);
571 FillModStructBuiltIn(lpModule
, &dll_builtin_table
[0]);
575 /**********************************************************************
576 * ModuleNext [TOOLHELP.60]
578 BOOL
ModuleNext(MODULEENTRY
*lpModule
)
582 dprintf_module(stddeb
,"ModuleNext(%08X)\n", (int) lpModule
);
584 if (IS_BUILTIN_DLL(lpModule
->hModule
))
586 int builtin_no
=lpModule
->hModule
& 0xff;
588 /* last built-in ? */
589 if (builtin_no
== (N_BUILTINS
- 1) ) {
591 FillModStructLoaded(lpModule
, wine_files
);
597 }while(!dll_builtin_table
[builtin_no
].dll_is_used
);
599 FillModStructBuiltIn(lpModule
, &dll_builtin_table
[builtin_no
]);
602 w
= GetFileInfo(lpModule
->hModule
);
604 FillModStructLoaded(lpModule
, w
->next
);
610 /**********************************************************************
611 * ModuleFindHandle [TOOLHELP.62]
613 HMODULE
ModuleFindHandle(MODULEENTRY
*lpModule
, HMODULE hModule
)
617 dprintf_module(stddeb
,"ModuleFindHandle(%08X, %04X)\n", (int) lpModule
, (int)hModule
);
620 if (IS_BUILTIN_DLL(hModule
)) {
621 FillModStructBuiltIn(lpModule
, &dll_builtin_table
[hModule
& 0xff]);
625 /* check loaded dlls */
626 if ((w
= GetFileInfo(hModule
)) == NULL
)
627 return (HMODULE
) NULL
;
629 FillModStructLoaded(lpModule
, w
);
633 /**********************************************************************
634 * ModuleFindName [TOOLHELP.61]
636 HMODULE
ModuleFindName(MODULEENTRY
*lpModule
, LPCSTR lpstrName
)
638 return (ModuleFindHandle(lpModule
, GetModuleHandle((char*)lpstrName
)));