⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpp.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
static const rtti_object_hierachy __non_rtti_object_type_hierachy =
{
  0,
  0,
  3,
  &__non_rtti_object_rtti_base_array
};

static const rtti_object_locator __non_rtti_object_rtti =
{
  0,
  0,
  0,
  &__non_rtti_object_type_info,
  &__non_rtti_object_type_hierachy
};

static const cxx_type_info __non_rtti_object_cxx_type_info =
{
  0,
  &__non_rtti_object_type_info,
  0,
  -1,
  0,
  sizeof(exception),
  (cxx_copy_ctor)__thiscall_MSVCRT___non_rtti_object_copy_ctor
};

static type_info type_info_type_info =
{
  (void*)&MSVCRT_type_info_vtable,
  NULL,
  ".?AVtype_info@@"
};

static const rtti_base_descriptor type_info_rtti_base_descriptor =
{
  &type_info_type_info,
  0,
  0,
  0xffffffff,
  0,
  0
};

static const rtti_base_array type_info_rtti_base_array =
{
  {
    &type_info_rtti_base_descriptor,
    NULL,
    NULL
  }
};

static const rtti_object_hierachy type_info_type_hierachy =
{
  0,
  0,
  1,
  &type_info_rtti_base_array
};

static const rtti_object_locator type_info_rtti =
{
  0,
  0,
  0,
  &type_info_type_info,
  &type_info_type_hierachy
};

/*
 * Exception RTTI for cpp objects
 */
static const cxx_type_info_table bad_cast_type_info_table =
{
  3,
  {
   &__non_rtti_object_cxx_type_info,
   &bad_typeid_cxx_type_info,
   &exception_cxx_type_info
  }
};

static const cxx_exception_type bad_cast_exception_type =
{
  0,
  (void*)__thiscall_MSVCRT_bad_cast_dtor,
  NULL,
  &bad_cast_type_info_table
};

static const cxx_type_info_table bad_typeid_type_info_table =
{
  2,
  {
   &bad_cast_cxx_type_info,
   &exception_cxx_type_info,
   NULL
  }
};

static const cxx_exception_type bad_typeid_exception_type =
{
  0,
  (void*)__thiscall_MSVCRT_bad_typeid_dtor,
  NULL,
  &bad_cast_type_info_table
};

static const cxx_exception_type __non_rtti_object_exception_type =
{
  0,
  (void*)__thiscall_MSVCRT___non_rtti_object_dtor,
  NULL,
  &bad_typeid_type_info_table
};

#endif  /* __i386__ */


/******************************************************************
 *		?set_terminate@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
 *
 * Install a handler to be called when terminate() is called.
 *
 * PARAMS
 *  func [I] Handler function to install
 *
 * RETURNS
 *  The previously installed handler function, if any.
 */
terminate_function MSVCRT_set_terminate(terminate_function func)
{
    MSVCRT_thread_data *data = msvcrt_get_thread_data();
    terminate_function previous = data->terminate_handler;
    TRACE("(%p) returning %p\n",func,previous);
    data->terminate_handler = func;
    return previous;
}

/******************************************************************
 *		?set_unexpected@@YAP6AXXZP6AXXZ@Z (MSVCRT.@)
 *
 * Install a handler to be called when unexpected() is called.
 *
 * PARAMS
 *  func [I] Handler function to install
 *
 * RETURNS
 *  The previously installed handler function, if any.
 */
unexpected_function MSVCRT_set_unexpected(unexpected_function func)
{
    MSVCRT_thread_data *data = msvcrt_get_thread_data();
    unexpected_function previous = data->unexpected_handler;
    TRACE("(%p) returning %p\n",func,previous);
    data->unexpected_handler = func;
    return previous;
}

/******************************************************************
 *              ?_set_se_translator@@YAP6AXIPAU_EXCEPTION_POINTERS@@@ZP6AXI0@Z@Z  (MSVCRT.@)
 */
_se_translator_function MSVCRT__set_se_translator(_se_translator_function func)
{
    MSVCRT_thread_data *data = msvcrt_get_thread_data();
    _se_translator_function previous = data->se_translator;
    TRACE("(%p) returning %p\n",func,previous);
    data->se_translator = func;
    return previous;
}

