C++ get appdata path of other users - c++

In my program I have been using SHGetFolderPath to get the AppData path. However I need to get the AppData path of the other users on the computer. The only way I can think to do it is to get the path for the current user, and then replace the current user's name with the other users names. I don't know how to get a list of the users. There's probably a much more elegant solution aswell... If you have insight I would greatly appreciate it.

For your situation I would recommend the following:
Continue to store configuration files in AppData, but store it in CSIDL_COMMON_APPDATA (SHGetFolderPath). This AppData is shared with all users. Your setup program (or an administrator user) can set up a folder in this location named after your program that gives "Everyone" full access (this is very easy with Windows Installer). That way, any user can read/write to it. Everything in "Program Files" should never change. It should only contain read-only executables, DLLs, and other such resources. Microsoft has long discouraged writing to this location and many administrators no longer expect to encounter custom user data that requires regular backup & restore in Program Files.
When your software runs, you can check for data in the current user's AppData (i.e. stored by your old version) and merge it with the data in the machine's AppData (described by #1 above). To migrate the data for the user, log in as that user and run your software.
There really isn't a great way that I'm aware of for gathering all that data from other user profiles. Nothing supported by Microsoft, that is (that I'm aware of!).
Regarding storage of data in Program Files: http://msdn.microsoft.com/en-us/library/bb776776(VS.85).aspx "Do not store user data under the Program Files folder." There are many other references that say similar.

Related

How to name path for App Data to use on different computers

I created a simple application to allow users to register, add friends, and send private DM's.
I made the mistake of using local paths relative to my machine to import/export fstream .txt files for storage.
For example, the global list of users is located in:
C:\Users\19097\Desktop\Programs\Registration Application\App files\usernames\usernames.txt
This will obviously not work when ran on another computer. So my question, how can I create this directory of Storage for the objects in the app relative to the user?
I have briefly read on environment variables and from my understanding of it, they are used to reference various default window paths.
Since I do not know where the user would install and save the application files, how can I still create and read files dynamically, within a certain path relative to the computer it is installed on?
For example:
[Whatever this path is]\Registration Application\App files\usernames\usernames.txt

Completely restricting all types of access to a folder

I am making a cocoa application, which creates some folders at my specified location in the user's environment. Now i want to protect these folders from any type of read, write, copy, drag access from all type of users(i.e Not accessible for admin and non-admin users).Is there a way to protect these folders from any type of access.
Can we use, NSFileManager method -setAttributes:OfItemAtPath:error:
But i am not sure on attributes dictionary of this method.
Basically i want to provide trail of some files to the user (let's say 1 day trial), and removing those files as soon as the trail expires, and all those files are placed inside a certain folder in the user's environment. What should be the best approach i should use to protect those files?
You could use NSFileManager setAttributes:OfItemAtPath:error: with the attributes key NSFilePosixPermissions. With this, you can set the Unix file permissions of your folder by specifying them with an integer value that represents the permission bit pattern. Setting it to zero would mean no access at all to that directory:
NSDictionary *attribs = [NSDictionary dictionaryWithObjectsAndKeys:
NSFilePosixPermissions, [NSNumber numberWithInt:0], nil];
However, it would still be possible to move or rename that directory.
Short answer: No. Someone with elevated privileges can do just about anything. No playing with permissions will get you there and still allow your application to access the files.
If you could just turn off all access rights how would you expect your own application to access the files? Turning on the access rights is itself an access right...
Longer answer: Maybe. This depends on what you are trying to achieve. Do you really want to stop the files being copied, or just their contents accessed?
Encryption can be used to protect content (e.g. at the file level, using an encrypted sparsebundle image, etc.), storing identification information in a file can alert you that you’re using a copy (e.g. see what happens if you move/copy a VMWare virtual machine or recreate a Google Drive folder), etc.
And you can always implement your own filesystem using FUSE; and prevent copying, access, etc. by your own mechanism, however the filesystem as a whole could still be copied (i.e. effectively implement your own equivalent of an encrypted sparsebundle via FUSE and implement your own access mechanism).
What are you trying to achieve? If you spell that out folk might be able to suggest alternative solutions.
See also this question on preventing root from writing to files.

C:\ file scan with C++, access denied to specific files

Ok so I have written a code with recursive function that scans my (or any other) C:\ disc.
Using chdir() I'm changing the active directory to C:\ and using system("dir >> C:\Test\"filename") to get the files in that directory written in .txt and then reading it to know what I have. After that I'm checking for additional directories with temp.substr("<DIR>") and calling the function again just with longer path for that specific directory.
The code itself works as it should but I've ran to some directories that I can't access such as Administrator or specific folders in Windows. The only way I've found around them is by adding exeptions to the code so that it just avoids those folders. I'd like to know if there is a way to get a list of folders/files that I don't have access to from cmd since it would make my code a lot more precise or a way to access those directories.
While C++ file API does not have any idea about file permissions and such other than you'll fall when you try to read a file you don't have permissions to, C++ do have access to the Windows API. The Windows API are system calls that gives you access to native OS functionalities, such as calls to GetFileSecurity.
Note that using Windows API means your code would need to take extra steps to ensure portability if you want to run it on non Windows platforms.
The process (your program) runs with certain privileges, normally the users one. The access rights in Windows aren't as simple as "Administrator is god". Even if your user account is member of the "Administrators" group, you can not simply access everything. It usually depends if the OWNER of a file system object grants privileges to other groups and users.
A member of the "Administrators" group might be able to gain access by overriding security settings, but I would advise against that.
You might need elevated privileges and even might need to run your application under a SYSTEM account, it very much depends on what you are trying to achieve.
For more details I suggest to read the "Best practices for Security API" here:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms717796(v=vs.85).aspx
and especially the chapter "Running with Special Privileges".

Xml file are saved in two different path

I created application that store some data to XML file. The issues is with the path of the XML saving. Am using TinyXML to save the data in vc++.
When I deploy this application, it installs in "C:\Program files(x86)\applicationname " and when I run the application the XML file is saving in
"C:\Users\UserName\AppData\Local\VirtualStore\Program Files (x86)\ApplicationName ".
I have made this application to work on system startup. So when I restart this application,
the xml file is stored in different path "C:\Users\UserName\AppData\Local\VirtualStore\windows\sysWOW64"
I want my XML to be stored in the path where I installed or should be stored in appdata, application name
What should I do to store XML file in one places where application is installed?
doc.SaveFile( "test.xml" ); // xml saving code in tinyxml library
Firstly, this has nothing to do with C++, as the C++ code is probably working. Same with XML and tinyxml and even visual-c++.
It seems that windows redirects those write accesses to a user-specific "VirtualStore\Program Files", but I'll leave it to you to research the actual semantics of that. On startup, when there is no user, this path obviously differs, since the former user is not logged in.
Now, in order to get a fixed path, you can use the function GetModuleFileName() to find out the location of your executable and use that path to locate Smartmeter.xml. However, the problem you are facing now is that programs installed under "Program Files" don't magically gain write access rights to their install directory. This is to protect one user from messing with data of another user.
I think that what you are doing is writing a program that runs in the background, which would be called a "service" under MS Windows. What is still unclear is what you want to achieve with this file and also what you are planning to do overall, and these are things that decide the future steps. In any case, take a look at the possibilities that services provide, maybe there is something that fits your needs.

How to get paths to user desktops from a service?

I need to enumerate paths to desktop folders for all users on a local Windows system from a service application. The catch is that some users may not be logged in at the time. So is there any API, or some other method to do that?
EDIT1: For those who didn't read the first paragraph let me repeat -- I do not have a token to a user account, a user may not be logged in at the time.
EDIT2: I need this to remove a shortcut from user desktops before a feature supported by my application is turned off, or the app is uninstalled.
Here's the best method I was able to come up so far. So I'd appreciate if someone with a non-English installation of Windows could check this for me?
(I'm posting just a pseudo-code for brevity.)
1 - All of the steps below are done from a local service application.
2 - To get paths to all user profiles enumerate subfolders in the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList key and read ProfileImagePath value from them. It will give profile paths for each user account.
3 - To get the folder name for the desktop, read the Desktop value from the HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders key from the service app (yes, I know HKCU sounds strange, but it worked for me.) After that get the path for the %USERPROFILE% environment variable, using environment variable APIs. So you'll get two paths, something like this:
C:\Windows\system32\config\systemprofile\Desktop
and
C:\Windows\system32\config\systemprofile
Then simply isolate the 2nd string from the 1st, using case-insensitive comparison, and you'll get the folder name for the desktop, (i.e. "\Desktop" in this case.)
4 - Add the desktop folder to the path obtained in step 2 to produce the full path to that user's desktop folder.
From userenv.h : GetProfilesDirectory (win2k+, iirc)
msdn.microsoft.com/en-us/library/windows/desktop/bb762278(v=vs.85).aspx
Use this to find the directory containing all the local user account profile directories.
To find the desktop folder:
Shlobj.h : SHGetKnownFolderPath (vista+)
msdn.microsoft.com/en-us/library/windows/desktop/bb762188(v=vs.85).aspx
You'll need FOLDERID_Desktop as the known-folder id. This symbol is declared in Knownfolders.h
msdn.microsoft.com/en-us/library/windows/desktop/dd378457(v=vs.85).aspx
Using these, you might get closer to what you want without directly reading the registry. Of course this belies any elegant way of enumerating the users aside from inferring from the folder list within the
GetProfilesDirectory. Perhaps there is a more api appropriate way to enumerate the local users.
Secondly, and this depends on the purpose of your service, but perhaps by working with the 'allusers' profile, instead of each individually you won't need to know the current list of local users.