ReactOS  0.4.15-dev-1171-gab82533
path.c
Go to the documentation of this file.
1 /*
2  * File path.c - managing path in debugging environments
3  *
4  * Copyright (C) 2004,2008, Eric Pouech
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 
25 #include "dbghelp_private.h"
26 #include "image_private.h"
27 #include "winnls.h"
28 #include "winternl.h"
29 #include "wine/debug.h"
30 #include "wine/heap.h"
31 
33 
34 static inline BOOL is_sepA(char ch) {return ch == '/' || ch == '\\';}
35 static inline BOOL is_sep(WCHAR ch) {return ch == '/' || ch == '\\';}
36 
37 const char* file_nameA(const char* str)
38 {
39  const char* p;
40 
41  for (p = str + strlen(str) - 1; p >= str && !is_sepA(*p); p--);
42  return p + 1;
43 }
44 
45 const WCHAR* file_name(const WCHAR* str)
46 {
47  const WCHAR* p;
48 
49  for (p = str + lstrlenW(str) - 1; p >= str && !is_sep(*p); p--);
50  return p + 1;
51 }
52 
53 static inline void file_pathW(const WCHAR *src, WCHAR *dst)
54 {
55  int len;
56 
57  for (len = lstrlenW(src) - 1; (len > 0) && (!is_sep(src[len])); len--);
58  memcpy( dst, src, len * sizeof(WCHAR) );
59  dst[len] = 0;
60 }
61 
62 /******************************************************************
63  * FindDebugInfoFile (DBGHELP.@)
64  *
65  */
67 {
68  HANDLE h;
69 
72  if (h == INVALID_HANDLE_VALUE)
73  {
74  if (!SearchPathA(SymbolPath, file_nameA(FileName), NULL, MAX_PATH, DebugFilePath, NULL))
75  return NULL;
76  h = CreateFileA(DebugFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
78  }
79  return (h == INVALID_HANDLE_VALUE) ? NULL : h;
80 }
81 
82 /******************************************************************
83  * FindDebugInfoFileEx (DBGHELP.@)
84  *
85  */
87  PSTR DebugFilePath,
89  PVOID CallerData)
90 {
91  FIXME("(%s %s %s %p %p): stub\n", debugstr_a(FileName), debugstr_a(SymbolPath),
92  debugstr_a(DebugFilePath), Callback, CallerData);
93  return NULL;
94 }
95 
96 /******************************************************************
97  * FindExecutableImageExW (DBGHELP.@)
98  *
99  */
102 {
103  HANDLE h;
104 
105  if (Callback) FIXME("Unsupported callback yet\n");
106  if (!SearchPathW(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL))
107  return NULL;
108  h = CreateFileW(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
110  return (h == INVALID_HANDLE_VALUE) ? NULL : h;
111 }
112 
113 /******************************************************************
114  * FindExecutableImageEx (DBGHELP.@)
115  *
116  */
119 {
120  HANDLE h;
121 
122  if (Callback) FIXME("Unsupported callback yet\n");
123  if (!SearchPathA(SymbolPath, FileName, NULL, MAX_PATH, ImageFilePath, NULL))
124  return NULL;
125  h = CreateFileA(ImageFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
127  return (h == INVALID_HANDLE_VALUE) ? NULL : h;
128 }
129 
130 /******************************************************************
131  * FindExecutableImage (DBGHELP.@)
132  *
133  */
135 {
136  return FindExecutableImageEx(FileName, SymbolPath, ImageFilePath, NULL, NULL);
137 }
138 
139 /***********************************************************************
140  * MakeSureDirectoryPathExists (DBGHELP.@)
141  */
143 {
144  char path[MAX_PATH];
145  const char *p = DirPath;
146  int n;
147 
148  if (p[0] && p[1] == ':') p += 2;
149  while (*p == '\\') p++; /* skip drive root */
150  while ((p = strchr(p, '\\')) != NULL)
151  {
152  n = p - DirPath + 1;
153  memcpy(path, DirPath, n);
154  path[n] = '\0';
155  if( !CreateDirectoryA(path, NULL) &&
157  return FALSE;
158  p++;
159  }
162 
163  return TRUE;
164 }
165 
166 /******************************************************************
167  * SymMatchFileNameW (DBGHELP.@)
168  *
169  */
171  PWSTR* filestop, PWSTR* matchstop)
172 {
173  PCWSTR fptr;
174  PCWSTR mptr;
175 
176  TRACE("(%s %s %p %p)\n",
177  debugstr_w(file), debugstr_w(match), filestop, matchstop);
178 
179  fptr = file + lstrlenW(file) - 1;
180  mptr = match + lstrlenW(match) - 1;
181 
182  while (fptr >= file && mptr >= match)
183  {
184  if (towupper(*fptr) != towupper(*mptr) && !(is_sep(*fptr) && is_sep(*mptr)))
185  break;
186  fptr--; mptr--;
187  }
188  if (filestop) *filestop = (PWSTR)fptr;
189  if (matchstop) *matchstop = (PWSTR)mptr;
190 
191  return mptr == match - 1;
192 }
193 
194 /******************************************************************
195  * SymMatchFileName (DBGHELP.@)
196  *
197  */
199  PSTR* filestop, PSTR* matchstop)
200 {
201  PCSTR fptr;
202  PCSTR mptr;
203 
204  TRACE("(%s %s %p %p)\n", debugstr_a(file), debugstr_a(match), filestop, matchstop);
205 
206  fptr = file + strlen(file) - 1;
207  mptr = match + strlen(match) - 1;
208 
209  while (fptr >= file && mptr >= match)
210  {
211  if (toupper(*fptr) != toupper(*mptr) && !(is_sepA(*fptr) && is_sepA(*mptr)))
212  break;
213  fptr--; mptr--;
214  }
215  if (filestop) *filestop = (PSTR)fptr;
216  if (matchstop) *matchstop = (PSTR)mptr;
217 
218  return mptr == match - 1;
219 }
220 
223 {
224  HANDLE h;
226  unsigned pos;
227  BOOL found = FALSE;
228  static const WCHAR S_AllW[] = {'*','.','*','\0'};
229  static const WCHAR S_DotW[] = {'.','\0'};
230  static const WCHAR S_DotDotW[] = {'.','.','\0'};
231 
232  pos = lstrlenW(buffer);
233  if (pos == 0) return FALSE;
234  if (buffer[pos - 1] != '\\') buffer[pos++] = '\\';
235  lstrcpyW(buffer + pos, S_AllW);
237  return FALSE;
238  /* doc doesn't specify how the tree is enumerated...
239  * doing a depth first based on, but may be wrong
240  */
241  do
242  {
243  if (!wcscmp(fd.cFileName, S_DotW) || !wcscmp(fd.cFileName, S_DotDotW)) continue;
244 
245  lstrcpyW(buffer + pos, fd.cFileName);
246  if (recurse && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
247  found = do_searchW(file, buffer, TRUE, cb, user);
248  else if (SymMatchFileNameW(buffer, file, NULL, NULL))
249  {
250  if (!cb || cb(buffer, user)) found = TRUE;
251  }
252  } while (!found && FindNextFileW(h, &fd));
253  if (!found) buffer[--pos] = '\0';
254  FindClose(h);
255 
256  return found;
257 }
258 
259 /***********************************************************************
260  * SearchTreeForFileW (DBGHELP.@)
261  */
263 {
264  TRACE("(%s, %s, %p)\n",
266  lstrcpyW(buffer, root);
267  return do_searchW(file, buffer, TRUE, NULL, NULL);
268 }
269 
270 /***********************************************************************
271  * SearchTreeForFile (DBGHELP.@)
272  */
274 {
277  WCHAR bufferW[MAX_PATH];
278  BOOL ret;
279 
282  ret = SearchTreeForFileW(rootW, fileW, bufferW);
283  if (ret)
284  WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
285  return ret;
286 }
287 
288 /******************************************************************
289  * EnumDirTreeW (DBGHELP.@)
290  *
291  *
292  */
295 {
296  TRACE("(%p %s %s %p %p %p)\n",
298 
299  lstrcpyW(buffer, root);
300  return do_searchW(file, buffer, TRUE, cb, user);
301 }
302 
303 /******************************************************************
304  * EnumDirTree (DBGHELP.@)
305  *
306  *
307  */
309 {
311  void* user;
312  char name[MAX_PATH];
313 };
314 
316 {
317  struct enum_dir_treeWA* edt = user;
318 
320  return edt->cb(edt->name, edt->user);
321 }
322 
325 {
328  WCHAR bufferW[MAX_PATH];
329  struct enum_dir_treeWA edt;
330  BOOL ret;
331 
332  edt.cb = cb;
333  edt.user = user;
336  if ((ret = EnumDirTreeW(hProcess, rootW, fileW, bufferW, enum_dir_treeWA, &edt)))
337  WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
338  return ret;
339 }
340 
341 struct sffip
342 {
344  void* user;
345 };
346 
347 /* checks that buffer (as found by matching the name) matches the info
348  * (information is based on file type)
349  * returns TRUE when file is found, FALSE to continue searching
350  * (NB this is the opposite convention of SymFindFileInPathProc)
351  */
353 {
354  struct sffip* s = user;
355 
356  if (!s->cb) return TRUE;
357  /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
358  * convention to stop/continue enumeration. sigh.
359  */
360  return !(s->cb)(buffer, s->user);
361 }
362 
363 /******************************************************************
364  * SymFindFileInPathW (DBGHELP.@)
365  *
366  */
368  PVOID id, DWORD two, DWORD three, DWORD flags,
370  PVOID user)
371 {
372  struct sffip s;
373  struct process* pcs = process_find_by_handle(hProcess);
374  WCHAR tmp[MAX_PATH];
375  WCHAR* ptr;
376  const WCHAR* filename;
377 
378  TRACE("(hProcess = %p, searchPath = %s, full_path = %s, id = %p, two = 0x%08x, three = 0x%08x, flags = 0x%08x, buffer = %p, cb = %p, user = %p)\n",
379  hProcess, debugstr_w(searchPath), debugstr_w(full_path),
380  id, two, three, flags, buffer, cb, user);
381 
382  if (!pcs) return FALSE;
383  if (!searchPath) searchPath = pcs->search_path;
384 
385  s.cb = cb;
386  s.user = user;
387 
388  filename = file_name(full_path);
389 
390  /* first check full path to file */
391  if (sffip_cb(full_path, &s))
392  {
393  lstrcpyW(buffer, full_path);
394  return TRUE;
395  }
396 
397  while (searchPath)
398  {
399  ptr = wcschr(searchPath, ';');
400  if (ptr)
401  {
402  memcpy(tmp, searchPath, (ptr - searchPath) * sizeof(WCHAR));
403  tmp[ptr - searchPath] = 0;
404  searchPath = ptr + 1;
405  }
406  else
407  {
408  lstrcpyW(tmp, searchPath);
409  searchPath = NULL;
410  }
411  if (do_searchW(filename, tmp, FALSE, sffip_cb, &s))
412  {
413  lstrcpyW(buffer, tmp);
414  return TRUE;
415  }
416  }
417  return FALSE;
418 }
419 
420 /******************************************************************
421  * SymFindFileInPath (DBGHELP.@)
422  *
423  */
425  PVOID id, DWORD two, DWORD three, DWORD flags,
427  PVOID user)
428 {
429  WCHAR searchPathW[MAX_PATH];
430  WCHAR full_pathW[MAX_PATH];
431  WCHAR bufferW[MAX_PATH];
432  struct enum_dir_treeWA edt;
433  BOOL ret;
434 
435  /* a PFINDFILEINPATHCALLBACK and a PENUMDIRTREE_CALLBACK have actually the
436  * same signature & semantics, hence we can reuse the EnumDirTree W->A
437  * conversion helper
438  */
439  edt.cb = cb;
440  edt.user = user;
441  if (searchPath)
442  MultiByteToWideChar(CP_ACP, 0, searchPath, -1, searchPathW, MAX_PATH);
443  MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
444  if ((ret = SymFindFileInPathW(hProcess, searchPath ? searchPathW : NULL, full_pathW,
445  id, two, three, flags,
446  bufferW, enum_dir_treeWA, &edt)))
447  WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
448  return ret;
449 }
450 
452 {
454  /* pe: dw1 DWORD:timestamp
455  * dw2 size of image (from PE header)
456  * pdb: guid PDB guid (if DS PDB file)
457  * or dw1 PDB timestamp (if JG PDB file)
458  * dw2 PDB age
459  * elf: dw1 DWORD:CRC 32 of ELF image (Wine only)
460  */
461  const GUID* guid;
465  unsigned matched;
466 };
467 
468 /* checks that buffer (as found by matching the name) matches the info
469  * (information is based on file type)
470  * returns TRUE when file is found, FALSE to continue searching
471  * (NB this is the opposite convention of SymFindFileInPathProc)
472  */
474 {
475  struct module_find* mf = user;
477  unsigned matched = 0;
478 
479  /* the matching weights:
480  * +1 if a file with same name is found and is a decent file of expected type
481  * +1 if first parameter and second parameter match
482  */
483 
484  /* FIXME: should check that id/two match the file pointed
485  * by buffer
486  */
487  switch (mf->kind)
488  {
489  case DMT_PE:
490  {
491  HANDLE hFile, hMap;
492  void* mapping;
493 
494  timestamp = ~mf->dw1;
495  size = ~mf->dw2;
498  if (hFile == INVALID_HANDLE_VALUE) return FALSE;
499  if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
500  {
501  if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
502  {
504  if (!nth)
505  {
507  CloseHandle(hMap);
509  return FALSE;
510  }
511  matched++;
515  }
516  CloseHandle(hMap);
517  }
519  if (timestamp != mf->dw1)
520  WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
521  if (size != mf->dw2)
522  WARN("Found %s, but wrong size\n", debugstr_w(buffer));
523  if (timestamp == mf->dw1 && size == mf->dw2) matched++;
524  }
525  break;
526  case DMT_PDB:
527  {
528  struct pdb_lookup pdb_lookup;
529  char fn[MAX_PATH];
530 
533 
534  if (mf->guid)
535  {
537  pdb_lookup.timestamp = 0;
538  pdb_lookup.guid = *mf->guid;
539  }
540  else
541  {
543  pdb_lookup.timestamp = mf->dw1;
544  /* pdb_loopkup.guid = */
545  }
546  pdb_lookup.age = mf->dw2;
547 
548  if (!pdb_fetch_file_info(&pdb_lookup, &matched)) return FALSE;
549  }
550  break;
551  case DMT_DBG:
552  {
553  HANDLE hFile, hMap;
554  void* mapping;
555 
556  timestamp = ~mf->dw1;
559  if (hFile == INVALID_HANDLE_VALUE) return FALSE;
560  if ((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL)
561  {
562  if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
563  {
565  hdr = mapping;
566 
567  if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
568  {
569  matched++;
570  timestamp = hdr->TimeDateStamp;
571  }
573  }
574  CloseHandle(hMap);
575  }
577  if (timestamp == mf->dw1) matched++;
578  else WARN("Found %s, but wrong timestamp\n", debugstr_w(buffer));
579  }
580  break;
581  default:
582  FIXME("What the heck??\n");
583  return FALSE;
584  }
585  if (matched > mf->matched)
586  {
587  lstrcpyW(mf->filename, buffer);
588  mf->matched = matched;
589  }
590  /* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
591  * convention to stop/continue enumeration. sigh.
592  */
593  return mf->matched == 2;
594 }
595 
596 BOOL path_find_symbol_file(const struct process* pcs, const struct module* module,
597  PCSTR full_path, enum module_type type, const GUID* guid, DWORD dw1, DWORD dw2,
598  WCHAR *buffer, BOOL* is_unmatched)
599 {
600  struct module_find mf;
601  WCHAR full_pathW[MAX_PATH];
602  WCHAR* ptr;
603  const WCHAR* filename;
604  WCHAR* searchPath = pcs->search_path;
605 
606  TRACE("(pcs = %p, full_path = %s, guid = %s, dw1 = 0x%08x, dw2 = 0x%08x, buffer = %p)\n",
607  pcs, debugstr_a(full_path), debugstr_guid(guid), dw1, dw2, buffer);
608 
609  mf.guid = guid;
610  mf.dw1 = dw1;
611  mf.dw2 = dw2;
612  mf.matched = 0;
613 
614  MultiByteToWideChar(CP_ACP, 0, full_path, -1, full_pathW, MAX_PATH);
615  filename = file_name(full_pathW);
616  mf.kind = type;
617  *is_unmatched = FALSE;
618 
619  /* first check full path to file */
620  if (module_find_cb(full_pathW, &mf))
621  {
622  lstrcpyW( buffer, full_pathW );
623  return TRUE;
624  }
625 
626  /* FIXME: Use Environment-Variables (see MS docs)
627  _NT_SYMBOL_PATH and _NT_ALT_SYMBOL_PATH
628  FIXME: Implement "Standard Path Elements" (Path) ... (see MS docs)
629  do a search for (every?) path-element like this ...
630  <path>
631  <path>\dll
632  <path>\symbols\dll
633  (dll may be exe, or sys depending on the file extension) */
634 
635  /* 2. check module-path */
637  if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
638  if (module->real_path)
639  {
641  if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
642  }
643 
644  while (searchPath)
645  {
646  ptr = wcschr(searchPath, ';');
647  if (ptr)
648  {
649  memcpy(buffer, searchPath, (ptr - searchPath) * sizeof(WCHAR));
650  buffer[ptr - searchPath] = '\0';
651  searchPath = ptr + 1;
652  }
653  else
654  {
655  lstrcpyW(buffer, searchPath);
656  searchPath = NULL;
657  }
658  /* return first fully matched file */
659  if (do_searchW(filename, buffer, FALSE, module_find_cb, &mf)) return TRUE;
660  }
661  /* if no fully matching file is found, return the best matching file if any */
663  {
664  lstrcpyW( buffer, mf.filename );
665  *is_unmatched = TRUE;
666  return TRUE;
667  }
668  return FALSE;
669 }
670 
672 {
673  WCHAR *dos_path;
674  size_t len;
675 
676  if (*filename == '/')
677  {
678  char *unix_path;
680  unix_path = heap_alloc(len * sizeof(WCHAR));
681  WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, unix_path, len, NULL, NULL);
682  dos_path = wine_get_dos_file_name(unix_path);
683  heap_free(unix_path);
684  }
685  else
686  {
687  len = lstrlenW(filename);
688  dos_path = heap_alloc((len + 1) * sizeof(WCHAR));
689  memcpy(dos_path, filename, (len + 1) * sizeof(WCHAR));
690  }
691  return dos_path;
692 }
693 
694 #ifndef __REACTOS__
695 BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param)
696 {
697  const WCHAR *env;
698  size_t len, i;
699  HANDLE file;
700  WCHAR *buf;
701  BOOL ret;
702 
703  name = file_name(name);
704 
705  if ((env = process_getenv(process, L"WINEBUILDDIR")))
706  {
707  WCHAR *p, *end;
708  const WCHAR dllsW[] = { '\\','d','l','l','s','\\' };
709  const WCHAR programsW[] = { '\\','p','r','o','g','r','a','m','s','\\' };
710  const WCHAR dot_dllW[] = {'.','d','l','l',0};
711  const WCHAR dot_exeW[] = {'.','e','x','e',0};
712  const WCHAR dot_soW[] = {'.','s','o',0};
713 
714 
715  len = lstrlenW(env);
716  if (!(buf = heap_alloc((len + 8 + 3 * lstrlenW(name)) * sizeof(WCHAR)))) return FALSE;
717  wcscpy(buf, env);
718  end = buf + len;
719 
720  memcpy(end, dllsW, sizeof(dllsW));
721  lstrcpyW(end + ARRAY_SIZE(dllsW), name);
722  if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_soW)) *p = 0;
723  if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_dllW)) *p = 0;
724  p = end + lstrlenW(end);
725  *p++ = '\\';
726  lstrcpyW(p, name);
728  if (file != INVALID_HANDLE_VALUE)
729  {
730  ret = match(param, file, buf);
731  CloseHandle(file);
732  if (ret) goto found;
733  }
734 
735  memcpy(end, programsW, sizeof(programsW));
736  end += ARRAY_SIZE(programsW);
737  lstrcpyW(end, name);
738  if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_soW)) *p = 0;
739  if ((p = wcsrchr(end, '.')) && !lstrcmpW(p, dot_exeW)) *p = 0;
740  p = end + lstrlenW(end);
741  *p++ = '\\';
742  lstrcpyW(p, name);
744  if (file != INVALID_HANDLE_VALUE)
745  {
746  ret = match(param, file, buf);
747  CloseHandle(file);
748  if (ret) goto found;
749  }
750 
751  heap_free(buf);
752  }
753 
754  for (i = 0;; i++)
755  {
756  WCHAR env_name[64];
757  swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i);
758  if (!(env = process_getenv(process, env_name))) return FALSE;
759  len = wcslen(env) + wcslen(name) + 2;
760  if (!(buf = heap_alloc(len * sizeof(WCHAR)))) return FALSE;
761  swprintf(buf, len, L"%s\\%s", env, name);
763  if (file != INVALID_HANDLE_VALUE)
764  {
765  ret = match(param, file, buf);
766  CloseHandle(file);
767  if (ret) goto found;
768  }
769  heap_free(buf);
770  }
771 
772  return FALSE;
773 
774 found:
775  TRACE("found %s\n", debugstr_w(buf));
776  heap_free(buf);
777  return TRUE;
778 }
779 
780 BOOL search_unix_path(const WCHAR *name, const WCHAR *path, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param)
781 {
782  const WCHAR *iter, *next;
783  size_t size, len;
784  WCHAR *dos_path;
785  char *buf;
786  BOOL ret = FALSE;
787 
788  if (!path) return FALSE;
789  name = file_name(name);
790 
792  + WideCharToMultiByte(CP_UNIXCP, 0, path, -1, NULL, 0, NULL, NULL);
793  if (!(buf = heap_alloc(size))) return FALSE;
794 
795  for (iter = path;; iter = next + 1)
796  {
797  if (!(next = wcschr(iter, ':'))) next = iter + lstrlenW(iter);
798  if (*iter == '/')
799  {
800  len = WideCharToMultiByte(CP_UNIXCP, 0, iter, next - iter, buf, size, NULL, NULL);
801  if (buf[len - 1] != '/') buf[len++] = '/';
803  if ((dos_path = wine_get_dos_file_name(buf)))
804  {
806  if (file != INVALID_HANDLE_VALUE)
807  {
808  ret = match(param, file, dos_path);
809  CloseHandle(file);
810  if (ret) TRACE("found %s\n", debugstr_w(dos_path));
811  }
812  heap_free(dos_path);
813  if (ret) break;
814  }
815  }
816  if (*next != ':') break;
817  }
818 
819  heap_free(buf);
820  return ret;
821 }
822 #endif
char name[MAX_PATH]
Definition: path.c:312
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
const uint16_t * PCWSTR
Definition: typedefs.h:57
WCHAR * search_path
HANDLE WINAPI FindDebugInfoFileEx(PCSTR FileName, PCSTR SymbolPath, PSTR DebugFilePath, PFIND_DEBUG_FILE_CALLBACK Callback, PVOID CallerData)
Definition: path.c:86
#define CloseHandle
Definition: compat.h:487
char hdr[14]
Definition: iptest.cpp:33
WCHAR * real_path
static BOOL is_sep(WCHAR ch)
Definition: path.c:35
#define ERROR_SUCCESS
Definition: deptool.c:10
#define MapViewOfFile
Definition: compat.h:493
#define WideCharToMultiByte
Definition: compat.h:111
BOOL(CALLBACK * PENUMDIRTREE_CALLBACKW)(PCWSTR, PVOID)
Definition: compat.h:926
HANDLE WINAPI FindExecutableImage(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath)
Definition: path.c:134
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
#define TRUE
Definition: types.h:120
Definition: match.c:28
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI EnumDirTree(HANDLE hProcess, PCSTR root, PCSTR file, PSTR buffer, PENUMDIRTREE_CALLBACK cb, PVOID user)
Definition: path.c:323
static const WCHAR rootW[]
Definition: chain.c:69
#define CP_ACP
Definition: compat.h:109
struct process * process_find_by_handle(HANDLE hProcess)
Definition: dbghelp.c:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define WARN(fmt,...)
Definition: debug.h:112
BOOL(CALLBACK * PFINDFILEINPATHCALLBACKW)(_In_ PCWSTR, _In_ PVOID)
Definition: dbghelp.h:1907
void * user
Definition: path.c:311
static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
Definition: path.c:473
#define CALLBACK
Definition: compat.h:35
GLdouble n
Definition: glext.h:7729
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
HANDLE WINAPI FindExecutableImageEx(PCSTR FileName, PCSTR SymbolPath, PSTR ImageFilePath, PFIND_EXE_FILE_CALLBACK Callback, PVOID user)
Definition: path.c:117
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
GLuint buffer
Definition: glext.h:5915
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:70
enum module_type kind
Definition: path.c:453
static int fd
Definition: io.c:51
GLuint GLuint end
Definition: gl.h:1545
const WCHAR * file_name(const WCHAR *str)
Definition: path.c:45
BOOL(CALLBACK * PFIND_EXE_FILE_CALLBACKW)(HANDLE, PCWSTR, PVOID)
Definition: compat.h:888
BOOL WINAPI SymMatchFileName(PCSTR file, PCSTR match, PSTR *filestop, PSTR *matchstop)
Definition: path.c:198
const char * filename
Definition: ioapi.h:135
#define lstrlenW
Definition: compat.h:498
#define IMAGE_SEPARATE_DEBUG_SIGNATURE
Definition: compat.h:155
DWORD ret
Definition: path.c:47
BOOL pdb_fetch_file_info(const struct pdb_lookup *pdb_lookup, unsigned *matched) DECLSPEC_HIDDEN
Definition: msc.c:2913
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define FILE_SHARE_READ
Definition: compat.h:136
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
BOOL(CALLBACK * PFIND_EXE_FILE_CALLBACK)(_In_ HANDLE, _In_ PCSTR, _In_opt_ PVOID)
Definition: dbghelp.h:1950
enum pdb_kind kind
WCHAR LoadedImageName[256]
Definition: compat.h:826
static const char const char const char * SymbolPath
Definition: image.c:34
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
const GUID * guid
BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR searchPath, PCSTR full_path, PVOID id, DWORD two, DWORD three, DWORD flags, PSTR buffer, PFINDFILEINPATHCALLBACK cb, PVOID user)
Definition: path.c:424
BOOL(CALLBACK * PENUMDIRTREE_CALLBACK)(_In_ PCSTR, _In_opt_ PVOID)
Definition: dbghelp.h:2065
BOOL WINAPI SymMatchFileNameW(PCWSTR file, PCWSTR match, PWSTR *filestop, PWSTR *matchstop)
Definition: path.c:170
#define FALSE
Definition: types.h:117
DWORD WINAPI SearchPathA(IN LPCSTR lpPath OPTIONAL, IN LPCSTR lpFileName, IN LPCSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPSTR lpBuffer, OUT LPSTR *lpFilePart OPTIONAL)
Definition: path.c:1122
unsigned int BOOL
Definition: ntddk_ex.h:94
static double two
Definition: jn_yn.c:52
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:111
static PVOID ptr
Definition: dispmode.c:27
const WCHAR * str
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
unsigned matched
Definition: path.c:465
smooth NULL
Definition: ftsmooth.c:416
static void file_pathW(const WCHAR *src, WCHAR *dst)
Definition: path.c:53
BOOL WINAPI EnumDirTreeW(HANDLE hProcess, PCWSTR root, PCWSTR file, PWSTR buffer, PENUMDIRTREE_CALLBACKW cb, PVOID user)
Definition: path.c:293
#define FILE_MAP_READ
Definition: compat.h:524
struct match match
Definition: match.c:33
static BOOL CALLBACK sffip_cb(PCWSTR buffer, PVOID user)
Definition: path.c:352
#define debugstr_guid
Definition: kernel32.h:35
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define OPEN_EXISTING
Definition: compat.h:523
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_path, PVOID id, DWORD two, DWORD three, DWORD flags, PWSTR buffer, PFINDFILEINPATHCALLBACKW cb, PVOID user)
Definition: path.c:367
int toupper(int c)
Definition: utclib.c:881
#define TRACE(s)
Definition: solgame.cpp:4
const WCHAR * process_getenv(const struct process *process, const WCHAR *name)
Definition: dbghelp.c:285
GLsizeiptr size
Definition: glext.h:5919
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define CP_UNIXCP
Definition: compat.h:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * get_dos_file_name(const WCHAR *filename)
Definition: path.c:671
static BOOL CALLBACK enum_dir_treeWA(PCWSTR name, PVOID user)
Definition: path.c:315
#define debugstr_a
Definition: kernel32.h:31
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:492
HANDLE WINAPI FindDebugInfoFile(PCSTR FileName, PCSTR SymbolPath, PSTR DebugFilePath)
Definition: path.c:66
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:34
#define swprintf(buf, format,...)
Definition: sprintf.c:56
#define WINAPI
Definition: msvc.h:6
const char file[]
Definition: icontest.c:11
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
BOOL search_unix_path(const WCHAR *name, const WCHAR *path, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param)
Definition: path.c:780
WCHAR filename[MAX_PATH]
Definition: path.c:464
#define SetLastError(x)
Definition: compat.h:500
BOOL WINAPI MakeSureDirectoryPathExists(PCSTR DirPath)
Definition: path.c:142
GLbitfield flags
Definition: glext.h:7161
static BOOL do_searchW(PCWSTR file, PWSTR buffer, BOOL recurse, PENUMDIRTREE_CALLBACKW cb, PVOID user)
Definition: path.c:221
BOOL WINAPI SearchTreeForFile(PCSTR root, PCSTR file, PSTR buffer)
Definition: path.c:273
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
BOOL path_find_symbol_file(const struct process *pcs, const struct module *module, PCSTR full_path, enum module_type type, const GUID *guid, DWORD dw1, DWORD dw2, WCHAR *buffer, BOOL *is_unmatched)
Definition: path.c:596
BOOL(CALLBACK * PFIND_DEBUG_FILE_CALLBACK)(_In_ HANDLE, _In_ PCSTR, _In_ PVOID)
Definition: dbghelp.h:1854
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
#define GENERIC_READ
Definition: compat.h:135
module_type
GLenum src
Definition: glext.h:6340
#define wcsrchr
Definition: compat.h:16
_In_ HANDLE hFile
Definition: mswsock.h:90
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp)
PFINDFILEINPATHCALLBACKW cb
Definition: path.c:343
#define SYMOPT_LOAD_ANYTHING
Definition: compat.h:739
const GUID * guid
Definition: path.c:461
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1297
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static BOOL is_sepA(char ch)
Definition: path.c:34
static unsigned __int64 next
Definition: rand_nt.c:6
#define lstrcpyW
Definition: compat.h:497
const char * file_nameA(const char *str)
Definition: path.c:37
#define ARRAY_SIZE(a)
Definition: main.h:24
signed char * PSTR
Definition: retypes.h:7
GLenum GLenum dst
Definition: glext.h:6340
HANDLE WINAPI FindExecutableImageExW(PCWSTR FileName, PCWSTR SymbolPath, PWSTR ImageFilePath, PFIND_EXE_FILE_CALLBACKW Callback, PVOID user)
Definition: path.c:100
Definition: path.c:341
unsigned dbghelp_options
Definition: dbghelp.c:73
#define PAGE_READONLY
Definition: compat.h:138
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:168
#define MultiByteToWideChar
Definition: compat.h:110
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define RtlImageNtHeader
Definition: compat.h:554
#define CreateFileW
Definition: compat.h:489
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
Definition: name.c:38
PENUMDIRTREE_CALLBACK cb
Definition: path.c:310
DWORD dw1
Definition: path.c:462
void * user
Definition: path.c:344
const char * PCSTR
Definition: typedefs.h:52
#define towupper(c)
Definition: wctype.h:99
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:488
GLfloat GLfloat p
Definition: glext.h:8902
BOOL(CALLBACK * PFINDFILEINPATHCALLBACK)(_In_ PCSTR, _In_ PVOID)
Definition: dbghelp.h:1902
#define UnmapViewOfFile
Definition: compat.h:494
const char * filename
static const WCHAR fileW[]
Definition: url.c:111
BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL(*match)(void *, HANDLE, const WCHAR *), void *param)
Definition: path.c:695
LPFNPSPCALLBACK Callback
Definition: desk.c:112
IMAGEHLP_MODULEW64 module
WCHAR *CDECL wine_get_dos_file_name(LPCSTR str)
Definition: path.c:42
void user(int argc, const char *argv[])
Definition: cmds.c:1350
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
DWORD dw2
Definition: path.c:463
BOOL WINAPI SearchTreeForFileW(PCWSTR root, PCWSTR file, PWSTR buffer)
Definition: path.c:262
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
Definition: fci.c:126
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502