Commit 2f0ed90c authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

dbghelp: Implemented SymFindFileInPathW.

parent 9e1f9ec1
......@@ -54,7 +54,7 @@
@ stub SymFindDebugInfoFile
@ stub SymFindDebugInfoFileW
@ stdcall SymFindFileInPath(long str str ptr long long long ptr ptr ptr)
@ stub SymFindFileInPathW
@ stdcall SymFindFileInPathW(long wstr wstr ptr long long long ptr ptr ptr)
@ stdcall SymFromAddr(ptr double ptr ptr)
@ stdcall SymFromAddrW(ptr double ptr ptr)
@ stub SymFromIndex
......
......@@ -1856,7 +1856,7 @@ static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols,
}
}
static BOOL CALLBACK pdb_match(char* file, void* user)
static BOOL CALLBACK pdb_match(const char* file, void* user)
{
/* accept first file that exists */
HANDLE h = CreateFileA(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
......
......@@ -42,6 +42,14 @@ static inline const char* file_name(const char* str)
return p + 1;
}
static inline const WCHAR* file_nameW(const WCHAR* str)
{
const WCHAR* p;
for (p = str + strlenW(str) - 1; p >= str && !is_sepW(*p); p--);
return p + 1;
}
/******************************************************************
* FindDebugInfoFile (DBGHELP.@)
*
......@@ -238,40 +246,6 @@ static BOOL do_searchW(const WCHAR* file, WCHAR* buffer, BOOL recurse,
return found;
}
static BOOL do_search(const char* file, char* buffer, BOOL recurse,
PENUMDIRTREE_CALLBACK cb, void* user)
{
HANDLE h;
WIN32_FIND_DATAA fd;
unsigned pos;
BOOL found = FALSE;
pos = strlen(buffer);
if (buffer[pos - 1] != '\\') buffer[pos++] = '\\';
strcpy(buffer + pos, "*.*");
if ((h = FindFirstFileA(buffer, &fd)) == INVALID_HANDLE_VALUE)
return FALSE;
/* doc doesn't specify how the tree is enumerated...
* doing a depth first based on, but may be wrong
*/
do
{
if (!strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..")) continue;
strcpy(buffer + pos, fd.cFileName);
if (recurse && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
found = do_search(file, buffer, TRUE, cb, user);
else if (SymMatchFileName(buffer, (char*)file, NULL, NULL))
{
if (!cb || cb(buffer, user)) found = TRUE;
}
} while (!found && FindNextFileA(h, &fd));
if (!found) buffer[--pos] = '\0';
FindClose(h);
return found;
}
/***********************************************************************
* SearchTreeForFileW (DBGHELP.@)
*/
......@@ -368,7 +342,7 @@ struct sffip
DWORD two;
DWORD three;
DWORD flags;
PFINDFILEINPATHCALLBACK cb;
PFINDFILEINPATHCALLBACKW cb;
void* user;
};
......@@ -377,7 +351,7 @@ struct sffip
* returns TRUE when file is found, FALSE to continue searching
* (NB this is the opposite conventions as for SymFindFileInPathProc)
*/
static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
static BOOL CALLBACK sffip_cb(LPCWSTR buffer, void* user)
{
struct sffip* s = (struct sffip*)user;
DWORD size, checksum;
......@@ -395,10 +369,10 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
timestamp = ~(DWORD_PTR)s->id;
size = ~s->two;
hFile = CreateFileA(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
hFile = CreateFileW(buffer, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
if ((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
{
if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
{
......@@ -412,32 +386,40 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
CloseHandle(hFile);
if (timestamp != (DWORD_PTR)s->id || size != s->two)
{
WARN("Found %s, but wrong size or timestamp\n", buffer);
WARN("Found %s, but wrong size or timestamp\n", debugstr_w(buffer));
return FALSE;
}
}
break;
case DMT_ELF:
if (elf_fetch_file_info(buffer, 0, &size, &checksum))
{
char fn[MAX_PATH];
WideCharToMultiByte(CP_ACP, 0, buffer, -1, fn, MAX_PATH, NULL, NULL);
if (elf_fetch_file_info(fn, 0, &size, &checksum))
{
if (checksum != (DWORD_PTR)s->id)
{
WARN("Found %s, but wrong checksums: %08x %08lx\n",
buffer, checksum, (DWORD_PTR)s->id);
debugstr_w(buffer), checksum, (DWORD_PTR)s->id);
return FALSE;
}
}
else
{
WARN("Couldn't read %s\n", buffer);
WARN("Couldn't read %s\n", debugstr_w(buffer));
return FALSE;
}
}
break;
case DMT_PDB:
{
struct pdb_lookup pdb_lookup;
char fn[MAX_PATH];
pdb_lookup.filename = buffer;
WideCharToMultiByte(CP_ACP, 0, buffer, -1, fn, MAX_PATH, NULL, NULL);
pdb_lookup.filename = fn;
if (!pdb_fetch_file_info(&pdb_lookup)) return FALSE;
switch (pdb_lookup.kind)
......@@ -445,26 +427,26 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
case PDB_JG:
if (s->flags & SSRVOPT_GUIDPTR)
{
WARN("Found %s, but wrong PDB version\n", buffer);
WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
return FALSE;
}
if (pdb_lookup.u.jg.timestamp != (DWORD_PTR)s->id)
{
WARN("Found %s, but wrong signature: %08x %08lx\n",
buffer, pdb_lookup.u.jg.timestamp, (DWORD_PTR)s->id);
debugstr_w(buffer), pdb_lookup.u.jg.timestamp, (DWORD_PTR)s->id);
return FALSE;
}
break;
case PDB_DS:
if (!(s->flags & SSRVOPT_GUIDPTR))
{
WARN("Found %s, but wrong PDB version\n", buffer);
WARN("Found %s, but wrong PDB version\n", debugstr_w(buffer));
return FALSE;
}
if (memcmp(&pdb_lookup.u.ds.guid, (GUID*)s->id, sizeof(GUID)))
{
WARN("Found %s, but wrong GUID: %s %s\n",
buffer, debugstr_guid(&pdb_lookup.u.ds.guid),
debugstr_w(buffer), debugstr_guid(&pdb_lookup.u.ds.guid),
debugstr_guid((GUID*)s->id));
return FALSE;
}
......@@ -473,7 +455,7 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
if (pdb_lookup.age != s->two)
{
WARN("Found %s, but wrong age: %08x %08x\n",
buffer, pdb_lookup.age, s->two);
debugstr_w(buffer), pdb_lookup.age, s->two);
return FALSE;
}
}
......@@ -485,39 +467,30 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
/* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
* convention to stop/continue enumeration. sigh.
*/
return !(s->cb)((char*)buffer, s->user);
return !(s->cb)((WCHAR*)buffer, s->user);
}
/******************************************************************
* SymFindFileInPath (DBGHELP.@)
* SymFindFileInPathW (DBGHELP.@)
*
*/
BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR inSearchPath, PCSTR full_path,
BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_path,
PVOID id, DWORD two, DWORD three, DWORD flags,
LPSTR buffer, PFINDFILEINPATHCALLBACK cb,
LPWSTR buffer, PFINDFILEINPATHCALLBACKW cb,
PVOID user)
{
struct sffip s;
struct process* pcs = process_find_by_handle(hProcess);
char tmp[MAX_PATH];
char* ptr;
char* buf = NULL;
const char* filename;
const char* searchPath = inSearchPath;
WCHAR tmp[MAX_PATH];
WCHAR* ptr;
const WCHAR* filename;
TRACE("(%p %s %s %p %08x %08x %08x %p %p %p)\n",
hProcess, searchPath, full_path, id, two, three, flags,
buffer, cb, user);
hProcess, debugstr_w(searchPath), debugstr_w(full_path),
id, two, three, flags, buffer, cb, user);
if (!pcs) return FALSE;
if (!searchPath)
{
unsigned len = WideCharToMultiByte(CP_ACP, 0, pcs->search_path, -1, NULL, 0, NULL, NULL);
searchPath = buf = HeapAlloc(GetProcessHeap(), 0, len);
if (!searchPath) return FALSE;
WideCharToMultiByte(CP_ACP, 0, pcs->search_path, -1, buf, len, NULL, NULL);
}
if (!searchPath) searchPath = pcs->search_path;
s.id = id;
s.two = two;
......@@ -526,38 +499,66 @@ BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR inSearchPath, PCSTR full_pa
s.cb = cb;
s.user = user;
filename = file_name(full_path);
s.kind = module_get_type_by_nameA(filename);
filename = file_nameW(full_path);
s.kind = module_get_type_by_name(filename);
/* first check full path to file */
if (sffip_cb(full_path, &s))
{
strcpy(buffer, full_path);
HeapFree(GetProcessHeap(), 0, buf);
strcpyW(buffer, full_path);
return TRUE;
}
while (searchPath)
{
ptr = strchr(searchPath, ';');
ptr = strchrW(searchPath, ';');
if (ptr)
{
memcpy(tmp, searchPath, ptr - searchPath);
memcpy(tmp, searchPath, (ptr - searchPath) * sizeof(WCHAR));
tmp[ptr - searchPath] = 0;
searchPath = ptr + 1;
}
else
{
strcpy(tmp, searchPath);
strcpyW(tmp, searchPath);
searchPath = NULL;
}
if (do_search(filename, tmp, FALSE, sffip_cb, &s))
if (do_searchW(filename, tmp, FALSE, sffip_cb, &s))
{
strcpy(buffer, tmp);
HeapFree(GetProcessHeap(), 0, buf);
strcpyW(buffer, tmp);
return TRUE;
}
}
HeapFree(GetProcessHeap(), 0, buf);
return FALSE;
}
/******************************************************************
* SymFindFileInPath (DBGHELP.@)
*
*/
BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR searchPath, PCSTR full_path,
PVOID id, DWORD two, DWORD three, DWORD flags,
LPSTR buffer, PFINDFILEINPATHCALLBACK cb,
PVOID user)
{
WCHAR searchPathW[MAX_PATH];
WCHAR full_pathW[MAX_PATH];
WCHAR bufferW[MAX_PATH];
struct enum_dir_treeWA edt;
BOOL ret;
/* a PFINDFILEINPATHCALLBACK and a PENUMDIRTREE_CALLBACK have actually the
* same signature & semantics, hence we can reuse the EnumDirTree W->A
* conversion helper
*/
edt.cb = cb;
edt.user = user;
if (searchPath)
MultiByteToWideChar(CP_ACP, 0, searchPath, -1, searchPathW, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
if ((ret = SymFindFileInPathW(hProcess, searchPath ? searchPathW : NULL, full_pathW,
id, two, three, flags,
bufferW, enum_dir_treeWA, &edt)))
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
return ret;
}
......@@ -77,7 +77,7 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module,
return ret;
}
static BOOL CALLBACK dbg_match(char* file, void* user)
static BOOL CALLBACK dbg_match(const char* file, void* user)
{
/* accept first file */
return FALSE;
......
......@@ -999,9 +999,12 @@ BOOL WINAPI SymCleanup(HANDLE);
HANDLE WINAPI FindDebugInfoFile(PCSTR, PCSTR, PSTR);
typedef BOOL (CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(HANDLE, PSTR, PVOID);
HANDLE WINAPI FindDebugInfoFileEx(PCSTR, PCSTR, PSTR, PFIND_DEBUG_FILE_CALLBACK, PVOID);
typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACK)(PSTR, PVOID);
typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACK)(PCSTR, PVOID);
BOOL WINAPI SymFindFileInPath(HANDLE, PCSTR, PCSTR, PVOID, DWORD, DWORD, DWORD,
PSTR, PFINDFILEINPATHCALLBACK, PVOID);
typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACKW)(PCWSTR, PVOID);
BOOL WINAPI SymFindFileInPathW(HANDLE, PCWSTR, PCWSTR, PVOID, DWORD, DWORD, DWORD,
PWSTR, PFINDFILEINPATHCALLBACKW, PVOID);
HANDLE WINAPI FindExecutableImage(PCSTR, PCSTR, PSTR);
typedef BOOL (CALLBACK *PFIND_EXE_FILE_CALLBACK)(HANDLE, PSTR, PVOID);
HANDLE WINAPI FindExecutableImageEx(PCSTR, PCSTR, PSTR, PFIND_EXE_FILE_CALLBACK, PVOID);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment