"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "dlls/imagehlp/tests/image.c" between
wine-6.0.tar.xz and wine-6.0.1.tar.xz

About: Wine is an Open Source implementation of the MS Windows API on top of X, OpenGL, and Unix. Think of Wine as a compatibility layer for running Windows programs.

image.c  (wine-6.0.tar.xz):image.c  (wine-6.0.1.tar.xz)
skipping to change at line 27 skipping to change at line 27
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#define NONAMELESSUNION #define NONAMELESSUNION
#include <windef.h> #include <windef.h>
#include <winbase.h> #include <winbase.h>
#include <winver.h> #include <winver.h>
#include <winnt.h> #include <winnt.h>
#include <winuser.h>
#include <imagehlp.h> #include <imagehlp.h>
#include "wine/test.h" #include "wine/test.h"
static HMODULE hImageHlp; static char *load_resource(const char *name)
{
static char path[MAX_PATH];
DWORD written;
HANDLE file;
HRSRC res;
void *ptr;
GetTempPathA(ARRAY_SIZE(path), path);
strcat(path, name);
file = CreateFileA(path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
0, 0);
ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %u.\n",
debugstr_a(path), GetLastError());
res = FindResourceA(NULL, name, "TESTDLL");
ok(!!res, "Failed to load resource, error %u.\n", GetLastError());
ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written,
NULL);
ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write
resource.\n");
CloseHandle(file);
static BOOL (WINAPI *pImageGetDigestStream)(HANDLE, DWORD, DIGEST_FUNCTION, DIGE return path;
ST_HANDLE); }
static BOOL (WINAPI *pBindImageEx)(DWORD Flags, const char *ImageName, const cha
r *DllPath,
const char *SymbolPath, PIMAGEHLP_STATUS_ROUT
INE StatusRoutine);
static DWORD (WINAPI *pGetImageUnusedHeaderBytes)(PLOADED_IMAGE, LPDWORD);
static PLOADED_IMAGE (WINAPI *pImageLoad)(PCSTR, PCSTR);
static BOOL (WINAPI *pImageUnload)(PLOADED_IMAGE);
/* minimal PE file image */ /* minimal PE file image */
#define VA_START 0x400000 #define VA_START 0x400000
#define FILE_PE_START 0x50 #define FILE_PE_START 0x50
#define NUM_SECTIONS 3 #define NUM_SECTIONS 3
#define FILE_TEXT 0x200 #define FILE_TEXT 0x200
#define RVA_TEXT 0x1000 #define RVA_TEXT 0x1000
#define RVA_BSS 0x2000 #define RVA_BSS 0x2000
#define FILE_IDATA 0x400 #define FILE_IDATA 0x400
#define RVA_IDATA 0x3000 #define RVA_IDATA 0x3000
skipping to change at line 157 skipping to change at line 174
struct blob *updates; struct blob *updates;
}; };
struct expected_update_accum struct expected_update_accum
{ {
DWORD cUpdates; DWORD cUpdates;
const struct expected_blob *updates; const struct expected_blob *updates;
BOOL todo; BOOL todo;
}; };
static int status_routine_called[BindSymbolsNotUpdated+1];
static BOOL WINAPI accumulating_stream_output(DIGEST_HANDLE handle, BYTE *pb, static BOOL WINAPI accumulating_stream_output(DIGEST_HANDLE handle, BYTE *pb,
DWORD cb) DWORD cb)
{ {
struct update_accum *accum = (struct update_accum *)handle; struct update_accum *accum = (struct update_accum *)handle;
BOOL ret = FALSE; BOOL ret = FALSE;
if (accum->cUpdates) if (accum->cUpdates)
accum->updates = HeapReAlloc(GetProcessHeap(), 0, accum->updates, accum->updates = HeapReAlloc(GetProcessHeap(), 0, accum->updates,
(accum->cUpdates + 1) * sizeof(struct blob)); (accum->cUpdates + 1) * sizeof(struct blob));
else else
skipping to change at line 281 skipping to change at line 296
{ {
sum = LOWORD(sum) + HIWORD(sum); sum = LOWORD(sum) + HIWORD(sum);
} }
} }
sum = (WORD)(LOWORD(sum) + HIWORD(sum)); sum = (WORD)(LOWORD(sum) + HIWORD(sum));
sum += sizeof(bin); sum += sizeof(bin);
bin.nt_headers.OptionalHeader.CheckSum = sum; bin.nt_headers.OptionalHeader.CheckSum = sum;
} }
static BOOL CALLBACK testing_status_routine(IMAGEHLP_STATUS_REASON reason, const
char *ImageName,
const char *DllName, ULONG_PTR Va, U
LONG_PTR Parameter)
{
char kernel32_path[MAX_PATH];
if (0 <= (int)reason && reason <= BindSymbolsNotUpdated)
status_routine_called[reason]++;
else
ok(0, "expected reason between 0 and %d, got %d\n", BindSymbolsNotUpdated+
1, reason);
switch(reason)
{
case BindImportModule:
ok(!strcmp(DllName, "KERNEL32.DLL"), "expected DllName to be KERNEL3
2.DLL, got %s\n",
DllName);
break;
case BindImportProcedure:
case BindForwarderNOT:
GetSystemDirectoryA(kernel32_path, MAX_PATH);
strcat(kernel32_path, "\\KERNEL32.DLL");
ok(!lstrcmpiA(DllName, kernel32_path), "expected DllName to be %s, g
ot %s\n",
kernel32_path, DllName);
ok(!strcmp((char *)Parameter, "ExitProcess"),
"expected Parameter to be ExitProcess, got %s\n", (char *)Paramet
er);
break;
default:
ok(0, "got unexpected reason %d\n", reason);
break;
}
return TRUE;
}
static void test_get_digest_stream(void) static void test_get_digest_stream(void)
{ {
BOOL ret; BOOL ret;
HANDLE file; HANDLE file;
char temp_file[MAX_PATH]; char temp_file[MAX_PATH];
DWORD count; DWORD count;
struct update_accum accum = { 0, NULL }; struct update_accum accum = { 0, NULL };
if (!pImageGetDigestStream)
{
win_skip("ImageGetDigestStream function is not available\n");
return;
}
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pImageGetDigestStream(NULL, 0, NULL, NULL); ret = ImageGetDigestStream(NULL, 0, NULL, NULL);
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
file = create_temp_file(temp_file); file = create_temp_file(temp_file);
if (file == INVALID_HANDLE_VALUE) if (file == INVALID_HANDLE_VALUE)
{ {
skip("couldn't create temp file\n"); skip("couldn't create temp file\n");
return; return;
} }
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pImageGetDigestStream(file, 0, NULL, NULL); ret = ImageGetDigestStream(file, 0, NULL, NULL);
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pImageGetDigestStream(NULL, 0, accumulating_stream_output, &accum); ret = ImageGetDigestStream(NULL, 0, accumulating_stream_output, &accum);
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
/* Even with "valid" parameters, it fails with an empty file */ /* Even with "valid" parameters, it fails with an empty file */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pImageGetDigestStream(file, 0, accumulating_stream_output, &accum); ret = ImageGetDigestStream(file, 0, accumulating_stream_output, &accum);
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
/* Finally, with a valid executable in the file, it succeeds. Note that /* Finally, with a valid executable in the file, it succeeds. Note that
* the file pointer need not be positioned at the beginning. * the file pointer need not be positioned at the beginning.
*/ */
update_checksum(); update_checksum();
WriteFile(file, &bin, sizeof(bin), &count, NULL); WriteFile(file, &bin, sizeof(bin), &count, NULL);
FlushFileBuffers(file); FlushFileBuffers(file);
/* zero out some fields ImageGetDigestStream would zero out */ /* zero out some fields ImageGetDigestStream would zero out */
bin.nt_headers.OptionalHeader.CheckSum = 0; bin.nt_headers.OptionalHeader.CheckSum = 0;
bin.nt_headers.OptionalHeader.SizeOfInitializedData = 0; bin.nt_headers.OptionalHeader.SizeOfInitializedData = 0;
bin.nt_headers.OptionalHeader.SizeOfImage = 0; bin.nt_headers.OptionalHeader.SizeOfImage = 0;
ret = pImageGetDigestStream(file, 0, accumulating_stream_output, &accum); ret = ImageGetDigestStream(file, 0, accumulating_stream_output, &accum);
ok(ret, "ImageGetDigestStream failed: %d\n", GetLastError()); ok(ret, "ImageGetDigestStream failed: %d\n", GetLastError());
check_updates("flags = 0", &a1, &accum); check_updates("flags = 0", &a1, &accum);
free_updates(&accum); free_updates(&accum);
ret = pImageGetDigestStream(file, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO, ret = ImageGetDigestStream(file, CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO,
accumulating_stream_output, &accum); accumulating_stream_output, &accum);
ok(ret, "ImageGetDigestStream failed: %d\n", GetLastError()); ok(ret, "ImageGetDigestStream failed: %d\n", GetLastError());
check_updates("flags = CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO", &a2, &accum); check_updates("flags = CERT_PE_IMAGE_DIGEST_ALL_IMPORT_INFO", &a2, &accum);
free_updates(&accum); free_updates(&accum);
CloseHandle(file); CloseHandle(file);
DeleteFileA(temp_file); DeleteFileA(temp_file);
} }
static void test_bind_image_ex(void) static unsigned int got_SysAllocString, got_GetOpenFileNameA, got_SHRegGetIntW;
static BOOL WINAPI bind_image_cb(IMAGEHLP_STATUS_REASON reason, const char *file
,
const char *module, ULONG_PTR va, ULONG_PTR param)
{ {
BOOL ret; static char last_module[MAX_PATH];
HANDLE file;
char temp_file[MAX_PATH]; if (winetest_debug > 1)
DWORD count; trace("reason %u, file %s, module %s, va %#Ix, param %#Ix\n",
reason, debugstr_a(file), debugstr_a(module), va, param);
if (!pBindImageEx) if (reason == BindImportModule)
{ {
win_skip("BindImageEx function is not available\n"); ok(!strchr(module, '\\'), "got module name %s\n", debugstr_a(module));
return; strcpy(last_module, module);
ok(!va, "got VA %#Ix\n", va);
ok(!param, "got param %#Ix\n", param);
} }
else if (reason == BindImportProcedure)
{
char full_path[MAX_PATH];
BOOL ret;
/* call with a non-existent file */ todo_wine ok(!!va, "expected nonzero VA\n");
SetLastError(0xdeadbeef); ret = SearchPathA(NULL, last_module, ".dll", sizeof(full_path), full_pat
ret = pBindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES, h, NULL);
"nonexistent.dll", 0, 0, ok(ret, "got error %u\n", GetLastError());
testing_status_routine); ok(!strcmp(module, full_path), "expected %s, got %s\n", debugstr_a(full_
todo_wine ok(!ret && ((GetLastError() == ERROR_FILE_NOT_FOUND) || path), debugstr_a(module));
(GetLastError() == ERROR_INVALID_PARAMETER)),
"expected ERROR_FILE_NOT_FOUND or ERROR_INVALID_PARAMETER, got
%d\n",
GetLastError());
file = create_temp_file(temp_file); if (!strcmp((const char *)param, "SysAllocString"))
if (file == INVALID_HANDLE_VALUE) {
ok(!strcmp(last_module, "oleaut32.dll"), "got wrong module %s\n", de
bugstr_a(module));
++got_SysAllocString;
}
else if (!strcmp((const char *)param, "GetOpenFileNameA"))
{
ok(!strcmp(last_module, "comdlg32.dll"), "got wrong module %s\n", de
bugstr_a(module));
++got_GetOpenFileNameA;
}
else if (!strcmp((const char *)param, "Ordinal117"))
{
ok(!strcmp(last_module, "shlwapi.dll"), "got wrong module %s\n", deb
ugstr_a(module));
++got_SHRegGetIntW;
}
}
else
{ {
skip("couldn't create temp file\n"); ok(0, "got unexpected reason %#x\n", reason);
return;
} }
return TRUE;
}
WriteFile(file, &bin, sizeof(bin), &count, NULL); static void test_bind_image_ex(void)
CloseHandle(file); {
const char *filename = load_resource("testdll.dll");
BOOL ret;
/* call with a proper PE file, but with StatusRoutine set to NULL */ SetLastError(0xdeadbeef);
ret = pBindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES, ret = BindImageEx(BIND_ALL_IMAGES | BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE,
temp_file, 0, 0, "nonexistent.dll", 0, 0, bind_image_cb);
NULL); ok(!ret, "expected failure\n");
ok(ret, "BindImageEx failed: %d\n", GetLastError()); ok(GetLastError() == ERROR_FILE_NOT_FOUND || GetLastError() == ERROR_INVALID
_PARAMETER,
/* call with a proper PE file and StatusRoutine */ "got error %u\n", GetLastError());
ret = pBindImageEx(BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE | BIND_ALL_IMAGES,
temp_file, 0, 0, ret = BindImageEx(BIND_ALL_IMAGES | BIND_NO_BOUND_IMPORTS | BIND_NO_UPDATE,
testing_status_routine); filename, NULL, NULL, bind_image_cb);
ok(ret, "BindImageEx failed: %d\n", GetLastError()); ok(ret, "got error %u\n", GetLastError());
ok(got_SysAllocString == 1, "got %u imports of SysAllocString\n", got_SysAll
todo_wine ok(status_routine_called[BindImportModule] == 1, ocString);
"StatusRoutine was called %d times\n", status_routine_called[Bi ok(got_GetOpenFileNameA == 1, "got %u imports of GetOpenFileNameA\n", got_Ge
ndImportModule]); tOpenFileNameA);
todo_wine ok(got_SHRegGetIntW == 1, "got %u imports of SHRegGetIntW\n", got_
todo_wine ok((status_routine_called[BindImportProcedure] == 1) SHRegGetIntW);
#if defined(_WIN64)
|| broken(status_routine_called[BindImportProcedure] == 0) /* <
Win8 */
#endif
, "StatusRoutine was called %d times\n", status_routine_called[
BindImportProcedure]);
DeleteFileA(temp_file); ret = DeleteFileA(filename);
ok(ret, "got error %u\n", GetLastError());
} }
static void test_image_load(void) static void test_image_load(void)
{ {
char temp_file[MAX_PATH]; char temp_file[MAX_PATH];
PLOADED_IMAGE img; PLOADED_IMAGE img;
DWORD ret, count; DWORD ret, count;
HANDLE file; HANDLE file;
if (!pImageLoad || !pImageUnload || !pGetImageUnusedHeaderBytes)
{
win_skip("ImageLoad functions are not available\n");
return;
}
file = create_temp_file(temp_file); file = create_temp_file(temp_file);
if (file == INVALID_HANDLE_VALUE) if (file == INVALID_HANDLE_VALUE)
{ {
skip("couldn't create temp file\n"); skip("couldn't create temp file\n");
return; return;
} }
WriteFile(file, &bin, sizeof(bin), &count, NULL); WriteFile(file, &bin, sizeof(bin), &count, NULL);
CloseHandle(file); CloseHandle(file);
img = pImageLoad(temp_file, NULL); img = ImageLoad(temp_file, NULL);
ok(img != NULL, "ImageLoad unexpectedly failed\n"); ok(img != NULL, "ImageLoad unexpectedly failed\n");
if (img) if (img)
{ {
ok(!strcmp(img->ModuleName, temp_file), ok(!strcmp(img->ModuleName, temp_file),
"unexpected ModuleName, got %s instead of %s\n", img->ModuleName, tem p_file); "unexpected ModuleName, got %s instead of %s\n", img->ModuleName, tem p_file);
ok(img->MappedAddress != NULL, "MappedAddress != NULL\n"); ok(img->MappedAddress != NULL, "MappedAddress != NULL\n");
if (img->MappedAddress) if (img->MappedAddress)
{ {
ok(!memcmp(img->MappedAddress, &bin.dos_header, sizeof(bin.dos_heade r)), ok(!memcmp(img->MappedAddress, &bin.dos_header, sizeof(bin.dos_heade r)),
skipping to change at line 500 skipping to change at line 490
ok(img->fDOSImage == 0, ok(img->fDOSImage == 0,
"unexpected fDOSImage, got %d instead of 0\n", img->fDOSImage); "unexpected fDOSImage, got %d instead of 0\n", img->fDOSImage);
todo_wine ok(img->fReadOnly == 1 || broken(!img->fReadOnly) /* <= WinXP */, todo_wine ok(img->fReadOnly == 1 || broken(!img->fReadOnly) /* <= WinXP */,
"unexpected fReadOnly, got %d instead of 1\n", img->fReadOnly); "unexpected fReadOnly, got %d instead of 1\n", img->fReadOnly);
todo_wine ok(img->Version == 1 || broken(!img->Version) /* <= WinXP */, todo_wine ok(img->Version == 1 || broken(!img->Version) /* <= WinXP */,
"unexpected Version, got %d instead of 1\n", img->Version); "unexpected Version, got %d instead of 1\n", img->Version);
ok(img->SizeOfImage == 0x600, ok(img->SizeOfImage == 0x600,
"unexpected SizeOfImage, got 0x%x instead of 0x600\n", img->SizeOfIma ge); "unexpected SizeOfImage, got 0x%x instead of 0x600\n", img->SizeOfIma ge);
count = 0xdeadbeef; count = 0xdeadbeef;
ret = pGetImageUnusedHeaderBytes(img, &count); ret = GetImageUnusedHeaderBytes(img, &count);
todo_wine todo_wine
ok(ret == 448, "GetImageUnusedHeaderBytes returned %u instead of 448\n", ret); ok(ret == 448, "GetImageUnusedHeaderBytes returned %u instead of 448\n", ret);
todo_wine todo_wine
ok(count == 64, "unexpected size for unused header bytes, got %u instead of 64\n", count); ok(count == 64, "unexpected size for unused header bytes, got %u instead of 64\n", count);
pImageUnload(img); ImageUnload(img);
} }
DeleteFileA(temp_file); DeleteFileA(temp_file);
} }
START_TEST(image) START_TEST(image)
{ {
hImageHlp = LoadLibraryA("imagehlp.dll");
if (!hImageHlp)
{
win_skip("ImageHlp unavailable\n");
return;
}
pImageGetDigestStream = (void *) GetProcAddress(hImageHlp, "ImageGetDigestSt
ream");
pBindImageEx = (void *) GetProcAddress(hImageHlp, "BindImageEx");
pGetImageUnusedHeaderBytes = (void *) GetProcAddress(hImageHlp, "GetImageUnu
sedHeaderBytes");
pImageLoad = (void *) GetProcAddress(hImageHlp, "ImageLoad");
pImageUnload = (void *) GetProcAddress(hImageHlp, "ImageUnload");
test_get_digest_stream(); test_get_digest_stream();
test_bind_image_ex(); test_bind_image_ex();
test_image_load(); test_image_load();
FreeLibrary(hImageHlp);
} }
 End of changes. 30 change blocks. 
138 lines changed or deleted 107 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)