Example #1
0
static HRESULT WINAPI HTMLDOMNode_replaceChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
                                               IHTMLDOMNode *oldChild, IHTMLDOMNode **node)
{
    HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
    HTMLDOMNode *node_new, *node_old, *ret_node;
    nsIDOMNode *nsnode;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, node);

    node_new = get_node_obj(newChild);
    if(!node_new)
        return E_FAIL;

    node_old = get_node_obj(oldChild);
    if(!node_old) {
        node_release(node_new);
        return E_FAIL;
    }

    nsres = nsIDOMNode_ReplaceChild(This->nsnode, node_new->nsnode, node_old->nsnode, &nsnode);
    node_release(node_new);
    node_release(node_old);
    if(NS_FAILED(nsres))
        return E_FAIL;

    hres = get_node(This->doc, nsnode, TRUE, &ret_node);
    nsIDOMNode_Release(nsnode);
    if(FAILED(hres))
        return hres;

    *node = &ret_node->IHTMLDOMNode_iface;
    return S_OK;
}
Example #2
0
static HRESULT WINAPI HTMLDOMNode_insertBefore(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
                                               VARIANT refChild, IHTMLDOMNode **node)
{
    HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
    HTMLDOMNode *new_child, *node_obj, *ref_node = NULL;
    nsIDOMNode *nsnode;
    nsresult nsres;
    HRESULT hres = S_OK;

    TRACE("(%p)->(%p %s %p)\n", This, newChild, debugstr_variant(&refChild), node);

    new_child = get_node_obj(This->doc, (IUnknown*)newChild);
    if(!new_child) {
        ERR("invalid newChild\n");
        return E_INVALIDARG;
    }

    switch(V_VT(&refChild)) {
    case VT_NULL:
        break;
    case VT_DISPATCH: {
        ref_node = get_node_obj(This->doc, (IUnknown*)V_DISPATCH(&refChild));
        if(!ref_node) {
            ERR("unvalid node\n");
            hres = E_FAIL;
            break;
        }
        break;
    }
    default:
        FIXME("unimplemented refChild %s\n", debugstr_variant(&refChild));
        hres = E_NOTIMPL;
    }

    if(SUCCEEDED(hres)) {
        nsres = nsIDOMNode_InsertBefore(This->nsnode, new_child->nsnode, ref_node ? ref_node->nsnode : NULL, &nsnode);
        if(NS_FAILED(nsres)) {
            ERR("InsertBefore failed: %08x\n", nsres);
            hres = E_FAIL;
        }
    }
    node_release(new_child);
    if(ref_node)
        node_release(ref_node);
    if(FAILED(hres))
        return hres;

    hres = get_node(This->doc, nsnode, TRUE, &node_obj);
    nsIDOMNode_Release(nsnode);
    if(FAILED(hres))
        return hres;

    *node = &node_obj->IHTMLDOMNode_iface;
    return S_OK;
}
Example #3
0
static HRESULT WINAPI HTMLDOMNode_appendChild(IHTMLDOMNode *iface, IHTMLDOMNode *newChild,
                                              IHTMLDOMNode **node)
{
    HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
    HTMLDOMNode *node_obj;
    nsIDOMNode *nsnode;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p %p)\n", This, newChild, node);

    node_obj = get_node_obj(newChild);
    if(!node_obj)
        return E_FAIL;

    nsres = nsIDOMNode_AppendChild(This->nsnode, node_obj->nsnode, &nsnode);
    node_release(node_obj);
    if(NS_FAILED(nsres)) {
        ERR("AppendChild failed: %08x\n", nsres);
        return E_FAIL;
    }

    hres = get_node(This->doc, nsnode, TRUE, &node_obj);
    nsIDOMNode_Release(nsnode);
    if(FAILED(hres))
        return hres;

    /* FIXME: Make sure that node != newChild */
    *node = &node_obj->IHTMLDOMNode_iface;
    return S_OK;
}
Example #4
0
void check_event_attr(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem)
{
    const PRUnichar *attr_value;
    nsAString attr_value_str;
    IDispatch *disp;
    HTMLDOMNode *node;
    int i;
    nsresult nsres;
    HRESULT hres;

    for(i=0; i < EVENTID_LAST; i++) {
        nsres = get_elem_attr_value(nselem, event_info[i].attr_name, &attr_value_str, &attr_value);
        if(NS_SUCCEEDED(nsres)) {
            if(!*attr_value)
                continue;

            TRACE("%p.%s = %s\n", nselem, debugstr_w(event_info[i].attr_name), debugstr_w(attr_value));

            disp = script_parse_event(doc->window, attr_value);
            if(disp) {
                hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node);
                if(SUCCEEDED(hres)) {
                    set_event_handler_disp(get_node_event_target(node), node->doc, i, disp);
                    node_release(node);
                }
                IDispatch_Release(disp);
            }
            nsAString_Finish(&attr_value_str);
        }
    }
}
Example #5
0
static nsresult run_bind_to_tree(HTMLDocumentNode *doc, nsISupports *nsiface, nsISupports *arg2)
{
    nsIDOMNode *nsnode;
    HTMLDOMNode *node;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", doc, nsiface);

    nsres = nsISupports_QueryInterface(nsiface, &IID_nsIDOMNode, (void**)&nsnode);
    if(NS_FAILED(nsres))
        return nsres;

    hres = get_node(doc, nsnode, TRUE, &node);
    nsIDOMNode_Release(nsnode);
    if(FAILED(hres)) {
        ERR("Could not get node\n");
        return nsres;
    }

    if(node->vtbl->bind_to_tree)
        node->vtbl->bind_to_tree(node);

    node_release(node);
    return nsres;
}
Example #6
0
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode *target, nsIDOMEvent *nsevent,
        IDispatch *script_this)
{
    HTMLEventObj *event_obj = NULL;
    HTMLDOMNode *node;
    HRESULT hres;

    if(set_event) {
        hres = get_node(doc, target, TRUE, &node);
        if(FAILED(hres))
            return;

        event_obj = create_event();
        node_release(node);
        if(!event_obj)
            return;

        hres = set_event_info(event_obj, node, eid, nsevent);
        if(FAILED(hres)) {
            IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
            return;
        }
    }

    fire_event_obj(doc, eid, event_obj, target, script_this);

    if(event_obj)
        IHTMLEventObj_Release(&event_obj->IHTMLEventObj_iface);
}
Example #7
0
void node_release(struct node *node)
{
    TRACE("RELEASE %p (%s) rc=%d\n", node, node->name, node->refcount);
    dec_refcount(node);
    if (node->refcount == 0) {
        if (node->parent->child == node) {
            node->parent->child = node->parent->child->next;
        } else {
            struct node *node2;

            node2 = node->parent->child;
            while (node2->next != node)
                node2 = node2->next;
            node2->next = node->next;            
        }

        TRACE("DESTROY %p (%s)\n", node, node->name);

        node_release(node->parent);

        node->parent = 0;
        node->next = 0;

            /* TODO: remove debugging - poison memory */
        memset(node->name, 0xef, node->namelen);
        free(node->name);
        free(node->actual_name);
        memset(node, 0xfc, sizeof(*node));
        free(node);
    }
}
Example #8
0
File: router.c Project: ireader/sdk
static void router_test2(void)
{
	int i;
	struct node_t* node;
	struct node_t* result[8];
	static struct node_t s_nodes[100000];
	uint8_t id[N_NODEID] = { 0xAB, 0xCD, 0xEF, 0x89, };

	heap_t* heap, *heap2;
	struct router_t* router;
	router = router_create(id);

	heap = heap_create(node_compare_less, (void*)id);
	heap_reserve(heap, 8 + 1);

	for (i = 0; i < sizeof(s_nodes) / sizeof(s_nodes[0]); i++)
	{
		int v = rand();

		memset(&s_nodes[i], 0, sizeof(s_nodes[i]));
		memcpy(s_nodes[i].id, &v, sizeof(v));
		s_nodes[i].ref = 1;

		if (0 == router_add(router, s_nodes[i].id, &s_nodes[i].addr, &node))
		{
			heap_push(heap, node);
			if (heap_size(heap) > 8)
			{
				node_release((struct node_t*)heap_top(heap));
				heap_pop(heap);
			}
		}
	}

	assert(8 == heap_size(heap));
	assert(8 == router_nearest(router, id, result, 8));

	heap2 = heap_create(node_compare_less, (void*)id);
	heap_reserve(heap2, 8);

	for (i = 0; i < 8; i++)
	{
		heap_push(heap2, result[i]);
	}

	assert(heap_size(heap) == heap_size(heap2));
	for (i = 0; i < 8; i++)
	{
		assert(heap_top(heap2) == heap_top(heap));
		heap_pop(heap);
		heap_pop(heap2);
	}

	router_destroy(router);
	heap_destroy(heap);
	heap_destroy(heap2);
	printf("router test ok!\n");
}
Example #9
0
File: router.c Project: ireader/sdk
static void rbtree_destroy(struct rbtree_node_t* node)
{
	struct rbitem_t* item;
	item = rbtree_entry(node, struct rbitem_t, link);

	if (node->left)
		rbtree_destroy(node->left);
	if (node->right)
		rbtree_destroy(node->right);

	node_release(item->node);
	free(item);
}
Example #10
0
static HRESULT WINAPI HTMLOptionElementFactory_create(IHTMLOptionElementFactory *iface,
        VARIANT text, VARIANT value, VARIANT defaultselected, VARIANT selected,
        IHTMLOptionElement **optelem)
{
    HTMLOptionElementFactory *This = impl_from_IHTMLOptionElementFactory(iface);
    nsIDOMHTMLElement *nselem;
    HTMLDOMNode *node;
    HRESULT hres;

    static const PRUnichar optionW[] = {'O','P','T','I','O','N',0};

    TRACE("(%p)->(%s %s %s %s %p)\n", This, debugstr_variant(&text), debugstr_variant(&value),
          debugstr_variant(&defaultselected), debugstr_variant(&selected), optelem);

    if(!This->window || !This->window->doc) {
        WARN("NULL doc\n");
        return E_UNEXPECTED;
    }

    *optelem = NULL;

    hres = create_nselem(This->window->doc, optionW, &nselem);
    if(FAILED(hres))
        return hres;

    hres = get_node(This->window->doc, (nsIDOMNode*)nselem, TRUE, &node);
    nsIDOMHTMLElement_Release(nselem);
    if(FAILED(hres))
        return hres;

    hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface,
            &IID_IHTMLOptionElement, (void**)optelem);
    node_release(node);

    if(V_VT(&text) == VT_BSTR)
        IHTMLOptionElement_put_text(*optelem, V_BSTR(&text));
    else if(V_VT(&text) != VT_EMPTY)
        FIXME("Unsupported text %s\n", debugstr_variant(&text));

    if(V_VT(&value) == VT_BSTR)
        IHTMLOptionElement_put_value(*optelem, V_BSTR(&value));
    else if(V_VT(&value) != VT_EMPTY)
        FIXME("Unsupported value %s\n", debugstr_variant(&value));

    if(V_VT(&defaultselected) != VT_EMPTY)
        FIXME("Unsupported defaultselected %s\n", debugstr_variant(&defaultselected));
    if(V_VT(&selected) != VT_EMPTY)
        FIXME("Unsupported selected %s\n", debugstr_variant(&selected));

    return S_OK;
}
Example #11
0
static Oc_bpt_node* node_get_xl(Oc_wu *wu_p, uint64 addr)
{
    Oc_bpt_node *node_p;

    while (1) {
        node_p = node_get(wu_p, addr);
        oc_utl_trk_crt_lock_write(wu_p, &node_p->lock);
        if (node_p->disk_addr != addr) {
            node_release(wu_p, node_p); 
        } else
            break;
    }
    oc_utl_debugassert(addr == node_p->disk_addr);
    
    return node_p;
}
Example #12
0
File: router.c Project: ireader/sdk
int router_add(struct router_t* router, const uint8_t id[N_NODEID], const struct sockaddr_storage* addr, struct node_t** node)
{
	int r;
	struct rbitem_t* item;
	struct rbtree_node_t **link;
	struct rbtree_node_t *parent;

	if (node) *node = NULL;

	item = calloc(1, sizeof(*item));
	if (!item)
		return ENOMEM;
	item->node = node_create2(id, addr);
	if (!item->node)
	{
		free(item->node);
		return ENOMEM;
	}

	locker_lock(&router->locker);
	r = rbtree_find(&router->rbtree, id, &parent);
	if (0 == r)
	{
		if (node)
		{
			*node = (rbtree_entry(parent, struct rbitem_t, link))->node;
			node_addref(*node);
		}
		locker_unlock(&router->locker);
		node_release(item->node);
		free(item);
		return EEXIST;
	}
	link = parent ? (r > 0 ? &parent->left : &parent->right) : NULL;
	assert(!link || !*link);

	rbtree_insert(&router->rbtree, parent, link, &item->link);
	router->count += 1;
	
	if (node)
	{
		node_addref(item->node);
		*node = item->node;
	}
	locker_unlock(&router->locker);
	return 0;
}
Example #13
0
static ULONG WINAPI HTMLElementCollection_Release(IHTMLElementCollection *iface)
{
    HTMLElementCollection *This = impl_from_IHTMLElementCollection(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        unsigned i;

        for(i=0; i < This->len; i++)
            node_release(&This->elems[i]->node);
        heap_free(This->elems);

        release_dispex(&This->dispex);
        heap_free(This);
    }

    return ref;
}
Example #14
0
static HRESULT WINAPI HTMLSelectElement_get_form(IHTMLSelectElement *iface, IHTMLFormElement **p)
{
    HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface);
    nsIDOMHTMLFormElement *nsform;
    nsIDOMNode *form_node;
    HTMLDOMNode *node;
    HRESULT hres;
    nsresult nsres;

    TRACE("(%p)->(%p)\n", This, p);

    if(!p)
        return E_POINTER;

    nsres = nsIDOMHTMLSelectElement_GetForm(This->nsselect, &nsform);
    FIXME("get form %08x : %p\n", nsres, nsform);
    if (NS_FAILED(nsres)) {
        ERR("GetForm failed: %08x, nsform: %p\n", nsres, nsform);
        *p = NULL;
        return E_FAIL;
    }
    if (nsform == NULL) {
        TRACE("nsform not found\n");
        *p = NULL;
        return S_OK;
    }

    nsres = nsIDOMHTMLFormElement_QueryInterface(nsform, &IID_nsIDOMNode, (void**)&form_node);
    nsIDOMHTMLFormElement_Release(nsform);
    assert(nsres == NS_OK);

    hres = get_node(This->element.node.doc, form_node, TRUE, &node);
    nsIDOMNode_Release(form_node);
    if (FAILED(hres))
        return hres;

    hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p);

    node_release(node);
    return hres;
}
Example #15
0
static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, IHTMLElement **p)
{
    HTMLDocument *This = impl_from_IHTMLDocument3(iface);
    nsIDOMElement *nselem = NULL;
    HTMLDOMNode *node;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, p);

    if(This->window->readystate == READYSTATE_UNINITIALIZED) {
        *p = NULL;
        return S_OK;
    }

    if(!This->doc_node->nsdoc) {
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

    nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem);
    if(NS_FAILED(nsres)) {
        ERR("GetDocumentElement failed: %08x\n", nsres);
        return E_FAIL;
    }

    if(!nselem) {
        *p = NULL;
        return S_OK;
    }

    hres = get_node(This->doc_node, (nsIDOMNode *)nselem, TRUE, &node);
    nsIDOMElement_Release(nselem);
    if(FAILED(hres))
        return hres;

    hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p);
    node_release(node);
    return hres;
}
Example #16
0
static HRESULT assoc_element(PluginHost *host, HTMLDocumentNode *doc, nsIDOMElement *nselem)
{
    HTMLPluginContainer *container_elem;
    HTMLDOMNode *node;
    HRESULT hres;

    hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node);
    if(FAILED(hres))
        return hres;

    hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_HTMLPluginContainer,
            (void**)&container_elem);
    node_release(node);
    if(FAILED(hres)) {
        ERR("Not an object element\n");
        return hres;
    }

    container_elem->plugin_host = host;
    host->element = container_elem;
    return S_OK;
}
Example #17
0
File: router.c Project: ireader/sdk
int router_remove(struct router_t* router, const uint8_t id[N_NODEID])
{
	int r;
	struct rbitem_t* item;
	struct rbtree_node_t* node;

	locker_lock(&router->locker);
	r = rbtree_find(&router->rbtree, id, &node);
	if (0 != r)
	{
		locker_unlock(&router->locker);
		return ENOENT;
	}
	
	router->count -= 1;
	item = rbtree_entry(node, struct rbitem_t, link);
	rbtree_delete(&router->rbtree, node);
	locker_unlock(&router->locker);
	node_release(item->node);
	free(item);
	return 0;
}
Example #18
0
static void fire_event_obj(HTMLDocumentNode *doc, eventid_t eid, HTMLEventObj *event_obj,
        nsIDOMNode *target, IDispatch *script_this)
{
    IHTMLEventObj *prev_event;
    nsIDOMNode *parent, *nsnode;
    BOOL prevent_default = FALSE;
    HTMLInnerWindow *window;
    HTMLDOMNode *node;
    UINT16 node_type;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p) %s\n", doc, debugstr_w(event_info[eid].name));

    window = doc->window;
    if(!window) {
        WARN("NULL window\n");
        return;
    }

    htmldoc_addref(&doc->basedoc);

    prev_event = window->event;
    window->event = event_obj ? &event_obj->IHTMLEventObj_iface : NULL;

    nsIDOMNode_GetNodeType(target, &node_type);
    nsnode = target;
    nsIDOMNode_AddRef(nsnode);

    switch(node_type) {
    case ELEMENT_NODE:
        do {
            hres = get_node(doc, nsnode, FALSE, &node);
            if(SUCCEEDED(hres) && node) {
                call_event_handlers(doc, event_obj, *get_node_event_target(node),
                        node->cp_container, eid, script_this ? script_this : (IDispatch*)&node->IHTMLDOMNode_iface);
                node_release(node);
            }

            if(!(event_info[eid].flags & EVENT_BUBBLE) || (event_obj && event_obj->cancel_bubble))
                break;

            nsIDOMNode_GetParentNode(nsnode, &parent);
            nsIDOMNode_Release(nsnode);
            nsnode = parent;
            if(!nsnode)
                break;

            nsIDOMNode_GetNodeType(nsnode, &node_type);
        }while(node_type == ELEMENT_NODE);

        if(!(event_info[eid].flags & EVENT_BUBBLE) || (event_obj && event_obj->cancel_bubble))
            break;

    case DOCUMENT_NODE:
        if(event_info[eid].flags & EVENT_FORWARDBODY) {
            nsIDOMHTMLElement *nsbody;
            nsresult nsres;

            nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody);
            if(NS_SUCCEEDED(nsres) && nsbody) {
                hres = get_node(doc, (nsIDOMNode*)nsbody, FALSE, &node);
                if(SUCCEEDED(hres) && node) {
                    call_event_handlers(doc, event_obj, *get_node_event_target(node),
                            node->cp_container, eid, script_this ? script_this : (IDispatch*)&node->IHTMLDOMNode_iface);
                    node_release(node);
                }
                nsIDOMHTMLElement_Release(nsbody);
            }else {
                ERR("Could not get body: %08x\n", nsres);
            }
        }

        call_event_handlers(doc, event_obj, doc->node.event_target, &doc->basedoc.cp_container, eid,
                script_this ? script_this : (IDispatch*)&doc->basedoc.IHTMLDocument2_iface);
        break;

    default:
        FIXME("unimplemented node type %d\n", node_type);
    }

    if(nsnode)
        nsIDOMNode_Release(nsnode);

    if(event_obj && event_obj->prevent_default)
        prevent_default = TRUE;
    window->event = prev_event;

    if(!prevent_default && (event_info[eid].flags & EVENT_HASDEFAULTHANDLERS)) {
        nsIDOMNode_AddRef(target);
        nsnode = target;

        do {
            hres = get_node(doc, nsnode, TRUE, &node);
            if(FAILED(hres))
                break;

            if(node) {
                if(node->vtbl->handle_event)
                    hres = node->vtbl->handle_event(node, eid, event_obj ? event_obj->nsevent : NULL, &prevent_default);
                node_release(node);
                if(FAILED(hres) || prevent_default || (event_obj && event_obj->cancel_bubble))
                    break;
            }

            nsres = nsIDOMNode_GetParentNode(nsnode, &parent);
            if(NS_FAILED(nsres))
                break;

            nsIDOMNode_Release(nsnode);
            nsnode = parent;
        } while(nsnode);

        if(nsnode)
            nsIDOMNode_Release(nsnode);
    }

    if(prevent_default && event_obj && event_obj->nsevent) {
        TRACE("calling PreventDefault\n");
        nsIDOMEvent_PreventDefault(event_obj->nsevent);
    }

    htmldoc_release(&doc->basedoc);
}
Example #19
0
void handle_fuse_request(struct fuse *fuse, struct fuse_in_header *hdr, void *data, unsigned len)
{
    struct node *node;

    if ((len < sizeof(*hdr)) || (hdr->len != len)) {
        ERROR("malformed header\n");
        return;
    }

    len -= hdr->len;

    if (hdr->nodeid) {
        node = lookup_by_inode(fuse, hdr->nodeid);
        if (!node) {
            fuse_status(fuse, hdr->unique, -ENOENT);
            return;
        }
    } else {
        node = 0;
    }

    switch (hdr->opcode) {
    case FUSE_LOOKUP: { /* bytez[] -> entry_out */
        TRACE("LOOKUP %llx %s\n", hdr->nodeid, (char*) data);
        lookup_entry(fuse, node, (char*) data, hdr->unique);
        return;
    }
    case FUSE_FORGET: {
        struct fuse_forget_in *req = data;
        TRACE("FORGET %llx (%s) #%lld\n", hdr->nodeid, node->name, req->nlookup);
            /* no reply */
        while (req->nlookup--)
            node_release(node);
        return;
    }
    case FUSE_GETATTR: { /* getattr_in -> attr_out */
        struct fuse_getattr_in *req = data;
        struct fuse_attr_out out;

        TRACE("GETATTR flags=%x fh=%llx\n", req->getattr_flags, req->fh);

        memset(&out, 0, sizeof(out));
        node_get_attr(node, &out.attr);
        out.attr_valid = 10;

        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        return;
    }
    case FUSE_SETATTR: { /* setattr_in -> attr_out */
        struct fuse_setattr_in *req = data;
        struct fuse_attr_out out;
        char *path, buffer[PATH_BUFFER_SIZE];
        int res = 0;
        struct timespec times[2];

        TRACE("SETATTR fh=%llx id=%llx valid=%x\n",
              req->fh, hdr->nodeid, req->valid);

        /* XXX: incomplete implementation on purpose.   chmod/chown
         * should NEVER be implemented.*/

        path = node_get_path(node, buffer, 0);
        if (req->valid & FATTR_SIZE)
            res = truncate(path, req->size);
        if (res)
            goto getout;

        /* Handle changing atime and mtime.  If FATTR_ATIME_and FATTR_ATIME_NOW
         * are both set, then set it to the current time.  Else, set it to the
         * time specified in the request.  Same goes for mtime.  Use utimensat(2)
         * as it allows ATIME and MTIME to be changed independently, and has
         * nanosecond resolution which fuse also has.
         */
        if (req->valid & (FATTR_ATIME | FATTR_MTIME)) {
            times[0].tv_nsec = UTIME_OMIT;
            times[1].tv_nsec = UTIME_OMIT;
            if (req->valid & FATTR_ATIME) {
                if (req->valid & FATTR_ATIME_NOW) {
                  times[0].tv_nsec = UTIME_NOW;
                } else {
                  times[0].tv_sec = req->atime;
                  times[0].tv_nsec = req->atimensec;
                }
            }
            if (req->valid & FATTR_MTIME) {
                if (req->valid & FATTR_MTIME_NOW) {
                  times[1].tv_nsec = UTIME_NOW;
                } else {
                  times[1].tv_sec = req->mtime;
                  times[1].tv_nsec = req->mtimensec;
                }
            }
            TRACE("Calling utimensat on %s with atime %ld, mtime=%ld\n", path, times[0].tv_sec, times[1].tv_sec);
            res = utimensat(-1, path, times, 0);
        }

        getout:
        memset(&out, 0, sizeof(out));
        node_get_attr(node, &out.attr);
        out.attr_valid = 10;

        if (res)
            fuse_status(fuse, hdr->unique, -errno);
        else
            fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        return;
    }
//    case FUSE_READLINK:
//    case FUSE_SYMLINK:
    case FUSE_MKNOD: { /* mknod_in, bytez[] -> entry_out */
        struct fuse_mknod_in *req = data;
        char *path, buffer[PATH_BUFFER_SIZE];
        char *name = ((char*) data) + sizeof(*req);
        int res;

        TRACE("MKNOD %s @ %llx\n", name, hdr->nodeid);
        path = node_get_path(node, buffer, name);

        req->mode = (req->mode & (~0777)) | 0664;
        res = mknod(path, req->mode, req->rdev); /* XXX perm?*/
        if (res < 0) {
            fuse_status(fuse, hdr->unique, -errno);
        } else {
            lookup_entry(fuse, node, name, hdr->unique);
        }
        return;
    }
    case FUSE_MKDIR: { /* mkdir_in, bytez[] -> entry_out */
        struct fuse_mkdir_in *req = data;
        struct fuse_entry_out out;
        char *path, buffer[PATH_BUFFER_SIZE];
        char *name = ((char*) data) + sizeof(*req);
        int res;

        TRACE("MKDIR %s @ %llx 0%o\n", name, hdr->nodeid, req->mode);
        path = node_get_path(node, buffer, name);

        req->mode = (req->mode & (~0777)) | 0775;
        res = mkdir(path, req->mode);
        if (res < 0) {
            fuse_status(fuse, hdr->unique, -errno);
        } else {
            lookup_entry(fuse, node, name, hdr->unique);
        }
        return;
    }
    case FUSE_UNLINK: { /* bytez[] -> */
        char *path, buffer[PATH_BUFFER_SIZE];
        int res;
        TRACE("UNLINK %s @ %llx\n", (char*) data, hdr->nodeid);
        path = node_get_path(node, buffer, (char*) data);
        res = unlink(path);
        fuse_status(fuse, hdr->unique, res ? -errno : 0);
        return;
    }
    case FUSE_RMDIR: { /* bytez[] -> */
        char *path, buffer[PATH_BUFFER_SIZE];
        int res;
        TRACE("RMDIR %s @ %llx\n", (char*) data, hdr->nodeid);
        path = node_get_path(node, buffer, (char*) data);
        res = rmdir(path);
        fuse_status(fuse, hdr->unique, res ? -errno : 0);
        return;
    }
    case FUSE_RENAME: { /* rename_in, oldname, newname ->  */
        struct fuse_rename_in *req = data;
        char *oldname = ((char*) data) + sizeof(*req);
        char *newname = oldname + strlen(oldname) + 1;
        char *oldpath, oldbuffer[PATH_BUFFER_SIZE];
        char *newpath, newbuffer[PATH_BUFFER_SIZE];
        struct node *target;
        struct node *newparent;
        int res;

        TRACE("RENAME %s->%s @ %llx\n", oldname, newname, hdr->nodeid);

        target = lookup_child_by_name(node, oldname);
        if (!target) {
            fuse_status(fuse, hdr->unique, -ENOENT);
            return;
        }
        oldpath = node_get_path(node, oldbuffer, oldname);

        newparent = lookup_by_inode(fuse, req->newdir);
        if (!newparent) {
            fuse_status(fuse, hdr->unique, -ENOENT);
            return;
        }
        if (newparent == node) {
            /* Special case for renaming a file where destination
             * is same path differing only by case.
             * In this case we don't want to look for a case insensitive match.
             * This allows commands like "mv foo FOO" to work as expected.
             */
            newpath = do_node_get_path(newparent, newbuffer, newname, NO_CASE_SENSITIVE_MATCH);
        } else {
            newpath = node_get_path(newparent, newbuffer, newname);
        }

        if (!remove_child(node, target->nid)) {
            ERROR("RENAME remove_child not found");
            fuse_status(fuse, hdr->unique, -ENOENT);
            return;
        }
        if (!rename_node(target, newname)) {
            fuse_status(fuse, hdr->unique, -ENOMEM);
            return;
        }
        add_node_to_parent(target, newparent);

        res = rename(oldpath, newpath);
        TRACE("RENAME result %d\n", res);

        fuse_status(fuse, hdr->unique, res ? -errno : 0);
        return;
    }
//    case FUSE_LINK:        
    case FUSE_OPEN: { /* open_in -> open_out */
        struct fuse_open_in *req = data;
        struct fuse_open_out out;
        char *path, buffer[PATH_BUFFER_SIZE];
        struct handle *h;

        h = malloc(sizeof(*h));
        if (!h) {
            fuse_status(fuse, hdr->unique, -ENOMEM);
            return;
        }

        path = node_get_path(node, buffer, 0);
        TRACE("OPEN %llx '%s' 0%o fh=%p\n", hdr->nodeid, path, req->flags, h);
        h->fd = open(path, req->flags);
        if (h->fd < 0) {
            ERROR("ERROR\n");
            fuse_status(fuse, hdr->unique, -errno);
            free(h);
            return;
        }
        out.fh = ptr_to_id(h);
        out.open_flags = 0;
        out.padding = 0;
        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        return;
    }
    case FUSE_READ: { /* read_in -> byte[] */
        char buffer[128 * 1024];
        struct fuse_read_in *req = data;
        struct handle *h = id_to_ptr(req->fh);
        int res;
        TRACE("READ %p(%d) %u@%llu\n", h, h->fd, req->size, req->offset);
        if (req->size > sizeof(buffer)) {
            fuse_status(fuse, hdr->unique, -EINVAL);
            return;
        }
        res = pread64(h->fd, buffer, req->size, req->offset);
        if (res < 0) {
            fuse_status(fuse, hdr->unique, -errno);
            return;
        }
        fuse_reply(fuse, hdr->unique, buffer, res);
        return;
    }
    case FUSE_WRITE: { /* write_in, byte[write_in.size] -> write_out */
        struct fuse_write_in *req = data;
        struct fuse_write_out out;
        struct handle *h = id_to_ptr(req->fh);
        int res;
        TRACE("WRITE %p(%d) %u@%llu\n", h, h->fd, req->size, req->offset);
        res = pwrite64(h->fd, ((char*) data) + sizeof(*req), req->size, req->offset);
        if (res < 0) {
            fuse_status(fuse, hdr->unique, -errno);
            return;
        }
        out.size = res;
        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        goto oops;
    }
    case FUSE_STATFS: { /* getattr_in -> attr_out */
        struct statfs stat;
        struct fuse_statfs_out out;
        int res;

        TRACE("STATFS\n");

        if (statfs(fuse->root.name, &stat)) {
            fuse_status(fuse, hdr->unique, -errno);
            return;
        }

        memset(&out, 0, sizeof(out));
        out.st.blocks = stat.f_blocks;
        out.st.bfree = stat.f_bfree;
        out.st.bavail = stat.f_bavail;
        out.st.files = stat.f_files;
        out.st.ffree = stat.f_ffree;
        out.st.bsize = stat.f_bsize;
        out.st.namelen = stat.f_namelen;
        out.st.frsize = stat.f_frsize;
        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        return;
    }
    case FUSE_RELEASE: { /* release_in -> */
        struct fuse_release_in *req = data;
        struct handle *h = id_to_ptr(req->fh);
        TRACE("RELEASE %p(%d)\n", h, h->fd);
        close(h->fd);
        free(h);
        fuse_status(fuse, hdr->unique, 0);
        return;
    }
//    case FUSE_FSYNC:
//    case FUSE_SETXATTR:
//    case FUSE_GETXATTR:
//    case FUSE_LISTXATTR:
//    case FUSE_REMOVEXATTR:
    case FUSE_FLUSH:
        fuse_status(fuse, hdr->unique, 0);
        return;
    case FUSE_OPENDIR: { /* open_in -> open_out */
        struct fuse_open_in *req = data;
        struct fuse_open_out out;
        char *path, buffer[PATH_BUFFER_SIZE];
        struct dirhandle *h;

        h = malloc(sizeof(*h));
        if (!h) {
            fuse_status(fuse, hdr->unique, -ENOMEM);
            return;
        }

        path = node_get_path(node, buffer, 0);
        TRACE("OPENDIR %llx '%s'\n", hdr->nodeid, path);
        h->d = opendir(path);
        if (h->d == 0) {
            ERROR("ERROR\n");
            fuse_status(fuse, hdr->unique, -errno);
            free(h);
            return;
        }
        out.fh = ptr_to_id(h);
        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        return;
    }
    case FUSE_READDIR: {
        struct fuse_read_in *req = data;
        char buffer[8192];
        struct fuse_dirent *fde = (struct fuse_dirent*) buffer;
        struct dirent *de;
        struct dirhandle *h = id_to_ptr(req->fh);
        TRACE("READDIR %p\n", h);
        if (req->offset == 0) {
            /* rewinddir() might have been called above us, so rewind here too */
            TRACE("calling rewinddir()\n");
            rewinddir(h->d);
        }
        de = readdir(h->d);
        if (!de) {
            fuse_status(fuse, hdr->unique, 0);
            return;
        }
        fde->ino = FUSE_UNKNOWN_INO;
        /* increment the offset so we can detect when rewinddir() seeks back to the beginning */
        fde->off = req->offset + 1;
        fde->type = de->d_type;
        fde->namelen = strlen(de->d_name);
        memcpy(fde->name, de->d_name, fde->namelen + 1);
        fuse_reply(fuse, hdr->unique, fde,
                   FUSE_DIRENT_ALIGN(sizeof(struct fuse_dirent) + fde->namelen));
        return;
    }
    case FUSE_RELEASEDIR: { /* release_in -> */
        struct fuse_release_in *req = data;
        struct dirhandle *h = id_to_ptr(req->fh);
        TRACE("RELEASEDIR %p\n",h);
        closedir(h->d);
        free(h);
        fuse_status(fuse, hdr->unique, 0);
        return;
    }
//    case FUSE_FSYNCDIR:
    case FUSE_INIT: { /* init_in -> init_out */
        struct fuse_init_in *req = data;
        struct fuse_init_out out;
        
        TRACE("INIT ver=%d.%d maxread=%d flags=%x\n",
                req->major, req->minor, req->max_readahead, req->flags);

        out.major = FUSE_KERNEL_VERSION;
        out.minor = FUSE_KERNEL_MINOR_VERSION;
        out.max_readahead = req->max_readahead;
        out.flags = FUSE_ATOMIC_O_TRUNC | FUSE_BIG_WRITES;
        out.max_background = 32;
        out.congestion_threshold = 32;
        out.max_write = 256 * 1024;

        fuse_reply(fuse, hdr->unique, &out, sizeof(out));
        return;
    }
    default: {
        struct fuse_out_header h;
        ERROR("NOTIMPL op=%d uniq=%llx nid=%llx\n",
                hdr->opcode, hdr->unique, hdr->nodeid);

        oops:
        h.len = sizeof(h);
        h.error = -ENOSYS;
        h.unique = hdr->unique;
        write(fuse->fd, &h, sizeof(h));
        break;
    }
    }   
}
Example #20
0
static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v,
                                                   IHTMLElement **pel)
{
    HTMLDocument *This = impl_from_IHTMLDocument3(iface);
    nsIDOMElement *nselem;
    HTMLDOMNode *node;
    nsIDOMNode *nsnode, *nsnode_by_id, *nsnode_by_name;
    nsIDOMNodeList *nsnode_list;
    nsAString id_str;
    nsresult nsres;
    HRESULT hres;

    TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pel);

    if(!This->doc_node->nsdoc) {
        WARN("NULL nsdoc\n");
        return E_UNEXPECTED;
    }

    nsAString_InitDepend(&id_str, v);
    /* get element by id attribute */
    nsres = nsIDOMHTMLDocument_GetElementById(This->doc_node->nsdoc, &id_str, &nselem);
    if(FAILED(nsres)) {
        ERR("GetElementById failed: %08x\n", nsres);
        nsAString_Finish(&id_str);
        return E_FAIL;
    }
    nsnode_by_id = (nsIDOMNode*)nselem;

    /* get first element by name attribute */
    nsres = nsIDOMHTMLDocument_GetElementsByName(This->doc_node->nsdoc, &id_str, &nsnode_list);
    nsAString_Finish(&id_str);
    if(FAILED(nsres)) {
        ERR("getElementsByName failed: %08x\n", nsres);
        if(nsnode_by_id)
            nsIDOMNode_Release(nsnode_by_id);
        return E_FAIL;
    }
    nsIDOMNodeList_Item(nsnode_list, 0, &nsnode_by_name);
    nsIDOMNodeList_Release(nsnode_list);


    if(nsnode_by_name && nsnode_by_id) {
        PRUint16 pos;

        nsres = nsIDOMNode_CompareDocumentPosition(nsnode_by_name, nsnode_by_id, &pos);
        if(NS_FAILED(nsres)) {
            FIXME("CompareDocumentPosition failed: 0x%08x\n", nsres);
            nsIDOMNode_Release(nsnode_by_name);
            nsIDOMNode_Release(nsnode_by_id);
            return E_FAIL;
        }

        TRACE("CompareDocumentPosition gave: 0x%x\n", pos);
        if(pos & (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS)) {
            nsnode = nsnode_by_id;
            nsIDOMNode_Release(nsnode_by_name);
        }else {
            nsnode = nsnode_by_name;
            nsIDOMNode_Release(nsnode_by_id);
        }
    }else
        nsnode = nsnode_by_name ? nsnode_by_name : nsnode_by_id;

    if(nsnode) {
        hres = get_node(This->doc_node, nsnode, TRUE, &node);
        nsIDOMNode_Release(nsnode);

        if(SUCCEEDED(hres)) {
            hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)pel);
            node_release(node);
        }
    }else {
        *pel = NULL;
        hres = S_OK;
    }

    return hres;
}