/******************************************************************
 *		?terminate@@YAXXZ (MSVCRT.@)
 *
 * Default handler for an unhandled exception.
 *
 * PARAMS
 *  None.
 *
 * RETURNS
 *  This function does not return. Either control resumes from any
 *  handler installed by calling set_terminate(), or (by default) abort()
 *  is called.
 */
void MSVCRT_terminate(void)
{
    MSVCRT_thread_data *data = msvcrt_get_thread_data();
    if (data->terminate_handler) data->terminate_handler();
    abort();
}

/******************************************************************
 *		?unexpected@@YAXXZ (MSVCRT.@)
 */
void MSVCRT_unexpected(void)
{
    MSVCRT_thread_data *data = msvcrt_get_thread_data();
    if (data->unexpected_handler) data->unexpected_handler();
    MSVCRT_terminate();
}

/* Get type info from an object (internal) */
static const rtti_object_locator* RTTI_GetObjectLocator(type_info *cppobj)
{
  const rtti_object_locator *obj_locator = NULL;

#ifdef __i386__
  const exception_vtable* vtable = (const exception_vtable*)cppobj->vtable;

  /* Perhaps this is one of classes we export? */
  if (vtable == &MSVCRT_exception_vtable)
  {
    TRACE("returning exception_rtti\n");
    return &exception_rtti;
  }
  else if (vtable == &MSVCRT_bad_typeid_vtable)
  {
    TRACE("returning bad_typeid_rtti\n");
    return &bad_typeid_rtti;
  }
  else if (vtable == &MSVCRT_bad_cast_vtable)
  {
    TRACE("returning bad_cast_rtti\n");
    return &bad_cast_rtti;
  }
  else if (vtable == &MSVCRT___non_rtti_object_vtable)
  {
    TRACE("returning __non_rtti_object_rtti\n");
    return &__non_rtti_object_rtti;
  }
  else if (vtable == &MSVCRT_type_info_vtable)
  {
    TRACE("returning type_info_rtti\n");
    return &type_info_rtti;
  }
#endif

  if (!IsBadReadPtr(cppobj, sizeof(void *)) &&
      !IsBadReadPtr(cppobj->vtable - 1,sizeof(void *)) &&
      !IsBadReadPtr((void*)cppobj->vtable[-1], sizeof(rtti_object_locator)))
  {
    obj_locator = (rtti_object_locator *)cppobj->vtable[-1];
    TRACE("returning type_info from vtable (%p)\n", obj_locator);
  }

  return obj_locator;
}

/******************************************************************
 *		__RTtypeid (MSVCRT.@)
 *
 * Retrieve the Run Time Type Information (RTTI) for a C++ object.
 *
 * PARAMS
 *  cppobj [I] C++ object to get type information for.
 *
 * RETURNS
 *  Success: A type_info object describing cppobj.
 *  Failure: If the object to be cast has no RTTI, a __non_rtti_object
 *           exception is thrown. If cppobj is NULL, a bad_typeid exception
 *           is thrown. In either case, this function does not return.
 *
 * NOTES
 *  This function is usually called by compiler generated code as a result
 *  of using one of the C++ dynamic cast statements.
 */
type_info* MSVCRT___RTtypeid(type_info *cppobj)
{
  const rtti_object_locator *obj_locator = RTTI_GetObjectLocator(cppobj);

#ifdef __i386__
  if (!obj_locator)
  {
    static const char* szNullPtr = "Attempted a typeid of NULL pointer!";
    static const char* szBadPtr = "Bad read pointer - no RTTI data!";
    const cxx_exception_type *e_type;
    exception e;

    /* Throw a bad_typeid or __non_rtti_object exception */
    if (!cppobj)
    {
      EXCEPTION_ctor(&e, &szNullPtr);
      e.vtable = &MSVCRT_bad_typeid_vtable;
      e_type = &bad_typeid_exception_type;
    }
    else
    {
      EXCEPTION_ctor(&e, &szBadPtr);
      e.vtable = &MSVCRT___non_rtti_object_vtable;
      e_type = &__non_rtti_object_exception_type;
    }

    _CxxThrowException(&e, e_type);
    DebugBreak();
  }
  return obj_locator->type_descriptor;
#else
  return NULL;
#endif
}

