Skip to content
This repository was archived by the owner on Jul 26, 2023. It is now read-only.

Conversation

@vatsan-madhavan
Copy link
Member

  • P/Invokes for kernel32!VerifyVersionInfo & ntdll!RtlVerifyVersionInfo
    • Could not identify a suitable API Set DLL for kernel32!VerifyVersionInfo, so using kernel32 directly in DllImport
  • Support methods
    • kernel32!VerSetConditionMask
  • Support types
    • OSVERSIONINFOEX, OS_TYPE, PRODUCT_SUITE, VER_MASK, VER_CONDITION

@vatsan-madhavan vatsan-madhavan changed the title kernel32!VerifyVersionInfoEx and ntdll!RtlVerifyVersionInfoEx kernel32!VerifyVersionInfo and ntdll!RtlVerifyVersionInfo Oct 13, 2019
Copy link
Collaborator

@AArnott AArnott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this valuable contribution. You've clearly taken great care to follow many of our guidelines. Just a few touch-ups please and I'll be happy to merge this.

@vatsan-madhavan
Copy link
Member Author

Thanks for the quick feedback - I hope I've addressed all of them.

@vatsan-madhavan
Copy link
Member Author

Something odd I noticed while working on this PR:

In the OS, kernel32.dll depends on ntdll.dll, and not the other way around. In the PInvoke library, PInvoke.NTDll depends on PInvoke.Kernel32, which was somewhat confusing for me.

There are functions in Kernel32.dll which are simple forwards into ntdll.dll. For e.g.,

