4 * Copyright 1995 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/port.h"
37 #include "wine/winbase16.h"
38 #include "wine/library.h"
45 #include "builtin16.h"
46 #include "stackframe.h"
48 #include "wine/exception.h"
49 #include "wine/debug.h"
51 WINE_DEFAULT_DEBUG_CHANNEL(module);
52 WINE_DECLARE_DEBUG_CHANNEL(loaddll);
55 typedef struct _GPHANDLERDEF
64 #define hFirstModule (pThhook->hExeHead)
67 /***********************************************************************
70 NE_MODULE *NE_GetPtr( HMODULE16 hModule )
72 return (NE_MODULE *)GlobalLock16( GetExePtr(hModule) );
76 /**********************************************************************
77 * GetModuleFileName (KERNEL.49)
79 * Comment: see GetModuleFileNameA
81 * Even if invoked by second instance of a program,
82 * it still returns path of first one.
84 INT16 WINAPI GetModuleFileName16( HINSTANCE16 hModule, LPSTR lpFileName,
89 /* Win95 does not query hModule if set to 0 !
90 * Is this wrong or maybe Win3.1 only ? */
91 if (!hModule) hModule = GetCurrentTask();
93 if (!(pModule = NE_GetPtr( hModule ))) return 0;
94 lstrcpynA( lpFileName, NE_MODULE_NAME(pModule), nSize );
95 if (pModule->expected_version >= 0x400)
96 GetLongPathNameA(NE_MODULE_NAME(pModule), lpFileName, nSize);
97 TRACE("%04x -> '%s'\n", hModule, lpFileName );
98 return strlen(lpFileName);
102 /***********************************************************************
103 * GetModuleHandle16 (KERNEL32.@)
105 HMODULE16 WINAPI GetModuleHandle16( LPCSTR name )
107 HMODULE16 hModule = hFirstModule;
109 BYTE len, *name_table;
110 char tmpstr[MAX_PATH];
113 TRACE("(%s)\n", name);
116 return GetExePtr(LOWORD(name));
122 lstrcpynA(tmpstr, name, sizeof(tmpstr));
124 /* If 'name' matches exactly the module name of a module:
127 for (hModule = hFirstModule; hModule ; hModule = pModule->next)
129 pModule = NE_GetPtr( hModule );
131 if (pModule->flags & NE_FFLAGS_WIN32) continue;
133 name_table = (BYTE *)pModule + pModule->name_table;
134 if ((*name_table == len) && !strncmp(name, name_table+1, len))
138 /* If uppercased 'name' matches exactly the module name of a module:
141 for (s = tmpstr; *s; s++) *s = FILE_toupper(*s);
143 for (hModule = hFirstModule; hModule ; hModule = pModule->next)
145 pModule = NE_GetPtr( hModule );
147 if (pModule->flags & NE_FFLAGS_WIN32) continue;
149 name_table = (BYTE *)pModule + pModule->name_table;
150 /* FIXME: the strncasecmp is WRONG. It should not be case insensitive,
151 * but case sensitive! (Unfortunately Winword 6 and subdlls have
152 * lowercased module names, but try to load uppercase DLLs, so this
153 * 'i' compare is just a quickfix until the loader handles that
154 * correctly. -MM 990705
156 if ((*name_table == len) && !FILE_strncasecmp(tmpstr, name_table+1, len))
160 /* If the base filename of 'name' matches the base filename of the module
161 * filename of some module (case-insensitive compare):
165 /* basename: search backwards in passed name to \ / or : */
166 s = tmpstr + strlen(tmpstr);
169 if (s[-1]=='/' || s[-1]=='\\' || s[-1]==':')
174 /* search this in loaded filename list */
175 for (hModule = hFirstModule; hModule ; hModule = pModule->next)
180 pModule = NE_GetPtr( hModule );
182 if (!pModule->fileinfo) continue;
183 if (pModule->flags & NE_FFLAGS_WIN32) continue;
185 ofs = (OFSTRUCT*)((BYTE *)pModule + pModule->fileinfo);
186 loadedfn = ((char*)ofs->szPathName) + strlen(ofs->szPathName);
187 /* basename: search backwards in pathname to \ / or : */
188 while (loadedfn > (char*)ofs->szPathName)
190 if (loadedfn[-1]=='/' || loadedfn[-1]=='\\' || loadedfn[-1]==':')
194 /* case insensitive compare ... */
195 if (!FILE_strcasecmp(loadedfn, s))