/* * Module & Library functions */ static char Copyright[] = "Copyright 1993, 1994 Martin Ayotte, Robert J. Amstadt, Erik Bos"; #include #include #include #include #include #include #include #include "neexe.h" #include "segmem.h" #include "dlls.h" #include "wine.h" #include "wineopts.h" #include "arch.h" #include "options.h" #include "prototypes.h" #include "windows.h" #include "task.h" #include "toolhelp.h" #include "stddebug.h" /* #define DEBUG_MODULE /* */ /* #undef DEBUG_MODULE /* */ #include "debug.h" extern char WindowsPath[256]; extern struct dll_name_table_entry_s dll_builtin_table[]; extern char *GetDosFileName(char *); extern HANDLE hSysRes; 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) InitNEDLL(wpnt); else InitPEDLL(wpnt); } void InitializeLoadedDLLs(struct w_files *wpnt) { static flagReadyToRun = 0; struct w_files *final_wpnt; printf("InitializeLoadedDLLs %08X\n", wpnt); if (wpnt == NULL) { flagReadyToRun = 1; fprintf(stderr, "Initializing DLLs\n"); } if (!flagReadyToRun) return; #if 1 if (wpnt != NULL) fprintf(stderr, "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); printf("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 = 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 = GetDosFileName(fullname); fprintf(stderr,"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)) { myerror("Unable to read MZ header from file"); } if (wpnt->mz_header->must_be_0x40 != 0x40) myerror("This is not a Windows program"); /* 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; if (header[0] == 'N' && header[1] == 'E') handle = LoadNEImage(wpnt); if (header[0] == 'P' && header[1] == 'E') handle = LoadPEImage(wpnt); wpnt->hinstance = handle; if (handle > 32) { /* ok, loaded, add to the end of the list */ if(wine_files == NULL) wine_files = wpnt; else { wpnt1 = wine_files; while(wpnt1->next) wpnt1 = wpnt1->next; wpnt1->next = wpnt; } wpnt->next = NULL; return handle; } else { fprintf(stderr, "wine: (%s) unknown fileformat !\n", wpnt->filename); 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) printf("GetModuleHandle('%s');\n", lpModuleName); else printf("GetModuleHandle('%x');\n", lpModuleName); /* printf("GetModuleHandle // searching in builtin libraries\n");*/ for (i = 0; i < N_BUILTINS; i++) { if (dll_builtin_table[i].dll_name == NULL) break; if (((int) lpModuleName & 0xffff0000) == 0) { if (0xFF00 + i == (int) lpModuleName) { printf("GetModuleHandle('%s') return %04X \n", lpModuleName, 0xff00 + i); return 0xFF00 + i; } } else if (strcasecmp(dll_builtin_table[i].dll_name, dllname) == 0) { printf("GetModuleHandle('%x') return %04X \n", lpModuleName, 0xFF00 + i); return (0xFF00 + i); } } printf("GetModuleHandle // searching in loaded modules\n"); while (w) { /* printf("GetModuleHandle // '%x' \n", w->name); */ if (((int) lpModuleName & 0xffff0000) == 0) { if (w->hinstance == (int) lpModuleName) { printf("GetModuleHandle('%x') return %04X \n", lpModuleName, w->hinstance); return w->hinstance; } } else if (strcasecmp(w->name, dllname) == 0) { printf("GetModuleHandle('%s') return %04X \n", lpModuleName, w->hinstance); return w->hinstance; } w = w->next; } printf("GetModuleHandle('%x') not found !\n", lpModuleName); return 0; } /********************************************************************** * GetModuleUsage [KERNEL.48] */ int GetModuleUsage(HANDLE hModule) { struct w_files *w; printf("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]; printf("GetModuleFileName(%04X, %08X, %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); printf("GetModuleFileName copied '%s' (internal dll) return %d \n", lpFileName, nSize); return strlen(lpFileName); } /* check loaded dlls */ if ((w = GetFileInfo(hModule)) == NULL) return 0; str = GetDosFileName(w->filename); if (nSize > strlen(str)) nSize = strlen(str) + 1; strncpy(lpFileName, str, nSize); printf("GetModuleFileName copied '%s' return %d \n", lpFileName, nSize); return nSize - 1; } /********************************************************************** * LoadLibrary [KERNEL.95] */ HANDLE LoadLibrary(LPSTR libname) { HANDLE h; 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) { struct w_files *wpnt; printf("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) NEunloadImage(wpnt); else PEunloadImage(wpnt); if (hLib != (HANDLE)NULL) GlobalFree(hLib); if (lpMod->ModuleName != NULL) free(lpMod->ModuleName); if (lpMod->FileName != NULL) free(lpMod->FileName); GlobalFree(lpMod->hModule); printf("FreeLibrary // freed !\n"); return; } lpMod->Count--; printf("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 sel, addr, ret; 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) { printf("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 { printf("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); printf("GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret, sel, addr); return (FARPROC)ret; } if (hModule == 0) { hTask = GetCurrentTask(); printf("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; printf("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; printf("GetProcAddress // Module Found ! w->filename='%s'\n", w->filename); if ((int)proc_name & 0xFFFF0000) { AnsiUpper(proc_name); printf("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'; #ifdef DEBUG_MODULE printf("pointing Function '%s' ordinal=%d !\n", C, *((unsigned short *)(cpnt + len))); #endif 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 { printf("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); printf("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->dll_table_length * 1024; strcpy(lpModule->szModule, dll->dll_name); lpModule->hModule = 0xff00 + dll->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) { printf("ModuleFirst(%08X)\n", (int) lpModule); FillModStructBuiltIn(lpModule, &dll_builtin_table[0]); return TRUE; } /********************************************************************** * ModuleNext [TOOLHELP.60] */ BOOL ModuleNext(MODULEENTRY *lpModule) { struct w_files *w; printf("ModuleNext(%08X)\n", (int) lpModule); if (IS_BUILTIN_DLL(lpModule->hModule)) { /* last built-in ? */ if ((lpModule->hModule & 0xff) == (N_BUILTINS - 1) ) { if (wine_files) { FillModStructLoaded(lpModule, wine_files); return TRUE; } else return FALSE; } FillModStructBuiltIn(lpModule, &dll_builtin_table[(lpModule->hModule & 0xff)+1]); 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; printf("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))); }