Bladeren bron

Move/rename implementation

Sylver Bruneau 9 jaren geleden
bovenliggende
commit
5557fa69d0
3 gewijzigde bestanden met toevoegingen van 94 en 0 verwijderingen
  1. 12 0
      include/bdsm/smb_file.h
  2. 67 0
      src/smb_file.c
  3. 15 0
      src/smb_packets.h

+ 12 - 0
include/bdsm/smb_file.h

@@ -125,4 +125,16 @@ ssize_t   smb_fseek(smb_session *s, smb_fd fd, ssize_t offset, int whence);
  */
 uint32_t  smb_file_rm(smb_session *s, smb_tid tid, const char *path);
 
+/**
+ * @brief move/rename a file/directory on a share.
+ * @details Use this function to move and/or rename a file/directory
+ *
+ * @param s The session object
+ * @param tid The tid of the share the file is in, obtained via smb_tree_connect()
+ * @param old_path The current path of the file/directory to move/rename
+ * @param new_path The new path of the file/directory
+ * @return 0 if move OK or -1 in case of error
+ */
+uint32_t  smb_file_mv(smb_session *s, smb_tid tid, const char *old_path, const char *new_path);
+
 #endif

+ 67 - 0
src/smb_file.c

@@ -351,3 +351,70 @@ uint32_t  smb_file_rm(smb_session *s, smb_tid tid, const char *path)
 
     return NT_STATUS_SUCCESS;
 }
+
+uint32_t  smb_file_mv(smb_session *s, smb_tid tid, const char *old_path, const char *new_path)
+{
+    smb_message           *req_msg, resp_msg;
+    smb_file_mv_req       req;
+    smb_file_mv_resp      *resp;
+    size_t                utf_old_len,utf_new_len;
+    char                  *utf_old_path,*utf_new_path;
+
+    if (s == NULL)
+        return -1;
+    if (tid == -1)
+        return -1;
+    if ((old_path == NULL) || (new_path == NULL))
+        return -1;
+
+    utf_old_len = smb_to_utf16(old_path, strlen(old_path) + 1, &utf_old_path);
+    if (utf_old_len == 0)
+        return -1;
+
+    utf_new_len = smb_to_utf16(new_path, strlen(new_path) + 1, &utf_new_path);
+    if (utf_new_len == 0)
+    {
+        free(utf_old_path);
+        return -1;
+    }
+
+    req_msg = smb_message_new(SMB_CMD_MOVE);
+    if (!req_msg)
+    {
+        free(utf_old_path);
+        free(utf_new_path);
+        return -1;
+    }
+
+    req_msg->packet->header.tid = (uint16_t)tid;
+    req_msg->packet->header.flags2 = SMB_FLAGS2_LONG_NAMES;
+
+    SMB_MSG_INIT_PKT(req);
+    req.wct               = 0x01; // Must be 1
+    req.search_attributes = SMB_ATTR_HIDDEN | SMB_ATTR_SYS;
+    req.bct               = (uint16_t)(utf_old_len + utf_new_len + 3); // We have 2 bytes for buffer formats and 1 padding byte
+    SMB_MSG_PUT_PKT(req_msg, req);
+    smb_message_put8(req_msg, 0x04); // Buffer format 1, must be 4
+    smb_message_append(req_msg, utf_old_path, utf_old_len);
+    smb_message_put8(req_msg, 0x00); // padding to have next byte 16 bits aligned
+    smb_message_put8(req_msg, 0x04); // Buffer format 2, must be 4
+    smb_message_append(req_msg, utf_new_path, utf_new_len);
+
+    smb_session_send_msg(s, req_msg);
+    smb_message_destroy(req_msg);
+
+    free(utf_old_path);
+    free(utf_new_path);
+
+    if (!smb_session_recv_msg(s, &resp_msg))
+        return -1;
+
+    if (resp_msg.packet->header.status != NT_STATUS_SUCCESS)
+        return -1;
+
+    resp = (smb_file_mv_resp *)resp_msg.packet->payload;
+    if ((resp->wct != 0) || (resp->bct != 0))
+        return -1;
+
+    return 0;
+}

+ 15 - 0
src/smb_packets.h

@@ -342,6 +342,21 @@ typedef struct
     uint16_t        bct;                // 0x0000
 } __attribute__((packed))   smb_directory_rm_resp;
 
+//-> Move File
+typedef struct
+{
+    uint8_t         wct;                // 0x01
+    uint16_t        search_attributes;  // 0x0000 for "normal" (not hidden/ystem) files
+    uint16_t        bct;                // >= 2
+} __attribute__((packed))   smb_file_mv_req;
+
+//<- Move File
+typedef struct
+{
+    uint8_t         wct;                // 0x00
+    uint16_t        bct;                // 0x0000
+} __attribute__((packed))   smb_file_mv_resp;
+
 //-> Trans
 typedef struct
 {