in vboxguest/vboxguest_core.c [1414:1451]
static int vbg_ioctl_hgcm_disconnect(struct vbg_dev *gdev,
struct vbg_session *session,
struct vbg_ioctl_hgcm_disconnect *disconn)
{
u32 client_id;
int i, ret;
if (vbg_ioctl_chk(&disconn->hdr, sizeof(disconn->u.in), 0))
return -EINVAL;
client_id = disconn->u.in.client_id;
if (client_id == 0 || client_id == U32_MAX)
return -EINVAL;
mutex_lock(&gdev->session_mutex);
for (i = 0; i < ARRAY_SIZE(session->hgcm_client_ids); i++) {
if (session->hgcm_client_ids[i] == client_id) {
session->hgcm_client_ids[i] = U32_MAX;
break;
}
}
mutex_unlock(&gdev->session_mutex);
if (i >= ARRAY_SIZE(session->hgcm_client_ids))
return -EINVAL;
ret = vbg_hgcm_disconnect(gdev, session->requestor, client_id,
&disconn->hdr.rc);
mutex_lock(&gdev->session_mutex);
if (ret == 0 && disconn->hdr.rc >= 0)
session->hgcm_client_ids[i] = 0;
else
session->hgcm_client_ids[i] = client_id;
mutex_unlock(&gdev->session_mutex);
return ret;
}