xref: /reactos/sdk/lib/cicero/cicbase.cpp (revision 6bc40d36)
1 /*
2  * PROJECT:     ReactOS Cicero
3  * LICENSE:     LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4  * PURPOSE:     Cicero base
5  * COPYRIGHT:   Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6  */
7 
8 #include "precomp.h"
9 #include "cicbase.h"
10 #include <shlwapi.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <tchar.h>
14 #include <strsafe.h>
15 
operator new(size_t size,const CicNoThrow &)16 void* operator new(size_t size, const CicNoThrow&) noexcept
17 {
18     return cicMemAllocClear(size);
19 }
operator new[](size_t size,const CicNoThrow &)20 void* operator new[](size_t size, const CicNoThrow&) noexcept
21 {
22     return cicMemAllocClear(size);
23 }
operator delete(void * ptr)24 void operator delete(void* ptr) noexcept
25 {
26     cicMemFree(ptr);
27 }
operator delete[](void * ptr)28 void operator delete[](void* ptr) noexcept
29 {
30     cicMemFree(ptr);
31 }
operator delete(void * ptr,size_t size)32 void operator delete(void* ptr, size_t size) noexcept
33 {
34     cicMemFree(ptr);
35 }
operator delete[](void * ptr,size_t size)36 void operator delete[](void* ptr, size_t size) noexcept
37 {
38     cicMemFree(ptr);
39 }
40 
41 // FIXME
42 typedef enum _PROCESSINFOCLASS
43 {
44     ProcessBasicInformation = 0,
45     ProcessDebugPort = 7,
46     ProcessWow64Information = 26,
47     ProcessImageFileName = 27,
48     ProcessBreakOnTermination = 29
49 } PROCESSINFOCLASS;
50 
51 // FIXME
52 typedef LONG NTSTATUS;
53 
54 /* ntdll!NtQueryInformationProcess */
55 typedef NTSTATUS (WINAPI *FN_NtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
56 
57 EXTERN_C
cicIsWow64(VOID)58 BOOL cicIsWow64(VOID)
59 {
60     static FN_NtQueryInformationProcess s_fnNtQueryInformationProcess = NULL;
61     ULONG_PTR Value;
62 
63     if (!s_fnNtQueryInformationProcess)
64     {
65         HMODULE hNTDLL = cicGetSystemModuleHandle(TEXT("ntdll.dll"), FALSE);
66         if (!hNTDLL)
67             return FALSE;
68 
69         s_fnNtQueryInformationProcess =
70             (FN_NtQueryInformationProcess)GetProcAddress(hNTDLL, "NtQueryInformationProcess");
71         if (!s_fnNtQueryInformationProcess)
72             return FALSE;
73     }
74 
75     Value = 0;
76     s_fnNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information,
77                                   &Value, sizeof(Value), NULL);
78     return !!Value;
79 }
80 
81 EXTERN_C
cicGetOSInfo(LPUINT puACP,LPDWORD pdwOSInfo)82 void cicGetOSInfo(LPUINT puACP, LPDWORD pdwOSInfo)
83 {
84     *pdwOSInfo = 0;
85 
86     /* Check OS version info */
87     OSVERSIONINFO VerInfo;
88     VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
89     GetVersionEx(&VerInfo);
90     if (VerInfo.dwPlatformId == DLLVER_PLATFORM_NT)
91     {
92         *pdwOSInfo |= CIC_OSINFO_NT;
93         if (VerInfo.dwMajorVersion >= 5)
94         {
95             *pdwOSInfo |= CIC_OSINFO_2KPLUS;
96             if (VerInfo.dwMinorVersion > 0)
97                 *pdwOSInfo |= CIC_OSINFO_XPPLUS;
98         }
99     }
100     else
101     {
102         if (VerInfo.dwMinorVersion >= 10)
103             *pdwOSInfo |= CIC_OSINFO_98PLUS;
104         else
105             *pdwOSInfo |= CIC_OSINFO_95;
106     }
107 
108     /* Check codepage */
109     *puACP = GetACP();
110     switch (*puACP)
111     {
112         case 932: /* Japanese (Japan) */
113         case 936: /* Chinese (PRC, Singapore) */
114         case 949: /* Korean (Korea) */
115         case 950: /* Chinese (Taiwan, Hong Kong) */
116             *pdwOSInfo |= CIC_OSINFO_CJK;
117             break;
118     }
119 
120     if (GetSystemMetrics(SM_IMMENABLED))
121         *pdwOSInfo |= CIC_OSINFO_IMM;
122 
123     if (GetSystemMetrics(SM_DBCSENABLED))
124         *pdwOSInfo |= CIC_OSINFO_DBCS;
125 }
126 
127 // Get an instance handle that is already loaded
128 EXTERN_C
129 HINSTANCE
cicGetSystemModuleHandle(_In_ LPCTSTR pszFileName,_In_ BOOL bSysWinDir)130 cicGetSystemModuleHandle(
131     _In_ LPCTSTR pszFileName,
132     _In_ BOOL bSysWinDir)
133 {
134     CicSystemModulePath ModPath;
135     if (!ModPath.Init(pszFileName, bSysWinDir))
136         return NULL;
137     return GetModuleHandle(ModPath.m_szPath);
138 }
139 
140 // Load a system library
141 EXTERN_C
142 HINSTANCE
cicLoadSystemLibrary(_In_ LPCTSTR pszFileName,_In_ BOOL bSysWinDir)143 cicLoadSystemLibrary(
144     _In_ LPCTSTR pszFileName,
145     _In_ BOOL bSysWinDir)
146 {
147     CicSystemModulePath ModPath;
148     if (!ModPath.Init(pszFileName, bSysWinDir))
149         return NULL;
150     return ::LoadLibrary(ModPath.m_szPath);
151 }
152 
153 BOOL
Init(_In_ LPCTSTR pszFileName,_In_ BOOL bSysWinDir)154 CicSystemModulePath::Init(
155     _In_ LPCTSTR pszFileName,
156     _In_ BOOL bSysWinDir)
157 {
158     SIZE_T cchPath;
159     if (bSysWinDir)
160     {
161         // Usually C:\Windows or C:\ReactOS
162         cchPath = ::GetSystemWindowsDirectory(m_szPath, _countof(m_szPath));
163     }
164     else
165     {
166         // Usually C:\Windows\system32 or C:\ReactOS\system32
167         cchPath = ::GetSystemDirectory(m_szPath, _countof(m_szPath));
168     }
169 
170     m_szPath[_countof(m_szPath) - 1] = TEXT('\0'); // Avoid buffer overrun
171 
172     if ((cchPath == 0) || (cchPath > _countof(m_szPath) - 2))
173         goto Failure;
174 
175     // Add backslash if necessary
176     if ((cchPath > 0) && (m_szPath[cchPath - 1] != TEXT('\\')))
177     {
178         m_szPath[cchPath + 0] = TEXT('\\');
179         m_szPath[cchPath + 1] = TEXT('\0');
180     }
181 
182     // Append pszFileName
183     if (FAILED(StringCchCat(m_szPath, _countof(m_szPath), pszFileName)))
184         goto Failure;
185 
186     m_cchPath = _tcslen(m_szPath);
187     return TRUE;
188 
189 Failure:
190     m_szPath[0] = UNICODE_NULL;
191     m_cchPath = 0;
192     return FALSE;
193 }
194 
195 static FN_CoCreateInstance
_cicGetSetUserCoCreateInstance(FN_CoCreateInstance fnUserCoCreateInstance)196 _cicGetSetUserCoCreateInstance(FN_CoCreateInstance fnUserCoCreateInstance)
197 {
198     static FN_CoCreateInstance s_fn = NULL;
199     if (fnUserCoCreateInstance)
200         s_fn = fnUserCoCreateInstance;
201     return s_fn;
202 }
203 
204 EXTERN_C
205 HRESULT
cicRealCoCreateInstance(_In_ REFCLSID rclsid,_In_ LPUNKNOWN pUnkOuter,_In_ DWORD dwClsContext,_In_ REFIID iid,_Out_ LPVOID * ppv)206 cicRealCoCreateInstance(
207     _In_ REFCLSID rclsid,
208     _In_ LPUNKNOWN pUnkOuter,
209     _In_ DWORD dwClsContext,
210     _In_ REFIID iid,
211     _Out_ LPVOID *ppv)
212 {
213     static HINSTANCE s_hOle32 = NULL;
214     static FN_CoCreateInstance s_fnCoCreateInstance = NULL;
215     if (!s_fnCoCreateInstance)
216     {
217         if (!s_hOle32)
218             s_hOle32 = cicLoadSystemLibrary(TEXT("ole32.dll"), FALSE);
219         s_fnCoCreateInstance = (FN_CoCreateInstance)GetProcAddress(s_hOle32, "CoCreateInstance");
220         if (!s_fnCoCreateInstance)
221             return E_NOTIMPL;
222     }
223 
224     return s_fnCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
225 }
226 
227 /**
228  * @implemented
229  */
230 HRESULT
cicCoCreateInstance(_In_ REFCLSID rclsid,_In_ LPUNKNOWN pUnkOuter,_In_ DWORD dwClsContext,_In_ REFIID iid,_Out_ LPVOID * ppv)231 cicCoCreateInstance(
232     _In_ REFCLSID rclsid,
233     _In_ LPUNKNOWN pUnkOuter,
234     _In_ DWORD dwClsContext,
235     _In_ REFIID iid,
236     _Out_ LPVOID *ppv)
237 {
238     // NOTE: It looks like Cicero wants to hook CoCreateInstance
239     FN_CoCreateInstance fnUserCoCreateInstance = _cicGetSetUserCoCreateInstance(NULL);
240     if (fnUserCoCreateInstance)
241         return fnUserCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
242 
243     return cicRealCoCreateInstance(rclsid, pUnkOuter, dwClsContext, iid, ppv);
244 }
245 
246 /**
247  * @implemented
248  */
249 EXTERN_C
250 BOOL
TFInitLib(FN_CoCreateInstance fnCoCreateInstance)251 TFInitLib(FN_CoCreateInstance fnCoCreateInstance)
252 {
253     if (fnCoCreateInstance)
254         _cicGetSetUserCoCreateInstance(fnCoCreateInstance);
255     return TRUE;
256 }
257