VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/win/vcc100-kernel32-fakes.cpp@ 70195

最後變更 在這個檔案從70195是 70195,由 vboxsync 提交於 7 年 前

IPRT/R3: Made the core work on NT 3.51 (still experimental).

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 14.1 KB
 
1/* $Id: vcc100-kernel32-fakes.cpp 70195 2017-12-18 13:40:26Z vboxsync $ */
2/** @file
3 * IPRT - Tricks to make the Visual C++ 2010 CRT work on NT4, W2K and XP.
4 */
5
6/*
7 * Copyright (C) 2012-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define RT_NO_STRICT /* Minimal deps so that it works on NT 3.51 too. */
32#include <iprt/cdefs.h>
33#include <iprt/types.h>
34#include <iprt/asm.h>
35#include <iprt/assert.h>
36#include <iprt/string.h>
37
38#ifndef RT_ARCH_X86
39# error "This code is X86 only"
40#endif
41
42#define DecodePointer Ignore_DecodePointer
43#define EncodePointer Ignore_EncodePointer
44#define InitializeCriticalSectionAndSpinCount Ignore_InitializeCriticalSectionAndSpinCount
45#define HeapSetInformation Ignore_HeapSetInformation
46#define HeapQueryInformation Ignore_HeapQueryInformation
47#define CreateTimerQueue Ignore_CreateTimerQueue
48#define CreateTimerQueueTimer Ignore_CreateTimerQueueTimer
49#define DeleteTimerQueueTimer Ignore_DeleteTimerQueueTimer
50#define InitializeSListHead Ignore_InitializeSListHead
51#define InterlockedFlushSList Ignore_InterlockedFlushSList
52#define InterlockedPopEntrySList Ignore_InterlockedPopEntrySList
53#define InterlockedPushEntrySList Ignore_InterlockedPushEntrySList
54#define QueryDepthSList Ignore_QueryDepthSList
55#define VerifyVersionInfoA Ignore_VerifyVersionInfoA
56#define VerSetConditionMask Ignore_VerSetConditionMask
57#define IsProcessorFeaturePresent Ignore_IsProcessorFeaturePresent /* NT 3.51 start */
58#define CancelIo Ignore_CancelIo
59
60#include <iprt/nt/nt-and-windows.h>
61
62#undef DecodePointer
63#undef EncodePointer
64#undef InitializeCriticalSectionAndSpinCount
65#undef HeapSetInformation
66#undef HeapQueryInformation
67#undef CreateTimerQueue
68#undef CreateTimerQueueTimer
69#undef DeleteTimerQueueTimer
70#undef InitializeSListHead
71#undef InterlockedFlushSList
72#undef InterlockedPopEntrySList
73#undef InterlockedPushEntrySList
74#undef QueryDepthSList
75#undef VerifyVersionInfoA
76#undef VerSetConditionMask
77#undef IsProcessorFeaturePresent
78#undef CancelIo
79
80
81#ifndef HEAP_STANDARD
82# define HEAP_STANDARD 0
83#endif
84
85
86/** Dynamically resolves an kernel32 API. */
87#define RESOLVE_ME(ApiNm) \
88 static bool volatile s_fInitialized = false; \
89 static decltype(ApiNm) *s_pfnApi = NULL; \
90 decltype(ApiNm) *pfnApi; \
91 if (!s_fInitialized) \
92 pfnApi = s_pfnApi; \
93 else \
94 { \
95 pfnApi = (decltype(pfnApi))GetProcAddress(GetModuleHandleW(L"kernel32"), #ApiNm); \
96 s_pfnApi = pfnApi; \
97 s_fInitialized = true; \
98 } do {} while (0)
99
100
101/** Dynamically resolves an NTDLL API we need. */
102#define RESOLVE_NTDLL_API(ApiNm) \
103 static bool volatile s_fInitialized##ApiNm = false; \
104 static decltype(ApiNm) *s_pfn##ApiNm = NULL; \
105 decltype(ApiNm) *pfn##ApiNm; \
106 if (!s_fInitialized##ApiNm) \
107 pfn##ApiNm = s_pfn##ApiNm; \
108 else \
109 { \
110 pfn##ApiNm = (decltype(pfn##ApiNm))GetProcAddress(GetModuleHandleW(L"ntdll"), #ApiNm); \
111 s_pfn##ApiNm = pfn##ApiNm; \
112 s_fInitialized##ApiNm = true; \
113 } do {} while (0)
114
115
116extern "C"
117__declspec(dllexport) PVOID WINAPI
118DecodePointer(PVOID pvEncoded)
119{
120 RESOLVE_ME(DecodePointer);
121 if (pfnApi)
122 return pfnApi(pvEncoded);
123
124 /*
125 * Fallback code.
126 */
127 return pvEncoded;
128}
129
130
131extern "C"
132__declspec(dllexport) PVOID WINAPI
133EncodePointer(PVOID pvNative)
134{
135 RESOLVE_ME(EncodePointer);
136 if (pfnApi)
137 return pfnApi(pvNative);
138
139 /*
140 * Fallback code.
141 */
142 return pvNative;
143}
144
145
146extern "C"
147__declspec(dllexport) BOOL WINAPI
148InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION pCritSect, DWORD cSpin)
149{
150 RESOLVE_ME(InitializeCriticalSectionAndSpinCount);
151 if (pfnApi)
152 return pfnApi(pCritSect, cSpin);
153
154 /*
155 * Fallback code.
156 */
157 InitializeCriticalSection(pCritSect);
158 return TRUE;
159}
160
161
162extern "C"
163__declspec(dllexport) BOOL WINAPI
164HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS enmInfoClass, PVOID pvBuf, SIZE_T cbBuf)
165{
166 RESOLVE_ME(HeapSetInformation);
167 if (pfnApi)
168 return pfnApi(hHeap, enmInfoClass, pvBuf, cbBuf);
169
170 /*
171 * Fallback code.
172 */
173 if (enmInfoClass == HeapCompatibilityInformation)
174 {
175 if ( cbBuf != sizeof(ULONG)
176 || !pvBuf
177 || *(PULONG)pvBuf == HEAP_STANDARD
178 )
179 {
180 SetLastError(ERROR_INVALID_PARAMETER);
181 return FALSE;
182 }
183 return TRUE;
184 }
185
186 SetLastError(ERROR_INVALID_PARAMETER);
187 return FALSE;
188}
189
190
191extern "C"
192__declspec(dllexport) BOOL WINAPI
193HeapQueryInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS enmInfoClass, PVOID pvBuf, SIZE_T cbBuf, PSIZE_T pcbRet)
194{
195 RESOLVE_ME(HeapQueryInformation);
196 if (pfnApi)
197 return pfnApi(hHeap, enmInfoClass, pvBuf, cbBuf, pcbRet);
198
199 /*
200 * Fallback code.
201 */
202 if (enmInfoClass == HeapCompatibilityInformation)
203 {
204 *pcbRet = sizeof(ULONG);
205 if (cbBuf < sizeof(ULONG) || !pvBuf)
206 {
207 SetLastError(ERROR_INSUFFICIENT_BUFFER);
208 return FALSE;
209 }
210 *(PULONG)pvBuf = HEAP_STANDARD;
211 return TRUE;
212 }
213
214 SetLastError(ERROR_INVALID_PARAMETER);
215 return FALSE;
216}
217
218
219/* These are used by INTEL\mt_obj\Timer.obj: */
220
221extern "C"
222__declspec(dllexport)
223HANDLE WINAPI CreateTimerQueue(void)
224{
225 RESOLVE_ME(CreateTimerQueue);
226 if (pfnApi)
227 return pfnApi();
228 SetLastError(ERROR_NOT_SUPPORTED);
229 return NULL;
230}
231
232extern "C"
233__declspec(dllexport)
234BOOL WINAPI CreateTimerQueueTimer(PHANDLE phTimer, HANDLE hTimerQueue, WAITORTIMERCALLBACK pfnCallback, PVOID pvUser,
235 DWORD msDueTime, DWORD msPeriod, ULONG fFlags)
236{
237 RESOLVE_ME(CreateTimerQueueTimer);
238 if (pfnApi)
239 return pfnApi(phTimer, hTimerQueue, pfnCallback, pvUser, msDueTime, msPeriod, fFlags);
240 SetLastError(ERROR_NOT_SUPPORTED);
241 return FALSE;
242}
243
244extern "C"
245__declspec(dllexport)
246BOOL WINAPI DeleteTimerQueueTimer(HANDLE hTimerQueue, HANDLE hTimer, HANDLE hEvtCompletion)
247{
248 RESOLVE_ME(DeleteTimerQueueTimer);
249 if (pfnApi)
250 return pfnApi(hTimerQueue, hTimer, hEvtCompletion);
251 SetLastError(ERROR_NOT_SUPPORTED);
252 return FALSE;
253}
254
255/* This is used by several APIs. */
256
257extern "C"
258__declspec(dllexport)
259VOID WINAPI InitializeSListHead(PSLIST_HEADER pHead)
260{
261 RESOLVE_ME(InitializeSListHead);
262 if (pfnApi)
263 pfnApi(pHead);
264 else /* fallback: */
265 pHead->Alignment = 0;
266}
267
268
269extern "C"
270__declspec(dllexport)
271PSLIST_ENTRY WINAPI InterlockedFlushSList(PSLIST_HEADER pHead)
272{
273 RESOLVE_ME(InterlockedFlushSList);
274 if (pfnApi)
275 return pfnApi(pHead);
276
277 /* fallback: */
278 PSLIST_ENTRY pRet = NULL;
279 if (pHead->Next.Next)
280 {
281 for (;;)
282 {
283 SLIST_HEADER OldHead = *pHead;
284 SLIST_HEADER NewHead;
285 NewHead.Alignment = 0;
286 NewHead.Sequence = OldHead.Sequence + 1;
287 if (ASMAtomicCmpXchgU64(&pHead->Alignment, NewHead.Alignment, OldHead.Alignment))
288 {
289 pRet = OldHead.Next.Next;
290 break;
291 }
292 }
293 }
294 return pRet;
295}
296
297extern "C"
298__declspec(dllexport)
299PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER pHead)
300{
301 RESOLVE_ME(InterlockedPopEntrySList);
302 if (pfnApi)
303 return pfnApi(pHead);
304
305 /* fallback: */
306 PSLIST_ENTRY pRet = NULL;
307 for (;;)
308 {
309 SLIST_HEADER OldHead = *pHead;
310 pRet = OldHead.Next.Next;
311 if (pRet)
312 {
313 SLIST_HEADER NewHead;
314 __try
315 {
316 NewHead.Next.Next = pRet->Next;
317 }
318 __except(EXCEPTION_EXECUTE_HANDLER)
319 {
320 continue;
321 }
322 NewHead.Depth = OldHead.Depth - 1;
323 NewHead.Sequence = OldHead.Sequence + 1;
324 if (ASMAtomicCmpXchgU64(&pHead->Alignment, NewHead.Alignment, OldHead.Alignment))
325 break;
326 }
327 else
328 break;
329 }
330 return pRet;
331}
332
333extern "C"
334__declspec(dllexport)
335PSLIST_ENTRY WINAPI InterlockedPushEntrySList(PSLIST_HEADER pHead, PSLIST_ENTRY pEntry)
336{
337 RESOLVE_ME(InterlockedPushEntrySList);
338 if (pfnApi)
339 return pfnApi(pHead, pEntry);
340
341 /* fallback: */
342 PSLIST_ENTRY pRet = NULL;
343 for (;;)
344 {
345 SLIST_HEADER OldHead = *pHead;
346 pRet = OldHead.Next.Next;
347 pEntry->Next = pRet;
348 SLIST_HEADER NewHead;
349 NewHead.Next.Next = pEntry;
350 NewHead.Depth = OldHead.Depth + 1;
351 NewHead.Sequence = OldHead.Sequence + 1;
352 if (ASMAtomicCmpXchgU64(&pHead->Alignment, NewHead.Alignment, OldHead.Alignment))
353 break;
354 }
355 return pRet;
356}
357
358extern "C"
359__declspec(dllexport)
360WORD WINAPI QueryDepthSList(PSLIST_HEADER pHead)
361{
362 RESOLVE_ME(QueryDepthSList);
363 if (pfnApi)
364 return pfnApi(pHead);
365 return pHead->Depth;
366}
367
368
369/* curl drags these in: */
370extern "C"
371__declspec(dllexport)
372BOOL WINAPI VerifyVersionInfoA(LPOSVERSIONINFOEXA pInfo, DWORD fTypeMask, DWORDLONG fConditionMask)
373{
374 RESOLVE_ME(VerifyVersionInfoA);
375 if (pfnApi)
376 return pfnApi(pInfo, fTypeMask, fConditionMask);
377
378 /* fallback to make curl happy: */
379 OSVERSIONINFOEXA VerInfo;
380 RT_ZERO(VerInfo);
381 VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
382 if (!GetVersionEx((OSVERSIONINFO *)&VerInfo))
383 {
384 RT_ZERO(VerInfo);
385 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
386 AssertReturn(GetVersionEx((OSVERSIONINFO *)&VerInfo), FALSE);
387 }
388
389 BOOL fRet = TRUE;
390 for (unsigned i = 0; i < 8 && fRet; i++)
391 if (fTypeMask & RT_BIT_32(i))
392 {
393 uint32_t uLeft, uRight;
394 switch (RT_BIT_32(i))
395 {
396#define MY_CASE(a_Num, a_Member) case a_Num: uLeft = VerInfo.a_Member; uRight = pInfo->a_Member; break
397 MY_CASE(VER_MINORVERSION, dwMinorVersion);
398 MY_CASE(VER_MAJORVERSION, dwMajorVersion);
399 MY_CASE(VER_BUILDNUMBER, dwBuildNumber);
400 MY_CASE(VER_PLATFORMID, dwPlatformId);
401 MY_CASE(VER_SERVICEPACKMINOR, wServicePackMinor);
402 MY_CASE(VER_SERVICEPACKMAJOR, wServicePackMinor);
403 MY_CASE(VER_SUITENAME, wSuiteMask);
404 MY_CASE(VER_PRODUCT_TYPE, wProductType);
405#undef MY_CASE
406 default: uLeft = uRight = 0; AssertFailed();
407 }
408 switch ((uint8_t)(fConditionMask >> (i*8)))
409 {
410 case VER_EQUAL: fRet = uLeft == uRight; break;
411 case VER_GREATER: fRet = uLeft > uRight; break;
412 case VER_GREATER_EQUAL: fRet = uLeft >= uRight; break;
413 case VER_LESS: fRet = uLeft < uRight; break;
414 case VER_LESS_EQUAL: fRet = uLeft <= uRight; break;
415 case VER_AND: fRet = (uLeft & uRight) == uRight; break;
416 case VER_OR: fRet = (uLeft & uRight) != 0; break;
417 default: fRet = FALSE; AssertFailed(); break;
418 }
419 }
420
421 return fRet;
422}
423
424
425extern "C"
426__declspec(dllexport)
427ULONGLONG WINAPI VerSetConditionMask(ULONGLONG fConditionMask, DWORD fTypeMask, BYTE bOperator)
428{
429 RESOLVE_ME(VerSetConditionMask);
430 if (pfnApi)
431 return pfnApi(fConditionMask, fTypeMask, bOperator);
432
433 /* fallback: */
434 for (unsigned i = 0; i < 8; i++)
435 if (fTypeMask & RT_BIT_32(i))
436 {
437 uint64_t fMask = UINT64_C(0xff) << (i*8);
438 fConditionMask &= ~fMask;
439 fConditionMask |= (uint64_t)bOperator << (i*8);
440
441 }
442 return fConditionMask;
443}
444
445
446/*
447 * NT 3.51 stuff.
448 */
449
450extern "C" DECLEXPORT(BOOL) WINAPI IsProcessorFeaturePresent(DWORD enmProcessorFeature)
451{
452 RESOLVE_ME(IsProcessorFeaturePresent);
453 if (pfnApi)
454 return pfnApi(enmProcessorFeature);
455
456 /* Could make more of an effort here... */
457 return FALSE;
458}
459
460
461extern "C" DECLEXPORT(BOOL) WINAPI CancelIo(HANDLE hHandle)
462{
463 RESOLVE_ME(CancelIo);
464 if (pfnApi)
465 return pfnApi(hHandle);
466
467 /* NT 3.51 have the NTDLL API this corresponds to. */
468 RESOLVE_NTDLL_API(NtCancelIoFile);
469 if (pfnNtCancelIoFile)
470 {
471 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
472 NTSTATUS rcNt = pfnNtCancelIoFile(hHandle, &Ios);
473 if (RT_SUCCESS(rcNt))
474 return TRUE;
475 if (rcNt == STATUS_INVALID_HANDLE)
476 SetLastError(ERROR_INVALID_HANDLE);
477 else
478 SetLastError(ERROR_INVALID_FUNCTION);
479 }
480 else
481 SetLastError(ERROR_NOT_SUPPORTED);
482 return FALSE;
483}
484
485
486/* Dummy to force dragging in this object in the link, so the linker
487 won't accidentally use the symbols from kernel32. */
488extern "C" int vcc100_kernel32_fakes_cpp(void)
489{
490 return 42;
491}
492
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette