views:

612

answers:

0

I am trying to find a folder which members of the Users group in Vista and Windows 7, by default, have permission to write to, without elevation.

This is to be used for storage of common data (a database and a regularly updated document pack), which needs to be shared and writable by all users..

I thought I had got somewhere with CSIDL_COMMON_APPDATA, which on Vista resolves to c:\ProgramData, however in testing we have found that members of the Users group only have Read/Execute permissions when the machine is joined to the domain. This seems contradictory to the documentation:

CSIDL _ COMMON _ APPDATA (FOLDERID_ProgramData) Version 5.0.

The file system directory that contains application data for all users. A typical path is C:\Documents and Settings\All Users\Application Data. This folder is used for application data that is not user specific. For example, an application can store a spell-check dictionary, a database of clip art, or a log file in the CSIDL_COMMON_APPDATA folder. This information will not roam and is available to anyone using the computer.

http://msdn.microsoft.com/en-us/library/bb762494(VS.85).aspx

I don't want to use a documents folder (like CSIDL_COMMON_DOCUMENTS) because these files shouldn't be particularly visible to the user.

For interest here's the code I use to resolve CSIDL values to a path.

public enum CSIDL : int
{
  COMMON_APPDATA = 0x0023
  // etc
}

public static class Folders
{
  [DllImport("shell32.dll")]
  static extern bool SHGetSpecialFolderPath(IntPtr hwndOwner, [Out]StringBuilder lpszPath, int nFolder, bool fCreate);

  public static string GetCsidlValue(CSIDL csidl)
  {
    StringBuilder path = new StringBuilder(260);
    SHGetSpecialFolderPath(IntPtr.Zero, path, (int)csidl, false);
    return path.ToString();
  }

  public static string GetCommonAppDataFolder()
  {
    return GetCsidlValue(CSIDL.COMMON_APPDATA);
  }
}

Any suggestions?

Edit: asked why we don't use System.Environment.SpecialFolder. We use a folder (COMMON_DOCUMENTS - 0x002e) that isn't defined in that enumeration:

public enum SpecialFolder
{
  ApplicationData = 0x1a,
  CommonApplicationData = 0x23,
  CommonProgramFiles = 0x2b,
  Cookies = 0x21,
  Desktop = 0,
  DesktopDirectory = 0x10,
  Favorites = 6,
  History = 0x22,
  InternetCache = 0x20,
  LocalApplicationData = 0x1c,
  MyComputer = 0x11,
  MyDocuments = 5,
  MyMusic = 13,
  MyPictures = 0x27,
  Personal = 5,
  ProgramFiles = 0x26,
  Programs = 2,
  Recent = 8,
  SendTo = 9,
  StartMenu = 11,
  Startup = 7,
  System = 0x25,
  Templates = 0x15
}

Edit: I think I've asked an unanswerable question.

http://blogs.msdn.com/oldnewthing/archive/2004/11/22/267890.aspx

This seems to imply this is deliberately made impossible. I'm back to altering the ACLs on our folder using an elevated CLI application then. Dirty, but required for our case.