smb_file *smb_session_file_remove(smb_session *s, smb_fd fd) { smb_share *share; smb_file *iter, *keep; assert(s != NULL && fd); if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL) return (NULL); iter = share->files; if (iter == NULL) return (NULL); if (iter->fid == SMB_FD_FID(fd)) { share->files = iter->next; return (iter); } while(iter->next != NULL && iter->next->fid != SMB_FD_TID(fd)) iter = iter->next; if (iter->next != NULL) { keep = iter->next; iter->next = iter->next->next; return (keep); } else return (NULL); }
int smb_session_file_add(smb_session *s, smb_tid tid, smb_file *f) { smb_share *share; smb_file *iter; assert(s != NULL && f != NULL); if(s != NULL && f != NULL){ if ((share = smb_session_share_get(s, tid)) == NULL) return 0; if (share->files == NULL) share->files = f; else { iter = share->files; while (iter->next != NULL) iter = iter->next; iter->next = f; } return 1; } return 0; }
smb_file *smb_session_file_get(smb_session *s, smb_fd fd) { smb_share *share; smb_file *iter; assert(s != NULL && fd); if ((share = smb_session_share_get(s, SMB_FD_TID(fd))) == NULL) return (NULL); iter = share->files; while(iter != NULL && iter->fid != SMB_FD_FID(fd)) iter = iter->next; return (iter); }
smb_fd smb_fopen(smb_session *s, smb_tid tid, const char *path, uint32_t o_flags) { smb_share *share; smb_file *file; smb_message *req_msg, resp_msg; smb_create_req req; smb_create_resp *resp; size_t path_len; int res; char *utf_path; assert(s != NULL && path != NULL); if ((share = smb_session_share_get(s, tid)) == NULL) return (0); path_len = smb_to_utf16(path, strlen(path) + 1, &utf_path); if (path_len == 0) return (0); req_msg = smb_message_new(SMB_CMD_CREATE); if (!req_msg) { free(utf_path); return (0); } // Set SMB Headers req_msg->packet->header.tid = tid; // Create AndX Params SMB_MSG_INIT_PKT_ANDX(req); req.wct = 24; req.flags = 0; req.root_fid = 0; req.access_mask = o_flags; req.alloc_size = 0; req.file_attr = 0; req.share_access = SMB_SHARE_READ | SMB_SHARE_WRITE; req.disposition = 1; // 1 = Open and file if doesn't exist req.create_opts = 0; // We dont't support create req.impersonation = 2; // ????? req.security_flags = 0; // ??? req.path_length = path_len; req.bct = path_len + 1; SMB_MSG_PUT_PKT(req_msg, req); // Create AndX 'Body' smb_message_put8(req_msg, 0); // Align beginning of path smb_message_append(req_msg, utf_path, path_len); free(utf_path); // smb_message_put16(req_msg, 0); // ?? res = smb_session_send_msg(s, req_msg); smb_message_destroy(req_msg); if (!res) return (0); if (!smb_session_recv_msg(s, &resp_msg)) return (0); if (resp_msg.packet->header.status != NT_STATUS_SUCCESS) return (0); resp = (smb_create_resp *)resp_msg.packet->payload; file = calloc(1, sizeof(smb_file)); if (!file) return (0); file->fid = resp->fid; file->tid = tid; file->created = resp->created; file->accessed = resp->accessed; file->written = resp->written; file->changed = resp->changed; file->alloc_size = resp->alloc_size; file->size = resp->size; file->attr = resp->attr; file->is_dir = resp->is_dir; smb_session_file_add(s, tid, file); // XXX Check return return (SMB_FD(tid, file->fid)); }