352 lines
16 KiB
C
352 lines
16 KiB
C
/*
|
|
* msvcp71 specific functions
|
|
*
|
|
* Copyright 2010 Piotr Caban for CodeWeavers
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wine/unicode.h"
|
|
|
|
/* Copied from dlls/msvcrt/cpp.c */
|
|
#ifdef __i386__ /* thiscall functions are i386-specific */
|
|
|
|
#define THISCALL(func) __thiscall_ ## func
|
|
#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func)
|
|
#define __thiscall __stdcall
|
|
#define DEFINE_THISCALL_WRAPPER(func,args) \
|
|
extern void THISCALL(func)(void); \
|
|
__ASM_GLOBAL_FUNC(__thiscall_ ## func, \
|
|
"popl %eax\n\t" \
|
|
"pushl %ecx\n\t" \
|
|
"pushl %eax\n\t" \
|
|
"jmp " __ASM_NAME(#func) __ASM_STDCALL(args) )
|
|
#else /* __i386__ */
|
|
|
|
#define THISCALL(func) func
|
|
#define THISCALL_NAME(func) __ASM_NAME(#func)
|
|
#define __thiscall __cdecl
|
|
#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
|
|
|
|
#endif /* __i386__ */
|
|
|
|
/* Copied from dlls/msvcp90/msvcp90.h */
|
|
typedef SIZE_T MSVCP_size_t;
|
|
typedef unsigned short MSVCP_wchar_t;
|
|
|
|
#define BUF_SIZE_CHAR 16
|
|
typedef struct
|
|
{
|
|
void *allocator;
|
|
union {
|
|
char buf[BUF_SIZE_CHAR];
|
|
char *ptr;
|
|
} data;
|
|
MSVCP_size_t size;
|
|
MSVCP_size_t res;
|
|
} basic_string_char;
|
|
|
|
#define BUF_SIZE_WCHAR 8
|
|
typedef struct
|
|
{
|
|
void *allocator;
|
|
union {
|
|
MSVCP_wchar_t buf[BUF_SIZE_WCHAR];
|
|
MSVCP_wchar_t *ptr;
|
|
} data;
|
|
MSVCP_size_t size;
|
|
MSVCP_size_t res;
|
|
} basic_string_wchar;
|
|
|
|
basic_string_char* (__stdcall *pbasic_string_char_replace)(basic_string_char*,
|
|
MSVCP_size_t, MSVCP_size_t, const char*, MSVCP_size_t);
|
|
basic_string_wchar* (__stdcall *pbasic_string_wchar_replace)(basic_string_wchar*,
|
|
MSVCP_size_t, MSVCP_size_t, const MSVCP_wchar_t*, MSVCP_size_t);
|
|
void (__cdecl *p_String_base_Xlen)(void);
|
|
void (__cdecl *p_String_base_Xran)(void);
|
|
|
|
typedef struct {
|
|
const char *pos;
|
|
} basic_string_char_iterator;
|
|
|
|
typedef struct {
|
|
const MSVCP_wchar_t *pos;
|
|
} basic_string_wchar_iterator;
|
|
|
|
static char* basic_string_char_ptr(basic_string_char *this)
|
|
{
|
|
if(this->res == BUF_SIZE_CHAR-1)
|
|
return this->data.buf;
|
|
return this->data.ptr;
|
|
}
|
|
|
|
static MSVCP_wchar_t* basic_string_wchar_ptr(basic_string_wchar *this)
|
|
{
|
|
if(this->res == BUF_SIZE_WCHAR-1)
|
|
return this->data.buf;
|
|
return this->data.ptr;
|
|
}
|
|
|
|
/* ?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AViterator@12@XZ */
|
|
/* ?begin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AVconst_iterator@12@XZ */
|
|
/* ?rend@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$reverse_iterator@Viterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
|
|
/* ?rend@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$reverse_iterator@Vconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_begin, 8)
|
|
basic_string_char_iterator* __thiscall basic_string_char_begin(
|
|
basic_string_char *this, basic_string_char_iterator *ret)
|
|
{
|
|
ret->pos = basic_string_char_ptr(this);
|
|
return ret;
|
|
}
|
|
|
|
/* ?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AViterator@12@XZ */
|
|
/* ?end@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AVconst_iterator@12@XZ */
|
|
/* ?rbegin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE?AV?$reverse_iterator@Viterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
|
|
/* ?rbegin@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBE?AV?$reverse_iterator@Vconst_iterator@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@XZ */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_end, 8)
|
|
basic_string_char_iterator* __thiscall basic_string_char_end(
|
|
basic_string_char *this, basic_string_char_iterator *ret)
|
|
{
|
|
ret->pos = basic_string_char_ptr(this)+this->size;
|
|
return ret;
|
|
}
|
|
|
|
/* ?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Viterator@12@0ABV12@@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_replace_iter_bstr, 16)
|
|
basic_string_char* __thiscall basic_string_char_replace_iter_bstr(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end, basic_string_char *str)
|
|
{
|
|
return pbasic_string_char_replace(this, beg.pos-basic_string_char_ptr(this),
|
|
end.pos-beg.pos, basic_string_char_ptr(str), str->size);
|
|
}
|
|
|
|
/* ?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Viterator@12@0ID@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_replace_iter_ch, 20)
|
|
basic_string_char* __thiscall basic_string_char_replace_iter_ch(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end, MSVCP_size_t count, char ch)
|
|
{
|
|
/* TODO: add more efficient implementation */
|
|
MSVCP_size_t off = beg.pos-basic_string_char_ptr(this);
|
|
|
|
pbasic_string_char_replace(this, off, end.pos-beg.pos, NULL, 0);
|
|
while(count--)
|
|
pbasic_string_char_replace(this, off, 0, &ch, 1);
|
|
return this;
|
|
}
|
|
|
|
/* ?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Viterator@12@0PBD1@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_replace_iter_beg_end, 20)
|
|
basic_string_char* __thiscall basic_string_char_replace_iter_beg_end(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end, const char *rbeg, const char *rend)
|
|
{
|
|
return pbasic_string_char_replace(this, beg.pos-basic_string_char_ptr(this),
|
|
end.pos-beg.pos, rbeg, rend-rbeg);
|
|
}
|
|
|
|
/* ?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Viterator@12@0PBD@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_replace_iter_cstr, 16)
|
|
basic_string_char* __thiscall basic_string_char_replace_iter_cstr(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end, const char *str)
|
|
{
|
|
return pbasic_string_char_replace(this, beg.pos-basic_string_char_ptr(this),
|
|
end.pos-beg.pos, str, strlen(str));
|
|
}
|
|
|
|
/* ?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Viterator@12@0PBDI@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_replace_iter_cstr_len, 20)
|
|
basic_string_char* __thiscall basic_string_char_replace_iter_cstr_len(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end, const char *str, MSVCP_size_t len)
|
|
{
|
|
return pbasic_string_char_replace(this, beg.pos-basic_string_char_ptr(this),
|
|
end.pos-beg.pos, str, len);
|
|
}
|
|
|
|
/* ?replace@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Viterator@12@0Vconst_iterator@12@1@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_replace_iter_iter, 20)
|
|
basic_string_char* __thiscall basic_string_char_replace_iter_iter(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end,
|
|
basic_string_char_iterator rbeg, basic_string_char_iterator rend)
|
|
{
|
|
return pbasic_string_char_replace(this, beg.pos-basic_string_char_ptr(this),
|
|
end.pos-beg.pos, rbeg.pos, rend.pos-rbeg.pos);
|
|
}
|
|
|
|
/* ?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@Vconst_iterator@12@0@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_char_append_iter, 12)
|
|
basic_string_char* __thiscall basic_string_char_append_iter(basic_string_char *this,
|
|
basic_string_char_iterator beg, basic_string_char_iterator end)
|
|
{
|
|
return pbasic_string_char_replace(this, this->size, 0, beg.pos, end.pos-beg.pos);
|
|
}
|
|
|
|
/* ?begin@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE?AViterator@12@XZ */
|
|
/* ?begin@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBE?AVconst_iterator@12@XZ */
|
|
/* ?begin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AViterator@12@XZ */
|
|
/* ?begin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AVconst_iterator@12@XZ */
|
|
/* ?rend@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE?AV?$reverse_iterator@Viterator@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@2@XZ */
|
|
/* ?rend@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBE?AV?$reverse_iterator@Vconst_iterator@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@2@XZ */
|
|
/* ?rend@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AV?$reverse_iterator@Viterator@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
|
|
/* ?rend@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV?$reverse_iterator@Vconst_iterator@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_begin, 8)
|
|
basic_string_wchar_iterator* __thiscall basic_string_wchar_begin(
|
|
basic_string_wchar *this, basic_string_wchar_iterator *ret)
|
|
{
|
|
ret->pos = basic_string_wchar_ptr(this);
|
|
return ret;
|
|
}
|
|
|
|
/* ?end@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE?AViterator@12@XZ */
|
|
/* ?end@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBE?AVconst_iterator@12@XZ */
|
|
/* ?end@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AViterator@12@XZ */
|
|
/* ?end@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AVconst_iterator@12@XZ */
|
|
/* ?rbegin@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAE?AV?$reverse_iterator@Viterator@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@2@XZ */
|
|
/* ?rbegin@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QBE?AV?$reverse_iterator@Vconst_iterator@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@@2@XZ */
|
|
/* ?rbegin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAE?AV?$reverse_iterator@Viterator@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
|
|
/* ?rbegin@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QBE?AV?$reverse_iterator@Vconst_iterator@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@@2@XZ */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_end, 8)
|
|
basic_string_wchar_iterator* __thiscall basic_string_wchar_end(
|
|
basic_string_wchar *this, basic_string_wchar_iterator *ret)
|
|
{
|
|
ret->pos = basic_string_wchar_ptr(this)+this->size;
|
|
return ret;
|
|
}
|
|
|
|
/* ?replace@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Viterator@12@0ABV12@@Z */
|
|
/* ?replace@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Viterator@12@0ABV12@@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_replace_iter_bstr, 16)
|
|
basic_string_wchar* __thiscall basic_string_wchar_replace_iter_bstr(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end, basic_string_wchar *str)
|
|
{
|
|
return pbasic_string_wchar_replace(this, beg.pos-basic_string_wchar_ptr(this),
|
|
end.pos-beg.pos, basic_string_wchar_ptr(str), str->size);
|
|
}
|
|
|
|
/* ?replace@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Viterator@12@0IG@Z */
|
|
/* ?replace@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Viterator@12@0I_W@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_replace_iter_ch, 20)
|
|
basic_string_wchar* __thiscall basic_string_wchar_replace_iter_ch(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end, MSVCP_size_t count, MSVCP_wchar_t ch)
|
|
{
|
|
/* TODO: add more efficient implementation */
|
|
MSVCP_size_t off = beg.pos-basic_string_wchar_ptr(this);
|
|
|
|
pbasic_string_wchar_replace(this, off, end.pos-beg.pos, NULL, 0);
|
|
while(count--)
|
|
pbasic_string_wchar_replace(this, off, 0, &ch, 1);
|
|
return this;
|
|
}
|
|
|
|
/* ?replace@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Viterator@12@0PBG1@Z */
|
|
/* ?replace@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Viterator@12@0PB_W1@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_replace_iter_beg_end, 20)
|
|
basic_string_wchar* __thiscall basic_string_wchar_replace_iter_beg_end(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end,
|
|
const MSVCP_wchar_t *rbeg, const MSVCP_wchar_t *rend)
|
|
{
|
|
return pbasic_string_wchar_replace(this, beg.pos-basic_string_wchar_ptr(this),
|
|
end.pos-beg.pos, rbeg, rend-rbeg);
|
|
}
|
|
|
|
/* ?replace@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Viterator@12@0PBG@Z */
|
|
/* ?replace@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Viterator@12@0PB_W@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_replace_iter_cstr, 16)
|
|
basic_string_wchar* __thiscall basic_string_wchar_replace_iter_cstr(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end, const MSVCP_wchar_t *str)
|
|
{
|
|
return pbasic_string_wchar_replace(this, beg.pos-basic_string_wchar_ptr(this),
|
|
end.pos-beg.pos, str, strlenW(str));
|
|
}
|
|
|
|
/* ?replace@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Viterator@12@0PBGI@Z */
|
|
/* ?replace@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Viterator@12@0PB_WI@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_replace_iter_cstr_len, 20)
|
|
basic_string_wchar* __thiscall basic_string_wchar_replace_iter_cstr_len(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end,
|
|
const MSVCP_wchar_t *str, MSVCP_size_t len)
|
|
{
|
|
return pbasic_string_wchar_replace(this, beg.pos-basic_string_wchar_ptr(this),
|
|
end.pos-beg.pos, str, len);
|
|
}
|
|
|
|
/* ?replace@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Viterator@12@0Vconst_iterator@12@1@Z */
|
|
/* ?replace@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Viterator@12@0Vconst_iterator@12@1@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_replace_iter_iter, 20)
|
|
basic_string_wchar* __thiscall basic_string_wchar_replace_iter_iter(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end,
|
|
basic_string_wchar_iterator rbeg, basic_string_wchar_iterator rend)
|
|
{
|
|
return pbasic_string_wchar_replace(this, beg.pos-basic_string_wchar_ptr(this),
|
|
end.pos-beg.pos, rbeg.pos, rend.pos-rbeg.pos);
|
|
}
|
|
|
|
/* ?append@?$basic_string@GU?$char_traits@G@std@@V?$allocator@G@2@@std@@QAEAAV12@Vconst_iterator@12@0@Z */
|
|
/* ?append@?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@QAEAAV12@Vconst_iterator@12@0@Z */
|
|
DEFINE_THISCALL_WRAPPER(basic_string_wchar_append_iter, 12)
|
|
basic_string_wchar* __thiscall basic_string_wchar_append_iter(basic_string_wchar *this,
|
|
basic_string_wchar_iterator beg, basic_string_wchar_iterator end)
|
|
{
|
|
return pbasic_string_wchar_replace(this, this->size, 0, beg.pos, end.pos-beg.pos);
|
|
}
|
|
|
|
/* ?_Xlen@_String_base@std@@QBEXXZ */
|
|
DEFINE_THISCALL_WRAPPER(_String_base__Xlen, 4)
|
|
void __thiscall _String_base__Xlen(const void/*_String_base*/ *this)
|
|
{
|
|
p_String_base_Xlen();
|
|
}
|
|
|
|
/* ?_Xran@_String_base@std@@QBEXXZ */
|
|
DEFINE_THISCALL_WRAPPER(_String_base__Xran, 4)
|
|
void __thiscall _String_base__Xran(const void/*_String_base*/ *this)
|
|
{
|
|
p_String_base_Xran();
|
|
}
|
|
|
|
static BOOL init_funcs(void)
|
|
{
|
|
HMODULE hmod = GetModuleHandleA("msvcp90.dll");
|
|
if(!hmod)
|
|
return FALSE;
|
|
|
|
pbasic_string_char_replace = (void*)GetProcAddress(hmod, "basic_string_char_replace_helper");
|
|
pbasic_string_wchar_replace = (void*)GetProcAddress(hmod, "basic_string_wchar_replace_helper");
|
|
|
|
p_String_base_Xlen = (void*)GetProcAddress(hmod, "?_Xlen@_String_base@std@@SAXXZ");
|
|
p_String_base_Xran = (void*)GetProcAddress(hmod, "?_Xran@_String_base@std@@SAXXZ");
|
|
|
|
return pbasic_string_char_replace && pbasic_string_wchar_replace;
|
|
}
|
|
|
|
BOOL WINAPI DllMain(HINSTANCE hdll, DWORD reason, LPVOID reserved)
|
|
{
|
|
switch (reason)
|
|
{
|
|
case DLL_WINE_PREATTACH:
|
|
return FALSE; /* prefer native version */
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
DisableThreadLibraryCalls(hdll);
|
|
if(!init_funcs())
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|