diff --git a/sesman/chansrv/chansrv_fuse.c b/sesman/chansrv/chansrv_fuse.c index 4f461bcf..36e884c3 100644 --- a/sesman/chansrv/chansrv_fuse.c +++ b/sesman/chansrv/chansrv_fuse.c @@ -116,7 +116,7 @@ void xfuse_devredir_cb_file_close(void *vp) {} #define LOG_ERROR 0 #define LOG_INFO 1 #define LOG_DEBUG 2 -#define LOG_LEVEL LOG_DEBUG +#define LOG_LEVEL LOG_ERROR #define log_error(_params...) \ { \ @@ -308,8 +308,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent, static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi); -static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct - fuse_file_info *fi); +static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct + fuse_file_info *fi); static void xfuse_cb_read(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off, struct fuse_file_info *fi); @@ -378,19 +378,19 @@ int xfuse_init() /* setup FUSE callbacks */ g_memset(&g_xfuse_ops, 0, sizeof(g_xfuse_ops)); - g_xfuse_ops.lookup = xfuse_cb_lookup; - g_xfuse_ops.readdir = xfuse_cb_readdir; - g_xfuse_ops.mkdir = xfuse_cb_mkdir; - g_xfuse_ops.rmdir = xfuse_cb_rmdir; - g_xfuse_ops.unlink = xfuse_cb_unlink; - g_xfuse_ops.rename = xfuse_cb_rename; - g_xfuse_ops.open = xfuse_cb_open; - g_xfuse_ops.flush = xfuse_cb_flush; - g_xfuse_ops.read = xfuse_cb_read; - g_xfuse_ops.write = xfuse_cb_write; - g_xfuse_ops.create = xfuse_cb_create; - g_xfuse_ops.getattr = xfuse_cb_getattr; - g_xfuse_ops.setattr = xfuse_cb_setattr; + g_xfuse_ops.lookup = xfuse_cb_lookup; + g_xfuse_ops.readdir = xfuse_cb_readdir; + g_xfuse_ops.mkdir = xfuse_cb_mkdir; + g_xfuse_ops.rmdir = xfuse_cb_rmdir; + g_xfuse_ops.unlink = xfuse_cb_unlink; + g_xfuse_ops.rename = xfuse_cb_rename; + g_xfuse_ops.open = xfuse_cb_open; + g_xfuse_ops.release = xfuse_cb_release; + g_xfuse_ops.read = xfuse_cb_read; + g_xfuse_ops.write = xfuse_cb_write; + g_xfuse_ops.create = xfuse_cb_create; + g_xfuse_ops.getattr = xfuse_cb_getattr; + g_xfuse_ops.setattr = xfuse_cb_setattr; fuse_opt_add_arg(&args, "xrdp-chansrv"); fuse_opt_add_arg(&args, g_fuse_root_path); @@ -1723,6 +1723,9 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 DeviceId, tui32 FileId) goto done; } + log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p DeviceId=%d FileId=%d", + fip, fip->fi, DeviceId, FileId); + if (fip->fi != NULL) { if ((fh = calloc(1, sizeof(XFUSE_HANDLE))) == NULL) @@ -1739,6 +1742,8 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 DeviceId, tui32 FileId) fh->FileId = FileId; fip->fi->fh = (uint64_t) ((long) fh); + log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p", + fip, fip->fi, fip->fi->fh); } if (fip->invoke_fuse) @@ -1793,6 +1798,9 @@ void xfuse_devredir_cb_open_file(void *vp, tui32 DeviceId, tui32 FileId) e.attr.st_ctime = xinode->ctime; e.generation = 1; + /* update open count */ + xinode->nopen++; + if (fip->mode == S_IFDIR) fuse_reply_entry(fip->req, &e); else @@ -1830,6 +1838,9 @@ void xfuse_devredir_cb_write_file(void *vp, char *buf, size_t length) if (fip == NULL) return; + log_debug("+++ XFUSE_INFO=%p, XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p", + fip, fip->fi, fip->fi->fh); + fuse_reply_write(fip->req, length); /* update file size */ @@ -1944,6 +1955,9 @@ void xfuse_devredir_cb_file_close(void *vp) if (fip == NULL) return; + log_debug("+++ XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p", + fip, fip->fi, fip->fi->fh); + if ((xinode = g_xrdp_fs.inode_table[fip->inode]) == NULL) fuse_reply_err(fip->req, EBADF); @@ -1952,11 +1966,17 @@ void xfuse_devredir_cb_file_close(void *vp) if (xinode->nopen > 0) xinode->nopen--; + /* LK_TODO */ +#if 0 if ((xinode->nopen == 0) && fip->fi && fip->fi->fh) { + printf("LK_TODO: ################################ fi=%p fi->fh=%p\n", + fip->fi, fip->fi->fh); + free((char *) (tintptr) (fip->fi->fh)); fip->fi->fh = NULL; } +#endif fuse_reply_err(fip->req, 0); } @@ -2562,6 +2582,8 @@ static void xfuse_create_dir_or_file(fuse_req_t req, fuse_ino_t parent, strncpy(fip->name, name, 1024); fip->name[1023] = 0; + log_debug("+++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p", fip, fip->fi); + /* LK_TODO need to handle open permissions */ /* we want path minus 'root node of the share' */ @@ -2642,6 +2664,9 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, fip->invoke_fuse = 1; fip->device_id = device_id; fip->fi = fi; + + log_debug("LK_TODO: fip->fi = %p", fip->fi); + strncpy(fip->name, full_path, 1024); fip->name[1023] = 0; fip->reply_type = RT_FUSE_REPLY_OPEN; @@ -2670,13 +2695,14 @@ static void xfuse_cb_open(fuse_req_t req, fuse_ino_t ino, } } -static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct - fuse_file_info *fi) +static void xfuse_cb_release(fuse_req_t req, fuse_ino_t ino, struct + fuse_file_info *fi) { XFUSE_INFO *fip = NULL; XFUSE_HANDLE *handle = (XFUSE_HANDLE *) (tintptr) (fi->fh); + tui32 FileId; - log_debug("ino=%d", (int) ino); + log_debug("entered: ino=%d fi=%p fi->fh=%p", (int) ino, fi, fi->fh); if (!xfuse_is_inode_valid(ino)) { @@ -2695,6 +2721,16 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct /* specified file resides on redirected share */ + log_debug("nopen=%d", xinode->nopen); + + /* if file is not opened, just return */ + if (xinode->nopen == 0) + { + log_debug("cannot close because file not opened"); + fuse_reply_err(req, 0); + return; + } + if ((fip = calloc(1, sizeof(XFUSE_INFO))) == NULL) { log_error("system out of memory"); @@ -2708,6 +2744,13 @@ static void xfuse_cb_flush(fuse_req_t req, fuse_ino_t ino, struct fip->device_id = handle->DeviceId; fip->fi = fi; + log_debug(" +++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p", + fip, fip->fi, fip->fi->fh); + + FileId = handle->FileId; + free(handle); + fip->fi->fh = NULL; + if (devredir_file_close((void *) fip, fip->device_id, handle->FileId)) { log_error("failed to send devredir_close_file() cmd"); @@ -2823,12 +2866,16 @@ static void xfuse_cb_write(fuse_req_t req, fuse_ino_t ino, const char *buf, fuse_reply_err(req, ENOMEM); return; } + fusep->req = req; fusep->inode = ino; fusep->invoke_fuse = 1; fusep->device_id = fh->DeviceId; fusep->fi = fi; + log_debug("+++ created XFUSE_INFO=%p XFUSE_INFO->fi=%p XFUSE_INFO->fi->fh=%p", + fusep, fusep->fi, fusep->fi->fh); + dev_redir_file_write(fusep, fh->DeviceId, fh->FileId, buf, size, off); log_debug("exiting"); } @@ -2843,7 +2890,8 @@ static void xfuse_cb_create(fuse_req_t req, fuse_ino_t parent, static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, int to_set, struct fuse_file_info *fi) { - XRDP_INODE *xinode; + XRDP_INODE *xinode; + struct stat st; log_debug("entered to_set=0x%x", to_set); @@ -2906,7 +2954,17 @@ static void xfuse_cb_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, log_debug("FUSE_SET_ATTR_MTIME_NOW"); } - fuse_reply_attr(req, attr, 1.0); /* LK_TODO just faking for now */ + memset(&st, 0, sizeof(st)); + st.st_ino = xinode->inode; + st.st_mode = xinode->mode; + st.st_size = xinode->size; + st.st_uid = xinode->uid; + st.st_gid = xinode->gid; + st.st_atime = xinode->atime; + st.st_mtime = xinode->mtime; + st.st_ctime = xinode->ctime; + + fuse_reply_attr(req, &st, 1.0); /* LK_TODO just faking for now */ } #endif /* end else #ifndef XRDP_FUSE */ diff --git a/sesman/chansrv/devredir.c b/sesman/chansrv/devredir.c index f14c17dc..0a0a6681 100644 --- a/sesman/chansrv/devredir.c +++ b/sesman/chansrv/devredir.c @@ -56,7 +56,7 @@ #define LOG_DEBUG 2 #ifndef LOG_LEVEL -#define LOG_LEVEL LOG_DEBUG +#define LOG_LEVEL LOG_ERROR #endif #define log_error(_params...) \ @@ -742,7 +742,7 @@ void dev_redir_proc_device_iocompletion(struct stream *s) { /* we were trying to create a request to enumerate a dir */ /* that does not exist; let FUSE know */ - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_enum_dir_done(fuse_data->data_ptr, @@ -764,7 +764,7 @@ void dev_redir_proc_device_iocompletion(struct stream *s) xstream_rd_u32_le(s, irp->FileId); log_debug("got CID_CREATE_OPEN_REQ IoStatus=0x%x FileId=%d", IoStatus, irp->FileId); - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); xfuse_devredir_cb_open_file(fuse_data->data_ptr, DeviceId, irp->FileId); if (irp->type == S_IFDIR) @@ -774,14 +774,14 @@ void dev_redir_proc_device_iocompletion(struct stream *s) case CID_READ: log_debug("got CID_READ"); xstream_rd_u32_le(s, Length); - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); xfuse_devredir_cb_read_file(fuse_data->data_ptr, s->p, Length); break; case CID_WRITE: log_debug("got CID_WRITE"); xstream_rd_u32_le(s, Length); - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); xfuse_devredir_cb_write_file(fuse_data->data_ptr, s->p, Length); break; @@ -794,7 +794,7 @@ void dev_redir_proc_device_iocompletion(struct stream *s) case CID_FILE_CLOSE: log_debug("got CID_FILE_CLOSE"); - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); xfuse_devredir_cb_file_close(fuse_data->data_ptr); devredir_irp_delete(irp); break; @@ -840,7 +840,10 @@ void dev_redir_proc_device_iocompletion(struct stream *s) done: if (fuse_data) + { + log_debug("free FUSE_DATA=%p", fuse_data); free(fuse_data); + } log_debug("exiting"); } @@ -880,7 +883,7 @@ void dev_redir_proc_query_dir_response(IRP *irp, (IoStatus == STATUS_NO_MORE_FILES)) { status = (IoStatus == STATUS_NO_MORE_FILES) ? 0 : IoStatus; - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); xfuse_devredir_cb_enum_dir_done(fuse_data->data_ptr, status); irp->completion_type = CID_CLOSE; dev_redir_send_drive_close_request(RDPDR_CTYP_CORE, @@ -940,7 +943,7 @@ void dev_redir_proc_query_dir_response(IRP *irp, if ((xinode = calloc(1, sizeof(struct xrdp_inode))) == NULL) { log_error("system out of memory"); - fuse_data = dev_redir_fuse_data_peek(irp); + fuse_data = devredir_fuse_data_peek(irp); xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, NULL); return; } @@ -953,7 +956,7 @@ void dev_redir_proc_query_dir_response(IRP *irp, xinode->ctime = WINDOWS_TO_LINUX_TIME(CreationTime); /* add this entry to xrdp file system */ - fuse_data = dev_redir_fuse_data_peek(irp); + fuse_data = devredir_fuse_data_peek(irp); xfuse_devredir_cb_enum_dir(fuse_data->data_ptr, xinode); } @@ -990,7 +993,7 @@ int dev_redir_get_dir_listing(void *fusep, tui32 device_id, char *path) irp->completion_type = CID_CREATE_DIR_REQ; irp->DeviceId = device_id; strcpy(irp->pathname, path); - dev_redir_fuse_data_enqueue(irp, fusep); + devredir_fuse_data_enqueue(irp, fusep); DesiredAccess = DA_FILE_READ_DATA | DA_SYNCHRONIZE; CreateOptions = CO_FILE_DIRECTORY_FILE | CO_FILE_SYNCHRONOUS_IO_NONALERT; @@ -1041,7 +1044,7 @@ int dev_redir_file_open(void *fusep, tui32 device_id, char *path, irp->CompletionId = g_completion_id++; irp->DeviceId = device_id; strcpy(irp->pathname, path); - dev_redir_fuse_data_enqueue(irp, fusep); + devredir_fuse_data_enqueue(irp, fusep); if (mode & O_CREAT) { @@ -1090,7 +1093,8 @@ int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId) { IRP *irp; - log_debug("entered"); + log_debug("entered: fusep=%p device_id=%d FileId=%d", + fusep, device_id, FileId); #if 0 if ((irp = devredir_irp_new()) == NULL) @@ -1106,7 +1110,7 @@ int devredir_file_close(void *fusep, tui32 device_id, tui32 FileId) #endif irp->completion_type = CID_FILE_CLOSE; irp->DeviceId = device_id; - dev_redir_fuse_data_enqueue(irp, fusep); + devredir_fuse_data_enqueue(irp, fusep); return dev_redir_send_drive_close_request(RDPDR_CTYP_CORE, PAKID_CORE_DEVICE_IOREQUEST, @@ -1136,7 +1140,7 @@ int devredir_rmdir_or_file(void *fusep, tui32 device_id, char *path, int mode) irp->completion_type = CID_RMDIR_OR_FILE; irp->DeviceId = device_id; strcpy(irp->pathname, path); - dev_redir_fuse_data_enqueue(irp, fusep); + devredir_fuse_data_enqueue(irp, fusep); //DesiredAccess = DA_DELETE | DA_FILE_READ_ATTRIBUTES | DA_SYNCHRONIZE; DesiredAccess = 0x00100080; /* got this value from windows */ @@ -1179,7 +1183,7 @@ int dev_redir_file_read(void *fusep, tui32 DeviceId, tui32 FileId, } irp->completion_type = CID_READ; - dev_redir_fuse_data_enqueue(irp, fusep); + devredir_fuse_data_enqueue(irp, fusep); devredir_insert_DeviceIoRequest(s, DeviceId, FileId, @@ -1219,7 +1223,7 @@ int dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId, } irp->completion_type = CID_WRITE; - dev_redir_fuse_data_enqueue(irp, fusep); + devredir_fuse_data_enqueue(irp, fusep); devredir_insert_DeviceIoRequest(s, DeviceId, FileId, @@ -1252,8 +1256,9 @@ int dev_redir_file_write(void *fusep, tui32 DeviceId, tui32 FileId, * @return FUSE_DATA on success, or NULL on failure *****************************************************************************/ -void *dev_redir_fuse_data_peek(IRP *irp) +void *devredir_fuse_data_peek(IRP *irp) { + log_debug("returning %p", irp->fd_head); return irp->fd_head; } @@ -1263,12 +1268,15 @@ void *dev_redir_fuse_data_peek(IRP *irp) * @return FUSE_DATA on success, NULL on failure *****************************************************************************/ -void *dev_redir_fuse_data_dequeue(IRP *irp) +void *devredir_fuse_data_dequeue(IRP *irp) { FUSE_DATA *head; if ((irp == NULL) || (irp->fd_head == NULL)) + { + log_debug("+++ returning NULL"); return NULL; + } if (irp->fd_head->next == NULL) { @@ -1276,13 +1284,16 @@ void *dev_redir_fuse_data_dequeue(IRP *irp) head = irp->fd_head; irp->fd_head = NULL; irp->fd_tail = NULL; + log_debug("+++ returning FUSE_DATA=%p containing FUSE_INFO=%p", + head, head->data_ptr); return head; } /* more than one element in queue */ head = irp->fd_head; irp->fd_head = head->next; - + log_debug("+++ returning FUSE_DATA=%p containing FUSE_INFO=%p", + head, head->data_ptr); return head; } @@ -1292,7 +1303,7 @@ void *dev_redir_fuse_data_dequeue(IRP *irp) * @return 0 on success, -1 on failure *****************************************************************************/ -int dev_redir_fuse_data_enqueue(IRP *irp, void *vp) +int devredir_fuse_data_enqueue(IRP *irp, void *vp) { FUSE_DATA *fd; FUSE_DATA *tail; @@ -1311,6 +1322,8 @@ int dev_redir_fuse_data_enqueue(IRP *irp, void *vp) /* queue is empty, insert at head */ irp->fd_head = fd; irp->fd_tail = fd; + log_debug("+++ inserted FUSE_DATA=%p containing FUSE_INFO=%p at head", + fd, vp); return 0; } @@ -1318,6 +1331,8 @@ int dev_redir_fuse_data_enqueue(IRP *irp, void *vp) tail = irp->fd_tail; tail->next = fd; irp->fd_tail = fd; + log_debug("+++ inserted FUSE_DATA=%p containing FUSE_INFO=%p at tail", + fd, vp); return 0; } @@ -1407,7 +1422,7 @@ void devredir_proc_cid_rmdir_or_file(IRP *irp, tui32 IoStatus) if (IoStatus != NT_STATUS_SUCCESS) { - FUSE_DATA *fuse_data = dev_redir_fuse_data_dequeue(irp); + FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_rmdir_or_file(fuse_data->data_ptr, IoStatus); @@ -1440,7 +1455,7 @@ void devredir_proc_cid_rmdir_or_file_resp(IRP *irp, tui32 IoStatus) { FUSE_DATA *fuse_data; - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_rmdir_or_file(fuse_data->data_ptr, IoStatus); @@ -1474,7 +1489,7 @@ void devredir_proc_cid_rename_file(IRP *irp, tui32 IoStatus) { log_debug("rename returned with IoStatus=0x%x", IoStatus); - FUSE_DATA *fuse_data = dev_redir_fuse_data_dequeue(irp); + FUSE_DATA *fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_rename_file(fuse_data->data_ptr, IoStatus); @@ -1519,7 +1534,7 @@ void devredir_proc_cid_rename_file_resp(IRP *irp, tui32 IoStatus) log_debug("entered"); - fuse_data = dev_redir_fuse_data_dequeue(irp); + fuse_data = devredir_fuse_data_dequeue(irp); if (fuse_data) { xfuse_devredir_cb_rename_file(fuse_data->data_ptr, IoStatus); diff --git a/sesman/chansrv/devredir.h b/sesman/chansrv/devredir.h index d56b4457..da49350b 100644 --- a/sesman/chansrv/devredir.h +++ b/sesman/chansrv/devredir.h @@ -27,9 +27,9 @@ #define USE_SHORT_NAMES_IN_DIR_LISTING -void *dev_redir_fuse_data_peek(IRP *irp); -void *dev_redir_fuse_data_dequeue(IRP *irp); -int dev_redir_fuse_data_enqueue(IRP *irp, void *vp); +void *devredir_fuse_data_peek(IRP *irp); +void *devredir_fuse_data_dequeue(IRP *irp); +int devredir_fuse_data_enqueue(IRP *irp, void *vp); int APP_CC dev_redir_init(void); int APP_CC dev_redir_deinit(void); diff --git a/sesman/chansrv/irp.c b/sesman/chansrv/irp.c index 9faaabf5..5c21fe0f 100644 --- a/sesman/chansrv/irp.c +++ b/sesman/chansrv/irp.c @@ -31,7 +31,7 @@ #define LOG_DEBUG 2 #ifndef LOG_LEVEL -#define LOG_LEVEL LOG_DEBUG +#define LOG_LEVEL LOG_ERROR #endif #define log_error(_params...) \ @@ -95,6 +95,7 @@ IRP * devredir_irp_new() irp->prev = irp_last; } + log_debug("new IRP=%p", irp); return irp; } @@ -108,12 +109,12 @@ int devredir_irp_delete(IRP *irp) { IRP *lirp = g_irp_head; - log_debug("=== entered; completion_id=%d type=%d", - irp->CompletionId, irp->completion_type); - if ((irp == NULL) || (lirp == NULL)) return -1; + log_debug("irp=%p completion_id=%d type=%d", + irp, irp->CompletionId, irp->completion_type); + devredir_irp_dump(); // LK_TODO while (lirp) @@ -173,11 +174,15 @@ IRP *devredir_irp_find(tui32 completion_id) while (irp) { if (irp->CompletionId == completion_id) + { + log_debug("returning irp=%p", irp); return irp; + } irp = irp->next; } + log_debug("returning irp=NULL"); return NULL; } @@ -188,11 +193,15 @@ IRP * devredir_irp_find_by_fileid(tui32 FileId) while (irp) { if (irp->FileId == FileId) + { + log_debug("returning irp=%p", irp); return irp; + } irp = irp->next; } + log_debug("returning irp=NULL"); return NULL; } @@ -212,6 +221,7 @@ IRP * devredir_irp_get_last() irp = irp->next; } + log_debug("returning irp=%p", irp); return irp; }