Christian St.
Christian St.

Reputation: 1911

How to check access rights on remote hosts and local and UNC paths?

I write a program, where the user can select local and remote directories. Before performing any operation on a selected path, I want to check if it's valid and if the user has read/write permission(s) granted on it. That's what I have:

private bool checkInput(string dirPath, string depthStr, string filename)
{
    ...
    string reason = null;
    try
    {
        ...
        else if ((reason = CAN_ACCESS(dirPath)) == null)
        {
            if (!(new DirectoryInfo(dirPath)).Exists)
                reason = string.Format("The directory '{0}' is no directory or does not exist!", dirPath);
            ...
        }
    }
    catch (Exception ex)
    {
        reason = ex.Message;
    }

    if (reason != null)
    {
        MessageBox.Show(reason, "Wrong input", MessageBoxButton.OK, MessageBoxImage.Error);
        return false;
    }
    return true;
}

public static string CAN_ACCESS(string dirPath)
{
    Uri uri = new Uri(dirPath);
    //UserFileAccessRights rights = new UserFileAccessRights(dirPath);

    string errorMsg = null;
    if (uri.IsUnc && !haveAccessPermissionOnHost(uri))
    {
        string domain = new Uri(dirPath).Host;
        domain = dirPath;
        ErrorClass res = PinvokeWindowsNetworking.connectToRemote(domain, null, null, true);
        if (res == null)
            return null;
        else
            errorMsg = string.Format("(Code {0}): {1}", res.num, res.message);
    }

    return errorMsg;
}

private static bool haveAccessPermissionOnHost(Uri uri)
{
    throw new NotImplementedException();
}

The primary question is, how to simple check in haveAccessPermissionOnHost(Uri uri), if a user has read/write permission(s) on a remote host and unc path granted.

Hint: If no permissions granted, the well known Windows logon window pops up to force the user to enter some credentials, which is working fine:

ErrorClass res = PinvokeWindowsNetworking.connectToRemote(domain, null, null, true);

I got it from this question (and changed the provided code to return the ErrorClass, null on success).

My secondary question is, if my structure in general is the way to go to check a path, whether it's local or remote, for validity (that's why I provided more code as necessary).

Upvotes: 1

Views: 1981

Answers (1)

Christian St.
Christian St.

Reputation: 1911

I found myself a workaround, since nobody replied to this question:

public static bool canAccess(DirectoryInfo dirInfo)
{
    Uri uri = new Uri(dirInfo.FullName);

    // is this a remote path?
    if (uri.IsUnc)
    {
        if (hostOnline(uri.Host))
        {
            // check if remote path exists
            if (!dirInfo.Exists)
            {
                string domain = dirInfo.FullName;
                ErrorClass res = PinvokeWindowsNetworking.connectToRemote(domain, null, null, true);
                if (res == null)
                {
                    if (!dirInfo.Exists)
                        throw new Exception(
                            string.Format("No access permissions or directory not existing."));
                    return true;
                }
                else if (res.num == 53)
                    throw new Exception("Remote directory not existing.");
                else
                    throw new Exception(
                        string.Format("(Code {0}): {1}", res.num, res.message));
            }
        }
        else
            throw new Exception("Unknown host or not online.");
    }

    // local directory existing?
    return dirInfo.Exists;
}

private static bool hostOnline(string hostname)
{
    Ping ping = new Ping();
    try
    {
        PingReply pr = ping.Send(hostname);
        return pr.Status == IPStatus.Success;
    }
    catch (Exception)
    {
        return false;
    }
}

Upvotes: 1

Related Questions