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 16 void* operator new(size_t size, const CicNoThrow&) noexcept 17 { 18 return cicMemAllocClear(size); 19 } 20 void* operator new[](size_t size, const CicNoThrow&) noexcept 21 { 22 return cicMemAllocClear(size); 23 } 24 void operator delete(void* ptr) noexcept 25 { 26 cicMemFree(ptr); 27 } 28 void operator delete[](void* ptr) noexcept 29 { 30 cicMemFree(ptr); 31 } 32 void operator delete(void* ptr, size_t size) noexcept 33 { 34 cicMemFree(ptr); 35 } 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 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 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 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 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 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 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 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 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 251 TFInitLib(FN_CoCreateInstance fnCoCreateInstance) 252 { 253 if (fnCoCreateInstance) 254 _cicGetSetUserCoCreateInstance(fnCoCreateInstance); 255 return TRUE; 256 } 257