1010OSDefineMetaClassAndStructors (HyperVShutdownUserClient, super);
1111
1212#if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
13- const IOExternalMethodDispatch HyperVShutdownUserClient::sShutdownMethods [kHyperVShutdownUserClientMethodNumberOfMethods ] = {
14- { // kHyperVShutdownUserClientMethodReportShutdownAbility
15- reinterpret_cast <IOExternalMethodAction>(&HyperVShutdownUserClient::methodReportShutdownAbility), // Method pointer
16- 1 , // Num of scalar input values
17- 0 , // Size of struct input
18- 0 , // Num of scalar output values
19- 0 // Size of struct output
13+ IOReturn HyperVShutdownUserClient::externalMethod (uint32_t selector, IOExternalMethodArguments *arguments, IOExternalMethodDispatch *dispatch,
14+ OSObject *target, void *reference) {
15+ static const IOExternalMethodDispatch methods[kHyperVShutdownUserClientMethodNumberOfMethods ] = {
16+ { // kHyperVShutdownUserClientMethodReportShutdownAbility
17+ reinterpret_cast <IOExternalMethodAction>(&HyperVShutdownUserClient::sMethodReportShutdownAbility ), // Method pointer
18+ 1 , // Num of scalar input values
19+ 0 , // Size of struct input
20+ 0 , // Num of scalar output values
21+ 0 // Size of struct output
22+ }
23+ };
24+
25+ if (selector >= kHyperVShutdownUserClientMethodNumberOfMethods ) {
26+ return kIOReturnUnsupported ;
2027 }
21- } ;
28+ dispatch = const_cast <IOExternalMethodDispatch*>(&methods[selector]) ;
2229
23- /* IOExternalMethod* HyperVShutdownUserClient::getTargetAndMethodForIndex(IOService **targetP, UInt32 index) {
24- static IOExternalMethod sMethods[kHyperVShutdownUserClientMethodNumberOfMethods] = {
25- { // kHyperVShutdownUserClientMethodReportShutdownAbility, 0
26- 0, (IOMethod)&HyperVShutdownUserClient::reportShutdownAbility, kIOUCScalarIScalarO, 1, 0
27- },
30+ target = this ;
31+ reference = nullptr ;
32+
33+ return super::externalMethod (selector, arguments, dispatch, target, reference);
34+ }
35+
36+ #else
37+ IOExternalMethod* HyperVShutdownUserClient::getTargetAndMethodForIndex (IOService **target, UInt32 index) {
38+ static const IOExternalMethod methods[kHyperVShutdownUserClientMethodNumberOfMethods ] = {
39+ { // kHyperVShutdownUserClientMethodReportShutdownAbility
40+ NULL ,
41+ #if (defined(__i386__) && defined(__clang__))
42+ // Required to match GCC behavior on 32-bit when building with clang
43+ kIOExternalMethodACID32Padding ,
44+ (IOMethodACID32) &HyperVShutdownUserClient::reportShutdownAbility,
45+ #else
46+ (IOMethod) &HyperVShutdownUserClient::reportShutdownAbility,
47+ #endif
48+ kIOUCScalarIScalarO ,
49+ 1 ,
50+ 0
51+ }
2852 };
2953
3054 if (index >= kHyperVShutdownUserClientMethodNumberOfMethods ) {
3155 return nullptr ;
32- } else {
33- *targetP = this;
34- return &sMethods[index];
3556 }
36- }*/
3757
58+ *target = this ;
59+ return (IOExternalMethod *) &methods[index];
60+ }
3861#endif
3962
4063bool HyperVShutdownUserClient::start (IOService *provider) {
@@ -55,22 +78,6 @@ void HyperVShutdownUserClient::stop(IOService *provider) {
5578 super::stop (provider);
5679}
5780
58- #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
59- IOReturn HyperVShutdownUserClient::externalMethod (uint32_t selector, IOExternalMethodArguments *arguments, IOExternalMethodDispatch *dispatch,
60- OSObject *target, void *reference) {
61- if (selector >= kHyperVShutdownUserClientMethodNumberOfMethods ) {
62- return kIOReturnUnsupported ;
63- }
64- dispatch = const_cast <IOExternalMethodDispatch*>(&sShutdownMethods [selector]);
65-
66- target = this ;
67- reference = nullptr ;
68-
69- return super::externalMethod (selector, arguments, dispatch, target, reference);
70- }
71- #else
72- #endif
73-
7481IOReturn HyperVShutdownUserClient::notifyClientApplication (HyperVShutdownUserClientNotificationType type) {
7582 HyperVShutdownUserClientNotificationMessage notificationMsg = { };
7683
@@ -80,27 +87,39 @@ IOReturn HyperVShutdownUserClient::notifyClientApplication(HyperVShutdownUserCli
8087 }
8188
8289 HVDBGLOG (" Sending shutdown notification type %u" , type);
83-
8490 notificationMsg.header .msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0 );
8591 notificationMsg.header .msgh_size = sizeof (notificationMsg);
8692 notificationMsg.header .msgh_remote_port = _notificationPort;
8793 notificationMsg.header .msgh_local_port = MACH_PORT_NULL;
8894 notificationMsg.header .msgh_reserved = 0 ;
8995 notificationMsg.header .msgh_id = 0 ;
90-
91- notificationMsg.type = type;
96+ notificationMsg.type = type;
9297
9398 return mach_msg_send_from_kernel (¬ificationMsg.header , notificationMsg.header .msgh_size );
9499}
95100
96- IOReturn HyperVShutdownUserClient::methodReportShutdownAbility (HyperVShutdownUserClient *target, void *ref, IOExternalMethodArguments *args) {
97- target->wakeThread (static_cast <bool >(args->scalarInput [0 ]) ? kIOReturnSuccess : kIOReturnUnsupported );
101+ #if __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_5
102+ IOReturn HyperVShutdownUserClient::sMethodReportShutdownAbility (HyperVShutdownUserClient *target, void *ref, IOExternalMethodArguments *args) {
103+ return target->reportShutdownAbility ((UInt32)args->scalarInput [0 ]);
104+ }
105+ #endif
106+
107+ #if (defined(__i386__) && defined(__clang__))
108+ IOReturn HyperVShutdownUserClient::reportShutdownAbility (HyperVShutdownUserClient* that, UInt32 arg) {
109+ that->wakeThread ((arg == kHyperVShutdownMagic ) ? kIOReturnSuccess : kIOReturnUnsupported );
110+ #else
111+ IOReturn HyperVShutdownUserClient::reportShutdownAbility (UInt32 arg) {
112+ wakeThread ((arg == kHyperVShutdownMagic ) ? kIOReturnSuccess : kIOReturnUnsupported );
113+ #endif
98114 return kIOReturnSuccess ;
99115}
100116
101117bool HyperVShutdownUserClient::canShutdown () {
102118 IOReturn status;
103119
120+ //
121+ // Check if userspace daemon is running and responsive.
122+ //
104123 _isSleeping = true ;
105124 status = notifyClientApplication (kHyperVShutdownUserClientNotificationTypeCheck );
106125 if (status != kIOReturnSuccess ) {
0 commit comments