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