Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

There are many APIs that are exported as stdcall but are now declared to be cdecl #1217

Closed
kennykerr opened this issue Sep 2, 2022 · 7 comments · Fixed by #1232
Closed
Labels
rust Critical for Rust adoption

Comments

@kennykerr
Copy link
Contributor

There are a lot more now cdecl that aren't in the real DLLs (probably incomplete list):

__imp__WTSEnableChildSessions
__imp__WTSGetChildSessionId
__imp__WTSIsChildSessionsEnabled
__imp__CreatePrinterIC
__imp__DeletePrinterIC
__imp__ExtDeviceMode
__imp__PlayGdiScriptOnPrinterIC
__imp__RouterFreeBidiResponseContainer
__imp__DoConnectoidsExist
__imp__IsProfilesEnabled
__imp__PerformOperationOverUrlCacheA
__imp__UrlCacheFreeGlobalSpace
__imp__UrlCacheGetGlobalCacheSize
__imp__WerFreeString
__imp__WerStoreClose
__imp__WerStoreGetFirstReportKey
__imp__WerStoreGetNextReportKey
__imp__WerStoreGetReportCount
__imp__WerStoreGetSizeOnDisk
__imp__WerStoreOpen
__imp__WerStorePurge
__imp__WerStoreQueryReportMetadataV1
__imp__WerStoreQueryReportMetadataV2
__imp__WerStoreQueryReportMetadataV3
__imp__WerStoreUploadReport
__imp__PxeProviderFreeInfo
__imp__GetDeviceIDString
__imp__SrpIsTokenService
__imp__AppendPrinterNotifyInfoData
__imp__CallRouterFindFirstPrinterChangeNotification
__imp__GetJobAttributesEx
__imp__ImpersonatePrinterClient
__imp__PartialReplyPrinterChangeNotification
__imp__ProvidorFindClosePrinterChangeNotification
__imp__ProvidorFindFirstPrinterChangeNotification
__imp__ReplyPrinterChangeNotificationEx
__imp__RevertToPrinterSelf
__imp__RouterAllocBidiMem
__imp__RouterAllocBidiResponseContainer
__imp__RouterAllocPrinterNotifyInfo
__imp__RouterFreeBidiMem
__imp__RouterFreePrinterNotifyInfo
__imp__SplIsSessionZero
__imp__SplPromptUIInUsersSession
__imp__SpoolerFindClosePrinterChangeNotification
__imp__SpoolerFindFirstPrinterChangeNotification
__imp__SpoolerFindNextPrinterChangeNotification
__imp__SpoolerFreePrinterNotifyInfo
__imp__SpoolerRefreshPrinterChangeNotification
__imp__CollectionsListAllocateBufferAndSerialize
__imp__CollectionsListCopyAndMarshall
__imp__CollectionsListDeserializeFromBuffer
__imp__CollectionsListGetFillableCount
__imp__CollectionsListGetMarshalledSizeWithoutSerialization
__imp__CollectionsListGetSerializedSize
__imp__CollectionsListMarshall
__imp__CollectionsListSerializeToBuffer
__imp__CollectionsListSortSubscribedActivitiesByConfidence
__imp__CollectionsListUpdateMarshalledPointer
__imp__EvaluateActivityThresholds
__imp__GetPerformanceTime
__imp__InitPropVariantFromCLSIDArray
__imp__InitPropVariantFromFloat
__imp__IsCollectionListSame
__imp__IsGUIDPresentInList
__imp__IsKeyPresentInCollectionList
__imp__IsKeyPresentInPropertyList
__imp__IsSensorSubscribed
__imp__PropKeyFindKeyGetBool
__imp__PropKeyFindKeyGetDouble
__imp__PropKeyFindKeyGetFileTime
__imp__PropKeyFindKeyGetFloat
__imp__PropKeyFindKeyGetGuid
__imp__PropKeyFindKeyGetInt32
__imp__PropKeyFindKeyGetInt64
__imp__PropKeyFindKeyGetNthInt64
__imp__PropKeyFindKeyGetNthUlong
__imp__PropKeyFindKeyGetNthUshort
__imp__PropKeyFindKeyGetPropVariant
__imp__PropKeyFindKeyGetUlong
__imp__PropKeyFindKeyGetUshort
__imp__PropKeyFindKeySetPropVariant
__imp__PropVariantGetInformation
__imp__PropertiesListCopy
__imp__PropertiesListGetFillableCount
__imp__SensorCollectionGetAt
__imp__SerializationBufferAllocate
__imp__SerializationBufferFree
__imp__AcceptSecurityContext@40
__imp__CredMarshalTargetInfo
__imp__CredUnmarshalTargetInfo
__imp__InitializeSecurityContextA@52
__imp__InitializeSecurityContextW@52
__imp__SaslAcceptSecurityContext@40
__imp__SaslInitializeSecurityContextA@52
__imp__SaslInitializeSecurityContextW@52
__imp__LogErrorW
__imp__LogEventW
__imp__RouterAssert
__imp__RouterGetErrorStringA
__imp__RouterGetErrorStringW
__imp__RouterLogDeregisterA
__imp__RouterLogDeregisterW
__imp__RouterLogEventA
__imp__RouterLogEventDataA
__imp__RouterLogEventDataW
__imp__RouterLogEventStringA
__imp__RouterLogEventStringW
__imp__RouterLogEventValistExA
__imp__RouterLogEventValistExW
__imp__RouterLogEventW
__imp__RouterLogRegisterA
__imp__RouterLogRegisterW
__imp__MgmAddGroupMembershipEntry
__imp__MgmDeRegisterMProtocol
__imp__MgmDeleteGroupMembershipEntry
__imp__MgmGetFirstMfeStats
__imp__MgmGetMfeStats
__imp__MgmGetNextMfeStats
__imp__MgmGetProtocolOnInterface
__imp__MgmGroupEnumerationEnd
__imp__MgmGroupEnumerationGetNext
__imp__MgmGroupEnumerationStart
__imp__MgmRegisterMProtocol
__imp__MgmReleaseInterfaceOwnership
__imp__MgmTakeInterfaceOwnership
__imp__RtmConvertIpv6AddressAndLengthToNetAddress
__imp__RtmConvertNetAddressToIpv6AddressAndLength
__imp__I_RpcServerInqAddressChangeFn
__imp__ClusWorkersTerminate
__imp__FreeClusterHealthFaultArray
__imp__InitializeClusterHealthFaultArray
__imp__ResUtilLeftPaxosIsLessThanRight
__imp__ResUtilPaxosComparer
__imp__ResUtilsDeleteKeyTree
__imp__NetAddServiceAccount
__imp__NetEnumerateServiceAccounts
__imp__NetIsServiceAccount
__imp__NetQueryServiceAccount
__imp__NetRemoveServiceAccount
__imp__DestroyIndexedResults
__imp__DestroyResourceIndexer
__imp__WNetSetLastErrorA
__imp__WNetSetLastErrorW
__imp__BackupPerfRegistryToFileW
__imp__RestorePerfRegistryFromFileW
__imp__GetCurrentClockTransactionManager
__imp__GetTransactionManagerId
__imp__KeyCredentialManagerFreeInformation
__imp__GetOwnerModuleFromPidAndInfo
__imp__DnsConnectionDeleteProxyInfo
__imp__DnsConnectionFreeNameList
__imp__DnsConnectionFreeProxyInfoEx
__imp__DnsConnectionFreeProxyList
__imp__DnsConnectionGetNameList
__imp__DnsConnectionGetProxyInfoForHostUrl
__imp__DnsConnectionGetProxyList
__imp__DnsConnectionSetProxyInfo
__imp__DnsConnectionUpdateIfIndexTable
__imp__DnsRecordSetDetach
__imp__DnsValidateName_A
__imp__DnsValidateName_UTF8
__imp__DnsValidateName_W
__imp__DhcpAddServer
__imp__DhcpAuditLogGetParams
__imp__DhcpAuditLogSetParams
__imp__DhcpCreateOptionV5
__imp__DhcpDeleteServer
__imp__DhcpDeleteSuperScopeV4
__imp__DhcpDsCleanup
__imp__DhcpDsInit
__imp__DhcpEnumOptionValuesV5
__imp__DhcpEnumOptionsV5
__imp__DhcpEnumServers
__imp__DhcpGetClassInfo
__imp__DhcpGetMibInfoV6
__imp__DhcpGetOptionInfoV5
__imp__DhcpGetOptionValueV5
__imp__DhcpGetOptionValueV6
__imp__DhcpGetSuperScopeInfoV4
__imp__DhcpGetThreadOptions
__imp__DhcpHlprFindV4DhcpProperty
__imp__DhcpRemoveOptionV5
__imp__DhcpRemoveOptionValueV5
__imp__DhcpServerBackupDatabase
__imp__DhcpServerQueryAttributes
__imp__DhcpServerQueryDnsRegCredentials
__imp__DhcpServerRedoAuthorization
__imp__DhcpServerRestoreDatabase
__imp__DhcpServerSetDnsRegCredentialsV5
__imp__DhcpSetOptionInfoV5
__imp__DhcpSetOptionValueV5
__imp__DhcpSetOptionValuesV5
__imp__DhcpSetSubnetInfoV6
__imp__DhcpSetSuperScopeV4
__imp__DhcpSetThreadOptions
__imp__NetworkIsolationDiagnoseConnectFailureAndGetInfo
__imp__NetworkIsolationEnumAppContainers
__imp__NetworkIsolationFreeAppContainers
__imp__NetworkIsolationGetAppContainerConfig
__imp__NetworkIsolationRegisterForAppContainerChanges
__imp__NetworkIsolationSetAppContainerConfig
__imp__NetworkIsolationSetupAppContainerBinaries
__imp__NetworkIsolationUnregisterForAppContainerChanges
__imp__GetFeatureVariant
__imp__GetFeatureEnabledState
__imp__RecordFeatureError
__imp__RecordFeatureUsage
__imp__SubscribeFeatureStateChangeNotification
__imp__UnsubscribeFeatureStateChangeNotification
__imp__TraceMessageVa

