2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Support functions for dbghelp api test
5 * PROGRAMMER: Mark Jansen
12 #include "wine/test.h"
14 extern IMAGE_DOS_HEADER __ImageBase
;
16 static char szTempPath
[MAX_PATH
];
18 static const char* tmpdir()
20 if (szTempPath
[0] == '\0')
22 GetTempPathA(MAX_PATH
, szTempPath
);
23 lstrcatA(szTempPath
, "dbghelp_tst");
28 static int extract_one(const char* filename
, const char* resid
)
30 HMODULE mod
= (HMODULE
)&__ImageBase
;
32 PVOID data
, decompressed
;
37 HRSRC rsrc
= FindResourceA(mod
, resid
, MAKEINTRESOURCEA(RT_RCDATA
));
38 ok(rsrc
!= 0, "Failed finding '%s' res\n", resid
);
42 size
= SizeofResource(mod
, rsrc
);
43 glob
= LoadResource(mod
, rsrc
);
44 ok(glob
!= NULL
, "Failed loading '%s' res\n", resid
);
48 data
= LockResource(glob
);
51 decompressed
= malloc(dstsize
);
53 if (uncompress(decompressed
, &dstsize
, data
, size
) != Z_OK
)
55 ok(0, "uncompress failed for %s\n", resid
);
61 file
= CreateFileA(filename
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
63 ret
= WriteFile(file
, decompressed
, dstsize
, &gccSize
, NULL
);
64 dwErr
= GetLastError();
67 ok(ret
, "WriteFile failed (%d)\n", dwErr
);
68 return ret
&& dstsize
== gccSize
;
72 int extract_msvc_exe(char szFile
[MAX_PATH
])
74 const char* dir
= tmpdir();
75 BOOL ret
= CreateDirectoryA(dir
, NULL
);
76 ok(ret
, "CreateDirectoryA failed(%d)\n", GetLastError());
78 sprintf(szFile
, "%s\\uffs.pdb", dir
);
79 if (!extract_one(szFile
, "msvc_uffs.pdb"))
82 sprintf(szFile
, "%s\\uffs.dll", dir
);
83 if (!extract_one(szFile
, "msvc_uffs.dll"))
89 void cleanup_msvc_exe()
91 char szFile
[MAX_PATH
];
93 const char* dir
= tmpdir();
95 sprintf(szFile
, "%s\\uffs.pdb", dir
);
96 ret
= DeleteFileA(szFile
);
97 ok(ret
, "DeleteFileA failed(%d)\n", GetLastError());
99 sprintf(szFile
, "%s\\uffs.dll", dir
);
100 ret
= DeleteFileA(szFile
);
101 ok(ret
, "DeleteFileA failed(%d)\n", GetLastError());
102 ret
= RemoveDirectoryA(dir
);
103 ok(ret
, "RemoveDirectoryA failed(%d)\n", GetLastError());
106 int extract_gcc_exe(char szFile
[MAX_PATH
])
108 const char* dir
= tmpdir();
109 BOOL ret
= CreateDirectoryA(dir
, NULL
);
110 ok(ret
, "CreateDirectoryA failed(%d)\n", GetLastError());
112 sprintf(szFile
, "%s\\uffs.dll", dir
);
113 if (!extract_one(szFile
, "gcc_uffs.dll"))
119 void cleanup_gcc_exe()
121 char szFile
[MAX_PATH
];
123 const char* dir
= tmpdir();
125 sprintf(szFile
, "%s\\uffs.dll", dir
);
126 ret
= DeleteFileA(szFile
);
127 ok(ret
, "DeleteFileA failed(%d)\n", GetLastError());
128 ret
= RemoveDirectoryA(dir
);
129 ok(ret
, "RemoveDirectoryA failed(%d)\n", GetLastError());
134 static int compress_one(const char* src
, const char* dest
)
136 DWORD size
, size2
, res
;
137 FILE* file
= fopen(src
, "rb");
138 fseek(file
, 0, SEEK_END
);
140 fseek(file
, 0, SEEK_SET
);
142 Bytef
* buffer
, *buffer2
;
143 DWORD dwErr
= GetLastError();
145 buffer
= malloc(size
);
146 res
= fread(buffer
, 1, size
, file
);
152 printf("Could not read file: 0x%x\n", dwErr
);
158 buffer2
= malloc(size2
);
159 res
= compress(buffer2
, &size2
, buffer
, size
);
169 file
= fopen(dest
, "wb");
170 res
= fwrite(buffer2
, 1, size2
, file
);
178 void create_compressed_files()
180 SetCurrentDirectoryA("R:/src/trunk/reactos/modules/rostests/apitests/dbghelp");
181 if (!compress_one("testdata/msvc_uffs.dll", "testdata/msvc_uffs.dll.compr"))
182 printf("msvc_uffs.dll failed\n");
183 if (!compress_one("testdata/msvc_uffs.pdb", "testdata/msvc_uffs.pdb.compr"))
184 printf("msvc_uffs.pdb failed\n");
185 if (!compress_one("testdata/gcc_uffs.dll", "testdata/gcc_uffs.dll.compr"))
186 printf("gcc_uffs.dll failed\n");
191 typedef struct _SYMBOLFILE_HEADER
{
196 } SYMBOLFILE_HEADER
, *PSYMBOLFILE_HEADER
;
198 typedef struct _ROSSYM_ENTRY
{
200 ULONG FunctionOffset
;
203 } ROSSYM_ENTRY
, *PROSSYM_ENTRY
;
206 static int is_metadata(const char* name
)
208 size_t len
= name
? strlen(name
) : 0;
209 return len
> 3 && name
[0] == '_' && name
[1] != '_' && name
[len
-1] == '_' && name
[len
-2] == '_';
212 static void dump_rsym_internal(void* data
)
214 PSYMBOLFILE_HEADER RosSymHeader
= (PSYMBOLFILE_HEADER
)data
;
215 PROSSYM_ENTRY Entries
= (PROSSYM_ENTRY
)((char *)data
+ RosSymHeader
->SymbolsOffset
);
216 size_t symbols
= RosSymHeader
->SymbolsLength
/ sizeof(ROSSYM_ENTRY
);
218 char *Strings
= (char *)data
+ RosSymHeader
->StringsOffset
;
220 for (i
= 0; i
< symbols
; i
++)
222 PROSSYM_ENTRY Entry
= Entries
+ i
;
223 if (!Entry
->FileOffset
)
225 if (Entry
->SourceLine
)
226 printf("ERR: SOURCELINE (%D) ", Entry
->SourceLine
);
227 if (is_metadata(Strings
+ Entry
->FunctionOffset
))
228 printf("metadata: %s: 0x%x\n", Strings
+ Entry
->FunctionOffset
, Entry
->Address
);
230 printf("0x%x: %s\n", Entry
->Address
, Strings
+ Entry
->FunctionOffset
);
234 printf("0x%x: %s (%s:%u)\n", Entry
->Address
,
235 Strings
+ Entry
->FunctionOffset
,
236 Strings
+ Entry
->FileOffset
,
243 void dump_rsym(const char* filename
)
247 PIMAGE_FILE_HEADER PEFileHeader
;
248 PIMAGE_OPTIONAL_HEADER PEOptHeader
;
249 PIMAGE_SECTION_HEADER PESectionHeaders
;
252 FILE* f
= fopen(filename
, "rb");
254 fseek(f
, 0, SEEK_END
);
256 fseek(f
, 0, SEEK_SET
);
259 res
= fread(data
, 1, size
, f
);
262 PEFileHeader
= (PIMAGE_FILE_HEADER
)((char *)data
+ ((PIMAGE_DOS_HEADER
)data
)->e_lfanew
+ sizeof(ULONG
));
263 PEOptHeader
= (PIMAGE_OPTIONAL_HEADER
)(PEFileHeader
+ 1);
264 PESectionHeaders
= (PIMAGE_SECTION_HEADER
)((char *)PEOptHeader
+ PEFileHeader
->SizeOfOptionalHeader
);
266 for (i
= 0; i
< PEFileHeader
->NumberOfSections
; i
++)
268 if (!strcmp((char *)PESectionHeaders
[i
].Name
, ".rossym"))
270 dump_rsym_internal(data
+ PESectionHeaders
[i
].PointerToRawData
);