#ifndef _GNU_SOURCE #define _GNU_SOURCE 1 #endif #include "device.h" #define EXPORT_BOOLEAN #include #include #include #include #include #include #include #include /* LINTLIBRARY */ #ifndef mig_internal #define mig_internal static #endif #ifndef mig_external #define mig_external #endif #ifndef TypeCheck #define TypeCheck 1 #endif #ifndef UseExternRCSId #define UseExternRCSId 1 #endif #define BAD_TYPECHECK(type, check) ({\ union { mach_msg_type_t t; unsigned32_t w; } _t, _c;\ _t.t = *(type); _c.t = *(check); _t.w != _c.w; }) #define msgh_request_port msgh_remote_port #define msgh_reply_port msgh_local_port #include #include #include #include /* Routine device_open */ mig_external kern_return_t device_open ( mach_port_t master_port, dev_mode_t mode, dev_name_t name, mach_port_t *device ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t modeType; dev_mode_t mode; mach_msg_type_long_t nameType; dev_name_t name; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_t deviceType; mach_port_t device; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck boolean_t msgh_simple; #endif /* TypeCheck */ #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t modeType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_long_t nameType = { { /* msgt_name = */ 0, /* msgt_size = */ 0, /* msgt_number = */ 0, /* msgt_inline = */ TRUE, /* msgt_longform = */ TRUE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }, /* msgtl_name = */ 12, /* msgtl_size = */ 1024, /* msgtl_number = */ 1, }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t deviceCheck = { /* msgt_name = */ 17, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->modeType = modeType; InP->mode = mode; InP->nameType = nameType; (void) mig_strncpy(InP->name, name, 128); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = master_port; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2800; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 172, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2900) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX); if (((msgh_size != 40) || msgh_simple) && ((msgh_size != sizeof(mig_reply_header_t)) || !msgh_simple || (OutP->RetCode == KERN_SUCCESS))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if (BAD_TYPECHECK (&OutP->deviceType, &deviceCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ *device = OutP->device; return KERN_SUCCESS; } /* Routine device_close */ mig_external kern_return_t device_close ( mach_port_t device ) { typedef struct { mach_msg_header_t Head; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2801; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 24, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2901) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || (OutP->Head.msgh_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ return OutP->RetCode; } /* Routine device_write */ mig_external kern_return_t device_write ( mach_port_t device, dev_mode_t mode, recnum_t recnum, io_buf_ptr_t data, mach_msg_type_number_t dataCnt, int *bytes_written ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t modeType; dev_mode_t mode; mach_msg_type_t recnumType; recnum_t recnum; mach_msg_type_long_t dataType; io_buf_ptr_t data; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_t bytes_writtenType; int bytes_written; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t modeType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t recnumType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_long_t dataType = { { /* msgt_name = */ 0, /* msgt_size = */ 0, /* msgt_number = */ 0, /* msgt_inline = */ FALSE, /* msgt_longform = */ TRUE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }, /* msgtl_name = */ 9, /* msgtl_size = */ 8, /* msgtl_number = */ 0, }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t bytes_writtenCheck = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->modeType = modeType; InP->mode = mode; InP->recnumType = recnumType; InP->recnum = recnum; InP->dataType = dataType; InP->data = data; InP->dataType.msgtl_number = dataCnt; InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2802; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 56, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2902) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || ((msgh_size != 40) && ((msgh_size != sizeof(mig_reply_header_t)) || (OutP->RetCode == KERN_SUCCESS)))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if (BAD_TYPECHECK (&OutP->bytes_writtenType, &bytes_writtenCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ *bytes_written = OutP->bytes_written; return KERN_SUCCESS; } /* Routine device_write_inband */ mig_external kern_return_t device_write_inband ( mach_port_t device, dev_mode_t mode, recnum_t recnum, io_buf_ptr_inband_t data, mach_msg_type_number_t dataCnt, int *bytes_written ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t modeType; dev_mode_t mode; mach_msg_type_t recnumType; recnum_t recnum; mach_msg_type_t dataType; char data[128]; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_t bytes_writtenType; int bytes_written; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; unsigned int msgh_size; auto const mach_msg_type_t modeType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t recnumType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t dataType = { /* msgt_name = */ 8, /* msgt_size = */ 8, /* msgt_number = */ 128, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t bytes_writtenCheck = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->modeType = modeType; InP->mode = mode; InP->recnumType = recnumType; InP->recnum = recnum; InP->dataType = dataType; if (dataCnt > 128) { return MIG_ARRAY_TOO_LARGE; } else { memcpy(InP->data, data, dataCnt); } InP->dataType.msgt_number = dataCnt; msgh_size = 44 + ((dataCnt + 3) & ~3); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2803; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2903) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || ((msgh_size != 40) && ((msgh_size != sizeof(mig_reply_header_t)) || (OutP->RetCode == KERN_SUCCESS)))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if (BAD_TYPECHECK (&OutP->bytes_writtenType, &bytes_writtenCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ *bytes_written = OutP->bytes_written; return KERN_SUCCESS; } /* Routine device_read */ mig_external kern_return_t device_read ( mach_port_t device, dev_mode_t mode, recnum_t recnum, int bytes_wanted, io_buf_ptr_t *data, mach_msg_type_number_t *dataCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t modeType; dev_mode_t mode; mach_msg_type_t recnumType; recnum_t recnum; mach_msg_type_t bytes_wantedType; int bytes_wanted; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_long_t dataType; io_buf_ptr_t data; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck boolean_t msgh_simple; #endif /* TypeCheck */ #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t modeType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t recnumType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t bytes_wantedType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->modeType = modeType; InP->mode = mode; InP->recnumType = recnumType; InP->recnum = recnum; InP->bytes_wantedType = bytes_wantedType; InP->bytes_wanted = bytes_wanted; InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2804; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 48, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2904) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX); if (((msgh_size != 48) || msgh_simple) && ((msgh_size != sizeof(mig_reply_header_t)) || !msgh_simple || (OutP->RetCode == KERN_SUCCESS))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if ((OutP->dataType.msgtl_header.msgt_inline != FALSE) || (OutP->dataType.msgtl_header.msgt_longform != TRUE) || (OutP->dataType.msgtl_name != 9) || (OutP->dataType.msgtl_size != 8)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ *data = OutP->data; *dataCnt = OutP->dataType.msgtl_number; return KERN_SUCCESS; } /* Routine device_read_inband */ mig_external kern_return_t device_read_inband ( mach_port_t device, dev_mode_t mode, recnum_t recnum, int bytes_wanted, io_buf_ptr_inband_t data, mach_msg_type_number_t *dataCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t modeType; dev_mode_t mode; mach_msg_type_t recnumType; recnum_t recnum; mach_msg_type_t bytes_wantedType; int bytes_wanted; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_t dataType; char data[128]; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t modeType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t recnumType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t bytes_wantedType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->modeType = modeType; InP->mode = mode; InP->recnumType = recnumType; InP->recnum = recnum; InP->bytes_wantedType = bytes_wantedType; InP->bytes_wanted = bytes_wanted; InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2805; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 48, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2905) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || ((msgh_size < 36) && ((msgh_size != sizeof(mig_reply_header_t)) || (OutP->RetCode == KERN_SUCCESS)))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if ((OutP->dataType.msgt_inline != TRUE) || (OutP->dataType.msgt_longform != FALSE) || (OutP->dataType.msgt_name != 8) || (OutP->dataType.msgt_size != 8)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (msgh_size != 36 + ((OutP->dataType.msgt_number + 3) & ~3)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->dataType.msgt_number > *dataCnt) { memcpy(data, OutP->data, *dataCnt); *dataCnt = OutP->dataType.msgt_number; return MIG_ARRAY_TOO_LARGE; } else { memcpy(data, OutP->data, OutP->dataType.msgt_number); } *dataCnt = OutP->dataType.msgt_number; return KERN_SUCCESS; } /* Routine xxx_device_set_status */ mig_external kern_return_t xxx_device_set_status ( mach_port_t device, dev_flavor_t flavor, dev_status_t status, mach_msg_type_number_t statusCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t flavorType; dev_flavor_t flavor; mach_msg_type_long_t statusType; int status[1024]; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; unsigned int msgh_size; auto const mach_msg_type_t flavorType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_long_t statusType = { { /* msgt_name = */ 0, /* msgt_size = */ 0, /* msgt_number = */ 0, /* msgt_inline = */ TRUE, /* msgt_longform = */ TRUE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }, /* msgtl_name = */ 2, /* msgtl_size = */ 32, /* msgtl_number = */ 1024, }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->flavorType = flavorType; InP->flavor = flavor; InP->statusType = statusType; if (statusCnt > 1024) { return MIG_ARRAY_TOO_LARGE; } else { memcpy(InP->status, status, 4 * statusCnt); } InP->statusType.msgtl_number = statusCnt; msgh_size = 44 + (4 * statusCnt); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2806; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2906) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || (OutP->Head.msgh_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ return OutP->RetCode; } /* Routine xxx_device_get_status */ mig_external kern_return_t xxx_device_get_status ( mach_port_t device, dev_flavor_t flavor, dev_status_t status, mach_msg_type_number_t *statusCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t flavorType; dev_flavor_t flavor; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_long_t statusType; int status[1024]; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t flavorType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->flavorType = flavorType; InP->flavor = flavor; InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2807; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 32, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2907) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || ((msgh_size < 44) && ((msgh_size != sizeof(mig_reply_header_t)) || (OutP->RetCode == KERN_SUCCESS)))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if ((OutP->statusType.msgtl_header.msgt_inline != TRUE) || (OutP->statusType.msgtl_header.msgt_longform != TRUE) || (OutP->statusType.msgtl_name != 2) || (OutP->statusType.msgtl_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (msgh_size != 44 + (4 * OutP->statusType.msgtl_number)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->statusType.msgtl_number > *statusCnt) { memcpy(status, OutP->status, 4 * *statusCnt); *statusCnt = OutP->statusType.msgtl_number; return MIG_ARRAY_TOO_LARGE; } else { memcpy(status, OutP->status, 4 * OutP->statusType.msgtl_number); } *statusCnt = OutP->statusType.msgtl_number; return KERN_SUCCESS; } /* Routine xxx_device_set_filter */ mig_external kern_return_t xxx_device_set_filter ( mach_port_t device, mach_port_t receive_port, mach_msg_type_name_t receive_portPoly, int priority, filter_array_t filter, mach_msg_type_number_t filterCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t receive_portType; mach_port_t receive_port; mach_msg_type_t priorityType; int priority; mach_msg_type_long_t filterType; filter_t filter[128]; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; boolean_t msgh_simple = TRUE; unsigned int msgh_size; auto const mach_msg_type_t receive_portType = { /* msgt_name = */ -1, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t priorityType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_long_t filterType = { { /* msgt_name = */ 0, /* msgt_size = */ 0, /* msgt_number = */ 0, /* msgt_inline = */ TRUE, /* msgt_longform = */ TRUE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }, /* msgtl_name = */ 1, /* msgtl_size = */ 16, /* msgtl_number = */ 128, }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->receive_portType = receive_portType; InP->receive_port = receive_port; if (MACH_MSG_TYPE_PORT_ANY(receive_portPoly)) msgh_simple = FALSE; InP->receive_portType.msgt_name = receive_portPoly; InP->priorityType = priorityType; InP->priority = priority; InP->filterType = filterType; if (filterCnt > 128) { return MIG_ARRAY_TOO_LARGE; } else { memcpy(InP->filter, filter, 2 * filterCnt); } InP->filterType.msgtl_number = filterCnt; msgh_size = 52 + ((2 * filterCnt + 3) & ~3); InP->Head.msgh_bits = msgh_simple ? MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE) : (MACH_MSGH_BITS_COMPLEX| MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE)); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2808; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2908) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || (OutP->Head.msgh_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ return OutP->RetCode; } /* Routine device_map */ mig_external kern_return_t device_map ( mach_port_t device, vm_prot_t prot, vm_offset_t offset, vm_size_t size, mach_port_t *pager, int unmap ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t protType; vm_prot_t prot; mach_msg_type_t offsetType; vm_offset_t offset; mach_msg_type_t sizeType; vm_size_t size; mach_msg_type_t unmapType; int unmap; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_t pagerType; mach_port_t pager; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck boolean_t msgh_simple; #endif /* TypeCheck */ #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t protType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t offsetType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t sizeType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t unmapType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t pagerCheck = { /* msgt_name = */ 17, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->protType = protType; InP->prot = prot; InP->offsetType = offsetType; InP->offset = offset; InP->sizeType = sizeType; InP->size = size; InP->unmapType = unmapType; InP->unmap = unmap; InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2809; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 56, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2909) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX); if (((msgh_size != 40) || msgh_simple) && ((msgh_size != sizeof(mig_reply_header_t)) || !msgh_simple || (OutP->RetCode == KERN_SUCCESS))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if (BAD_TYPECHECK (&OutP->pagerType, &pagerCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ *pager = OutP->pager; return KERN_SUCCESS; } /* Routine device_set_status */ mig_external kern_return_t device_set_status ( mach_port_t device, dev_flavor_t flavor, dev_status_t status, mach_msg_type_number_t statusCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t flavorType; dev_flavor_t flavor; mach_msg_type_t statusType; int status[1024]; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; unsigned int msgh_size; auto const mach_msg_type_t flavorType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t statusType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1024, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->flavorType = flavorType; InP->flavor = flavor; InP->statusType = statusType; if (statusCnt > 1024) { return MIG_ARRAY_TOO_LARGE; } else { memcpy(InP->status, status, 4 * statusCnt); } InP->statusType.msgt_number = statusCnt; msgh_size = 36 + (4 * statusCnt); InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2810; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2910) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || (OutP->Head.msgh_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ return OutP->RetCode; } /* Routine device_get_status */ mig_external kern_return_t device_get_status ( mach_port_t device, dev_flavor_t flavor, dev_status_t status, mach_msg_type_number_t *statusCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t flavorType; dev_flavor_t flavor; mach_msg_type_t statusCntType; mach_msg_type_number_t statusCnt; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; mach_msg_type_t statusType; int status[1024]; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; #if TypeCheck unsigned int msgh_size; #endif /* TypeCheck */ auto const mach_msg_type_t flavorType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t statusCntType = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->flavorType = flavorType; InP->flavor = flavor; InP->statusCntType = statusCntType; if (*statusCnt < 1024) InP->statusCnt = *statusCnt; else InP->statusCnt = 1024; InP->Head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2811; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 40, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2911) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck msgh_size = OutP->Head.msgh_size; if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || ((msgh_size < 36) && ((msgh_size != sizeof(mig_reply_header_t)) || (OutP->RetCode == KERN_SUCCESS)))) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->RetCode != KERN_SUCCESS) return OutP->RetCode; #if TypeCheck if ((OutP->statusType.msgt_inline != TRUE) || (OutP->statusType.msgt_longform != FALSE) || (OutP->statusType.msgt_name != 2) || (OutP->statusType.msgt_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (msgh_size != 36 + (4 * OutP->statusType.msgt_number)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ if (OutP->statusType.msgt_number > *statusCnt) { memcpy(status, OutP->status, 4 * *statusCnt); *statusCnt = OutP->statusType.msgt_number; return MIG_ARRAY_TOO_LARGE; } else { memcpy(status, OutP->status, 4 * OutP->statusType.msgt_number); } *statusCnt = OutP->statusType.msgt_number; return KERN_SUCCESS; } /* Routine device_set_filter */ mig_external kern_return_t device_set_filter ( mach_port_t device, mach_port_t receive_port, mach_msg_type_name_t receive_portPoly, int priority, filter_array_t filter, mach_msg_type_number_t filterCnt ) { typedef struct { mach_msg_header_t Head; mach_msg_type_t receive_portType; mach_port_t receive_port; mach_msg_type_t priorityType; int priority; mach_msg_type_t filterType; filter_t filter[128]; } Request; typedef struct { mach_msg_header_t Head; mach_msg_type_t RetCodeType; kern_return_t RetCode; } Reply; union { Request In; Reply Out; } Mess; register Request *InP = &Mess.In; register Reply *OutP = &Mess.Out; mach_msg_return_t msg_result; boolean_t msgh_simple = TRUE; unsigned int msgh_size; auto const mach_msg_type_t receive_portType = { /* msgt_name = */ -1, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t priorityType = { /* msgt_name = */ 2, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t filterType = { /* msgt_name = */ 1, /* msgt_size = */ 16, /* msgt_number = */ 128, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; auto const mach_msg_type_t RetCodeCheck = { /* msgt_name = */ MACH_MSG_TYPE_INTEGER_32, /* msgt_size = */ 32, /* msgt_number = */ 1, /* msgt_inline = */ TRUE, /* msgt_longform = */ FALSE, /* msgt_deallocate = */ FALSE, /* msgt_unused = */ 0 }; InP->receive_portType = receive_portType; InP->receive_port = receive_port; if (MACH_MSG_TYPE_PORT_ANY(receive_portPoly)) msgh_simple = FALSE; InP->receive_portType.msgt_name = receive_portPoly; InP->priorityType = priorityType; InP->priority = priority; InP->filterType = filterType; if (filterCnt > 128) { return MIG_ARRAY_TOO_LARGE; } else { memcpy(InP->filter, filter, 2 * filterCnt); } InP->filterType.msgt_number = filterCnt; msgh_size = 44 + ((2 * filterCnt + 3) & ~3); InP->Head.msgh_bits = msgh_simple ? MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE) : (MACH_MSGH_BITS_COMPLEX| MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE)); /* msgh_size passed as argument */ InP->Head.msgh_request_port = device; InP->Head.msgh_reply_port = mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 2812; msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 2912) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } #if TypeCheck if ((OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || (OutP->Head.msgh_size != 32)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ #if TypeCheck if (BAD_TYPECHECK (&OutP->RetCodeType, &RetCodeCheck)) return MIG_TYPE_ERROR; #endif /* TypeCheck */ return OutP->RetCode; }