/******************************************************************
 *		__RTDynamicCast (MSVCRT.@)
 *
 * Dynamically cast a C++ object to one of its base classes.
 *
 * PARAMS
 *  cppobj   [I] Any C++ object to cast
 *  unknown  [I] Reserved, set to 0
 *  src      [I] type_info object describing cppobj
 *  dst      [I] type_info object describing the base class to cast to
 *  do_throw [I] TRUE = throw an exception if the cast fails, FALSE = don't
 *
 * RETURNS
 *  Success: The address of cppobj, cast to the object described by dst.
 *  Failure: NULL, If the object to be cast has no RTTI, or dst is not a
 *           valid cast for cppobj. If do_throw is TRUE, a bad_cast exception
 *           is thrown and this function does not return.
 *
 * NOTES
 *  This function is usually called by compiler generated code as a result
 *  of using one of the C++ dynamic cast statements.
 */
void* MSVCRT___RTDynamicCast(type_info *cppobj, int unknown,
                             type_info *src, type_info *dst,
                             int do_throw)
{
  const rtti_object_locator *obj_locator;

  /* Note: cppobj _isn't_ a type_info, we use that struct for its vtable ptr */
  TRACE("(%p,%d,%p,%p,%d)\n", cppobj, unknown, src, dst, do_throw);
  if (!cppobj)
    return 0;
  obj_locator= RTTI_GetObjectLocator(cppobj);
  if (unknown)
    FIXME("Unknown parameter is non-zero: please report\n");

  /* To cast an object at runtime:
   * 1.Find out the true type of the object from the typeinfo at vtable[-1]
   * 2.Search for the destination type in the class heirachy
   * 3.If destination type is found, return base object address + dest offset
   *   Otherwise, fail the cast
   */
  if (obj_locator)
  {
    int count = 0;
    const rtti_object_hierachy *obj_bases = obj_locator->type_hierachy;
    const rtti_base_descriptor* const *base_desc = obj_bases->base_classes->bases;
    int src_offset = obj_locator->base_class_offset, dst_offset = -1;

    while (count < obj_bases->array_len)
    {
      const type_info *typ = (*base_desc)->type_descriptor;

      if (!strcmp(typ->mangled, dst->mangled))
      {
        dst_offset = (*base_desc)->base_class_offset;
        break;
      }
      base_desc++;
      count++;
    }
    if (dst_offset >= 0)
      return (void*)((unsigned long)cppobj - src_offset + dst_offset);
  }

#ifdef __i386__
  /* VC++ sets do_throw to 1 when the result of a dynamic_cast is assigned
   * to a reference, since references cannot be NULL.
   */
  if (do_throw)
  {
    static const char* exception_text = "Bad dynamic_cast!";
    exception e;

    /* Throw a bad_cast exception */
    EXCEPTION_ctor(&e, &exception_text);
    e.vtable = &MSVCRT_bad_cast_vtable;
    _CxxThrowException(&e, &bad_cast_exception_type);
    DebugBreak();
  }
#endif
  return NULL;
}


/******************************************************************
 *		__RTCastToVoid (MSVCRT.@)
 *
 * Dynamically cast a C++ object to a void*.
 *
 * PARAMS
 *  cppobj [I] The C++ object to cast
 *
 * RETURNS
 *  Success: The base address of the object as a void*.
 *  Failure: NULL, if cppobj is NULL or has no RTTI.
 *
 * NOTES
 *  This function is usually called by compiler generated code as a result
 *  of using one of the C++ dynamic cast statements.
 */
void* MSVCRT___RTCastToVoid(type_info *cppobj)
{
  const rtti_object_locator *obj_locator = RTTI_GetObjectLocator(cppobj);

  /* Note: cppobj _isn't_ a type_info, we use that struct for its vtable ptr */
  TRACE("(%p)\n", cppobj);

  /* Casts to void* simply cast to the base object */
  if (obj_locator)
    return (void*)((unsigned long)cppobj - obj_locator->base_class_offset);
  return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -