We've written an application that works fairly well in XP, but is having serious migration issues to Vista and Windows 7, probably due to where user data is being written.
The use case is this:
Individual users need to log in to the machine and use it to acquire data. Supervisor users need to be able to look over the shoulder of individual users and verify that they're performing their jobs properly. These supervisors also need to check system logs to make sure that the system is performing properly.
The way that we accomplished these tasks in XP was to write to a folder on the C:\ drive directly. Maybe that's bad practice, maybe it isn't, but basically all users of the system needed to be able to access this data as shared data. In some installations of the program, the IT situation was just not secure at all, and there was a single user for the computer, and then each individual logged in to our program separately. In other installations of the program, the IT staff is competent and has different logins for different users, but each user can still access C: and each user can still check other users as necessary.
In Vista/Windows 7, that all changes. If the IT staff locks everything down to individual users, these users still need to share this common data, and writing application-specific configuration parameters and user lists to the directory of the application is just not allowed. If the system is in a location with a domain, then the user does not have local admin rights, and even installation could be a problem.
Is the solution to this to have the installer make a directory that every user can write to, and then put all user-specific data in that directory? If so, is it possible to have an installer behave that way (even if it has to be given admin rights)? Or is there a way to make Vista/7 behave in the more liberal XP fashion?
The most definitive resource is the "Data and Settings Management in the Application Specification for each windows version in MSDN. Read this to see the rationale behind the various special folders that exist on Windows, and how to choose which one to write data to.
Next, your application would need to use the SHGetSpecialFolderLocation API to retrieve the paths to the special location.
The folder that most likley serves your needs - being written to by one user, read by administrators, would be CSIDL_APPDATA
- which, on Windows 6.X, corresponds to C:\ProgramData\
By default the rights on folders created in this location are full control for administrators and owners (i.e. the user that created it) and read only access to members of the Users group.
A completely seperate excercise is writing the code necessary to modify Access Control Lists (ACLs) on Directories. One that will be necessary if the defaults rights on your chosen location arn't sufficient for your purposes.
A portion of your app could possibly run as a system service and its own user. That way it could also have its own secure store away from your human-users. This would also remove the overarching need to have the user running a program with permissions out of their regular scope.
The actual user-space portion of your app could connect to the service and perform simple storage/retrieval operations.
The way that we accomplished these tasks in XP was to write to a folder on the C:\ drive directly. Maybe that's bad practice, maybe it isn't
It definitely is. 'C:\Users\Public\Public Documents' is where this is appropriate. Use NTFS ACLs to control who can read and write to the files.
By default, there is no directory where all users have write access (excepting maybe a system-wide TEMP directory, but I wouldn't go writing logging information there).
If your installation program is run with administrative privileges, it can create such a directory and give everybody write permissions. The most logical place would be the ALLUSERSPROFILE
(C:\Documents and Settings\All Users
on XP, C:\Users\Public
on Vista/7).
Another fairly simple solution is to have every user just log to a directory in his or her profile, for example, to Application Data\Your App
. All the logging information can then still be aggregated fairly easily by an administrative app, and if the Read permissions are not locked down, users can even read each other's data if that's required.
Wouldn't it be better to store the data somewhere on the network? This way you only have to setup the security once and it's easier to maintain. Supervisors can easily read the data for many pc's and don't have to visit the individual pc's...