static int accept_into_socket( struct sock *sock, struct sock *acceptsock ) { int acceptfd; struct fd *newfd; if ( sock->deferred ) { newfd = dup_fd_object( sock->deferred->fd, 0, 0, get_fd_options( acceptsock->fd ) ); if ( !newfd ) return FALSE; set_fd_user( newfd, &sock_fd_ops, &acceptsock->obj ); release_object( sock->deferred ); sock->deferred = NULL; } else { if ((acceptfd = accept_new_fd( sock )) == -1) return FALSE; if (!(newfd = create_anonymous_fd( &sock_fd_ops, acceptfd, &acceptsock->obj, get_fd_options( acceptsock->fd ) ))) return FALSE; } acceptsock->state |= FD_WINE_CONNECTED|FD_READ|FD_WRITE; acceptsock->hmask = 0; acceptsock->pmask = 0; acceptsock->polling = 0; acceptsock->type = sock->type; acceptsock->family = sock->family; acceptsock->wparam = 0; acceptsock->deferred = NULL; release_object( acceptsock->fd ); acceptsock->fd = newfd; clear_error(); sock->pmask &= ~FD_ACCEPT; sock->hmask &= ~FD_ACCEPT; sock_reselect( sock ); return TRUE; }
/* create a file by duplicating an fd object */ struct file *create_file_for_fd_obj( struct fd *fd, unsigned int access, unsigned int sharing ) { struct file *file; struct stat st; if (fstat( get_unix_fd(fd), &st ) == -1) { file_set_error(); return NULL; } if ((file = alloc_object( &file_ops ))) { file->mode = st.st_mode; file->access = default_fd_map_access( &file->obj, access ); if (!(file->fd = dup_fd_object( fd, access, sharing, FILE_SYNCHRONOUS_IO_NONALERT ))) { release_object( file ); return NULL; } set_fd_user( file->fd, &file_fd_ops, &file->obj ); } return file; }
static struct object *create_mapping( struct object *root, const struct unicode_str *name, unsigned int attr, mem_size_t size, unsigned int flags, obj_handle_t handle, unsigned int file_access, const struct security_descriptor *sd ) { struct mapping *mapping; struct file *file; struct fd *fd; int unix_fd; struct stat st; if (!page_mask) page_mask = sysconf( _SC_PAGESIZE ) - 1; if (!(mapping = create_named_object( root, &mapping_ops, name, attr, sd ))) return NULL; if (get_error() == STATUS_OBJECT_NAME_EXISTS) return &mapping->obj; /* Nothing else to do */ mapping->size = size; mapping->fd = NULL; mapping->shared = NULL; mapping->committed = NULL; if (!(mapping->flags = get_mapping_flags( handle, flags ))) goto error; if (handle) { const unsigned int sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; unsigned int mapping_access = FILE_MAPPING_ACCESS; if (!(file = get_file_obj( current->process, handle, file_access ))) goto error; fd = get_obj_fd( (struct object *)file ); /* file sharing rules for mappings are different so we use magic the access rights */ if (flags & SEC_IMAGE) mapping_access |= FILE_MAPPING_IMAGE; else if (file_access & FILE_WRITE_DATA) mapping_access |= FILE_MAPPING_WRITE; if (!(mapping->fd = get_fd_object_for_mapping( fd, mapping_access, sharing ))) { mapping->fd = dup_fd_object( fd, mapping_access, sharing, FILE_SYNCHRONOUS_IO_NONALERT ); if (mapping->fd) set_fd_user( mapping->fd, &mapping_fd_ops, NULL ); } release_object( file ); release_object( fd ); if (!mapping->fd) goto error; if ((unix_fd = get_unix_fd( mapping->fd )) == -1) goto error; if (fstat( unix_fd, &st ) == -1) { file_set_error(); goto error; } if (flags & SEC_IMAGE) { unsigned int err = get_image_params( mapping, st.st_size, unix_fd ); if (!err) return &mapping->obj; set_error( err ); goto error; } if (!mapping->size) { if (!(mapping->size = st.st_size)) { set_error( STATUS_MAPPED_FILE_SIZE_ZERO ); goto error; } } else if (st.st_size < mapping->size) { if (!(file_access & FILE_WRITE_DATA)) { set_error( STATUS_SECTION_TOO_BIG ); goto error; } if (!grow_file( unix_fd, mapping->size )) goto error; } } else /* Anonymous mapping (no associated file) */ { if (!mapping->size) { set_error( STATUS_INVALID_PARAMETER ); goto error; } if ((flags & SEC_RESERVE) && !(mapping->committed = create_ranges())) goto error; mapping->size = (mapping->size + page_mask) & ~((mem_size_t)page_mask); if ((unix_fd = create_temp_file( mapping->size )) == -1) goto error; if (!(mapping->fd = create_anonymous_fd( &mapping_fd_ops, unix_fd, &mapping->obj, FILE_SYNCHRONOUS_IO_NONALERT ))) goto error; allow_fd_caching( mapping->fd ); } return &mapping->obj; error: release_object( mapping ); return NULL; }