Added tests for CryptSetProviderEx.
[wine/wine-kai.git] / dlls / dbghelp / type.c
blob5595b9e6f696d47a5945d57f9c5d232aa2efbc93
1 /*
2 * File types.c - management of types (hierarchical tree)
4 * Copyright (C) 1997, Eric Youngdale.
5 * 2004, Eric Pouech.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * Note: This really doesn't do much at the moment, but it forms the framework
22 * upon which full support for datatype handling will eventually be built.
24 #include "config.h"
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <assert.h>
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winreg.h"
32 #include "winnls.h"
33 #include "wine/debug.h"
34 #include "dbghelp_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
37 WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt);
39 static const char* symt_get_tag_str(DWORD tag)
41 switch (tag)
43 case SymTagNull: return "SymTagNull";
44 case SymTagExe: return "SymTagExe";
45 case SymTagCompiland: return "SymTagCompiland";
46 case SymTagCompilandDetails: return "SymTagCompilandDetails";
47 case SymTagCompilandEnv: return "SymTagCompilandEnv";
48 case SymTagFunction: return "SymTagFunction";
49 case SymTagBlock: return "SymTagBlock";
50 case SymTagData: return "SymTagData";
51 case SymTagAnnotation: return "SymTagAnnotation";
52 case SymTagLabel: return "SymTagLabel";
53 case SymTagPublicSymbol: return "SymTagPublicSymbol";
54 case SymTagUDT: return "SymTagUDT";
55 case SymTagEnum: return "SymTagEnum";
56 case SymTagFunctionType: return "SymTagFunctionType";
57 case SymTagPointerType: return "SymTagPointerType";
58 case SymTagArrayType: return "SymTagArrayType";
59 case SymTagBaseType: return "SymTagBaseType";
60 case SymTagTypedef: return "SymTagTypedef,";
61 case SymTagBaseClass: return "SymTagBaseClass";
62 case SymTagFriend: return "SymTagFriend";
63 case SymTagFunctionArgType: return "SymTagFunctionArgType,";
64 case SymTagFuncDebugStart: return "SymTagFuncDebugStart,";
65 case SymTagFuncDebugEnd: return "SymTagFuncDebugEnd";
66 case SymTagUsingNamespace: return "SymTagUsingNamespace,";
67 case SymTagVTableShape: return "SymTagVTableShape";
68 case SymTagVTable: return "SymTagVTable";
69 case SymTagCustom: return "SymTagCustom";
70 case SymTagThunk: return "SymTagThunk";
71 case SymTagCustomType: return "SymTagCustomType";
72 case SymTagManagedType: return "SymTagManagedType";
73 case SymTagDimension: return "SymTagDimension";
74 default: return "---";
78 const char* symt_get_name(const struct symt* sym)
80 switch (sym->tag)
82 /* lexical tree */
83 case SymTagData: return ((const struct symt_data*)sym)->hash_elt.name;
84 case SymTagFunction: return ((const struct symt_function*)sym)->hash_elt.name;
85 case SymTagPublicSymbol: return ((const struct symt_public*)sym)->hash_elt.name;
86 case SymTagBaseType: return ((const struct symt_basic*)sym)->hash_elt.name;
87 case SymTagLabel: return ((const struct symt_function_point*)sym)->name;
88 case SymTagThunk: return ((const struct symt_thunk*)sym)->hash_elt.name;
89 /* hierarchy tree */
90 case SymTagEnum: return ((const struct symt_enum*)sym)->name;
91 case SymTagTypedef: return ((const struct symt_typedef*)sym)->hash_elt.name;
92 case SymTagUDT: return ((const struct symt_udt*)sym)->hash_elt.name;
93 default:
94 FIXME("Unsupported sym-tag %s\n", symt_get_tag_str(sym->tag));
95 /* fall through */
96 case SymTagArrayType:
97 case SymTagPointerType:
98 case SymTagFunctionType:
99 return NULL;
103 static struct symt* symt_find_type_by_name(struct module* module,
104 enum SymTagEnum sym_tag,
105 const char* typename)
107 void* ptr;
108 struct symt_ht* type;
109 struct hash_table_iter hti;
111 assert(typename);
112 assert(module);
114 hash_table_iter_init(&module->ht_types, &hti, typename);
115 while ((ptr = hash_table_iter_up(&hti)))
117 type = GET_ENTRY(ptr, struct symt_ht, hash_elt);
119 if ((sym_tag == SymTagNull || type->symt.tag == sym_tag) &&
120 type->hash_elt.name && !strcmp(type->hash_elt.name, typename))
121 return &type->symt;
123 SetLastError(ERROR_INVALID_NAME); /* FIXME ?? */
124 return NULL;
127 struct symt_basic* symt_new_basic(struct module* module, enum BasicType bt,
128 const char* typename, unsigned size)
130 struct symt_basic* sym;
132 if (typename)
134 sym = (struct symt_basic*)symt_find_type_by_name(module, SymTagBaseType,
135 typename);
136 if (sym && sym->bt == bt && sym->size == size)
137 return sym;
139 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
141 sym->symt.tag = SymTagBaseType;
142 if (typename)
144 sym->hash_elt.name = pool_strdup(&module->pool, typename);
145 hash_table_add(&module->ht_types, &sym->hash_elt);
146 } else sym->hash_elt.name = NULL;
147 sym->bt = bt;
148 sym->size = size;
150 return sym;
153 struct symt_udt* symt_new_udt(struct module* module, const char* typename,
154 unsigned size, enum UdtKind kind)
156 struct symt_udt* sym;
158 TRACE_(dbghelp_symt)("Adding udt %s:%s\n", module->module.ModuleName, typename);
159 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
161 sym->symt.tag = SymTagUDT;
162 sym->kind = kind;
163 sym->size = size;
164 if (typename)
166 sym->hash_elt.name = pool_strdup(&module->pool, typename);
167 hash_table_add(&module->ht_types, &sym->hash_elt);
168 } else sym->hash_elt.name = NULL;
169 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
171 return sym;
174 BOOL symt_set_udt_size(struct module* module, struct symt_udt* udt, unsigned size)
176 assert(udt->symt.tag == SymTagUDT);
177 if (vector_length(&udt->vchildren) != 0)
179 if (udt->size != size)
180 FIXME_(dbghelp_symt)("Changing size for %s from %u to %u\n",
181 udt->hash_elt.name, udt->size, size);
182 return TRUE;
184 udt->size = size;
185 return TRUE;
188 /******************************************************************
189 * symt_add_udt_element
191 * add an element to a udt (struct, class, union)
192 * the size & offset parameters are expressed in bits (not bytes) so that
193 * we can mix in the single call bytes aligned elements (regular fields) and
194 * the others (bit fields)
196 BOOL symt_add_udt_element(struct module* module, struct symt_udt* udt_type,
197 const char* name, struct symt* elt_type,
198 unsigned offset, unsigned size)
200 struct symt_data* m;
201 struct symt** p;
203 assert(udt_type->symt.tag == SymTagUDT);
205 TRACE_(dbghelp_symt)("Adding %s to UDT %s\n", name, udt_type->hash_elt.name);
206 p = NULL;
207 while ((p = vector_iter_up(&udt_type->vchildren, p)))
209 m = (struct symt_data*)*p;
210 assert(m);
211 assert(m->symt.tag == SymTagData);
212 if (m->hash_elt.name[0] == name[0] && strcmp(m->hash_elt.name, name) == 0)
213 return TRUE;
216 if ((m = pool_alloc(&module->pool, sizeof(*m))) == NULL) return FALSE;
217 memset(m, 0, sizeof(*m));
218 m->symt.tag = SymTagData;
219 m->hash_elt.name = pool_strdup(&module->pool, name);
220 m->hash_elt.next = NULL;
222 m->kind = DataIsMember;
223 m->container = &udt_type->symt;
224 m->type = elt_type;
225 m->u.s.offset = offset;
226 m->u.s.length = ((offset & 7) || (size & 7)) ? size : 0;
227 m->u.s.reg_id = 0;
228 p = vector_add(&udt_type->vchildren, &module->pool);
229 *p = &m->symt;
231 return TRUE;
234 struct symt_enum* symt_new_enum(struct module* module, const char* typename)
236 struct symt_enum* sym;
238 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
240 sym->symt.tag = SymTagEnum;
241 sym->name = (typename) ? pool_strdup(&module->pool, typename) : NULL;
242 vector_init(&sym->vchildren, sizeof(struct symt*), 8);
244 return sym;
247 BOOL symt_add_enum_element(struct module* module, struct symt_enum* enum_type,
248 const char* name, int value)
250 struct symt_data* e;
251 struct symt** p;
253 assert(enum_type->symt.tag == SymTagEnum);
254 e = pool_alloc(&module->pool, sizeof(*e));
255 if (e == NULL) return FALSE;
257 e->symt.tag = SymTagData;
258 e->hash_elt.name = pool_strdup(&module->pool, name);
259 e->hash_elt.next = NULL;
260 e->kind = DataIsConstant;
261 e->container = &enum_type->symt;
262 /* CV defines the underlying type for the enumeration */
263 e->type = &symt_new_basic(module, btInt, "int", 4)->symt;
264 e->u.value.n1.n2.vt = VT_I4;
265 e->u.value.n1.n2.n3.lVal = value;
267 p = vector_add(&enum_type->vchildren, &module->pool);
268 if (!p) return FALSE; /* FIXME we leak e */
269 *p = &e->symt;
271 return TRUE;
274 struct symt_array* symt_new_array(struct module* module, int min, int max,
275 struct symt* base)
277 struct symt_array* sym;
279 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
281 sym->symt.tag = SymTagArrayType;
282 sym->start = min;
283 sym->end = max;
284 sym->basetype = base;
286 return sym;
289 struct symt_function_signature* symt_new_function_signature(struct module* module,
290 struct symt* ret_type)
292 struct symt_function_signature* sym;
294 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
296 sym->symt.tag = SymTagFunctionType;
297 sym->rettype = ret_type;
298 vector_init(&sym->vchildren, sizeof(struct symt*), 4);
300 return sym;
303 BOOL symt_add_function_signature_parameter(struct module* module,
304 struct symt_function_signature* sig_type,
305 struct symt* param)
307 struct symt** p;
309 assert(sig_type->symt.tag == SymTagFunctionType);
310 p = vector_add(&sig_type->vchildren, &module->pool);
311 if (!p) return FALSE; /* FIXME we leak e */
312 *p = param;
314 return TRUE;
317 struct symt_pointer* symt_new_pointer(struct module* module, struct symt* ref_type)
319 struct symt_pointer* sym;
321 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
323 sym->symt.tag = SymTagPointerType;
324 sym->pointsto = ref_type;
326 return sym;
329 struct symt_typedef* symt_new_typedef(struct module* module, struct symt* ref,
330 const char* name)
332 struct symt_typedef* sym;
334 if ((sym = pool_alloc(&module->pool, sizeof(*sym))))
336 sym->symt.tag = SymTagTypedef;
337 sym->type = ref;
338 sym->hash_elt.name = pool_strdup(&module->pool, name);
339 hash_table_add(&module->ht_types, &sym->hash_elt);
341 return sym;
344 /******************************************************************
345 * SymEnumTypes (DBGHELP.@)
348 BOOL WINAPI SymEnumTypes(HANDLE hProcess, unsigned long BaseOfDll,
349 PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
350 void* UserContext)
352 struct process* pcs;
353 struct module* module;
354 struct symt_ht* type;
355 void* ptr;
356 char buffer[sizeof(SYMBOL_INFO) + 256];
357 SYMBOL_INFO* sym_info = (SYMBOL_INFO*)buffer;
358 struct hash_table_iter hti;
359 const char* tmp;
361 TRACE("(%p %08lx %p %p)\n",
362 hProcess, BaseOfDll, EnumSymbolsCallback, UserContext);
364 if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
365 module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
366 if (!(module = module_get_debug(pcs, module))) return FALSE;
368 sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
369 sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
371 hash_table_iter_init(&module->ht_types, &hti, NULL);
372 while ((ptr = hash_table_iter_up(&hti)))
374 type = GET_ENTRY(ptr, struct symt_ht, hash_elt);
375 sym_info->TypeIndex = (DWORD)type;
376 sym_info->info = 0; /* FIXME */
377 symt_get_info(&type->symt, TI_GET_LENGTH, &sym_info->Size);
378 sym_info->ModBase = module->module.BaseOfImage;
379 sym_info->Flags = 0; /* FIXME */
380 sym_info->Value = 0; /* FIXME */
381 sym_info->Address = 0; /* FIXME */
382 sym_info->Register = 0; /* FIXME */
383 sym_info->Scope = 0; /* FIXME */
384 sym_info->Tag = type->symt.tag;
385 tmp = symt_get_name(&type->symt);
386 sym_info->NameLen = strlen(tmp) + 1;
387 strncpy(sym_info->Name, tmp, min(sym_info->NameLen, sym_info->MaxNameLen));
388 sym_info->Name[sym_info->MaxNameLen - 1] = '\0';
389 if (!EnumSymbolsCallback(sym_info, sym_info->Size, UserContext)) break;
391 return TRUE;
394 /******************************************************************
395 * symt_get_info
397 * Retrieves inforamtion about a symt (either symbol or type)
399 BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
400 void* pInfo)
402 unsigned len;
404 if (!type) return FALSE;
406 /* helper to typecast pInfo to its expected type (_t) */
407 #define X(_t) (*((_t*)pInfo))
409 switch (req)
411 case TI_FINDCHILDREN:
413 const struct vector* v;
414 struct symt** pt;
415 unsigned i;
416 TI_FINDCHILDREN_PARAMS* tifp = pInfo;
418 switch (type->tag)
420 case SymTagUDT: v = &((const struct symt_udt*)type)->vchildren; break;
421 case SymTagEnum: v = &((const struct symt_enum*)type)->vchildren; break;
422 case SymTagFunctionType: v = &((const struct symt_function_signature*)type)->vchildren; break;
423 case SymTagFunction: v = &((const struct symt_function*)type)->vchildren; break;
424 default:
425 FIXME("Unsupported sym-tag %s for find-children\n",
426 symt_get_tag_str(type->tag));
427 return FALSE;
429 for (i = 0; i < tifp->Count; i++)
431 if (!(pt = vector_at(v, tifp->Start + i))) return FALSE;
432 tifp->ChildId[i] = (DWORD)*pt;
435 break;
437 case TI_GET_ADDRESS:
438 switch (type->tag)
440 case SymTagData:
441 switch (((const struct symt_data*)type)->kind)
443 case DataIsGlobal:
444 case DataIsFileStatic:
445 X(DWORD) = ((const struct symt_data*)type)->u.address;
446 break;
447 default: return FALSE;
449 break;
450 case SymTagFunction:
451 X(DWORD) = ((const struct symt_function*)type)->address;
452 break;
453 case SymTagPublicSymbol:
454 X(DWORD) = ((const struct symt_public*)type)->address;
455 break;
456 case SymTagFuncDebugStart:
457 case SymTagFuncDebugEnd:
458 case SymTagLabel:
459 X(DWORD) = ((const struct symt_function_point*)type)->parent->address +
460 ((const struct symt_function_point*)type)->offset;
461 break;
462 case SymTagThunk:
463 X(DWORD) = ((const struct symt_thunk*)type)->address;
464 break;
465 default:
466 FIXME("Unsupported sym-tag %s for get-address\n",
467 symt_get_tag_str(type->tag));
468 return FALSE;
470 break;
472 case TI_GET_BASETYPE:
473 switch (type->tag)
475 case SymTagBaseType:
476 X(DWORD) = ((const struct symt_basic*)type)->bt;
477 break;
478 case SymTagEnum:
479 X(DWORD) = btInt;
480 break;
481 default:
482 return FALSE;
484 break;
486 case TI_GET_BITPOSITION:
487 if (type->tag != SymTagData ||
488 ((const struct symt_data*)type)->kind != DataIsMember ||
489 ((const struct symt_data*)type)->u.s.length == 0)
490 return FALSE;
491 X(DWORD) = ((const struct symt_data*)type)->u.s.offset & 7;
492 break;
494 case TI_GET_CHILDRENCOUNT:
495 switch (type->tag)
497 case SymTagUDT:
498 X(DWORD) = vector_length(&((const struct symt_udt*)type)->vchildren);
499 break;
500 case SymTagEnum:
501 X(DWORD) = vector_length(&((const struct symt_enum*)type)->vchildren);
502 break;
503 case SymTagFunctionType:
504 X(DWORD) = vector_length(&((const struct symt_function_signature*)type)->vchildren);
505 break;
506 case SymTagFunction:
507 X(DWORD) = vector_length(&((const struct symt_function*)type)->vchildren);
508 break;
509 case SymTagPointerType: /* MS does it that way */
510 case SymTagArrayType: /* MS does it that way */
511 case SymTagThunk: /* MS does it that way */
512 X(DWORD) = 0;
513 break;
514 default:
515 FIXME("Unsupported sym-tag %s for get-children-count\n",
516 symt_get_tag_str(type->tag));
517 /* fall through */
518 case SymTagData:
519 case SymTagPublicSymbol:
520 case SymTagBaseType:
521 return FALSE;
523 break;
525 case TI_GET_COUNT:
526 /* it seems that FunctionType also react to GET_COUNT (same value as
527 * GET_CHILDREN_COUNT ?, except for C++ methods, where it seems to
528 * also include 'this' (GET_CHILDREN_COUNT+1)
530 if (type->tag != SymTagArrayType) return FALSE;
531 X(DWORD) = ((const struct symt_array*)type)->end -
532 ((const struct symt_array*)type)->start + 1;
533 break;
535 case TI_GET_DATAKIND:
536 if (type->tag != SymTagData) return FALSE;
537 X(DWORD) = ((const struct symt_data*)type)->kind;
538 break;
540 case TI_GET_LENGTH:
541 switch (type->tag)
543 case SymTagBaseType:
544 X(DWORD) = ((const struct symt_basic*)type)->size;
545 break;
546 case SymTagFunction:
547 X(DWORD) = ((const struct symt_function*)type)->size;
548 break;
549 case SymTagPointerType:
550 X(DWORD) = sizeof(void*);
551 break;
552 case SymTagUDT:
553 X(DWORD) = ((const struct symt_udt*)type)->size;
554 break;
555 case SymTagEnum:
556 X(DWORD) = sizeof(int); /* FIXME: should be size of base-type of enum !!! */
557 break;
558 case SymTagData:
559 if (((const struct symt_data*)type)->kind != DataIsMember ||
560 !((const struct symt_data*)type)->u.s.length)
561 return FALSE;
562 X(DWORD) = ((const struct symt_data*)type)->u.s.length;
563 break;
564 case SymTagArrayType:
565 if (!symt_get_info(((const struct symt_array*)type)->basetype,
566 TI_GET_LENGTH, pInfo))
567 return FALSE;
568 X(DWORD) *= ((const struct symt_array*)type)->end -
569 ((const struct symt_array*)type)->start + 1;
570 break;
571 case SymTagPublicSymbol:
572 X(DWORD) = ((const struct symt_public*)type)->size;
573 break;
574 case SymTagTypedef:
575 return symt_get_info(((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
576 break;
577 case SymTagThunk:
578 X(DWORD) = ((const struct symt_thunk*)type)->size;
579 break;
580 default:
581 FIXME("Unsupported sym-tag %s for get-length\n",
582 symt_get_tag_str(type->tag));
583 return 0;
585 break;
587 case TI_GET_LEXICALPARENT:
588 switch (type->tag)
590 case SymTagBlock:
591 X(DWORD) = (DWORD)((const struct symt_block*)type)->container;
592 break;
593 case SymTagData:
594 X(DWORD) = (DWORD)((const struct symt_data*)type)->container;
595 break;
596 case SymTagFunction:
597 X(DWORD) = (DWORD)((const struct symt_function*)type)->container;
598 break;
599 case SymTagThunk:
600 X(DWORD) = (DWORD)((const struct symt_thunk*)type)->container;
601 break;
602 default:
603 FIXME("Unsupported sym-tag %s for get-lexical-parent\n",
604 symt_get_tag_str(type->tag));
605 return FALSE;
607 break;
609 case TI_GET_NESTED:
610 switch (type->tag)
612 case SymTagUDT:
613 case SymTagEnum:
614 X(DWORD) = 0;
615 break;
616 default:
617 return FALSE;
619 break;
621 case TI_GET_OFFSET:
622 switch (type->tag)
624 case SymTagData:
625 switch (((const struct symt_data*)type)->kind)
627 case DataIsParam:
628 case DataIsLocal:
629 case DataIsMember:
630 X(ULONG) = ((const struct symt_data*)type)->u.s.offset >> 3;
631 break;
632 default:
633 FIXME("Unknown kind (%u) for get-offset\n",
634 ((const struct symt_data*)type)->kind);
635 return FALSE;
637 break;
638 default:
639 FIXME("Unsupported sym-tag %s for get-offset\n",
640 symt_get_tag_str(type->tag));
641 return FALSE;
643 break;
645 case TI_GET_SYMNAME:
647 const char* name = symt_get_name(type);
648 if (!name) return FALSE;
649 len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0);
650 X(WCHAR*) = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
651 if (!X(WCHAR*)) return FALSE;
652 MultiByteToWideChar(CP_ACP, 0, name, -1, X(WCHAR*), len);
654 break;
656 case TI_GET_SYMTAG:
657 X(DWORD) = type->tag;
658 break;
660 case TI_GET_TYPE:
661 case TI_GET_TYPEID:
662 switch (type->tag)
664 /* hierarchical => hierarchical */
665 case SymTagArrayType:
666 X(DWORD) = (DWORD)((const struct symt_array*)type)->basetype;
667 break;
668 case SymTagPointerType:
669 X(DWORD) = (DWORD)((const struct symt_pointer*)type)->pointsto;
670 break;
671 case SymTagFunctionType:
672 X(DWORD) = (DWORD)((const struct symt_function_signature*)type)->rettype;
673 break;
674 case SymTagTypedef:
675 X(DWORD) = (DWORD)((const struct symt_typedef*)type)->type;
676 break;
677 /* lexical => hierarchical */
678 case SymTagData:
679 X(DWORD) = (DWORD)((const struct symt_data*)type)->type;
680 break;
681 case SymTagFunction:
682 X(DWORD) = (DWORD)((const struct symt_function*)type)->type;
683 break;
684 /* FIXME: should also work for enums and FunctionArgType */
685 default:
686 FIXME("Unsupported sym-tag %s for get-type\n",
687 symt_get_tag_str(type->tag));
688 case SymTagThunk:
689 return FALSE;
691 break;
693 case TI_GET_UDTKIND:
694 if (type->tag != SymTagUDT) return FALSE;
695 X(DWORD) = ((const struct symt_udt*)type)->kind;
696 break;
698 case TI_GET_VALUE:
699 if (type->tag != SymTagData || ((const struct symt_data*)type)->kind != DataIsConstant)
700 return FALSE;
701 X(VARIANT) = ((const struct symt_data*)type)->u.value;
702 break;
704 #undef X
706 case TI_GET_ADDRESSOFFSET:
707 case TI_GET_ARRAYINDEXTYPEID:
708 case TI_GET_CALLING_CONVENTION:
709 case TI_GET_CLASSPARENTID:
710 case TI_GET_SYMINDEX:
711 case TI_GET_THISADJUST:
712 case TI_GET_VIRTUALBASECLASS:
713 case TI_GET_VIRTUALBASEPOINTEROFFSET:
714 case TI_GET_VIRTUALTABLESHAPEID:
715 case TI_IS_EQUIV_TO:
716 FIXME("Unsupported GetInfo request (%u)\n", req);
717 return FALSE;
720 return TRUE;
723 /******************************************************************
724 * SymGetTypeInfo (DBGHELP.@)
727 BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, unsigned long ModBase,
728 ULONG TypeId, IMAGEHLP_SYMBOL_TYPE_INFO GetType,
729 PVOID pInfo)
731 struct process* pcs = process_find_by_handle(hProcess);
732 struct module* module;
734 if (!pcs) return FALSE;
736 module = module_find_by_addr(pcs, ModBase, DMT_UNKNOWN);
737 if (!(module = module_get_debug(pcs, module)))
739 FIXME("Someone didn't properly set ModBase (0x%08lx)\n", ModBase);
740 return FALSE;
743 return symt_get_info((struct symt*)TypeId, GetType, pInfo);
746 /******************************************************************
747 * SymGetTypeFromName (DBGHELP.@)
750 BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, unsigned long BaseOfDll,
751 LPSTR Name, PSYMBOL_INFO Symbol)
753 struct process* pcs = process_find_by_handle(hProcess);
754 struct module* module;
755 struct symt* type;
757 if (!pcs) return FALSE;
758 module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
759 if (!module) return FALSE;
760 type = symt_find_type_by_name(module, SymTagNull, Name);
761 if (!type) return FALSE;
762 Symbol->TypeIndex = (DWORD)type;
764 return TRUE;