ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

source.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.