Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensource.c
Go to the documentation of this file.
00001 /* 00002 * File source.c - source files management 00003 * 00004 * Copyright (C) 2004, Eric Pouech. 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 * 00020 */ 00021 #include "config.h" 00022 #include <stdlib.h> 00023 #include <stdio.h> 00024 #include <string.h> 00025 #include <assert.h> 00026 00027 #include "dbghelp_private.h" 00028 #include "wine/debug.h" 00029 00030 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); 00031 00032 static struct module* rb_module; 00033 struct source_rb 00034 { 00035 struct wine_rb_entry entry; 00036 unsigned source; 00037 }; 00038 00039 static void *source_rb_alloc(size_t size) 00040 { 00041 return HeapAlloc(GetProcessHeap(), 0, size); 00042 } 00043 00044 static void *source_rb_realloc(void *ptr, size_t size) 00045 { 00046 return HeapReAlloc(GetProcessHeap(), 0, ptr, size); 00047 } 00048 00049 static void source_rb_free(void *ptr) 00050 { 00051 HeapFree(GetProcessHeap(), 0, ptr); 00052 } 00053 00054 static int source_rb_compare(const void *key, const struct wine_rb_entry *entry) 00055 { 00056 const struct source_rb *t = WINE_RB_ENTRY_VALUE(entry, const struct source_rb, entry); 00057 00058 return strcmp((const char*)key, rb_module->sources + t->source); 00059 } 00060 00061 const struct wine_rb_functions source_rb_functions = 00062 { 00063 source_rb_alloc, 00064 source_rb_realloc, 00065 source_rb_free, 00066 source_rb_compare, 00067 }; 00068 00069 /****************************************************************** 00070 * source_find 00071 * 00072 * check whether a source file has already been stored 00073 */ 00074 static unsigned source_find(const char* name) 00075 { 00076 struct wine_rb_entry* e; 00077 00078 e = wine_rb_get(&rb_module->sources_offsets_tree, name); 00079 if (!e) return -1; 00080 return WINE_RB_ENTRY_VALUE(e, struct source_rb, entry)->source; 00081 } 00082 00083 /****************************************************************** 00084 * source_new 00085 * 00086 * checks if source exists. if not, add it 00087 */ 00088 unsigned source_new(struct module* module, const char* base, const char* name) 00089 { 00090 unsigned ret = -1; 00091 const char* full; 00092 char* tmp = NULL; 00093 00094 if (!name) return ret; 00095 if (!base || *name == '/') 00096 full = name; 00097 else 00098 { 00099 unsigned bsz = strlen(base); 00100 00101 tmp = HeapAlloc(GetProcessHeap(), 0, bsz + 1 + strlen(name) + 1); 00102 if (!tmp) return ret; 00103 full = tmp; 00104 strcpy(tmp, base); 00105 if (tmp[bsz - 1] != '/') tmp[bsz++] = '/'; 00106 strcpy(&tmp[bsz], name); 00107 } 00108 rb_module = module; 00109 if (!module->sources || (ret = source_find(full)) == (unsigned)-1) 00110 { 00111 char* new; 00112 int len = strlen(full) + 1; 00113 struct source_rb* rb; 00114 00115 if (module->sources_used + len + 1 > module->sources_alloc) 00116 { 00117 if (!module->sources) 00118 { 00119 module->sources_alloc = (module->sources_used + len + 1 + 255) & ~255; 00120 new = HeapAlloc(GetProcessHeap(), 0, module->sources_alloc); 00121 } 00122 else 00123 { 00124 module->sources_alloc = max( module->sources_alloc * 2, 00125 (module->sources_used + len + 1 + 255) & ~255 ); 00126 new = HeapReAlloc(GetProcessHeap(), 0, module->sources, 00127 module->sources_alloc); 00128 } 00129 if (!new) goto done; 00130 module->sources = new; 00131 } 00132 ret = module->sources_used; 00133 memcpy(module->sources + module->sources_used, full, len); 00134 module->sources_used += len; 00135 module->sources[module->sources_used] = '\0'; 00136 if ((rb = pool_alloc(&module->pool, sizeof(*rb)))) 00137 { 00138 rb->source = ret; 00139 wine_rb_put(&module->sources_offsets_tree, full, &rb->entry); 00140 } 00141 } 00142 done: 00143 HeapFree(GetProcessHeap(), 0, tmp); 00144 return ret; 00145 } 00146 00147 /****************************************************************** 00148 * source_get 00149 * 00150 * returns a stored source file name 00151 */ 00152 const char* source_get(const struct module* module, unsigned idx) 00153 { 00154 if (idx == -1) return ""; 00155 assert(module->sources); 00156 return module->sources + idx; 00157 } 00158 00159 /****************************************************************** 00160 * SymEnumSourceFilesW (DBGHELP.@) 00161 * 00162 */ 00163 BOOL WINAPI SymEnumSourceFilesW(HANDLE hProcess, ULONG64 ModBase, PCWSTR Mask, 00164 PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles, 00165 PVOID UserContext) 00166 { 00167 struct module_pair pair; 00168 SOURCEFILEW sf; 00169 char* ptr; 00170 WCHAR* conversion_buffer = NULL; 00171 DWORD conversion_buffer_len = 0; 00172 00173 if (!cbSrcFiles) return FALSE; 00174 pair.pcs = process_find_by_handle(hProcess); 00175 if (!pair.pcs) return FALSE; 00176 00177 if (ModBase) 00178 { 00179 pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN); 00180 if (!module_get_debug(&pair)) return FALSE; 00181 } 00182 else 00183 { 00184 if (Mask[0] == '!') 00185 { 00186 pair.requested = module_find_by_nameW(pair.pcs, Mask + 1); 00187 if (!module_get_debug(&pair)) return FALSE; 00188 } 00189 else 00190 { 00191 FIXME("Unsupported yet (should get info from current context)\n"); 00192 return FALSE; 00193 } 00194 } 00195 if (!pair.effective->sources) return FALSE; 00196 for (ptr = pair.effective->sources; *ptr; ptr += strlen(ptr) + 1) 00197 { 00198 DWORD len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0); 00199 00200 if (len > conversion_buffer_len) 00201 { 00202 HeapFree(GetProcessHeap(), 0, conversion_buffer); 00203 conversion_buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00204 if (!conversion_buffer) return FALSE; 00205 conversion_buffer_len = len; 00206 } 00207 00208 MultiByteToWideChar(CP_ACP, 0, ptr, -1, conversion_buffer, len); 00209 00210 /* FIXME: not using Mask */ 00211 sf.ModBase = ModBase; 00212 sf.FileName = conversion_buffer; 00213 if (!cbSrcFiles(&sf, UserContext)) break; 00214 } 00215 00216 HeapFree(GetProcessHeap(), 0, conversion_buffer); 00217 return TRUE; 00218 } 00219 00220 struct enum_sources_files_context 00221 { 00222 PSYM_ENUMSOURCEFILES_CALLBACK callbackA; 00223 PVOID caller_context; 00224 char *conversion_buffer; 00225 DWORD conversion_buffer_len; 00226 DWORD callback_error; 00227 }; 00228 00229 static BOOL CALLBACK enum_source_files_W_to_A(PSOURCEFILEW source_file, PVOID context) 00230 { 00231 struct enum_sources_files_context *ctx = context; 00232 SOURCEFILE source_fileA; 00233 DWORD len; 00234 00235 len = WideCharToMultiByte(CP_ACP, 0, source_file->FileName, -1, NULL, 0, NULL, NULL); 00236 if (len > ctx->conversion_buffer_len) 00237 { 00238 char *ptr = ctx->conversion_buffer ? HeapReAlloc(GetProcessHeap(), 0, ctx->conversion_buffer, len) : 00239 HeapAlloc(GetProcessHeap(), 0, len); 00240 00241 if (!ptr) 00242 { 00243 ctx->callback_error = ERROR_OUTOFMEMORY; 00244 return FALSE; 00245 } 00246 00247 ctx->conversion_buffer = ptr; 00248 ctx->conversion_buffer_len = len; 00249 } 00250 00251 WideCharToMultiByte(CP_ACP, 0, source_file->FileName, -1, ctx->conversion_buffer, len, NULL, NULL); 00252 00253 source_fileA.ModBase = source_file->ModBase; 00254 source_fileA.FileName = ctx->conversion_buffer; 00255 return ctx->callbackA(&source_fileA, ctx->caller_context); 00256 } 00257 00258 /****************************************************************** 00259 * SymEnumSourceFiles (DBGHELP.@) 00260 * 00261 */ 00262 BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask, 00263 PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, 00264 PVOID UserContext) 00265 { 00266 WCHAR *maskW = NULL; 00267 PSYM_ENUMSOURCEFILES_CALLBACKW callbackW; 00268 PVOID context; 00269 struct enum_sources_files_context callback_context = {cbSrcFiles, UserContext}; 00270 BOOL ret; 00271 00272 if (Mask) 00273 { 00274 DWORD len = MultiByteToWideChar(CP_ACP, 0, Mask, -1, NULL, 0); 00275 00276 maskW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 00277 if (!maskW) 00278 { 00279 SetLastError(ERROR_OUTOFMEMORY); 00280 return FALSE; 00281 } 00282 00283 MultiByteToWideChar(CP_ACP, 0, Mask, -1, maskW, len); 00284 } 00285 00286 if (cbSrcFiles) 00287 { 00288 callbackW = enum_source_files_W_to_A; 00289 context = &callback_context; 00290 } 00291 else 00292 { 00293 callbackW = NULL; 00294 context = UserContext; 00295 } 00296 00297 ret = SymEnumSourceFilesW(hProcess, ModBase, maskW, callbackW, context); 00298 00299 if (callback_context.callback_error) 00300 { 00301 SetLastError(callback_context.callback_error); 00302 ret = FALSE; 00303 } 00304 00305 HeapFree(GetProcessHeap(), 0, callback_context.conversion_buffer); 00306 HeapFree(GetProcessHeap(), 0, maskW); 00307 00308 return ret; 00309 } 00310 00311 /****************************************************************** 00312 * SymEnumSourceLines (DBGHELP.@) 00313 * 00314 */ 00315 BOOL WINAPI SymEnumSourceLines(HANDLE hProcess, ULONG64 base, PCSTR obj, 00316 PCSTR file, DWORD line, DWORD flags, 00317 PSYM_ENUMLINES_CALLBACK EnumLinesCallback, 00318 PVOID UserContext) 00319 { 00320 FIXME("%p %s %s %s %u %u %p %p: stub!\n", 00321 hProcess, wine_dbgstr_longlong(base), debugstr_a(obj), debugstr_a(file), 00322 line, flags, EnumLinesCallback, UserContext); 00323 SetLastError(ERROR_NOT_SUPPORTED); 00324 return FALSE; 00325 } 00326 00327 /****************************************************************** 00328 * SymEnumSourceLinesW(DBGHELP.@) 00329 * 00330 */ 00331 BOOL WINAPI SymEnumSourceLinesW(HANDLE hProcess, ULONG64 base, PCWSTR obj, 00332 PCWSTR file, DWORD line, DWORD flags, 00333 PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, 00334 PVOID UserContext) 00335 { 00336 FIXME("%p %s %s %s %u %u %p %p: stub!\n", 00337 hProcess, wine_dbgstr_longlong(base), debugstr_w(obj), debugstr_w(file), 00338 line, flags, EnumLinesCallback, UserContext); 00339 SetLastError(ERROR_NOT_SUPPORTED); 00340 return FALSE; 00341 } 00342 00343 /****************************************************************** 00344 * SymGetSourceFileToken (DBGHELP.@) 00345 * 00346 */ 00347 BOOL WINAPI SymGetSourceFileToken(HANDLE hProcess, ULONG64 base, 00348 PCSTR src, PVOID* token, DWORD* size) 00349 { 00350 FIXME("%p %s %s %p %p: stub!\n", 00351 hProcess, wine_dbgstr_longlong(base), debugstr_a(src), token, size); 00352 SetLastError(ERROR_NOT_SUPPORTED); 00353 return FALSE; 00354 } 00355 00356 /****************************************************************** 00357 * SymGetSourceFileTokenW (DBGHELP.@) 00358 * 00359 */ 00360 BOOL WINAPI SymGetSourceFileTokenW(HANDLE hProcess, ULONG64 base, 00361 PCWSTR src, PVOID* token, DWORD* size) 00362 { 00363 FIXME("%p %s %s %p %p: stub!\n", 00364 hProcess, wine_dbgstr_longlong(base), debugstr_w(src), token, size); 00365 SetLastError(ERROR_NOT_SUPPORTED); 00366 return FALSE; 00367 } Generated on Sat May 26 2012 04:22:01 for ReactOS by
1.7.6.1
|