Sun Apr 2 18:31:12 1995 Alexandre Julliard (julliard@sunsite.unc.edu) * [Configure] [if1632/Imakefile] Removed new build and short names options. * [if1632/*.c] [tools/build.c] Implemented compiled call-back functions for better performance; all the relay code is now done in assembly code generated by the build program. Relay code is no longer dependent on being loaded below 64K. * [loader/resource.c] Fixed memory leak in LoadString(). A fix will also be needed for other resources. * [memory/global.c] Implemented global heap arenas, so we can store informations about global blocks, like lock counts or owner handle. Implemented FarGetOwner() and FarSetOwner(). Implemented global heap TOOLHELP functions. * [memory/selector.c] Bug fix: it was not possible to re-use a free selector. Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis (csapuntz@mit.edu) * [controls/listbox.c] Major work on listbox code - Many bugs fixed (still many bugs) - More messages supported - Code simplified Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu) * [controls/edit.c] Lots of bug fixes related to diappearing text, lost carets, highlighting, segmentation faults, occurance of random characters, insertion of characters over selection, misplaced caret location, display corruption, end of line behavior, etc. * [controls/widgets.c] EDIT class doesn't want to use CS_PARENTDC flag. Thu Mar 30 20:58:25 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [loader/selector.c] FixupFunctionPrologs() should also handle multiple data modules. (this bug only became visible because MakeProcInstance() was fixed in 950319) * [misc/dosfs.c] Simplified DOS_SimplifyPath. Small fix to DOS_opendir to reuse an entry if an open directory is opened again, to prevent "too many open directories" messages. Thu Mar 30 12:05:05 1995 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/compobj.spec][include/compobj.h][misc/compobj.c] CoDisconnectObject: new stub function * [include/msdos.h] fix DOSVERSION * [loader/ne_image.c] NE_FixupSegment: Be more generous on additive fixups * [if1632/user.spec][misc/network.c] Add more WNet* stubs Wed Mar 29 11:47:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [controls/listbox.c] DlgDirList(): send segptr instead of linear pointer in message to static control * [controls/menu.c] Tried to implement ownerdrawn menuitems. Doesn't work. * [if1632/gdi.spec] [include/windows.h] [objects/font.c] Provide a stub for GetRasterizerCaps() * [loader/selector.c] Pass end address instead of length to LocalInit() in CreateSelectors() * [memory/local.c] LocalInit(): If there's already a local heap in the segment, do nothing and return TRUE * [objects/linedda.c] Replaced buggy LineDDA() with a Bresenham algorithm. Should work now. * [windows/cursor.c] LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some more work still. Tue Mar 21 17:54:43 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [if1632/relay.c] [if1632/callback.c] [include/dlls.h] [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h] [controls/widgets.c] [misc/shell.c] [misc/commdlg.c] [windows/nonclient.c] [misc/message.c] Added a new builtin DLL that provides 16 bit entry points for all the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work again. * [misc/shell.c] RegOpenKey()/RegCreateKey() bugs fixed. * [loader/ne_image.c] Skipping the initialization of a DLL when CS == 0 was broken.
642 lines
16 KiB
C
642 lines
16 KiB
C
/*
|
||
* Module & Library functions
|
||
static char Copyright[] = "Copyright 1993, 1994 Martin Ayotte, Robert J. Amstadt, Erik Bos";
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <fcntl.h>
|
||
#include <unistd.h>
|
||
#include "neexe.h"
|
||
#include "dlls.h"
|
||
#include "if1632.h"
|
||
#include "wineopts.h"
|
||
#include "arch.h"
|
||
#include "options.h"
|
||
#include "dos_fs.h"
|
||
#include "windows.h"
|
||
#include "task.h"
|
||
#include "toolhelp.h"
|
||
#include "selectors.h"
|
||
#include "stddebug.h"
|
||
#include "debug.h"
|
||
#include "prototypes.h"
|
||
#include "library.h"
|
||
#include "ne_image.h"
|
||
#include "pe_image.h"
|
||
|
||
struct w_files *wine_files = NULL;
|
||
static char *DLL_Extensions[] = { "dll", NULL };
|
||
static char *EXE_Extensions[] = { "exe", NULL };
|
||
|
||
#define IS_BUILTIN_DLL(handle) ((handle >> 8) == 0xff)
|
||
|
||
/**********************************************************************/
|
||
|
||
void ExtractDLLName(char *libname, char *temp)
|
||
{
|
||
int i;
|
||
|
||
strcpy(temp, libname);
|
||
if (strchr(temp, '\\') || strchr(temp, '/'))
|
||
for (i = strlen(temp) - 1; i ; i--)
|
||
if (temp[i] == '\\' || temp[i] == '/') {
|
||
strcpy(temp, temp + i + 1);
|
||
break;
|
||
}
|
||
for (i = strlen(temp) - 1; i ; i--)
|
||
if (temp[i] == '.') {
|
||
temp[i] = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
struct w_files *GetFileInfo(unsigned short instance)
|
||
{
|
||
register struct w_files *w = wine_files;
|
||
|
||
while (w && w->hinstance != instance)
|
||
w = w->next;
|
||
|
||
return w;
|
||
}
|
||
|
||
int IsDLLLoaded(char *name)
|
||
{
|
||
struct w_files *wpnt;
|
||
|
||
if(FindDLLTable(name))
|
||
return 1;
|
||
|
||
for(wpnt = wine_files; wpnt; wpnt = wpnt->next)
|
||
if(strcmp(wpnt->name, name) == 0)
|
||
return 1;
|
||
|
||
return 0;
|
||
}
|
||
|
||
void InitDLL(struct w_files *wpnt)
|
||
{
|
||
if (wpnt->ne)
|
||
NE_InitDLL(wpnt);
|
||
else
|
||
PE_InitDLL(wpnt);
|
||
}
|
||
|
||
void InitializeLoadedDLLs(struct w_files *wpnt)
|
||
{
|
||
static flagReadyToRun = 0;
|
||
struct w_files *final_wpnt;
|
||
|
||
dprintf_module(stddeb,"InitializeLoadedDLLs(%p)\n", wpnt);
|
||
|
||
if (wpnt == NULL)
|
||
{
|
||
flagReadyToRun = 1;
|
||
dprintf_module(stddeb,"Initializing DLLs\n");
|
||
}
|
||
|
||
if (!flagReadyToRun)
|
||
return;
|
||
|
||
#if 1
|
||
if (wpnt != NULL)
|
||
dprintf_module(stddeb,"Initializing %s\n", wpnt->name);
|
||
#endif
|
||
|
||
/*
|
||
* Initialize libraries
|
||
*/
|
||
if (!wpnt)
|
||
{
|
||
wpnt = wine_files;
|
||
final_wpnt = NULL;
|
||
}
|
||
else
|
||
{
|
||
final_wpnt = wpnt->next;
|
||
}
|
||
|
||
for( ; wpnt != final_wpnt; wpnt = wpnt->next)
|
||
InitDLL(wpnt);
|
||
}
|
||
|
||
/**********************************************************************
|
||
* LoadImage
|
||
* Load one executable into memory
|
||
*/
|
||
HINSTANCE LoadImage(char *module, int filetype, int change_dir)
|
||
{
|
||
HINSTANCE handle;
|
||
struct w_files *wpnt, *wpnt1;
|
||
char buffer[256], header[2], modulename[64], *fullname;
|
||
|
||
ExtractDLLName(module, modulename);
|
||
dprintf_module(stddeb,"LoadImage [%s]\n", module);
|
||
/* built-in one ? */
|
||
if (FindDLLTable(modulename)) {
|
||
return GetModuleHandle(modulename);
|
||
}
|
||
|
||
/* already loaded ? */
|
||
for (wpnt = wine_files ; wpnt ; wpnt = wpnt->next)
|
||
if (strcasecmp(wpnt->name, modulename) == 0)
|
||
return wpnt->hinstance;
|
||
|
||
/*
|
||
* search file
|
||
*/
|
||
fullname = DOS_FindFile(buffer, sizeof(buffer), module,
|
||
(filetype == EXE ? EXE_Extensions : DLL_Extensions),
|
||
WindowsPath);
|
||
if (fullname == NULL)
|
||
{
|
||
fprintf(stderr, "LoadImage: I can't find %s.dll | %s.exe !\n",
|
||
module, module);
|
||
return 2;
|
||
}
|
||
|
||
fullname = DOS_GetDosFileName(fullname);
|
||
|
||
dprintf_module(stddeb,"LoadImage: loading %s (%s)\n [%s]\n",
|
||
module, buffer, fullname);
|
||
|
||
if (change_dir && fullname)
|
||
{
|
||
char dirname[256];
|
||
char *p;
|
||
|
||
strcpy(dirname, fullname);
|
||
p = strrchr(dirname, '\\');
|
||
*p = '\0';
|
||
|
||
DOS_SetDefaultDrive(dirname[0] - 'A');
|
||
DOS_ChangeDir(dirname[0] - 'A', dirname + 2);
|
||
}
|
||
|
||
/* First allocate a spot to store the info we collect, and add it to
|
||
* our linked list if we could load the file.
|
||
*/
|
||
|
||
wpnt = (struct w_files *) malloc(sizeof(struct w_files));
|
||
|
||
/*
|
||
* Open file for reading.
|
||
*/
|
||
wpnt->fd = open(buffer, O_RDONLY);
|
||
if (wpnt->fd < 0)
|
||
return 2;
|
||
|
||
/*
|
||
* Establish header pointers.
|
||
*/
|
||
wpnt->filename = strdup(buffer);
|
||
wpnt->name = strdup(modulename);
|
||
|
||
/* read mz header */
|
||
wpnt->mz_header = (struct mz_header_s *) malloc(sizeof(struct mz_header_s));;
|
||
lseek(wpnt->fd, 0, SEEK_SET);
|
||
if (read(wpnt->fd, wpnt->mz_header, sizeof(struct mz_header_s)) !=
|
||
sizeof(struct mz_header_s))
|
||
{
|
||
fprintf(stderr, "Unable to read MZ header from file '%s'\n", buffer);
|
||
exit(1);
|
||
}
|
||
|
||
/* This field is ignored according to "Windows Internals", p.242 */
|
||
#if 0
|
||
if (wpnt->mz_header->must_be_0x40 != 0x40)
|
||
myerror("This is not a Windows program");
|
||
#endif
|
||
|
||
/* read first two bytes to determine filetype */
|
||
lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
|
||
read(wpnt->fd, &header, sizeof(header));
|
||
|
||
handle = 0;
|
||
|
||
/*
|
||
* Stick this file into the list of loaded files so we don't try to reload
|
||
* it again if another module references this module. Do this before
|
||
* calling NE_LoadImage because we might get back here before NE_loadImage
|
||
* returns.
|
||
*/
|
||
if(wine_files == NULL)
|
||
wine_files = wpnt;
|
||
else {
|
||
wpnt1 = wine_files;
|
||
while(wpnt1->next)
|
||
wpnt1 = wpnt1->next;
|
||
wpnt1->next = wpnt;
|
||
}
|
||
wpnt->next = NULL;
|
||
|
||
if (header[0] == 'N' && header[1] == 'E')
|
||
handle = NE_LoadImage(wpnt);
|
||
if (header[0] == 'P' && header[1] == 'E')
|
||
handle = PE_LoadImage(wpnt);
|
||
wpnt->hinstance = handle;
|
||
|
||
if (handle > 32) {
|
||
return handle;
|
||
} else {
|
||
fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename);
|
||
|
||
/* Remove this module from the list of loaded modules */
|
||
if (wine_files == wpnt)
|
||
wine_files = NULL;
|
||
else
|
||
wpnt1->next = NULL;
|
||
close(wpnt->fd);
|
||
free(wpnt->filename);
|
||
free(wpnt->name);
|
||
free(wpnt);
|
||
|
||
return 14;
|
||
}
|
||
}
|
||
|
||
/**********************************************************************
|
||
* GetModuleHandle [KERNEL.47]
|
||
*/
|
||
HANDLE GetModuleHandle(LPSTR lpModuleName)
|
||
{
|
||
register struct w_files *w = wine_files;
|
||
int i;
|
||
char dllname[256];
|
||
|
||
if ((int) lpModuleName & 0xffff0000)
|
||
ExtractDLLName(lpModuleName, dllname);
|
||
|
||
if ((int) lpModuleName & 0xffff0000)
|
||
dprintf_module(stddeb,"GetModuleHandle('%s');\n", lpModuleName);
|
||
else
|
||
dprintf_module(stddeb,"GetModuleHandle('%p');\n", lpModuleName);
|
||
|
||
/* dprintf_module(stddeb,"GetModuleHandle // searching in builtin libraries\n");*/
|
||
for (i = 0; i < N_BUILTINS; i++) {
|
||
if (dll_builtin_table[i].dll_name == NULL) break;
|
||
if (!dll_builtin_table[i].dll_is_used){
|
||
dprintf_module(stddeb,"Skipping builtin %s\n",
|
||
dll_builtin_table[i].dll_name);
|
||
continue;
|
||
}
|
||
if (((int) lpModuleName & 0xffff0000) == 0) {
|
||
if (0xFF00 + i == (int) lpModuleName) {
|
||
dprintf_module(stddeb,"GetModuleHandle('%s') return %04X \n",
|
||
lpModuleName, 0xff00 + i);
|
||
return 0xFF00 + i;
|
||
}
|
||
}
|
||
else if (strcasecmp(dll_builtin_table[i].dll_name, dllname) == 0) {
|
||
dprintf_module(stddeb,"GetModuleHandle('%p') return %04X \n",
|
||
lpModuleName, 0xFF00 + i);
|
||
return (0xFF00 + i);
|
||
}
|
||
}
|
||
|
||
dprintf_module(stddeb,"GetModuleHandle // searching in loaded modules\n");
|
||
while (w) {
|
||
/* dprintf_module(stddeb,"GetModuleHandle // '%x' \n", w->name); */
|
||
if (((int) lpModuleName & 0xffff0000) == 0) {
|
||
if (w->hinstance == (int) lpModuleName) {
|
||
dprintf_module(stddeb,"GetModuleHandle('%p') return %04X \n",
|
||
lpModuleName, w->hinstance);
|
||
return w->hinstance;
|
||
}
|
||
}
|
||
else if (strcasecmp(w->name, dllname) == 0) {
|
||
dprintf_module(stddeb,"GetModuleHandle('%s') return %04X \n",
|
||
lpModuleName, w->hinstance);
|
||
return w->hinstance;
|
||
}
|
||
w = w->next;
|
||
}
|
||
printf("GetModuleHandle('%p') not found !\n", lpModuleName);
|
||
return 0;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* GetModuleUsage [KERNEL.48]
|
||
*/
|
||
int GetModuleUsage(HANDLE hModule)
|
||
{
|
||
struct w_files *w;
|
||
|
||
dprintf_module(stddeb,"GetModuleUsage(%04X);\n", hModule);
|
||
|
||
/* built-in dll ? */
|
||
if (IS_BUILTIN_DLL(hModule))
|
||
return 2;
|
||
|
||
w = GetFileInfo(hModule);
|
||
/* return w->Usage; */
|
||
return 1;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* GetModuleFilename [KERNEL.49]
|
||
*/
|
||
int GetModuleFileName(HANDLE hModule, LPSTR lpFileName, short nSize)
|
||
{
|
||
struct w_files *w;
|
||
LPSTR str;
|
||
char windir[256], temp[256];
|
||
|
||
dprintf_module(stddeb,"GetModuleFileName(%04X, %p, %d);\n", hModule, lpFileName, nSize);
|
||
|
||
if (lpFileName == NULL) return 0;
|
||
if (nSize < 1) return 0;
|
||
|
||
/* built-in dll ? */
|
||
if (IS_BUILTIN_DLL(hModule)) {
|
||
GetWindowsDirectory(windir, sizeof(windir));
|
||
sprintf(temp, "%s\\%s.DLL", windir, dll_builtin_table[hModule & 0x00ff].dll_name);
|
||
ToDos(temp);
|
||
strncpy(lpFileName, temp, nSize);
|
||
dprintf_module(stddeb,"GetModuleFileName copied '%s' (internal dll) return %d \n", lpFileName, nSize);
|
||
return strlen(lpFileName);
|
||
}
|
||
|
||
/* check loaded dlls */
|
||
if ((w = GetFileInfo(hModule)) == NULL)
|
||
return 0;
|
||
str = DOS_GetDosFileName(w->filename);
|
||
if (nSize > strlen(str)) nSize = strlen(str) + 1;
|
||
strncpy(lpFileName, str, nSize);
|
||
dprintf_module(stddeb,"GetModuleFileName copied '%s' return %d \n", lpFileName, nSize);
|
||
return nSize - 1;
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* LoadLibrary [KERNEL.95]
|
||
*/
|
||
HANDLE LoadLibrary(LPSTR libname)
|
||
{
|
||
HANDLE h;
|
||
|
||
dprintf_module(stddeb,"LoadLibrary: (%08x) %s\n",(int)libname,libname);
|
||
|
||
if ((h = LoadImage(libname, DLL, 0)) < 32)
|
||
return h;
|
||
|
||
if (!IS_BUILTIN_DLL(h))
|
||
InitDLL(GetFileInfo(h));
|
||
|
||
return h;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* FreeLibrary [KERNEL.96]
|
||
*/
|
||
void FreeLibrary(HANDLE hLib)
|
||
{
|
||
dprintf_module(stddeb,"FreeLibrary(%04X);\n", hLib);
|
||
|
||
/* built-in dll ? */
|
||
if (IS_BUILTIN_DLL(hLib) || hLib == 0 || hLib == hSysRes)
|
||
return;
|
||
|
||
/*
|
||
while (lpMod != NULL) {
|
||
if (lpMod->hInst == hLib) {
|
||
if (lpMod->Count == 1) {
|
||
wpnt = GetFileInfo(hLib);
|
||
if (wpnt->ne)
|
||
NE_UnloadImage(wpnt);
|
||
else
|
||
PE_UnloadImage(wpnt);
|
||
if (hLib != (HANDLE)NULL) GlobalFree(hLib);
|
||
if (lpMod->ModuleName != NULL) free(lpMod->ModuleName);
|
||
if (lpMod->FileName != NULL) free(lpMod->FileName);
|
||
GlobalFree(lpMod->hModule);
|
||
dprintf_module(stddeb,"FreeLibrary // freed !\n");
|
||
return;
|
||
}
|
||
lpMod->Count--;
|
||
dprintf_module(stddeb,"FreeLibrary // Count decremented !\n");
|
||
return;
|
||
}
|
||
lpMod = lpMod->lpNextModule;
|
||
}
|
||
*/
|
||
}
|
||
|
||
|
||
/**********************************************************************
|
||
* GetProcAddress [KERNEL.50]
|
||
*/
|
||
FARPROC GetProcAddress(HANDLE hModule, char *proc_name)
|
||
{
|
||
#ifdef WINELIB
|
||
WINELIB_UNIMP ("GetProcAddress");
|
||
#else
|
||
int ret;
|
||
WORD sel, addr;
|
||
register struct w_files *w = wine_files;
|
||
int ordinal, len;
|
||
char * cpnt;
|
||
char C[128];
|
||
HTASK hTask;
|
||
LPTASKENTRY lpTask;
|
||
|
||
/* built-in dll ? */
|
||
if (IS_BUILTIN_DLL(hModule))
|
||
{
|
||
if ((int) proc_name & 0xffff0000)
|
||
{
|
||
dprintf_module(stddeb,"GetProcAddress: builtin %#04X, '%s'\n",
|
||
hModule, proc_name);
|
||
if (GetEntryDLLName(dll_builtin_table[hModule - 0xFF00].dll_name,
|
||
proc_name, &sel, &addr))
|
||
{
|
||
printf("Address not found !\n");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dprintf_module(stddeb,"GetProcAddress: builtin %#04X, %d\n",
|
||
hModule, (int)proc_name);
|
||
if (GetEntryDLLOrdinal(dll_builtin_table[hModule-0xFF00].dll_name,
|
||
(int)proc_name & 0x0000FFFF, &sel, &addr))
|
||
{
|
||
printf("Address not found !\n");
|
||
}
|
||
}
|
||
ret = MAKELONG(addr, sel);
|
||
dprintf_module(stddeb,"GetProcAddress // ret=%08X sel=%04X addr=%04X\n",
|
||
ret, sel, addr);
|
||
return (FARPROC)ret;
|
||
}
|
||
if (hModule == 0)
|
||
{
|
||
hTask = GetCurrentTask();
|
||
dprintf_module(stddeb,"GetProcAddress // GetCurrentTask()=%04X\n", hTask);
|
||
lpTask = (LPTASKENTRY) GlobalLock(hTask);
|
||
if (lpTask == NULL)
|
||
{
|
||
printf("GetProcAddress: can't find current module handle !\n");
|
||
return NULL;
|
||
}
|
||
hModule = lpTask->hInst;
|
||
dprintf_module(stddeb,"GetProcAddress: current module=%04X instance=%04X!\n",
|
||
lpTask->hModule, lpTask->hInst);
|
||
GlobalUnlock(hTask);
|
||
}
|
||
while (w && w->hinstance != hModule)
|
||
w = w->next;
|
||
if (w == NULL)
|
||
return NULL;
|
||
dprintf_module(stddeb,"GetProcAddress // Module Found ! w->filename='%s'\n", w->filename);
|
||
if ((int)proc_name & 0xFFFF0000)
|
||
{
|
||
AnsiUpper(proc_name);
|
||
dprintf_module(stddeb,"GetProcAddress: %04X, '%s'\n", hModule, proc_name);
|
||
cpnt = w->ne->nrname_table;
|
||
while(TRUE)
|
||
{
|
||
if (((int) cpnt) - ((int)w->ne->nrname_table) >
|
||
w->ne->ne_header->nrname_tab_length) return NULL;
|
||
len = *cpnt++;
|
||
strncpy(C, cpnt, len);
|
||
C[len] = '\0';
|
||
dprintf_module(stddeb,"pointing Function '%s' ordinal=%d !\n",
|
||
C, *((unsigned short *)(cpnt + len)));
|
||
if (strncmp(cpnt, proc_name, len) == 0)
|
||
{
|
||
ordinal = *((unsigned short *)(cpnt + len));
|
||
break;
|
||
}
|
||
cpnt += len + 2;
|
||
}
|
||
if (ordinal == 0)
|
||
{
|
||
printf("GetProcAddress // function '%s' not found !\n", proc_name);
|
||
return NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dprintf_module(stddeb,"GetProcAddress: %#04x, %d\n", hModule, (int) proc_name);
|
||
ordinal = (int)proc_name;
|
||
}
|
||
ret = GetEntryPointFromOrdinal(w, ordinal);
|
||
if (ret == -1)
|
||
{
|
||
printf("GetProcAddress // Function #%d not found !\n", ordinal);
|
||
return NULL;
|
||
}
|
||
addr = ret & 0xffff;
|
||
sel = (ret >> 16);
|
||
dprintf_module(stddeb,"GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret, sel, addr);
|
||
return (FARPROC) ret;
|
||
#endif /* WINELIB */
|
||
}
|
||
|
||
/* internal dlls */
|
||
static void
|
||
FillModStructBuiltIn(MODULEENTRY *lpModule, struct dll_name_table_entry_s *dll)
|
||
{
|
||
lpModule->dwSize = dll->table->dll_table_length * 1024;
|
||
strcpy(lpModule->szModule, dll->dll_name);
|
||
lpModule->hModule = 0xff00 + dll->table->dll_number;
|
||
lpModule->wcUsage = GetModuleUsage(lpModule->hModule);
|
||
GetModuleFileName(lpModule->hModule, lpModule->szExePath, MAX_PATH + 1);
|
||
lpModule->wNext = 0;
|
||
}
|
||
|
||
/* loaded dlls */
|
||
static void
|
||
FillModStructLoaded(MODULEENTRY *lpModule, struct w_files *dll)
|
||
{
|
||
lpModule->dwSize = 16384;
|
||
strcpy(lpModule->szModule, dll->name);
|
||
lpModule->hModule = dll->hinstance;
|
||
lpModule->wcUsage = GetModuleUsage(lpModule->hModule);
|
||
GetModuleFileName(lpModule->hModule, lpModule->szExePath, MAX_PATH + 1);
|
||
lpModule->wNext = 0;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* ModuleFirst [TOOLHELP.59]
|
||
*/
|
||
BOOL ModuleFirst(MODULEENTRY *lpModule)
|
||
{
|
||
dprintf_module(stddeb,"ModuleFirst(%08X)\n", (int) lpModule);
|
||
|
||
FillModStructBuiltIn(lpModule, &dll_builtin_table[0]);
|
||
return TRUE;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* ModuleNext [TOOLHELP.60]
|
||
*/
|
||
BOOL ModuleNext(MODULEENTRY *lpModule)
|
||
{
|
||
struct w_files *w;
|
||
|
||
dprintf_module(stddeb,"ModuleNext(%08X)\n", (int) lpModule);
|
||
|
||
if (IS_BUILTIN_DLL(lpModule->hModule))
|
||
{
|
||
int builtin_no=lpModule->hModule & 0xff;
|
||
do{
|
||
/* last built-in ? */
|
||
if (builtin_no == (N_BUILTINS - 1) ) {
|
||
if (wine_files) {
|
||
FillModStructLoaded(lpModule, wine_files);
|
||
return TRUE;
|
||
} else
|
||
return FALSE;
|
||
}
|
||
builtin_no++;
|
||
}while(!dll_builtin_table[builtin_no].dll_is_used);
|
||
|
||
FillModStructBuiltIn(lpModule, &dll_builtin_table[builtin_no]);
|
||
return TRUE;
|
||
}
|
||
w = GetFileInfo(lpModule->hModule);
|
||
if (w->next) {
|
||
FillModStructLoaded(lpModule, w->next);
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* ModuleFindHandle [TOOLHELP.62]
|
||
*/
|
||
HMODULE ModuleFindHandle(MODULEENTRY *lpModule, HMODULE hModule)
|
||
{
|
||
struct w_files *w;
|
||
|
||
dprintf_module(stddeb,"ModuleFindHandle(%08X, %04X)\n", (int) lpModule, (int)hModule);
|
||
|
||
/* built-in dll ? */
|
||
if (IS_BUILTIN_DLL(hModule)) {
|
||
FillModStructBuiltIn(lpModule, &dll_builtin_table[hModule & 0xff]);
|
||
return hModule;
|
||
}
|
||
|
||
/* check loaded dlls */
|
||
if ((w = GetFileInfo(hModule)) == NULL)
|
||
return (HMODULE) NULL;
|
||
|
||
FillModStructLoaded(lpModule, w);
|
||
return w->hinstance;
|
||
}
|
||
|
||
/**********************************************************************
|
||
* ModuleFindName [TOOLHELP.61]
|
||
*/
|
||
HMODULE ModuleFindName(MODULEENTRY *lpModule, LPCSTR lpstrName)
|
||
{
|
||
return (ModuleFindHandle(lpModule, GetModuleHandle((char*)lpstrName)));
|
||
}
|
||
|