Originally posted by @glandium in microsoft/windows-rs#1999 (comment)

@riverar
Copy link
Collaborator

riverar commented Sep 2, 2022

@tannergooding Can you confirm ClangSharp doesn't have the ability to set a default calling convention? It seems you can either choose to remap everything and lose all calling convention attribute output (--with-callconv *=Winapi) or choose to remap nothing and ClangSharp defaults to Cdecl.

Think we need a --default-callconv to override the defaults in ClangSharp?

@sotteson1
Copy link
Contributor

Maybe there’s an option we can give to clang. Unfortunately I’m out of town until Sunday so I can’t try it until then.

@riverar
Copy link
Collaborator

riverar commented Sep 2, 2022

@sotteson1 Good idea, will look now.

@riverar
Copy link
Collaborator

riverar commented Sep 2, 2022

I changed base settings for all archs as follows:

  • x86: --additional -mrtd ...
  • x64: --with-callconv *=stdcall
  • arm64: --with-callconv *=stdcall

With the hopes that x64/arm64 passes would simply drop the calling convention (but after grouping them during cross-arch operations since I mapped them all to stdcall). But this resulted in all the functions getting marked stdcall again regardless of architecture. I think there's some additional work needed to make this all work on our side.

No fast fix here, see you Sunday/Monday.

