VirtualBox

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

Last change on this file since 70384 was 70375, checked in by vboxsync, 7 years ago

iprt/vcc100-kernel32-fakes*: Redid the resolving to be more optimal for platforms that provides the APIs we fake, and also added version checks (in strict builds) that we're able to resolve the symbols.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.6 KB
Line 
1/* $Id: vcc100-kernel32-fakes.cpp 70375 2017-12-28 20:46:21Z 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.virtualbox.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#include <iprt/cdefs.h>
32#include <iprt/types.h>
33#include <iprt/asm.h>
34#include <iprt/assert.h>
35#include <iprt/string.h>
36#ifdef DEBUG
37# include <stdio.h> /* _snprintf */
38#endif
39
40#ifndef RT_ARCH_X86
41# error "This code is X86 only"
42#endif
43
44#include <iprt/nt/nt-and-windows.h>
45
46#include "vcc100-fakes.h"
47
48
49/*********************************************************************************************************************************
50* Defined Constants And Macros *
51*********************************************************************************************************************************/
52#ifndef HEAP_STANDARD
53# define HEAP_STANDARD 0
54#endif
55
56
57/** Declare a kernel32 API.
58 * @note We are not exporting them as that causes duplicate symbol troubles in
59 * the OpenGL bits. */
60#define DECL_KERNEL32(a_Type) extern "C" a_Type WINAPI
61
62
63
64/*********************************************************************************************************************************
65* Global Variables *
66*********************************************************************************************************************************/
67static volatile bool g_fInitialized = false;
68#define MAKE_IMPORT_ENTRY(a_uMajorVer, a_uMinorVer, a_Name, a_cb) DECLARE_FUNCTION_POINTER(a_Name, a_cb)
69#include "vcc100-kernel32-fakes.h"
70
71
72/**
73 * Resolves all the APIs ones and for all, updating the fake IAT entries.
74 */
75static void InitFakes(void)
76{
77 CURRENT_VERSION_VARIABLE();
78
79 HMODULE hmod = GetModuleHandleW(L"kernel32");
80 MY_ASSERT(hmod != NULL, "kernel32");
81
82#undef MAKE_IMPORT_ENTRY
83#define MAKE_IMPORT_ENTRY(a_uMajorVer, a_uMinorVer, a_Name, a_cb) RESOLVE_IMPORT(a_uMajorVer, a_uMinorVer, a_Name, a_cb)
84#include "vcc100-kernel32-fakes.h"
85
86 g_fInitialized = true;
87}
88
89
90DECL_KERNEL32(PVOID) Fake_DecodePointer(PVOID pvEncoded)
91{
92 INIT_FAKES(DecodePointer,(pvEncoded));
93
94 /*
95 * Fallback code.
96 */
97 return pvEncoded;
98}
99
100
101DECL_KERNEL32(PVOID) Fake_EncodePointer(PVOID pvNative)
102{
103 INIT_FAKES(EncodePointer, (pvNative));
104
105 /*
106 * Fallback code.
107 */
108 return pvNative;
109}
110
111
112DECL_KERNEL32(BOOL) Fake_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION pCritSect, DWORD cSpin)
113{
114 INIT_FAKES(InitializeCriticalSectionAndSpinCount, (pCritSect, cSpin));
115
116 /*
117 * Fallback code.
118 */
119 InitializeCriticalSection(pCritSect);
120 return TRUE;
121}
122
123
124DECL_KERNEL32(BOOL) Fake_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS enmInfoClass, PVOID pvBuf, SIZE_T cbBuf)
125{
126 INIT_FAKES(HeapSetInformation, (hHeap, enmInfoClass, pvBuf, cbBuf));
127
128 /*
129 * Fallback code.
130 */
131 if (enmInfoClass == HeapCompatibilityInformation)
132 {
133 if ( cbBuf != sizeof(ULONG)
134 || !pvBuf
135 || *(PULONG)pvBuf == HEAP_STANDARD
136 )
137 {
138 SetLastError(ERROR_INVALID_PARAMETER);
139 return FALSE;
140 }
141 return TRUE;
142 }
143
144 SetLastError(ERROR_INVALID_PARAMETER);
145 return FALSE;
146}
147
148
149DECL_KERNEL32(BOOL) Fake_HeapQueryInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS enmInfoClass,
150 PVOID pvBuf, SIZE_T cbBuf, PSIZE_T pcbRet)
151{
152 INIT_FAKES(HeapQueryInformation, (hHeap, enmInfoClass, pvBuf, cbBuf, pcbRet));
153
154 /*
155 * Fallback code.
156 */
157 if (enmInfoClass == HeapCompatibilityInformation)
158 {
159 *pcbRet = sizeof(ULONG);
160 if (cbBuf < sizeof(ULONG) || !pvBuf)
161 {
162 SetLastError(ERROR_INSUFFICIENT_BUFFER);
163 return FALSE;
164 }
165 *(PULONG)pvBuf = HEAP_STANDARD;
166 return TRUE;
167 }
168
169 SetLastError(ERROR_INVALID_PARAMETER);
170 return FALSE;
171}
172
173
174/* These are used by INTEL\mt_obj\Timer.obj: */
175
176DECL_KERNEL32(HANDLE) Fake_CreateTimerQueue(void)
177{
178 INIT_FAKES(CreateTimerQueue, ());
179
180 SetLastError(ERROR_NOT_SUPPORTED);
181 return NULL;
182}
183
184DECL_KERNEL32(BOOL) Fake_CreateTimerQueueTimer(PHANDLE phTimer, HANDLE hTimerQueue, WAITORTIMERCALLBACK pfnCallback, PVOID pvUser,
185 DWORD msDueTime, DWORD msPeriod, ULONG fFlags)
186{
187 INIT_FAKES(CreateTimerQueueTimer, (phTimer, hTimerQueue, pfnCallback, pvUser, msDueTime, msPeriod, fFlags));
188
189 SetLastError(ERROR_NOT_SUPPORTED);
190 return FALSE;
191}
192
193DECL_KERNEL32(BOOL) Fake_DeleteTimerQueueTimer(HANDLE hTimerQueue, HANDLE hTimer, HANDLE hEvtCompletion)
194{
195 INIT_FAKES(DeleteTimerQueueTimer, (hTimerQueue, hTimer, hEvtCompletion));
196
197 SetLastError(ERROR_NOT_SUPPORTED);
198 return FALSE;
199}
200
201/* This is used by several APIs. */
202
203DECL_KERNEL32(VOID) Fake_InitializeSListHead(PSLIST_HEADER pHead)
204{
205 INIT_FAKES_VOID(InitializeSListHead, (pHead));
206
207 /* fallback: */
208 pHead->Alignment = 0;
209}
210
211
212DECL_KERNEL32(PSLIST_ENTRY) Fake_InterlockedFlushSList(PSLIST_HEADER pHead)
213{
214 INIT_FAKES(InterlockedFlushSList, (pHead));
215
216 /* fallback: */
217 PSLIST_ENTRY pRet = NULL;
218 if (pHead->Next.Next)
219 {
220 for (;;)
221 {
222 SLIST_HEADER OldHead = *pHead;
223 SLIST_HEADER NewHead;
224 NewHead.Alignment = 0;
225 NewHead.Sequence = OldHead.Sequence + 1;
226 if (ASMAtomicCmpXchgU64(&pHead->Alignment, NewHead.Alignment, OldHead.Alignment))
227 {
228 pRet = OldHead.Next.Next;
229 break;
230 }
231 }
232 }
233 return pRet;
234}
235
236DECL_KERNEL32(PSLIST_ENTRY) Fake_InterlockedPopEntrySList(PSLIST_HEADER pHead)
237{
238 INIT_FAKES(InterlockedPopEntrySList, (pHead));
239
240 /* fallback: */
241 PSLIST_ENTRY pRet = NULL;
242 for (;;)
243 {
244 SLIST_HEADER OldHead = *pHead;
245 pRet = OldHead.Next.Next;
246 if (pRet)
247 {
248 SLIST_HEADER NewHead;
249 __try
250 {
251 NewHead.Next.Next = pRet->Next;
252 }
253 __except(EXCEPTION_EXECUTE_HANDLER)
254 {
255 continue;
256 }
257 NewHead.Depth = OldHead.Depth - 1;
258 NewHead.Sequence = OldHead.Sequence + 1;
259 if (ASMAtomicCmpXchgU64(&pHead->Alignment, NewHead.Alignment, OldHead.Alignment))
260 break;
261 }
262 else
263 break;
264 }
265 return pRet;
266}
267
268DECL_KERNEL32(PSLIST_ENTRY) Fake_InterlockedPushEntrySList(PSLIST_HEADER pHead, PSLIST_ENTRY pEntry)
269{
270 INIT_FAKES(InterlockedPushEntrySList, (pHead, pEntry));
271
272 /* fallback: */
273 PSLIST_ENTRY pRet = NULL;
274 for (;;)
275 {
276 SLIST_HEADER OldHead = *pHead;
277 pRet = OldHead.Next.Next;
278 pEntry->Next = pRet;
279 SLIST_HEADER NewHead;
280 NewHead.Next.Next = pEntry;
281 NewHead.Depth = OldHead.Depth + 1;
282 NewHead.Sequence = OldHead.Sequence + 1;
283 if (ASMAtomicCmpXchgU64(&pHead->Alignment, NewHead.Alignment, OldHead.Alignment))
284 break;
285 }
286 return pRet;
287}
288
289DECL_KERNEL32(WORD) Fake_QueryDepthSList(PSLIST_HEADER pHead)
290{
291 INIT_FAKES(QueryDepthSList, (pHead));
292
293 /* fallback: */
294 return pHead->Depth;
295}
296
297
298/* curl drags these in: */
299DECL_KERNEL32(BOOL) Fake_VerifyVersionInfoA(LPOSVERSIONINFOEXA pInfo, DWORD fTypeMask, DWORDLONG fConditionMask)
300{
301 INIT_FAKES(VerifyVersionInfoA, (pInfo, fTypeMask, fConditionMask));
302
303 /* fallback to make curl happy: */
304 OSVERSIONINFOEXA VerInfo;
305 RT_ZERO(VerInfo);
306 VerInfo.dwOSVersionInfoSize = sizeof(VerInfo);
307 if (!GetVersionExA((OSVERSIONINFO *)&VerInfo))
308 {
309 RT_ZERO(VerInfo);
310 VerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
311 BOOL fRet = GetVersionExA((OSVERSIONINFO *)&VerInfo);
312 if (fRet)
313 { /* likely */ }
314 else
315 {
316 MY_ASSERT(false, "VerifyVersionInfoA: #1");
317 return FALSE;
318 }
319 }
320
321 BOOL fRet = TRUE;
322 for (unsigned i = 0; i < 8 && fRet; i++)
323 if (fTypeMask & RT_BIT_32(i))
324 {
325 uint32_t uLeft, uRight;
326 switch (RT_BIT_32(i))
327 {
328#define MY_CASE(a_Num, a_Member) case a_Num: uLeft = VerInfo.a_Member; uRight = pInfo->a_Member; break
329 MY_CASE(VER_MINORVERSION, dwMinorVersion);
330 MY_CASE(VER_MAJORVERSION, dwMajorVersion);
331 MY_CASE(VER_BUILDNUMBER, dwBuildNumber);
332 MY_CASE(VER_PLATFORMID, dwPlatformId);
333 MY_CASE(VER_SERVICEPACKMINOR, wServicePackMinor);
334 MY_CASE(VER_SERVICEPACKMAJOR, wServicePackMinor);
335 MY_CASE(VER_SUITENAME, wSuiteMask);
336 MY_CASE(VER_PRODUCT_TYPE, wProductType);
337#undef MY_CASE
338 default: uLeft = uRight = 0; MY_ASSERT(false, "VerifyVersionInfoA: #2");
339 }
340 switch ((uint8_t)(fConditionMask >> (i*8)))
341 {
342 case VER_EQUAL: fRet = uLeft == uRight; break;
343 case VER_GREATER: fRet = uLeft > uRight; break;
344 case VER_GREATER_EQUAL: fRet = uLeft >= uRight; break;
345 case VER_LESS: fRet = uLeft < uRight; break;
346 case VER_LESS_EQUAL: fRet = uLeft <= uRight; break;
347 case VER_AND: fRet = (uLeft & uRight) == uRight; break;
348 case VER_OR: fRet = (uLeft & uRight) != 0; break;
349 default: fRet = FALSE; MY_ASSERT(false, "VerifyVersionInfoA: #3"); break;
350 }
351 }
352
353 return fRet;
354}
355
356
357DECL_KERNEL32(ULONGLONG) Fake_VerSetConditionMask(ULONGLONG fConditionMask, DWORD fTypeMask, BYTE bOperator)
358{
359 INIT_FAKES(VerSetConditionMask, (fConditionMask, fTypeMask, bOperator));
360
361 /* fallback: */
362 for (unsigned i = 0; i < 8; i++)
363 if (fTypeMask & RT_BIT_32(i))
364 {
365 uint64_t fMask = UINT64_C(0xff) << (i*8);
366 fConditionMask &= ~fMask;
367 fConditionMask |= (uint64_t)bOperator << (i*8);
368
369 }
370 return fConditionMask;
371}
372
373
374/*
375 * NT 3.51 stuff.
376 */
377
378DECL_KERNEL32(BOOL) Fake_IsProcessorFeaturePresent(DWORD enmProcessorFeature)
379{
380 INIT_FAKES(IsProcessorFeaturePresent, (enmProcessorFeature));
381
382 /* Could make more of an effort here... */
383 return FALSE;
384}
385
386
387DECL_KERNEL32(BOOL) Fake_CancelIo(HANDLE hHandle)
388{
389 INIT_FAKES(CancelIo, (hHandle));
390
391 /* NT 3.51 have the NTDLL API this corresponds to. */
392 RESOLVE_NTDLL_API(NtCancelIoFile);
393 if (pfnNtCancelIoFile)
394 {
395 IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
396 NTSTATUS rcNt = pfnNtCancelIoFile(hHandle, &Ios);
397 if (RT_SUCCESS(rcNt))
398 return TRUE;
399 if (rcNt == STATUS_INVALID_HANDLE)
400 SetLastError(ERROR_INVALID_HANDLE);
401 else
402 SetLastError(ERROR_INVALID_FUNCTION);
403 }
404 else
405 SetLastError(ERROR_NOT_SUPPORTED);
406 return FALSE;
407}
408
409
410/*
411 * NT 3.50 stuff.
412 */
413
414DECL_KERNEL32(BOOL) Fake_IsDebuggerPresent(VOID)
415{
416 INIT_FAKES(IsDebuggerPresent, ());
417
418 /* Fallback: */
419 return FALSE;
420}
421
422
423DECL_KERNEL32(VOID) Fake_GetSystemTimeAsFileTime(LPFILETIME pTime)
424{
425 INIT_FAKES_VOID(GetSystemTimeAsFileTime, (pTime));
426
427 DWORD dwVersion = GetVersion();
428 if ( (dwVersion & 0xff) > 3
429 || ( (dwVersion & 0xff) == 3
430 && ((dwVersion >> 8) & 0xff) >= 50) )
431 {
432 PKUSER_SHARED_DATA pUsd = (PKUSER_SHARED_DATA)MM_SHARED_USER_DATA_VA;
433
434 /* use interrupt time */
435 LARGE_INTEGER Time;
436 do
437 {
438 Time.HighPart = pUsd->SystemTime.High1Time;
439 Time.LowPart = pUsd->SystemTime.LowPart;
440 } while (pUsd->SystemTime.High2Time != Time.HighPart);
441
442 pTime->dwHighDateTime = Time.HighPart;
443 pTime->dwLowDateTime = Time.LowPart;
444 }
445 else
446 {
447 /* NT 3.1 didn't have a KUSER_SHARED_DATA nor a GetSystemTimeAsFileTime export. */
448 SYSTEMTIME SystemTime;
449 GetSystemTime(&SystemTime);
450 BOOL fRet = SystemTimeToFileTime(&SystemTime, pTime);
451 if (fRet)
452 { /* likely */ }
453 else
454 {
455 MY_ASSERT(false, "GetSystemTimeAsFileTime: #2");
456 pTime->dwHighDateTime = 0;
457 pTime->dwLowDateTime = 0;
458 }
459 }
460}
461
462
463/*
464 * NT 3.1 stuff.
465 */
466
467DECL_KERNEL32(BOOL) Fake_GetVersionExA(LPOSVERSIONINFOA pInfo)
468{
469 INIT_FAKES(GetVersionExA, (pInfo));
470
471 /*
472 * Fallback.
473 */
474 DWORD dwVersion = GetVersion();
475
476 /* Common fields: */
477 pInfo->dwMajorVersion = dwVersion & 0xff;
478 pInfo->dwMinorVersion = (dwVersion >> 8) & 0xff;
479 if (!(dwVersion & RT_BIT_32(31)))
480 pInfo->dwBuildNumber = dwVersion >> 16;
481 else
482 pInfo->dwBuildNumber = 511;
483 pInfo->dwPlatformId = VER_PLATFORM_WIN32_NT;
484/** @todo get CSD from registry. */
485 pInfo->szCSDVersion[0] = '\0';
486
487 /* OSVERSIONINFOEX fields: */
488 if (pInfo->dwOSVersionInfoSize > sizeof((*pInfo)))
489 {
490 LPOSVERSIONINFOEXA pInfoEx = (LPOSVERSIONINFOEXA)pInfo;
491 if (pInfoEx->dwOSVersionInfoSize > RT_UOFFSETOF(OSVERSIONINFOEXA, wServicePackMinor))
492 {
493 pInfoEx->wServicePackMajor = 0;
494 pInfoEx->wServicePackMinor = 0;
495 }
496 if (pInfoEx->dwOSVersionInfoSize > RT_UOFFSETOF(OSVERSIONINFOEXA, wSuiteMask))
497 pInfoEx->wSuiteMask = 0;
498 if (pInfoEx->dwOSVersionInfoSize > RT_UOFFSETOF(OSVERSIONINFOEXA, wProductType))
499 pInfoEx->wProductType = VER_NT_WORKSTATION;
500 if (pInfoEx->wReserved > RT_UOFFSETOF(OSVERSIONINFOEXA, wProductType))
501 pInfoEx->wReserved = 0;
502 }
503
504 return TRUE;
505}
506
507
508DECL_KERNEL32(BOOL) Fake_GetVersionExW(LPOSVERSIONINFOW pInfo)
509{
510 INIT_FAKES(GetVersionExW, (pInfo));
511
512 /*
513 * Fallback.
514 */
515 DWORD dwVersion = GetVersion();
516
517 /* Common fields: */
518 pInfo->dwMajorVersion = dwVersion & 0xff;
519 pInfo->dwMinorVersion = (dwVersion >> 8) & 0xff;
520 if (!(dwVersion & RT_BIT_32(31)))
521 pInfo->dwBuildNumber = dwVersion >> 16;
522 else
523 pInfo->dwBuildNumber = 511;
524 pInfo->dwPlatformId = VER_PLATFORM_WIN32_NT;
525/** @todo get CSD from registry. */
526 pInfo->szCSDVersion[0] = '\0';
527
528 /* OSVERSIONINFOEX fields: */
529 if (pInfo->dwOSVersionInfoSize > sizeof((*pInfo)))
530 {
531 LPOSVERSIONINFOEXW pInfoEx = (LPOSVERSIONINFOEXW)pInfo;
532 if (pInfoEx->dwOSVersionInfoSize > RT_UOFFSETOF(OSVERSIONINFOEXW, wServicePackMinor))
533 {
534 pInfoEx->wServicePackMajor = 0;
535 pInfoEx->wServicePackMinor = 0;
536 }
537 if (pInfoEx->dwOSVersionInfoSize > RT_UOFFSETOF(OSVERSIONINFOEXW, wSuiteMask))
538 pInfoEx->wSuiteMask = 0;
539 if (pInfoEx->dwOSVersionInfoSize > RT_UOFFSETOF(OSVERSIONINFOEXW, wProductType))
540 pInfoEx->wProductType = VER_NT_WORKSTATION;
541 if (pInfoEx->wReserved > RT_UOFFSETOF(OSVERSIONINFOEXW, wProductType))
542 pInfoEx->wReserved = 0;
543 }
544
545 return TRUE;
546}
547
548
549DECL_KERNEL32(LPWCH) Fake_GetEnvironmentStringsW(void)
550{
551 INIT_FAKES(GetEnvironmentStringsW, ());
552
553 /*
554 * Fallback:
555 *
556 * Environment is ANSI in NT 3.1. We should only be here for NT 3.1.
557 * For now, don't try do a perfect job converting it, just do it.
558 */
559 char *pszzEnv = (char *)RTNtCurrentPeb()->ProcessParameters->Environment;
560 size_t offEnv = 0;
561 while (pszzEnv[offEnv] != '\0')
562 {
563 size_t cchLen = strlen(&pszzEnv[offEnv]);
564 offEnv += cchLen + 1;
565 }
566 size_t const cchEnv = offEnv + 1;
567
568 PRTUTF16 pwszzEnv = (PRTUTF16)HeapAlloc(GetProcessHeap(), 0, cchEnv * sizeof(RTUTF16));
569 if (!pwszzEnv)
570 return NULL;
571 for (offEnv = 0; offEnv < cchEnv; offEnv++)
572 {
573 unsigned char ch = pwszzEnv[offEnv];
574 if (!(ch & 0x80))
575 pwszzEnv[offEnv] = ch;
576 else
577 pwszzEnv[offEnv] = '_';
578 }
579 return pwszzEnv;
580}
581
582
583DECL_KERNEL32(BOOL) Fake_FreeEnvironmentStringsW(LPWCH pwszzEnv)
584{
585 INIT_FAKES(FreeEnvironmentStringsW, (pwszzEnv));
586
587 /* Fallback: */
588 if (pwszzEnv)
589 HeapFree(GetProcessHeap(), 0, pwszzEnv);
590 return TRUE;
591}
592
593
594DECL_KERNEL32(int) Fake_GetLocaleInfoA(LCID idLocale, LCTYPE enmType, LPSTR pData, int cchData)
595{
596 INIT_FAKES(GetLocaleInfoA, (idLocale, enmType, pData, cchData));
597
598 /* Fallback: */
599 MY_ASSERT(false, "GetLocaleInfoA: idLocale=%#x enmType=%#x cchData=%#x", idLocale, enmType, cchData);
600 SetLastError(ERROR_NOT_SUPPORTED);
601 return 0;
602}
603
604
605DECL_KERNEL32(BOOL) Fake_EnumSystemLocalesA(LOCALE_ENUMPROCA pfnCallback, DWORD fFlags)
606{
607 INIT_FAKES(EnumSystemLocalesA, (pfnCallback, fFlags));
608
609 /* Fallback: */
610 MY_ASSERT(false, "EnumSystemLocalesA: pfnCallback=%p fFlags=%#x", pfnCallback, fFlags);
611 SetLastError(ERROR_NOT_SUPPORTED);
612 return FALSE;
613}
614
615
616DECL_KERNEL32(BOOL) Fake_IsValidLocale(LCID idLocale, DWORD fFlags)
617{
618 INIT_FAKES(IsValidLocale, (idLocale, fFlags));
619
620 /* Fallback: */
621 MY_ASSERT(false, "IsValidLocale: idLocale fFlags=%#x", idLocale, fFlags);
622 SetLastError(ERROR_NOT_SUPPORTED);
623 return FALSE;
624}
625
626
627DECL_KERNEL32(DWORD_PTR) Fake_SetThreadAffinityMask(HANDLE hThread, DWORD_PTR fAffinityMask)
628{
629 INIT_FAKES(SetThreadAffinityMask, (hThread, fAffinityMask));
630
631 /* Fallback: */
632 SYSTEM_INFO SysInfo;
633 GetSystemInfo(&SysInfo);
634 MY_ASSERT(false, "SetThreadAffinityMask: hThread=%p fAffinityMask=%p SysInfo.dwActiveProcessorMask=%p",
635 hThread, fAffinityMask, SysInfo.dwActiveProcessorMask);
636 if ( SysInfo.dwActiveProcessorMask == fAffinityMask
637 || fAffinityMask == ~(DWORD_PTR)0)
638 return fAffinityMask;
639
640 SetLastError(ERROR_NOT_SUPPORTED);
641 return 0;
642}
643
644
645DECL_KERNEL32(BOOL) Fake_GetProcessAffinityMask(HANDLE hProcess, PDWORD_PTR pfProcessAffinityMask, PDWORD_PTR pfSystemAffinityMask)
646{
647 INIT_FAKES(GetProcessAffinityMask, (hProcess, pfProcessAffinityMask, pfSystemAffinityMask));
648
649 /* Fallback: */
650 SYSTEM_INFO SysInfo;
651 GetSystemInfo(&SysInfo);
652 MY_ASSERT(false, "GetProcessAffinityMask: SysInfo.dwActiveProcessorMask=%p", SysInfo.dwActiveProcessorMask);
653 if (pfProcessAffinityMask)
654 *pfProcessAffinityMask = SysInfo.dwActiveProcessorMask;
655 if (pfSystemAffinityMask)
656 *pfSystemAffinityMask = SysInfo.dwActiveProcessorMask;
657 return TRUE;
658}
659
660
661DECL_KERNEL32(BOOL) Fake_GetHandleInformation(HANDLE hObject, DWORD *pfFlags)
662{
663 INIT_FAKES(GetHandleInformation, (hObject, pfFlags));
664
665 /* Fallback: */
666 OBJECT_HANDLE_FLAG_INFORMATION Info = { 0, 0 };
667 DWORD cbRet = sizeof(Info);
668 NTSTATUS rcNt = NtQueryObject(hObject, ObjectHandleFlagInformation, &Info, sizeof(Info), &cbRet);
669 if (NT_SUCCESS(rcNt))
670 {
671 *pfFlags = (Info.Inherit ? HANDLE_FLAG_INHERIT : 0)
672 | (Info.ProtectFromClose ? HANDLE_FLAG_PROTECT_FROM_CLOSE : 0);
673 return TRUE;
674 }
675 *pfFlags = 0;
676 MY_ASSERT(rcNt == STATUS_INVALID_HANDLE, "rcNt=%#x", rcNt);
677 SetLastError(rcNt == STATUS_INVALID_HANDLE ? ERROR_INVALID_HANDLE : ERROR_INVALID_FUNCTION); /* see also process-win.cpp */
678 return FALSE;
679}
680
681
682DECL_KERNEL32(BOOL) Fake_SetHandleInformation(HANDLE hObject, DWORD fMask, DWORD fFlags)
683{
684 INIT_FAKES(SetHandleInformation, (hObject, fMask, fFlags));
685
686 /* Fallback: */
687 SetLastError(ERROR_INVALID_FUNCTION);
688 return FALSE;
689}
690
691
692/* Dummy to force dragging in this object in the link, so the linker
693 won't accidentally use the symbols from kernel32. */
694extern "C" int vcc100_kernel32_fakes_cpp(void)
695{
696 return 42;
697}
698
Note: See TracBrowser for help on using the repository browser.

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