GetModuleFileName[AW] doesn't terminate the string if the buffer is

too small.
This commit is contained in:
Eric Pouech 2004-05-19 03:22:55 +00:00 committed by Alexandre Julliard
parent 48a865983d
commit df93f2eeee
21 changed files with 213 additions and 50 deletions

View File

@ -312,9 +312,12 @@ static HRESULT register_clsids(int count, const register_info * pRegInfo, LPCWST
== ERROR_SUCCESS ? S_OK : E_FAIL;
TRACE("HModule = %p\n", DEVENUM_hInstance);
if (!GetModuleFileNameW(DEVENUM_hInstance, dll_module,
sizeof(dll_module) / sizeof(WCHAR)))
i = GetModuleFileNameW(DEVENUM_hInstance, dll_module,
sizeof(dll_module) / sizeof(WCHAR));
if (!i)
return HRESULT_FROM_WIN32(GetLastError());
if (i >= sizeof(dll_module) / sizeof(WCHAR))
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
for (i = 0; i < count; i++)
{

View File

@ -143,6 +143,7 @@ void setup_dsound_options(void)
{
char buffer[MAX_PATH+1];
HKEY hkey, appkey = 0;
DWORD len;
buffer[MAX_PATH]='\0';
@ -153,7 +154,8 @@ void setup_dsound_options(void)
ExitProcess(1);
}
if (GetModuleFileNameA( 0, buffer, MAX_PATH ))
len = GetModuleFileNameA( 0, buffer, MAX_PATH );
if (len && len < MAX_PATH)
{
HKEY tmpkey;

View File

@ -1133,7 +1133,10 @@ BOOL WINAPI AllocConsole(void)
if (siCurrent.lpTitle)
siConsole.lpTitle = siCurrent.lpTitle;
else if (GetModuleFileNameA(0, buffer, sizeof(buffer)))
{
buffer[sizeof(buffer) - 1] = '\0';
siConsole.lpTitle = buffer;
}
if (!start_console_renderer(&siConsole))
goto the_end;

View File

@ -432,6 +432,8 @@ HMODULE WINAPI GetModuleHandleW(LPCWSTR module)
* This function always returns the long path of hModule (as opposed to
* GetModuleFileName16() which returns short paths when the modules version
* field is < 4.0).
* The function doesn't write a terminating '\0' is the buffer is too
* small.
*/
DWORD WINAPI GetModuleFileNameA(
HMODULE hModule, /* [in] Module handle (32 bit) */
@ -439,16 +441,20 @@ DWORD WINAPI GetModuleFileNameA(
DWORD size ) /* [in] Size of lpFileName in characters */
{
LPWSTR filenameW = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
DWORD len;
if (!filenameW)
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
GetModuleFileNameW( hModule, filenameW, size );
FILE_name_WtoA( filenameW, -1, lpFileName, size );
if ((len = GetModuleFileNameW( hModule, filenameW, size )))
{
len = FILE_name_WtoA( filenameW, len, lpFileName, size );
if (len < size) lpFileName[len] = '\0';
}
HeapFree( GetProcessHeap(), 0, filenameW );
return strlen( lpFileName );
return len;
}
/***********************************************************************
@ -458,16 +464,16 @@ DWORD WINAPI GetModuleFileNameA(
*/
DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size )
{
ULONG magic;
ULONG magic, len = 0;
LDR_MODULE *pldr;
NTSTATUS nts;
WIN16_SUBSYSTEM_TIB *win16_tib;
lpFileName[0] = 0;
if (!hModule && ((win16_tib = NtCurrentTeb()->Tib.SubSystemTib)) && win16_tib->exe_name)
{
lstrcpynW( lpFileName, win16_tib->exe_name->Buffer, size );
len = min(size, win16_tib->exe_name->Length / sizeof(WCHAR));
memcpy( lpFileName, win16_tib->exe_name->Buffer, len * sizeof(WCHAR) );
if (len < size) lpFileName[len] = '\0';
goto done;
}
@ -475,13 +481,18 @@ DWORD WINAPI GetModuleFileNameW( HMODULE hModule, LPWSTR lpFileName, DWORD size
if (!hModule) hModule = NtCurrentTeb()->Peb->ImageBaseAddress;
nts = LdrFindEntryForAddress( hModule, &pldr );
if (nts == STATUS_SUCCESS) lstrcpynW(lpFileName, pldr->FullDllName.Buffer, size);
if (nts == STATUS_SUCCESS)
{
len = min(size, pldr->FullDllName.Length / sizeof(WCHAR));
memcpy(lpFileName, pldr->FullDllName.Buffer, len * sizeof(WCHAR));
if (len < size) lpFileName[len] = '\0';
}
else SetLastError( RtlNtStatusToDosError( nts ) );
LdrUnlockLoaderLock( 0, magic );
done:
TRACE( "%s\n", debugstr_w(lpFileName) );
return strlenW(lpFileName);
TRACE( "%s\n", debugstr_wn(lpFileName, len) );
return len;
}

View File

@ -2095,7 +2095,8 @@ static HMODULE16 create_dummy_module( HMODULE module32 )
if (!nt) return (HMODULE16)11; /* invalid exe */
/* Extract base filename */
GetModuleFileNameA( module32, filename, sizeof(filename) );
len = GetModuleFileNameA( module32, filename, sizeof(filename) );
if (!len || len >= sizeof(filename)) return (HMODULE16)11; /* invalid exe */
basename = strrchr(filename, '\\');
if (!basename) basename = filename;
else basename++;

View File

@ -14,6 +14,7 @@ generated.ok
heap.ok
locale.ok
mailslot.ok
module.ok
path.ok
pipe.ok
process.ok

View File

@ -20,6 +20,7 @@ CTESTS = \
generated.c \
heap.c \
locale.c \
module.c \
mailslot.c \
path.c \
pipe.c \

View File

@ -0,0 +1,88 @@
/*
* Unit tests for module/DLL/library API
*
* Copyright (c) 2004 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "wine/test.h"
#include "wine/debug.h"
#include <windows.h>
static BOOL cmpStrAW(const char* a, const WCHAR* b, DWORD len)
{
WCHAR aw[1024];
MultiByteToWideChar( CP_ACP, 0, a, len, aw, sizeof(aw) / sizeof(aw[0]) );
return memcmp(aw, b, len * sizeof(WCHAR)) == 0;
}
static void testGetModuleFileName(const char* name)
{
HMODULE hMod;
char bufA[MAX_PATH];
WCHAR bufW[MAX_PATH];
DWORD len1A, len1W, len2A, len2W, l;
hMod = (name) ? GetModuleHandle(name) : NULL;
/* first test, with enough space in buffer */
memset(bufA, '-', sizeof(bufA));
len1A = GetModuleFileNameA(hMod, bufA, sizeof(bufA));
ok(len1A > 0, "Getting module filename for handle %p\n", hMod);
memset(bufW, '-', sizeof(bufW));
len1W = GetModuleFileNameW(hMod, bufW, sizeof(bufW) / sizeof(WCHAR));
ok(len1W > 0, "Getting module filename for handle %p\n", hMod);
ok(len1A == len1W, "Didn't get same A/W lengths (%ld/%ld)\n", len1A, len1W);
ok(len1A == strlen(bufA), "Unexpected length of GetModuleFilenameA (%ld/%d)\n", len1A, strlen(bufA));
ok(len1W == lstrlenW(bufW), "Unexpected length of GetModuleFilenameW (%ld/%d)\n", len1W, lstrlenW(bufW));
ok(cmpStrAW(bufA, bufW, l = min(len1A, len1W)), "Comparing GetModuleFilenameAW results\n");
/* second test with a buffer too small */
memset(bufA, '-', sizeof(bufA));
len2A = GetModuleFileNameA(hMod, bufA, len1A / 2);
ok(len2A > 0, "Getting module filename for handle %p\n", hMod);
memset(bufW, '-', sizeof(bufW));
len2W = GetModuleFileNameW(hMod, bufW, len1W / 2);
ok(len2W > 0, "Getting module filename for handle %p\n", hMod);
ok(len2A == len2W, "Didn't get same A/W lengths (%ld/%ld)\n", len2A, len2W);
l = min(len2A, len2W);
ok(cmpStrAW(bufA, bufW, l), "Comparing GetModuleFilenameAW results with buffer too small %s / %s\n", wine_dbgstr_an(bufA, l), wine_dbgstr_wn(bufW, l));
ok(len1A / 2 == len2A, "Correct length in GetModuleFilenameA with buffer too small (%ld/%ld)\n", len1A / 2, len2A);
ok(len1W / 2 == len2W, "Correct length in GetModuleFilenameW with buffer too small (%ld/%ld)\n", len1W / 2, len2W);
}
static void testGetModuleFileName_Wrong(void)
{
char bufA[MAX_PATH];
WCHAR bufW[MAX_PATH];
/* test wrong handle */
bufW[0] = '*';
ok(GetModuleFileNameW((void*)0xffffffff, bufW, sizeof(bufW) / sizeof(WCHAR)) == 0, "Unexpected success in module handle\n");
ok(bufW[0] == '*', "When failing, buffer shouldn't be written to\n");
bufA[0] = '*';
ok(GetModuleFileNameA((void*)0xffffffff, bufA, sizeof(bufA)) == 0, "Unexpected success in module handle\n");
ok(bufA[0] == '*', "When failing, buffer shouldn't be written to\n");
}
START_TEST(module)
{
testGetModuleFileName(NULL);
testGetModuleFileName("kernel32.dll");
testGetModuleFileName_Wrong();
}

View File

@ -82,6 +82,7 @@ WORD get_dos_version(void)
HKEY hkey, config_key;
WCHAR buffer[MAX_PATH];
WORD ret = 0;
DWORD len;
static const WCHAR configW[] = {'M','a','c','h','i','n','e','\\',
'S','o','f','t','w','a','r','e','\\',
@ -103,7 +104,8 @@ WORD get_dos_version(void)
attr.RootDirectory = config_key;
/* open AppDefaults\\appname\\Version key */
if (GetModuleFileNameW( 0, buffer, sizeof(buffer)/sizeof(WCHAR) ))
len = GetModuleFileNameW( 0, buffer, sizeof(buffer)/sizeof(WCHAR) );
if (len && len < sizeof(buffer)/sizeof(WCHAR))
{
WCHAR *p, *appname, appversion[MAX_PATH+20];

View File

@ -293,11 +293,21 @@ void msvcrt_init_args(void)
MSVCRT__pgmptr = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
if (MSVCRT__pgmptr)
GetModuleFileNameA(0, MSVCRT__pgmptr, MAX_PATH);
{
if (!GetModuleFileNameA(0, MSVCRT__pgmptr, MAX_PATH))
MSVCRT__pgmptr[0] = '\0';
else
MSVCRT__pgmptr[MAX_PATH - 1] = '\0';
}
MSVCRT__wpgmptr = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
if (MSVCRT__wpgmptr)
GetModuleFileNameW(0, MSVCRT__wpgmptr, MAX_PATH);
{
if (!GetModuleFileNameW(0, MSVCRT__wpgmptr, MAX_PATH))
MSVCRT__wpgmptr[0] = '\0';
else
MSVCRT__wpgmptr[MAX_PATH - 1] = '\0';
}
}

View File

@ -348,7 +348,11 @@ DWORD WINAPI GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule,
if (!lpFileName || !nSize) return 0;
if ( hProcess == GetCurrentProcess() )
return GetModuleFileNameA( hModule, lpFileName, nSize );
{
DWORD len = GetModuleFileNameA( hModule, lpFileName, nSize );
if (nSize) lpFileName[nSize - 1] = '\0';
return len;
}
if (!(ptr = HeapAlloc(GetProcessHeap(), 0, nSize * sizeof(WCHAR)))) return 0;
@ -380,7 +384,11 @@ DWORD WINAPI GetModuleFileNameExW(HANDLE hProcess, HMODULE hModule,
if (!lpFileName || !nSize) return 0;
if ( hProcess == GetCurrentProcess() )
return GetModuleFileNameW( hModule, lpFileName, nSize );
{
DWORD len = GetModuleFileNameW( hModule, lpFileName, nSize );
if (nSize) lpFileName[nSize - 1] = '\0';
return len;
}
lpFileName[0] = 0;

View File

@ -159,8 +159,9 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
const CLSID *pclsid)
{
LPSTR clsid;
char keyname[120], module[120];
char keyname[120], module[MAX_PATH];
HKEY key, subkey;
DWORD len;
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid);
@ -196,16 +197,18 @@ HRESULT WINAPI NdrDllRegisterProxy(HMODULE hDll,
/* register clsid to point to module */
snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid);
GetModuleFileNameA(hDll, module, sizeof(module));
TRACE("registering CLSID %s => %s\n", clsid, module);
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0,
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
RegSetValueExA(subkey, NULL, 0, REG_SZ, module, strlen(module));
RegCloseKey(subkey);
}
RegCloseKey(key);
len = GetModuleFileNameA(hDll, module, sizeof(module));
if (len && len < sizeof(module)) {
TRACE("registering CLSID %s => %s\n", clsid, module);
if (RegCreateKeyExA(HKEY_CLASSES_ROOT, keyname, 0, NULL, 0,
KEY_WRITE, NULL, &key, NULL) == ERROR_SUCCESS) {
if (RegCreateKeyExA(key, "InProcServer32", 0, NULL, 0,
KEY_WRITE, NULL, &subkey, NULL) == ERROR_SUCCESS) {
RegSetValueExA(subkey, NULL, 0, REG_SZ, module, strlen(module));
RegCloseKey(subkey);
}
RegCloseKey(key);
}
}
/* done */
@ -221,7 +224,8 @@ HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll,
const CLSID *pclsid)
{
LPSTR clsid;
char keyname[120], module[120];
char keyname[120], module[MAX_PATH];
DWORD len;
TRACE("(%p,%p,%s)\n", hDll, pProxyFileList, debugstr_guid(pclsid));
UuidToStringA((UUID*)pclsid, (unsigned char**)&clsid);
@ -246,9 +250,11 @@ HRESULT WINAPI NdrDllUnregisterProxy(HMODULE hDll,
/* unregister clsid */
snprintf(keyname, sizeof(keyname), "CLSID\\{%s}", clsid);
GetModuleFileNameA(hDll, module, sizeof(module));
TRACE("unregistering CLSID %s <= %s\n", clsid, module);
RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
len = GetModuleFileNameA(hDll, module, sizeof(module));
if (len && len < sizeof(module)) {
TRACE("unregistering CLSID %s <= %s\n", clsid, module);
RegDeleteKeyA(HKEY_CLASSES_ROOT, keyname);
}
/* done */
RpcStringFreeA((unsigned char**)&clsid);

View File

@ -490,8 +490,12 @@ HICON WINAPI ExtractAssociatedIconA(HINSTANCE hInst, LPSTR lpIconPath, LPWORD lp
else
*lpiIcon = 6; /* generic icon - found nothing */
GetModuleFileNameA(hInst, lpIconPath, 0x80);
hIcon = LoadIconA( hInst, MAKEINTRESOURCEA(*lpiIcon));
if (GetModuleFileNameA(hInst, lpIconPath, 0x80))
{
/* terminate string (GetModuleFileName doesn't do if buffer is too small) */
lpIconPath[0x80 - 1] = '\0';
hIcon = LoadIconA( hInst, MAKEINTRESOURCEA(*lpiIcon));
}
}
return hIcon;
}

View File

@ -91,11 +91,17 @@ LPWSTR* WINAPI CommandLineToArgvW(LPCWSTR lpCmdline, int* numargs)
if (*lpCmdline==0) {
/* Return the path to the executable */
DWORD size=16;
DWORD len, size=16;
hargv=GlobalAlloc(size, 0);
argv=GlobalLock(hargv);
while (GetModuleFileNameW(0, (LPWSTR)(argv+1), size-sizeof(LPWSTR)) == 0) {
for (;;) {
len = GetModuleFileNameW(0, (LPWSTR)(argv+1), size-sizeof(LPWSTR));
if (!len) {
GlobalFree(hargv);
return NULL;
}
if (len < size) break;
size*=2;
hargv=GlobalReAlloc(hargv, size, 0);
argv=GlobalLock(hargv);
@ -932,6 +938,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
/* get full path to this DLL for IExtractIconW_fnGetIconLocation() */
GetModuleFileNameW(hinstDLL, swShell32Name, MAX_PATH);
swShell32Name[MAX_PATH - 1] = '\0';
InitCommonControlsEx(NULL);

View File

@ -3265,9 +3265,12 @@ HMODULE WINAPI MLLoadLibraryA(LPCSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
*/
CHAR mod_path[2*MAX_PATH];
LPSTR ptr;
DWORD len;
FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_a(new_mod), inst_hwnd, dwFlags);
GetModuleFileNameA(inst_hwnd, mod_path, 2*MAX_PATH);
len = GetModuleFileNameA(inst_hwnd, mod_path, sizeof(mod_path));
if (!len || len >= sizeof(mod_path)) return NULL;
ptr = strrchr(mod_path, '\\');
if (ptr) {
strcpy(ptr+1, new_mod);
@ -3286,9 +3289,12 @@ HMODULE WINAPI MLLoadLibraryW(LPCWSTR new_mod, HMODULE inst_hwnd, DWORD dwFlags)
{
WCHAR mod_path[2*MAX_PATH];
LPWSTR ptr;
DWORD len;
FIXME("(%s,%p,0x%08lx) semi-stub!\n", debugstr_w(new_mod), inst_hwnd, dwFlags);
GetModuleFileNameW(inst_hwnd, mod_path, 2*MAX_PATH);
len = GetModuleFileNameW(inst_hwnd, mod_path, sizeof(mod_path) / sizeof(WCHAR));
if (!len || len >= sizeof(mod_path) / sizeof(WCHAR)) return NULL;
ptr = strrchrW(mod_path, '\\');
if (ptr) {
strcpyW(ptr+1, new_mod);

View File

@ -2428,8 +2428,10 @@ HRESULT WINAPI MLBuildResURLW(LPCWSTR lpszLibName, HMODULE hMod, DWORD dwFlags,
if (hMod)
{
WCHAR szBuff[MAX_PATH];
DWORD len;
if (GetModuleFileNameW(hMod, szBuff, sizeof(szBuff)/sizeof(WCHAR)))
len = GetModuleFileNameW(hMod, szBuff, sizeof(szBuff)/sizeof(WCHAR));
if (len && len < sizeof(szBuff)/sizeof(WCHAR))
{
DWORD dwPathLen = strlenW(szBuff) + 1;

View File

@ -122,6 +122,7 @@ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid,
{
HHOOK handle = 0;
WCHAR module[MAX_PATH];
DWORD len;
if (tid) /* thread-local hook */
{
@ -140,7 +141,7 @@ static HHOOK set_windows_hook( INT id, HOOKPROC proc, HINSTANCE inst, DWORD tid,
else /* system-global hook */
{
if (id == WH_KEYBOARD_LL || id == WH_MOUSE_LL) inst = 0;
else if (!inst || !GetModuleFileNameW( inst, module, MAX_PATH ))
else if (!inst || !(len = GetModuleFileNameW( inst, module, MAX_PATH )) || len >= MAX_PATH)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;

View File

@ -441,7 +441,6 @@ END:
DWORD WINAPI GetFileVersionInfoSizeW( LPCWSTR filename, LPDWORD handle )
{
DWORD ret, offset, len = (filename && strlenW(filename)) ? strlenW(filename) + 1: MAX_PATH;
DWORD nSize = len;
LPSTR filenameA = NULL;
LPWSTR filenameW;
VS_FIXEDFILEINFO *vffi;
@ -453,9 +452,12 @@ DWORD WINAPI GetFileVersionInfoSizeW( LPCWSTR filename, LPDWORD handle )
if (filename && strlenW(filename))
strcpyW(filenameW, filename);
else {
nSize = GetModuleFileNameW(NULL, filenameW, nSize);
if((nSize +1) >= len)
FIXME("buffer may be too small\n");
DWORD nSize = GetModuleFileNameW(NULL, filenameW, len);
if (!nSize || nSize >= len)
{
len = 0;
goto End;
}
}
len = VERSION_GetFileVersionInfo_PE(filenameW, handle, 0, NULL);

View File

@ -90,8 +90,11 @@ static HMMIO get_mmioFromProfile(UINT uFlags, LPCWSTR lpszName)
if (RegOpenKeyW(HKEY_CURRENT_USER, wszKey, &hRegSnd) != 0) goto none;
if (uFlags & SND_APPLICATION)
{
DWORD len;
err = 1; /* error */
if (GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0])))
len = GetModuleFileNameW(0, str, sizeof(str)/sizeof(str[0]));
if (len > 0 && len < sizeof(str)/sizeof(str[0]))
{
for (ptr = str + lstrlenW(str) - 1; ptr >= str; ptr--)
{

View File

@ -239,6 +239,7 @@ static void setup_options(void)
{
char buffer[MAX_PATH+16];
HKEY hkey, appkey = 0;
DWORD len;
if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\x11drv", 0, NULL,
REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ))
@ -249,7 +250,8 @@ static void setup_options(void)
/* open the app-specific key */
if (GetModuleFileNameA( 0, buffer, MAX_PATH ))
len = (GetModuleFileNameA( 0, buffer, MAX_PATH ));
if (len && len < MAX_PATH)
{
HKEY tmpkey;
char *p, *appname = buffer;

View File

@ -531,8 +531,8 @@ static BOOL DeferToRunOnce(LPWSTR link)
WINE_TRACE( "Deferring icon creation to reboot.\n");
if( !GetModuleFileNameW( 0, szExecutable, MAX_PATH ) )
return FALSE;
len = GetModuleFileNameW( 0, szExecutable, MAX_PATH );
if (!len || len >= MAX_PATH) return FALSE;
len = ( lstrlenW( link ) + lstrlenW( szExecutable ) + 4)*sizeof(WCHAR);
buffer = HeapAlloc( GetProcessHeap(), 0, len );