dumpbin /exports kernel32.dll | findstr /i ntdll 
          4    0          AcquireSRWLockExclusive (forwarded to NTDLL.RtlAcquireSRWLockExclusive)
          5    1          AcquireSRWLockShared (forwarded to NTDLL.RtlAcquireSRWLockShared)
         22   12          AddVectoredContinueHandler (forwarded to NTDLL.RtlAddVectoredContinueHandler)
         23   13          AddVectoredExceptionHandler (forwarded to NTDLL.RtlAddVectoredExceptionHandler)
        123   78          CancelThreadpoolIo (forwarded to NTDLL.TpCancelAsyncIoOperation)
        147   90          CloseThreadpool (forwarded to NTDLL.TpReleasePool)
        148   91          CloseThreadpoolCleanupGroup (forwarded to NTDLL.TpReleaseCleanupGroup)
        149   92          CloseThreadpoolCleanupGroupMembers (forwarded to NTDLL.TpReleaseCleanupGroupMembers)
        150   93          CloseThreadpoolIo (forwarded to NTDLL.TpReleaseIoCompletion)
        151   94          CloseThreadpoolTimer (forwarded to NTDLL.TpReleaseTimer)
        152   95          CloseThreadpoolWait (forwarded to NTDLL.TpReleaseWait)
        153   96          CloseThreadpoolWork (forwarded to NTDLL.TpReleaseWork)
        272  10D          DecodePointer (forwarded to NTDLL.RtlDecodePointer)
        273  10E          DecodeSystemPointer (forwarded to NTDLL.RtlDecodeSystemPointer)
        279  114          DeleteCriticalSection (forwarded to NTDLL.RtlDeleteCriticalSection)
        295  124          DisassociateCurrentThreadFromCallback (forwarded to NTDLL.TpDisassociateCallback)
        308  131          EncodePointer (forwarded to NTDLL.RtlEncodePointer)
        309  132          EncodeSystemPointer (forwarded to NTDLL.RtlEncodeSystemPointer)
        312  135          EnterCriticalSection (forwarded to NTDLL.RtlEnterCriticalSection)
        358  163          ExitThread (forwarded to NTDLL.RtlExitUserThread)
        424  1A5          FlushProcessWriteBuffers (forwarded to NTDLL.NtFlushProcessWriteBuffers)
        436  1B1          FreeLibraryWhenCallbackReturns (forwarded to NTDLL.TpCallbackUnloadDllOnCompletion)
        544  21D          GetCurrentProcessorNumber (forwarded to NTDLL.RtlGetCurrentProcessorNumber)
        545  21E          GetCurrentProcessorNumberEx (forwarded to NTDLL.RtlGetCurrentProcessorNumberEx)
        844  349          HeapAlloc (forwarded to NTDLL.RtlAllocateHeap)
        851  350          HeapReAlloc (forwarded to NTDLL.RtlReAllocateHeap)
        853  352          HeapSize (forwarded to NTDLL.RtlSizeHeap)
        865  35E          InitOnceInitialize (forwarded to NTDLL.RtlRunOnceInitialize)
        866  35F          InitializeConditionVariable (forwarded to NTDLL.RtlInitializeConditionVariable)
        869  362          InitializeCriticalSection (forwarded to NTDLL.RtlInitializeCriticalSection)
        874  367          InitializeSListHead (forwarded to NTDLL.RtlInitializeSListHead)
        875  368          InitializeSRWLock (forwarded to NTDLL.RtlInitializeSRWLock)
        878  36C          InterlockedCompareExchange64 (forwarded to NTDLL.RtlInterlockedCompareExchange64)
        883  370          InterlockedFlushSList (forwarded to NTDLL.RtlInterlockedFlushSList)
        885  372          InterlockedPopEntrySList (forwarded to NTDLL.RtlInterlockedPopEntrySList)
        886  373          InterlockedPushEntrySList (forwarded to NTDLL.RtlInterlockedPushEntrySList)
          2  374          InterlockedPushListSList (forwarded to NTDLL.RtlInterlockedPushListSList)
        887  375          InterlockedPushListSListEx (forwarded to NTDLL.RtlInterlockedPushListSListEx)
        911  38D          IsThreadpoolTimerSet (forwarded to NTDLL.TpIsTimerSet)
        964  3C2          LeaveCriticalSection (forwarded to NTDLL.RtlLeaveCriticalSection)
        965  3C3          LeaveCriticalSectionWhenCallbackReturns (forwarded to NTDLL.TpCallbackLeaveCriticalSectionOnCompletion)
       1096  446          QueryDepthSList (forwarded to NTDLL.RtlQueryDepthSList)
       1206  4B4          ReleaseMutexWhenCallbackReturns (forwarded to NTDLL.TpCallbackReleaseMutexOnCompletion)
       1207  4B5          ReleaseSRWLockExclusive (forwarded to NTDLL.RtlReleaseSRWLockExclusive)
       1208  4B6          ReleaseSRWLockShared (forwarded to NTDLL.RtlReleaseSRWLockShared)
       1210  4B8          ReleaseSemaphoreWhenCallbackReturns (forwarded to NTDLL.TpCallbackReleaseSemaphoreOnCompletion)
       1219  4C1          RemoveVectoredContinueHandler (forwarded to NTDLL.RtlRemoveVectoredContinueHandler)
       1220  4C2          RemoveVectoredExceptionHandler (forwarded to NTDLL.RtlRemoveVectoredExceptionHandler)
       1230  4CC          ResolveDelayLoadedAPI (forwarded to NTDLL.LdrResolveDelayLoadedAPI)
       1231  4CD          ResolveDelayLoadsFromDll (forwarded to NTDLL.LdrResolveDelayLoadsFromDll)
       1233  4CF          RestoreLastError (forwarded to NTDLL.RtlRestoreLastWin32Error)
       1238  4D4          RtlMoveMemory (forwarded to NTDLL.RtlMoveMemory)
       1241  4D7          RtlZeroMemory (forwarded to NTDLL.RtlZeroMemory)
       1291  509          SetCriticalSectionSpinCount (forwarded to NTDLL.RtlSetCriticalSectionSpinCount)
       1308  51A          SetEventWhenCallbackReturns (forwarded to NTDLL.TpCallbackSetEventOnCompletion)
       1386  568          SetThreadpoolThreadMaximum (forwarded to NTDLL.TpSetPoolMaxThreads)
       1388  56A          SetThreadpoolTimer (forwarded to NTDLL.TpSetTimer)
       1389  56B          SetThreadpoolTimerEx (forwarded to NTDLL.TpSetTimerEx)
       1390  56C          SetThreadpoolWait (forwarded to NTDLL.TpSetWait)
       1391  56D          SetThreadpoolWaitEx (forwarded to NTDLL.TpSetWaitEx)
       1416  586          StartThreadpoolIo (forwarded to NTDLL.TpStartAsyncIoOperation)
       1417  587          SubmitThreadpoolWork (forwarded to NTDLL.TpPostWork)
       1450  5A8          TryAcquireSRWLockExclusive (forwarded to NTDLL.RtlTryAcquireSRWLockExclusive)
       1451  5A9          TryAcquireSRWLockShared (forwarded to NTDLL.RtlTryAcquireSRWLockShared)
       1452  5AA          TryEnterCriticalSection (forwarded to NTDLL.RtlTryEnterCriticalSection)
       1478  5C4          VerSetConditionMask (forwarded to NTDLL.VerSetConditionMask)
       1502  5DC          WaitForThreadpoolIoCallbacks (forwarded to NTDLL.TpWaitForIoCompletion)
       1503  5DD          WaitForThreadpoolTimerCallbacks (forwarded to NTDLL.TpWaitForTimer)
       1504  5DE          WaitForThreadpoolWaitCallbacks (forwarded to NTDLL.TpWaitForWait)
       1505  5DF          WaitForThreadpoolWorkCallbacks (forwarded to NTDLL.TpWaitForWork)
       1508  5E2          WakeAllConditionVariable (forwarded to NTDLL.RtlWakeAllConditionVariable)
       1509  5E3          WakeConditionVariable (forwarded to NTDLL.RtlWakeConditionVariable)

I haven't analyzed to check whether any of these have public documentation for each of the kernel32 and ntdll exports respectively, which would in turn make it plausible to imagine a scenario where only an ntdll P/Invoke needs to be written, and the corresponding PInvoke.Kernel32 implementation would simply become a call into the PInvoke.NTDll P/Invoke method.

Even without necessarily invoking the (possibly dubious) optimization suggested above, the architectural inversion caught my eye.

@AArnott AArnott merged commit 5101d30 into dotnet:master Oct 15, 2019
@vatsan-madhavan vatsan-madhavan deleted the ntdll-versionapis branch October 15, 2019 02:40
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants