1919#include < ntstatus.h>
2020#endif
2121
22- std::vector <uint32_t > g_doNotDestroyHandles {};
22+ std::unordered_map <uint32_t , uint32_t > g_handleDuplicates {};
2323
2424struct Event final : KernelObject, HostObject<XKEVENT >
2525{
@@ -336,7 +336,6 @@ uint32_t XGetAVPack()
336336
337337void XamLoaderTerminateTitle ()
338338{
339- printf (" XamLoaderTerminateTitle\n " );
340339 LOG_UTILITY (" !!! STUB !!!" );
341340}
342341
@@ -376,7 +375,7 @@ uint32_t NtCreateFile
376375 uint32_t CreateOptions
377376)
378377{
379- printf ( " NtCreateFile \n " );
378+ LOG_UTILITY ( " !!! STUB !!! " );
380379 return 0 ;
381380}
382381
@@ -387,10 +386,13 @@ uint32_t NtClose(uint32_t handle)
387386
388387 if (IsKernelObject (handle))
389388 {
390- auto it = std::find (g_doNotDestroyHandles.begin (), g_doNotDestroyHandles.end (), handle);
391- if (it == g_doNotDestroyHandles.end ()) {
389+ // If the handle was duplicated, just decrement the duplication count. Otherwise, delete the object.
390+ const auto & it = g_handleDuplicates.find (handle);
391+ if (it == g_handleDuplicates.end () || it->second == 0 )
392392 DestroyKernelObject (handle);
393- }
393+ else if (--it->second == 0 )
394+ g_handleDuplicates.erase (it);
395+
394396 return 0 ;
395397 }
396398 else
@@ -432,6 +434,9 @@ uint32_t XamLoaderSetLaunchData()
432434
433435uint32_t NtWaitForSingleObjectEx (uint32_t Handle, uint32_t WaitMode, uint32_t Alertable, be<int64_t >* Timeout)
434436{
437+ if (Handle == GUEST_INVALID_HANDLE_VALUE )
438+ return 0xFFFFFFFF ;
439+
435440 uint32_t timeout = GuestTimeoutToMilliseconds (Timeout);
436441 // assert(timeout == 0 || timeout == INFINITE);
437442
@@ -555,11 +560,29 @@ void __C_specific_handler_x()
555560 LOG_UTILITY (" !!! STUB !!!" );
556561}
557562
558- void RtlNtStatusToDosError (int Status)
563+ uint32_t RtlNtStatusToDosError (uint32_t Status)
559564{
560- LOG_UTILITY (" !!! STUB !!!" );
561- printf (" RtlNtStatusToDosError: %x\n " , Status);
562- // __builtin_trap();
565+ // See https://github.com/wine-mirror/wine/blob/master/dlls/ntdll/error.c#L47-L64
566+ if (Status == 0 || (Status & 0x20000000 ) != 0 )
567+ return Status;
568+
569+ if ((Status & 0xF0000000 ) == 0xD0000000 )
570+ Status &= ~0x10000000 ;
571+
572+ const uint32_t hi = (Status >> 16 ) & 0xFFFF ;
573+ if (hi == 0x8007 || hi == 0xC001 || hi == 0xC007 )
574+ return Status & 0xFFFF ;
575+
576+ switch (Status)
577+ {
578+ case STATUS_NOT_IMPLEMENTED :
579+ return ERROR_CALL_NOT_IMPLEMENTED ;
580+ case STATUS_SEMAPHORE_LIMIT_EXCEEDED :
581+ return ERROR_TOO_MANY_POSTS ;
582+ default :
583+ LOGF_WARNING (" Unimplemented NtStatus translation: {:#08x}" , Status);
584+ return Status;
585+ }
563586}
564587
565588void XexGetProcedureAddress ()
@@ -642,20 +665,28 @@ void NtReadFile()
642665 LOG_UTILITY (" !!! STUB !!!" );
643666}
644667
645- int NtDuplicateObject (uint32_t sourceHandle , be<uint32_t >* targetHandle , uint32_t options )
668+ uint32_t NtDuplicateObject (uint32_t SourceHandle , be<uint32_t >* TargetHandle , uint32_t Options )
646669{
647- auto obj = GetKernelObject (sourceHandle);
648- // HACK: Duplicating handle doesn't supported now, so we just these handles to array to ignore of closing these handles
649- printf (" NtDuplicateObject: %x %x %d, obj: %x\n " , sourceHandle, targetHandle, options, obj);
650- auto it = std::find (g_doNotDestroyHandles.begin (), g_doNotDestroyHandles.end (), sourceHandle);
651- if (it == g_doNotDestroyHandles.end ()) {
652- g_doNotDestroyHandles.push_back (sourceHandle);
670+ if (SourceHandle == GUEST_INVALID_HANDLE_VALUE )
671+ return 0xFFFFFFFF ;
672+
673+ if (IsKernelObject (SourceHandle))
674+ {
675+ // Increment handle duplicate count.
676+ const auto & it = g_handleDuplicates.find (SourceHandle);
677+ if (it != g_handleDuplicates.end ())
678+ ++it->second ;
679+ else
680+ g_handleDuplicates[SourceHandle] = 1 ;
681+
682+ *TargetHandle = SourceHandle;
683+ return 0 ;
684+ }
685+ else
686+ {
687+ assert (false && " Unrecognized kernel object." );
688+ return 0xFFFFFFFF ;
653689 }
654- if (!obj) return -1 ;
655- uint32_t newHandle = 0 ;
656- newHandle = sourceHandle;
657- *targetHandle = newHandle;
658- return 0 ;
659690}
660691
661692void NtAllocateVirtualMemory ()
@@ -758,13 +789,11 @@ void RtlEnterCriticalSection(XRTL_CRITICAL_SECTION* cs)
758789
759790void RtlImageXexHeaderField ()
760791{
761- printf (" RtlImageXexHeaderField\n " );
762792 LOG_UTILITY (" !!! STUB !!!" );
763793}
764794
765795void HalReturnToFirmware ()
766796{
767- printf (" HalReturnToFirmware\n " );
768797 LOG_UTILITY (" !!! STUB !!!" );
769798}
770799
@@ -909,7 +938,7 @@ void sprintf_x()
909938
910939int32_t ExRegisterTitleTerminateNotification (uint32_t * reg, uint32_t create)
911940{
912- printf ( " ExRegisterTitleTerminateNotification: %x %d \n " , reg, create );
941+ LOG_UTILITY ( " !!! STUB !!! " );
913942 return 0 ;
914943}
915944
@@ -1111,7 +1140,6 @@ uint32_t KeTlsGetValue(uint32_t dwTlsIndex)
11111140
11121141uint32_t KeTlsSetValue (uint32_t dwTlsIndex, uint32_t lpTlsValue)
11131142{
1114- printf (" KeTlsSetValue\n " );
11151143 KeTlsGetValueRef (dwTlsIndex) = lpTlsValue;
11161144 return TRUE ;
11171145}
0 commit comments