hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
705 stars 179 forks source link

List all subfolders recursively #819

Closed DerozerDSP closed 5 months ago

DerozerDSP commented 5 months ago

Hi,

I've made this basic snippet in the hope to list all subfolders recursively on Android API Level 30 app starting from a Shared Folder I have on Windows 10:

package com.derozer.myapp;

import com.hierynomus.msfscc.FileAttributes;
import com.hierynomus.msfscc.fileinformation.FileIdBothDirectoryInformation;
import com.hierynomus.protocol.commons.EnumWithValue;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.SMBClient;
import com.derozer.myapp.models.TaskCallback;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class WindowsConnection {
    private final String ipAddress = "192.168.1.8";
    private final String username = "MyUsername";
    private final String password = "MyPassword";
    private final String sharedFolder = "DocumentsShared";
    private final Executor executor = Executors.newSingleThreadExecutor();
    List<String> subDirectories = new ArrayList<>();
    DiskShare share;

    public void executeAsyncTask(TaskCallback<Boolean> onSuccess, TaskCallback<Exception> onFailure) {
        FutureTask<Boolean> taskSyncFiles = new FutureTask<>(() -> {
            try (SMBClient client = new SMBClient(); Connection connection = client.connect(ipAddress)) {
                AuthenticationContext auth = new AuthenticationContext(username, password.toCharArray(), null);
                Session session = connection.authenticate(auth);
                share = (DiskShare) session.connectShare(sharedFolder);

                addSubFolders("");
                int count = subDirectories.size();
            } catch (Exception err) {
                err.printStackTrace();
            } finally {
                share.close();
            }

            return true;
        });

        executor.execute(taskSyncFiles);
        executor.execute(() -> {
            try {
                Boolean result = taskSyncFiles.get();
                onSuccess.execute(result);
            } catch (Exception err) {
                onFailure.execute(err);
            }
        });
    }

    private void addSubFolders(String folderName) {
        try {
            List<FileIdBothDirectoryInformation> fileList = share.list(folderName);
            for (FileIdBothDirectoryInformation file : fileList) {
                String filename = file.getFileName();
                if (".".equals(filename) || "..".equals(filename)) {
                    continue;
                }
                if (EnumWithValue.EnumUtils.isSet(file.getFileAttributes(), FileAttributes.FILE_ATTRIBUTE_DIRECTORY)) {
                    String folderPath = folderName + "\\" + filename;
                    addSubFolders(folderPath);
                    subDirectories.add(folderPath);
                }
            }
        } catch (Exception err) {
            err.printStackTrace();
        }
    }
}

It list the first levels directories of \192.168.1.8\DocumentsShared (i.e. \folder1, \folder2, and so on), but once I start to .list() on a subfolder (i.e. folder1 list), I got this error:

com.hierynomus.mssmb2.SMBApiException: STATUS_INVALID_PARAMETER (0xc000000d): Create failed for \\192.168.1.8\DocumentsShared\\folder 1

Where am I wrong? I'm using implementation 'com.hierynomus:smbj:0.9.1'.

Thanks for any hints!

BR-Nicholas-Prado commented 5 months ago

The error message has a double slash between DocumentsShared (the main share folder) and folder 1. On some posix systems, that is treated literally. Perhaps avoid adding a slash between folderName and filename if folderName has a trailing slash.

DerozerDSP commented 5 months ago

@BR-Nicholas-Prado thanks!