2 * File path.c - managing path in debugging environments
4 * Copyright (C) 2004, Eric Pouech
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
26 #include "dbghelp_private.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp
);
31 static inline BOOL
is_sep(char ch
) {return ch
== '/' || ch
== '\\';}
33 static inline char* file_name(char* str
)
37 for (p
= str
+ strlen(str
) - 1; p
>= str
&& !is_sep(*p
); p
--);
41 /******************************************************************
42 * FindDebugInfoFile (DBGHELP.@)
45 HANDLE WINAPI
FindDebugInfoFile(PSTR FileName
, PSTR SymbolPath
, PSTR DebugFilePath
)
49 h
= CreateFileA(DebugFilePath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
50 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
51 if (h
== INVALID_HANDLE_VALUE
)
53 if (!SearchPathA(SymbolPath
, file_name(FileName
), NULL
, MAX_PATH
, DebugFilePath
, NULL
))
55 h
= CreateFileA(DebugFilePath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
56 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
58 return (h
== INVALID_HANDLE_VALUE
) ? NULL
: h
;
61 /******************************************************************
62 * FindDebugInfoFileEx (DBGHELP.@)
65 HANDLE WINAPI
FindDebugInfoFileEx(PSTR FileName
, PSTR SymbolPath
,
67 PFIND_DEBUG_FILE_CALLBACK Callback
,
70 FIXME("(%s %s %p %p %p): stub\n",
71 FileName
, SymbolPath
, DebugFilePath
, Callback
, CallerData
);
75 /******************************************************************
76 * FindExecutableImage (DBGHELP.@)
79 HANDLE WINAPI
FindExecutableImage(PSTR FileName
, PSTR SymbolPath
, PSTR ImageFilePath
)
82 if (!SearchPathA(SymbolPath
, FileName
, NULL
, MAX_PATH
, ImageFilePath
, NULL
))
84 h
= CreateFileA(ImageFilePath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
,
85 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
86 return (h
== INVALID_HANDLE_VALUE
) ? NULL
: h
;
89 /***********************************************************************
90 * MakeSureDirectoryPathExists (DBGHELP.@)
92 BOOL WINAPI
MakeSureDirectoryPathExists(LPCSTR DirPath
)
94 if (CreateDirectoryA(DirPath
, NULL
)) return TRUE
;
95 if (GetLastError() == ERROR_ALREADY_EXISTS
)
97 SetLastError(ERROR_SUCCESS
);
103 /******************************************************************
104 * SymMatchFileName (DBGHELP.@)
107 BOOL WINAPI
SymMatchFileName(char* file
, char* match
,
108 char** filestop
, char** matchstop
)
113 TRACE("(%s %s %p %p)\n", file
, match
, filestop
, matchstop
);
115 fptr
= file
+ strlen(file
) - 1;
116 mptr
= match
+ strlen(match
) - 1;
118 while (fptr
>= file
&& mptr
>= match
)
120 if (toupper(*fptr
) != toupper(*mptr
) && !(is_sep(*fptr
) && is_sep(*mptr
)))
124 if (filestop
) *filestop
= fptr
;
125 if (matchstop
) *matchstop
= mptr
;
127 return mptr
== match
- 1;
130 static BOOL
do_search(const char* file
, char* buffer
,
131 PENUMDIRTREE_CALLBACK cb
, void* user
)
138 pos
= strlen(buffer
);
139 if (buffer
[pos
- 1] != '\\') buffer
[pos
++] = '\\';
140 strcpy(buffer
+ pos
, "*.*");
141 if ((h
= FindFirstFileA(buffer
, &fd
)) == INVALID_HANDLE_VALUE
)
143 /* doc doesn't specify how the tree is enumerated...
144 * doing a depth first based on, but may be wrong
148 if (!strcmp(fd
.cFileName
, ".") || !strcmp(fd
.cFileName
, "..")) continue;
150 strcpy(buffer
+ pos
, fd
.cFileName
);
151 if (fd
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)
152 found
= do_search(file
, buffer
, cb
, user
);
153 else if (SymMatchFileName(buffer
, (char*)file
, NULL
, NULL
))
155 if (!cb
|| cb(buffer
, user
)) found
= TRUE
;
157 } while (!found
&& FindNextFileA(h
, &fd
));
158 if (!found
) buffer
[--pos
] = '\0';
164 /***********************************************************************
165 * SearchTreeForFile (DBGHELP.@)
167 BOOL WINAPI
SearchTreeForFile(LPSTR root
, LPSTR file
, LPSTR buffer
)
169 TRACE("(%s, %s, %p)\n",
170 debugstr_a(root
), debugstr_a(file
), buffer
);
171 strcpy(buffer
, root
);
172 return do_search(file
, buffer
, NULL
, NULL
);
175 /******************************************************************
176 * EnumDirTree (DBGHELP.@)
180 BOOL WINAPI
EnumDirTree(HANDLE hProcess
, PCSTR root
, PCSTR file
,
181 LPSTR buffer
, PENUMDIRTREE_CALLBACK cb
, void* user
)
183 TRACE("(%p %s %s %p %p %p)\n", hProcess
, root
, file
, buffer
, cb
, user
);
185 strcpy(buffer
, root
);
186 return do_search(file
, buffer
, cb
, user
);
195 PFINDFILEINPATHCALLBACK cb
;
199 static BOOL CALLBACK
sffip_cb(LPCSTR buffer
, void* user
)
201 struct sffip
* s
= (struct sffip
*)user
;
203 /* FIXME: should check that id/two/three match the file pointed
206 /* yes, EnumDirTree and SymFindFileInPath callbacks use the opposite
207 * convention to stop/continue enumeration. sigh.
209 return !(s
->cb
)((char*)buffer
, s
->user
);
212 /******************************************************************
213 * SymFindFileInPath (DBGHELP.@)
216 BOOL WINAPI
SymFindFileInPath(HANDLE hProcess
, LPSTR searchPath
, LPSTR file
,
217 PVOID id
, DWORD two
, DWORD three
, DWORD flags
,
218 LPSTR buffer
, PFINDFILEINPATHCALLBACK cb
,
222 struct process
* pcs
= process_find_by_handle(hProcess
);
226 TRACE("(%p %s %s %p %08lx %08lx %08lx %p %p %p)\n",
227 hProcess
, searchPath
, file
, id
, two
, three
, flags
,
230 if (!pcs
) return FALSE
;
231 if (!searchPath
) searchPath
= pcs
->search_path
;
240 file
= file_name(file
);
244 ptr
= strchr(searchPath
, ';');
247 memcpy(tmp
, searchPath
, ptr
- searchPath
);
248 tmp
[ptr
- searchPath
] = 0;
249 searchPath
= ptr
+ 1;
253 strcpy(tmp
, searchPath
);
256 if (EnumDirTree(hProcess
, tmp
, file
, buffer
, sffip_cb
, &s
)) return TRUE
;