/* return a pointer to the request data following an object attributes structure */ const void *get_req_data_after_objattr( const struct object_attributes *attr, data_size_t *len ) { const void *ptr = (const WCHAR *)((const struct object_attributes *)get_req_data() + 1) + attr->sd_len / sizeof(WCHAR) + attr->name_len / sizeof(WCHAR); *len = get_req_data_size() - ((const char *)ptr - (const char *)get_req_data()); return ptr; }
void get_req_path(struct unicode_str *str, int skip_root) { static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\' }; str->str = get_req_data(); str->len = (get_req_data_size() / sizeof(WCHAR)) * sizeof(WCHAR); if (skip_root && str->len >= sizeof(root_name) && !memicmpW(str->str, root_name, sizeof(root_name) / sizeof(WCHAR))) { str->str += sizeof(root_name) / sizeof(WCHAR); str->len -= sizeof(root_name); } }
/* return object attributes from the current request */ const struct object_attributes *get_req_object_attributes( const struct security_descriptor **sd, struct unicode_str *name, struct object **root ) { static const struct object_attributes empty_attributes; const struct object_attributes *attr = get_req_data(); data_size_t size = get_req_data_size(); if (root) *root = NULL; if (!size) { *sd = NULL; name->len = 0; return &empty_attributes; } if ((size < sizeof(*attr)) || (size - sizeof(*attr) < attr->sd_len) || (size - sizeof(*attr) - attr->sd_len < attr->name_len)) { set_error( STATUS_ACCESS_VIOLATION ); return NULL; } if (attr->sd_len && !sd_is_valid( (const struct security_descriptor *)(attr + 1), attr->sd_len )) { set_error( STATUS_INVALID_SECURITY_DESCR ); return NULL; } if ((attr->name_len & (sizeof(WCHAR) - 1)) || attr->name_len >= 65534) { set_error( STATUS_OBJECT_NAME_INVALID ); return NULL; } if (root && attr->rootdir && attr->name_len) { if (!(*root = get_directory_obj( current->process, attr->rootdir ))) return NULL; } *sd = attr->sd_len ? (const struct security_descriptor *)(attr + 1) : NULL; name->len = attr->name_len; name->str = (const WCHAR *)(attr + 1) + attr->sd_len / sizeof(WCHAR); return attr; }
static obj_handle_t device_file_ioctl( struct fd *fd, ioctl_code_t code, const async_data_t *async_data, int blocking ) { struct device_file *file = get_fd_user( fd ); struct irp_call *irp; obj_handle_t handle; irp_params_t params; memset( ¶ms, 0, sizeof(params) ); params.ioctl.major = IRP_MJ_DEVICE_CONTROL; params.ioctl.code = code; params.ioctl.file = file->user_ptr; irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), get_reply_max_size() ); if (!irp) return 0; handle = queue_irp( file, irp, async_data, blocking ); release_object( irp ); return handle; }
static obj_handle_t device_file_write( struct fd *fd, const async_data_t *async_data, int blocking, file_pos_t pos, data_size_t *written ) { struct device_file *file = get_fd_user( fd ); struct irp_call *irp; obj_handle_t handle; irp_params_t params; memset( ¶ms, 0, sizeof(params) ); params.write.major = IRP_MJ_WRITE; params.write.key = 0; params.write.pos = pos; params.write.file = file->user_ptr; irp = create_irp( file, ¶ms, get_req_data(), get_req_data_size(), 0 ); if (!irp) return 0; handle = queue_irp( file, irp, async_data, blocking ); release_object( irp ); return handle; }