@kennykerr kennykerr added the rust Critical for Rust adoption label Sep 2, 2022
@tannergooding
Copy link
Member

The actual issue here is that Clang doesn't surface any calling convention information for x64 (outside vectorcall and varargs) because there isn't any other convention. As far as x64 windows is concerned, cdecl == stdcall == fastcall.

For 32-bit this matters, but Clang only surfaces that when the file was processed for -m32 (rather than -m64). There are some downside of processing as -m32 as well, such as various other defines/definitions being incorrect in certain edge cases.

However, processing as both -m32 and -m64 to observe the differences and then manually specify --with-callconv name=cdecl in the few places that aren't stdcall and to catch any structs where the layout is truly different between 32-bit/64-bit might be a good idea anyways.

I know one example where the 32-bit vs 64-bit layouts are incompatible is um/commctrl.h for TBBUTTON. IIRC there were others in setupapi and a couple other headers as well.

@sotteson1
Copy link
Contributor

We scan multiple times for x86 (using -m32) and x64/arm64 (using -m64), although if we previously detected they were all equivalent for a partition (a set of headers) we only scan once using x64. So maybe to detect calling convention, we need to scan the “common” ones using x86 (-m32). Would that get us the information we need?

@tannergooding
Copy link
Member

That should. Clang supports (and has tests) covering that the default calling convention detection works as expected for -m32.

Having a --with-callconv *=stdcall will prevent that from working, however. I could probably add something that reports a warning/error if targeting 32-bit and the override doesn't match -or- some special switch to state the default should be x without overriding other cases. Would need to double check on the latter case, however, as I think "default" reports as cdecl for x64 Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rust Critical for Rust adoption
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants