Search code examples
c#-4.0monoxamarin.iosxamarin.androidisolatedstorage

IsolatedStorage.GetFileNames fails on MonoTouch/MonoDroid


I was trying out MonoTouch/MonoAndroid and everything was going well until I called IsolatedStorageFile.GetFileNames(string) function. The parameter was "Foo/Foo1/*". The result is SecurityException with no message.

The directory "Foo/Foo1" exists, because it has just been found using IsolatedStorageFile.GetDirectoryNames() call.

I identified this bit in Mono sources that throws the exception (in IsolatedStorageFile.cs):

DirectoryInfo[] subdirs = directory.GetDirectories (path);
// we're looking for a single result, identical to path (no pattern here)
// we're also looking for something under the current path (not
outside isolated storage)
if ((subdirs.Length == 1) && (subdirs [0].Name == path) && (subdirs[0].FullName.IndexOf(directory.FullName) >= 0)) {
  afi = subdirs [0].GetFiles (pattern);
} else {
  // CAS, even in FullTrust, normally enforce IsolatedStorage
  throw new SecurityException ();
}

I can't step into it with the debugger so I don't know why the condition is false. This happens both on iOS and Android. There was a similar issue logged long time ago at http://www.digipedia.pl/usenet/thread/12492/1724/#post1724, but there are no replies.

The same code works on Windows Phone 7 without problems (with \ for path separators).

Has anyone got any ideas what might be causing it? Is it the uppercase in directory names a problem?


Solution

  • It is a bug in Mono. IsolatedStorage will not work with paths that contain more than one directory in a row (such as Foo/Foo1/*)

    I copied the code of GetFileNames() method from Mono to my project so that I can debug it. I found out that the problem is in the 2nd term of this condition (IsolatedStorageFile.cs:846):

    if ((subdirs.Length == 1) && (subdirs [0].Name == path) &&(subdirs[0].FullName.IndexOf(directory.FullName) >= 0)) {
      afi = subdirs [0].GetFiles (pattern);
    } else {
      // CAS, even in FullTrust, normally enforce IsolatedStorage
      throw new SecurityException ();
    }
    

    For example when path passed to GetFileNames() is "Foo/Bar/*", subdirs[0].Name will be "Bar" while path will be "Foo/Bar" and the condition will fail causing the exception.