2 * Module & Library functions
3 static char Copyright[] = "Copyright 1993, 1994 Martin Ayotte, Robert J. Amstadt, Erik Bos";
24 #include "selectors.h"
27 #include "prototypes.h"
32 struct w_files
*wine_files
= NULL
;
33 static char *DLL_Extensions
[] = { "dll", NULL
};
34 static char *EXE_Extensions
[] = { "exe", NULL
};
36 #define IS_BUILTIN_DLL(handle) ((handle >> 8) == 0xff)
38 /**********************************************************************/
40 void ExtractDLLName(char *libname
, char *temp
)
44 strcpy(temp
, libname
);
45 if (strchr(temp
, '\\') || strchr(temp
, '/'))
46 for (i
= strlen(temp
) - 1; i
; i
--)
47 if (temp
[i
] == '\\' || temp
[i
] == '/') {
48 strcpy(temp
, temp
+ i
+ 1);
51 for (i
= strlen(temp
) - 1; i
; i
--)
58 struct w_files
*GetFileInfo(unsigned short instance
)
60 register struct w_files
*w
= wine_files
;
62 while (w
&& w
->hinstance
!= instance
)
68 int IsDLLLoaded(char *name
)
72 if(FindDLLTable(name
))
75 for(wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
)
76 if(strcmp(wpnt
->name
, name
) == 0)
82 void InitDLL(struct w_files
*wpnt
)
90 void InitializeLoadedDLLs(struct w_files
*wpnt
)
92 static flagReadyToRun
= 0;
93 struct w_files
*final_wpnt
;
95 dprintf_module(stddeb
,"InitializeLoadedDLLs(%p)\n", wpnt
);
100 dprintf_module(stddeb
,"Initializing DLLs\n");
108 dprintf_module(stddeb
,"Initializing %s\n", wpnt
->name
);
112 * Initialize libraries
121 final_wpnt
= wpnt
->next
;
124 for( ; wpnt
!= final_wpnt
; wpnt
= wpnt
->next
)
128 /**********************************************************************
130 * Load one executable into memory
132 HINSTANCE
LoadImage(char *module
, int filetype
, int change_dir
)
135 struct w_files
*wpnt
, *wpnt1
;
136 char buffer
[256], header
[2], modulename
[64], *fullname
;
138 ExtractDLLName(module
, modulename
);
139 dprintf_module(stddeb
,"LoadImage [%s]\n", module
);
141 if (FindDLLTable(modulename
)) {
142 return GetModuleHandle(modulename
);
145 /* already loaded ? */
146 for (wpnt
= wine_files
; wpnt
; wpnt
= wpnt
->next
)
147 if (strcasecmp(wpnt
->name
, modulename
) == 0)
148 return wpnt
->hinstance
;
153 fullname
= DOS_FindFile(buffer
, sizeof(buffer
), module
,
154 (filetype
== EXE
? EXE_Extensions
: DLL_Extensions
),
156 if (fullname
== NULL
)
158 fprintf(stderr
, "LoadImage: I can't find %s.dll | %s.exe !\n",
163 fullname
= DOS_GetDosFileName(fullname
);
165 dprintf_module(stddeb
,"LoadImage: loading %s (%s)\n [%s]\n",
166 module
, buffer
, fullname
);
168 if (change_dir
&& fullname
)
173 strcpy(dirname
, fullname
);
174 p
= strrchr(dirname
, '\\');
177 DOS_SetDefaultDrive(dirname
[0] - 'A');
178 DOS_ChangeDir(dirname
[0] - 'A', dirname
+ 2);
181 /* First allocate a spot to store the info we collect, and add it to
182 * our linked list if we could load the file.
185 wpnt
= (struct w_files
*) malloc(sizeof(struct w_files
));
188 * Open file for reading.
190 wpnt
->fd
= open(buffer
, O_RDONLY
);
195 * Establish header pointers.
197 wpnt
->filename
= strdup(buffer
);
198 wpnt
->name
= strdup(modulename
);
201 wpnt
->mz_header
= (struct mz_header_s
*) malloc(sizeof(struct mz_header_s
));;
202 lseek(wpnt
->fd
, 0, SEEK_SET
);
203 if (read(wpnt
->fd
, wpnt
->mz_header
, sizeof(struct mz_header_s
)) !=
204 sizeof(struct mz_header_s
))
206 myerror("Unable to read MZ header from file");
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 (((int) lpModuleName
& 0xffff0000) == 0) {
283 if (0xFF00 + i
== (int) lpModuleName
) {
284 dprintf_module(stddeb
,"GetModuleHandle('%s') return %04X \n",
285 lpModuleName
, 0xff00 + i
);
289 else if (strcasecmp(dll_builtin_table
[i
].dll_name
, dllname
) == 0) {
290 dprintf_module(stddeb
,"GetModuleHandle('%p') return %04X \n",
291 lpModuleName
, 0xFF00 + i
);
296 dprintf_module(stddeb
,"GetModuleHandle // searching in loaded modules\n");
298 /* dprintf_module(stddeb,"GetModuleHandle // '%x' \n", w->name); */
299 if (((int) lpModuleName
& 0xffff0000) == 0) {
300 if (w
->hinstance
== (int) lpModuleName
) {
301 dprintf_module(stddeb
,"GetModuleHandle('%p') return %04X \n",
302 lpModuleName
, w
->hinstance
);
306 else if (strcasecmp(w
->name
, dllname
) == 0) {
307 dprintf_module(stddeb
,"GetModuleHandle('%s') return %04X \n",
308 lpModuleName
, w
->hinstance
);
313 printf("GetModuleHandle('%p') not found !\n", lpModuleName
);
318 /**********************************************************************
319 * GetModuleUsage [KERNEL.48]
321 int GetModuleUsage(HANDLE hModule
)
325 dprintf_module(stddeb
,"GetModuleUsage(%04X);\n", hModule
);
328 if (IS_BUILTIN_DLL(hModule
))
331 w
= GetFileInfo(hModule
);
332 /* return w->Usage; */
337 /**********************************************************************
338 * GetModuleFilename [KERNEL.49]
340 int GetModuleFileName(HANDLE hModule
, LPSTR lpFileName
, short nSize
)
344 char windir
[256], temp
[256];
346 dprintf_module(stddeb
,"GetModuleFileName(%04X, %p, %d);\n", hModule
, lpFileName
, nSize
);
348 if (lpFileName
== NULL
) return 0;
349 if (nSize
< 1) return 0;
352 if (IS_BUILTIN_DLL(hModule
)) {
353 GetWindowsDirectory(windir
, sizeof(windir
));
354 sprintf(temp
, "%s\\%s.DLL", windir
, dll_builtin_table
[hModule
& 0x00ff].dll_name
);
356 strncpy(lpFileName
, temp
, nSize
);
357 dprintf_module(stddeb
,"GetModuleFileName copied '%s' (internal dll) return %d \n", lpFileName
, nSize
);
358 return strlen(lpFileName
);
361 /* check loaded dlls */
362 if ((w
= GetFileInfo(hModule
)) == NULL
)
364 str
= DOS_GetDosFileName(w
->filename
);
365 if (nSize
> strlen(str
)) nSize
= strlen(str
) + 1;
366 strncpy(lpFileName
, str
, nSize
);
367 dprintf_module(stddeb
,"GetModuleFileName copied '%s' return %d \n", lpFileName
, nSize
);
372 /**********************************************************************
373 * LoadLibrary [KERNEL.95]
375 HANDLE
LoadLibrary(LPSTR libname
)
379 if ((h
= LoadImage(libname
, DLL
, 0)) < 32)
382 if (!IS_BUILTIN_DLL(h
))
383 InitDLL(GetFileInfo(h
));
388 /**********************************************************************
389 * FreeLibrary [KERNEL.96]
391 void FreeLibrary(HANDLE hLib
)
393 dprintf_module(stddeb
,"FreeLibrary(%04X);\n", hLib
);
396 if (IS_BUILTIN_DLL(hLib
) || hLib
== 0 || hLib
== hSysRes
)
400 while (lpMod != NULL) {
401 if (lpMod->hInst == hLib) {
402 if (lpMod->Count == 1) {
403 wpnt = GetFileInfo(hLib);
405 NE_UnloadImage(wpnt);
407 PE_UnloadImage(wpnt);
408 if (hLib != (HANDLE)NULL) GlobalFree(hLib);
409 if (lpMod->ModuleName != NULL) free(lpMod->ModuleName);
410 if (lpMod->FileName != NULL) free(lpMod->FileName);
411 GlobalFree(lpMod->hModule);
412 dprintf_module(stddeb,"FreeLibrary // freed !\n");
416 dprintf_module(stddeb,"FreeLibrary // Count decremented !\n");
419 lpMod = lpMod->lpNextModule;
425 /**********************************************************************
426 * GetProcAddress [KERNEL.50]
428 FARPROC
GetProcAddress(HANDLE hModule
, char *proc_name
)
431 WINELIB_UNIMP ("GetProcAddress");
434 register struct w_files
*w
= wine_files
;
442 if (IS_BUILTIN_DLL(hModule
))
444 if ((int) proc_name
& 0xffff0000)
446 dprintf_module(stddeb
,"GetProcAddress: builtin %#04X, '%s'\n",
448 if (GetEntryDLLName(dll_builtin_table
[hModule
- 0xFF00].dll_name
,
449 proc_name
, &sel
, &addr
))
451 printf("Address not found !\n");
456 dprintf_module(stddeb
,"GetProcAddress: builtin %#04X, %d\n",
457 hModule
, (int)proc_name
);
458 if (GetEntryDLLOrdinal(dll_builtin_table
[hModule
-0xFF00].dll_name
,
459 (int)proc_name
& 0x0000FFFF, &sel
, &addr
))
461 printf("Address not found !\n");
464 ret
= MAKELONG(addr
, sel
);
465 dprintf_module(stddeb
,"GetProcAddress // ret=%08X sel=%04X addr=%04X\n",
471 hTask
= GetCurrentTask();
472 dprintf_module(stddeb
,"GetProcAddress // GetCurrentTask()=%04X\n", hTask
);
473 lpTask
= (LPTASKENTRY
) GlobalLock(hTask
);
476 printf("GetProcAddress: can't find current module handle !\n");
479 hModule
= lpTask
->hInst
;
480 dprintf_module(stddeb
,"GetProcAddress: current module=%04X instance=%04X!\n",
481 lpTask
->hModule
, lpTask
->hInst
);
484 while (w
&& w
->hinstance
!= hModule
)
488 dprintf_module(stddeb
,"GetProcAddress // Module Found ! w->filename='%s'\n", w
->filename
);
489 if ((int)proc_name
& 0xFFFF0000)
491 AnsiUpper(proc_name
);
492 dprintf_module(stddeb
,"GetProcAddress: %04X, '%s'\n", hModule
, proc_name
);
493 cpnt
= w
->ne
->nrname_table
;
496 if (((int) cpnt
) - ((int)w
->ne
->nrname_table
) >
497 w
->ne
->ne_header
->nrname_tab_length
) return NULL
;
499 strncpy(C
, cpnt
, len
);
501 dprintf_module(stddeb
,"pointing Function '%s' ordinal=%d !\n",
502 C
, *((unsigned short *)(cpnt
+ len
)));
503 if (strncmp(cpnt
, proc_name
, len
) == 0)
505 ordinal
= *((unsigned short *)(cpnt
+ len
));
512 printf("GetProcAddress // function '%s' not found !\n", proc_name
);
518 dprintf_module(stddeb
,"GetProcAddress: %#04x, %d\n", hModule
, (int) proc_name
);
519 ordinal
= (int)proc_name
;
521 ret
= GetEntryPointFromOrdinal(w
, ordinal
);
524 printf("GetProcAddress // Function #%d not found !\n", ordinal
);
529 dprintf_module(stddeb
,"GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret
, sel
, addr
);
530 return (FARPROC
) ret
;
536 FillModStructBuiltIn(MODULEENTRY
*lpModule
, struct dll_name_table_entry_s
*dll
)
538 lpModule
->dwSize
= dll
->dll_table_length
* 1024;
539 strcpy(lpModule
->szModule
, dll
->dll_name
);
540 lpModule
->hModule
= 0xff00 + dll
->dll_number
;
541 lpModule
->wcUsage
= GetModuleUsage(lpModule
->hModule
);
542 GetModuleFileName(lpModule
->hModule
, lpModule
->szExePath
, MAX_PATH
+ 1);
548 FillModStructLoaded(MODULEENTRY
*lpModule
, struct w_files
*dll
)
550 lpModule
->dwSize
= 16384;
551 strcpy(lpModule
->szModule
, dll
->name
);
552 lpModule
->hModule
= dll
->hinstance
;
553 lpModule
->wcUsage
= GetModuleUsage(lpModule
->hModule
);
554 GetModuleFileName(lpModule
->hModule
, lpModule
->szExePath
, MAX_PATH
+ 1);
558 /**********************************************************************
559 * ModuleFirst [TOOLHELP.59]
561 BOOL
ModuleFirst(MODULEENTRY
*lpModule
)
563 dprintf_module(stddeb
,"ModuleFirst(%08X)\n", (int) lpModule
);
565 FillModStructBuiltIn(lpModule
, &dll_builtin_table
[0]);
569 /**********************************************************************
570 * ModuleNext [TOOLHELP.60]
572 BOOL
ModuleNext(MODULEENTRY
*lpModule
)
576 dprintf_module(stddeb
,"ModuleNext(%08X)\n", (int) lpModule
);
578 if (IS_BUILTIN_DLL(lpModule
->hModule
)) {
579 /* last built-in ? */
580 if ((lpModule
->hModule
& 0xff) == (N_BUILTINS
- 1) ) {
582 FillModStructLoaded(lpModule
, wine_files
);
587 FillModStructBuiltIn(lpModule
, &dll_builtin_table
[(lpModule
->hModule
& 0xff)+1]);
590 w
= GetFileInfo(lpModule
->hModule
);
592 FillModStructLoaded(lpModule
, w
->next
);
598 /**********************************************************************
599 * ModuleFindHandle [TOOLHELP.62]
601 HMODULE
ModuleFindHandle(MODULEENTRY
*lpModule
, HMODULE hModule
)
605 dprintf_module(stddeb
,"ModuleFindHandle(%08X, %04X)\n", (int) lpModule
, (int)hModule
);
608 if (IS_BUILTIN_DLL(hModule
)) {
609 FillModStructBuiltIn(lpModule
, &dll_builtin_table
[hModule
& 0xff]);
613 /* check loaded dlls */
614 if ((w
= GetFileInfo(hModule
)) == NULL
)
615 return (HMODULE
) NULL
;
617 FillModStructLoaded(lpModule
, w
);
621 /**********************************************************************
622 * ModuleFindName [TOOLHELP.61]
624 HMODULE
ModuleFindName(MODULEENTRY
*lpModule
, LPCSTR lpstrName
)
626 return (ModuleFindHandle(lpModule
, GetModuleHandle((char*)lpstrName
)));