Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

288 lines
8.1 KiB

/***************************************************************************
* msctls.c
*
* Utils library initialization code
*
***************************************************************************/
#include "ctlspriv.h"
HINSTANCE g_hinst;
int g_cProcesses = 0;
ATOM g_aCC32Subclass = 0;
CRITICAL_SECTION g_csControls = {{0},0, 0, NULL, NULL, 0 };
#ifdef DEBUG
int g_CriticalSectionCount=0;
DWORD g_CriticalSectionOwner=0;
#ifdef WINNT
#include <stdio.h>
#endif
#endif // DEBUG
BOOL FAR PASCAL InitAnimateClass(HINSTANCE hInstance);
BOOL ListView_Init(HINSTANCE hinst);
BOOL TV_Init(HINSTANCE hinst);
BOOL InitComboExClass(HINSTANCE hinst);
BOOL FAR PASCAL Header_Init(HINSTANCE hinst);
BOOL FAR PASCAL Tab_Init(HINSTANCE hinst);
void Mem_Terminate();
#define DECLARE_DELAYED_FUNC(_ret, _fn, _args, _nargs) \
_ret (__stdcall * g_pfn##_fn) _args = NULL; \
_ret __stdcall _fn _args \
{ \
if (!g_pfn##_fn) { \
AssertMsg((BOOL)g_pfn##_fn, TEXT("GetProcAddress failed")); \
return 0; \
} \
return g_pfn##_fn _nargs; \
}
#define LOAD_DELAYED_FUNC(_ret, _fn, _args) \
(*(FARPROC*)&(g_pfn##_fn) = GetProcAddress(hinst, TEXT(#_fn)))
DECLARE_DELAYED_FUNC(BOOL, ImmNotifyIME, (HIMC himc, DWORD dw1, DWORD dw2, DWORD dw3), (himc, dw1, dw2, dw3));
DECLARE_DELAYED_FUNC(HIMC, ImmAssociateContext, (HWND hwnd, HIMC himc), (hwnd, himc));
DECLARE_DELAYED_FUNC(BOOL, ImmReleaseContext, (HWND hwnd, HIMC himc), (hwnd, himc));
DECLARE_DELAYED_FUNC(HIMC, ImmGetContext, (HWND hwnd), (hwnd));
DECLARE_DELAYED_FUNC(LONG, ImmGetCompositionStringA, (HIMC himc, DWORD dw1, LPVOID p1, DWORD dw2), (himc, dw1, p1, dw2) );
DECLARE_DELAYED_FUNC(LONG, ImmGetCompositionStringW, (HIMC himc, DWORD dw1, LPVOID p1, DWORD dw2), (himc, dw1, p1, dw2) );
DECLARE_DELAYED_FUNC(BOOL, ImmSetCompositionStringA, (HIMC himc, DWORD dw1, LPCVOID p1, DWORD dw2, LPCVOID p2, DWORD dw3), (himc, dw1, p1, dw2, p2, dw3));
DECLARE_DELAYED_FUNC(BOOL, ImmSetCompositionStringW, (HIMC himc, DWORD dw1, LPCVOID p1, DWORD dw2, LPCVOID p2, DWORD dw3), (himc, dw1, p1, dw2, p2, dw3));
DECLARE_DELAYED_FUNC(BOOL, ImmSetCandidateWindow, (HIMC himc, LPCANDIDATEFORM pcf), (himc, pcf));
BOOL g_fDBCSEnabled = FALSE;
BOOL g_fMEEnabled = FALSE;
#if defined(FE_IME) || !defined(WINNT)
void InitIme()
{
g_fMEEnabled = GetSystemMetrics(SM_MIDEASTENABLED);
g_fDBCSEnabled = GetSystemMetrics(SM_DBCSENABLED);
if (g_fDBCSEnabled) {
HANDLE hinst = LoadLibrary(TEXT("imm32.dll"));
if (! hinst ||
! LOAD_DELAYED_FUNC(BOOL, ImmNotifyIME, (HIMC, DWORD, DWORD, DWORD)) ||
! LOAD_DELAYED_FUNC(HIMC, ImmAssociateContext, (HWND, HIMC)) ||
! LOAD_DELAYED_FUNC(BOOL, ImmReleaseContext, (HWND, HIMC)) ||
! LOAD_DELAYED_FUNC(HIMC, ImmGetContext, (HWND)) ||
! LOAD_DELAYED_FUNC(LONG, ImmGetCompositionStringA, (HIMC, DWORD, LPVOID, DWORD)) ||
! LOAD_DELAYED_FUNC(LONG, ImmGetCompositionStringW, (HIMC, DWORD, LPVOID, DWORD)) ||
! LOAD_DELAYED_FUNC(BOOL, ImmSetCompositionStringA, (HIMC, DWORD, LPCVOID, DWORD, LPCVOID, DWORD)) ||
! LOAD_DELAYED_FUNC(BOOL, ImmSetCompositionStringW, (HIMC, DWORD, LPCVOID, DWORD, LPCVOID, DWORD)) ||
! LOAD_DELAYED_FUNC(BOOL, ImmSetCandidateWindow, (HIMC, LPCANDIDATEFORM))) {
// if we were unable to load then bail on using IME.
g_fDBCSEnabled = FALSE;
}
}
}
#else
#define InitIme() 0
#endif
int PASCAL _ProcessAttach(HANDLE hInstance)
{
INITCOMMONCONTROLSEX icce;
ATOM a;
#ifdef DEBUG
CcshellGetDebugFlags();
#endif
g_hinst = hInstance;
#ifndef WINNT
ReinitializeCriticalSection(&g_csControls);
#else
InitializeCriticalSection(&g_csControls);
#endif
g_cProcesses++;
#ifndef WINNT
DebugMsg(DM_TRACE, TEXT("commctrl:ProcessAttach: %d"), g_cProcesses);
//
// HACK: we are intentionally incrementing the refcount on this atom
// WE DO NOT WANT IT TO GO BACK DOWN so we will not delete it in process
// detach (see comments for g_aCC32Subclass in subclass.c for more info)
//
if ((a = GlobalAddAtom(c_szCC32Subclass)) != 0)
g_aCC32Subclass = a; // in case the old atom got nuked
#endif
InitGlobalMetrics(0);
InitGlobalColors();
InitIme();
// BUGBUG: only do this for GetProcessVersion apps <= 0x40000
// Newer apps MUST use InitCommonControlsEx.
icce.dwSize = sizeof(icce);
icce.dwICC = ICC_WIN95_CLASSES;
return InitCommonControlsEx(&icce);
}
void NEAR PASCAL _ProcessDetach(HANDLE hInstance)
{
// BUGBUG serialize
ENTERCRITICAL
if (--g_cProcesses == 0) {
// terminate shared data
// Mem_Terminate must be called after all other termination routines
Mem_Terminate();
}
LEAVECRITICAL;
#ifdef WINNT
DeleteCriticalSection(&g_csControls);
#endif
}
#ifndef WINNT
#pragma data_seg(DATASEG_READONLY)
#endif
TCHAR const c_szCommCtrlDll[] = TEXT("commctrl.dll");
TCHAR const c_szComCtl32Dll[] = TEXT("comctl32.dll");
#ifndef WINNT
#pragma data_seg()
#endif
#ifndef WINNT
BOOL WINAPI Cctl1632_ThunkConnect32(LPCSTR pszDll16,LPCSTR pszDll32,HANDLE hIinst,DWORD dwReason);
#endif
BOOL APIENTRY LibMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
#ifndef WINNT
if (!Cctl1632_ThunkConnect32(c_szCommCtrlDll, c_szComCtl32Dll, hDll, dwReason))
return FALSE;
#endif
switch(dwReason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hDll);
_ProcessAttach(hDll);
break;
case DLL_PROCESS_DETACH:
_ProcessDetach(hDll);
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
default:
break;
} // end switch()
return TRUE;
} // end DllEntryPoint()
void Controls_EnterCriticalSection(void)
{
EnterCriticalSection(&g_csControls);
#ifdef DEBUG
if (g_CriticalSectionCount++ == 0)
g_CriticalSectionOwner = GetCurrentThreadId();
#endif
}
void Controls_LeaveCriticalSection(void)
{
#ifdef DEBUG
if (--g_CriticalSectionCount == 0)
g_CriticalSectionOwner = 0;
#endif
LeaveCriticalSection(&g_csControls);
}
/* Stub function to call if all you want to do is make sure this DLL is loaded
*/
void WINAPI InitCommonControls(void)
{
}
/* InitCommonControlsEx creates the classes. Only those classes requested are created!
** The process attach figures out if it's an old app and supplies ICC_WIN95_CLASSES.
*/
typedef BOOL (PASCAL *PFNINIT)(HINST);
struct {PFNINIT pfnInit; DWORD dw;} icc[] =
{
// Init function Requested class sets which use this class
{InitToolbarClass, ICC_BAR_CLASSES},
{InitReBarClass, ICC_COOL_CLASSES},
{InitToolTipsClass, ICC_TREEVIEW_CLASSES|ICC_BAR_CLASSES|ICC_TAB_CLASSES},
{InitStatusClass, ICC_BAR_CLASSES},
{ListView_Init, ICC_LISTVIEW_CLASSES},
{Header_Init, ICC_LISTVIEW_CLASSES},
{Tab_Init, ICC_TAB_CLASSES},
{TV_Init, ICC_TREEVIEW_CLASSES},
{InitTrackBar, ICC_BAR_CLASSES},
{InitUpDownClass, ICC_UPDOWN_CLASS},
{InitProgressClass, ICC_PROGRESS_CLASS},
{InitHotKeyClass, ICC_HOTKEY_CLASS},
{InitAnimateClass, ICC_ANIMATE_CLASS},
{InitDateClasses, ICC_DATE_CLASSES},
{InitComboExClass, ICC_USEREX_CLASSES}
};
BOOL WINAPI InitCommonControlsEx(LPINITCOMMONCONTROLSEX picce)
{
int i;
if (!picce ||
(picce->dwSize != sizeof(INITCOMMONCONTROLSEX)) ||
(picce->dwICC & ~ICC_ALL_CLASSES))
{
DebugMsg(DM_WARNING, TEXT("comctl32 - picce is bad"));
return(FALSE);
}
for (i=0 ; i < ARRAYSIZE(icc) ; i++)
if (picce->dwICC & icc[i].dw)
if (!icc[i].pfnInit(HINST_THISDLL))
return(FALSE);
return(TRUE);
}
#if defined(WIN32) && defined(DEBUG)
LRESULT
WINAPI
SendMessageD(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
ASSERTNONCRITICAL;
#ifdef UNICODE
return SendMessageW(hWnd, Msg, wParam, lParam);
#else
return SendMessageA(hWnd, Msg, wParam, lParam);
#endif
}
#endif // defined(WIN32) && defined(DEBUG)
#define COMPILE_MULTIMON_STUBS
#include "multimon.h"