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; }
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; }
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; }
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); } } }
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; }
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); }
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); } }
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"); }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; } } }
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; }