alternative to admin rights - fopen doesn't create C:\temp.txt in windows - c

In my current project I like to use fopen or fopen_s to create a file via "w" option.
Using a QT GUI the user may choose any file name which is basically the return string of a file dialog - similar to what is known to windows dialogs.
QFileDialog::getSaveFileName(this,"Save as...","","all files (*.*)");
However, depending on the file name it gets created or not.
So for instance I can write files in my build directory 'C:/SVN/builds/GUI/temp.txt'
And I can create files on the windows desktop 'C:/Users/XXX/Desktop/temp.txt'
I can even create files in other build dirs 'C:/SVN/builds/foo/bin/Release/temp.txt'
But fopen doesn't let me create 'C:/temp.txt' and returns "access denied" (errorno 13)
my issue can be solved like described here: https://stackoverflow.com/a/4735652/2220850
but this effectively requires the user to have admin rights for my silly little tool to run properly.
so isn't there another way to get permissions to write the file the user selected from within the GUI?
Or is there at least for the user and me a way to know where on the disks our tool may or may not create files?
cheers

I don't think you can solve this in a clean way. There are folders that are forbidden to non-admin users. That's the way it is (without tweaking to OS settings).
Displaying your users a sensible error message like "Access denied (you may need admin rights to write to this directory, select a directory you may write to)" is probably the best way.

Read/write stuff where the shell/OS tells you you can/should do. Call the shell API to find out the correct path for Windows OS:
SHGetFolderPath()
SHGetKnownFolderPath()

Related

How to write files in C:\Windows\System32 with full permissions

Iam working on POS software using winforms. Iam trying to programmatically writing XML file (which contain some encrypted information about software serial number) to C:\Windows\System32 directory. But when i write i get an error Access denied.
Can anyone please explain how can i write this file with full permissions in this directory in windows 7 as well as in windows XP???
Any other suggestion or better way to do this will also be welcome.
Thanks in advance.
You'll need to be an administrator on the machine to write to the Windows directory. In addition, on Vista and later, your process will need to be "elevated" (otherwise known as Run As Administrator). You can configure this on your application's property sheet, as discussed here, or with a bit more work, do it programmatically.
It's bad practice to write to that directory, though, notwithstanding all the (misguided) software that does that. Save your files somewhere else. %appdata% or %localappdata% (directories specifically meant for application data) are good choices.

saving file in "Program Files/myApplication" folder with fopen_s

My application saves its settings under its executable folder, which happens to be where it is installed under Windows(C:\ProgramFiles). The problem I'm having is that I use fopen_s and open the file as binary but when my application saves the settings Windows doesn't allow it. I'm thinking it has to do something with permissions but I'm not sure where to look. Maybe I should change the directory to where it saves the settings to something like users/Documents.
Any thoughts on this, and why it isn't working? Why is fopen_s not allowed to save a file where my application is installed?
Applications running under normal user privileges have read-only access to the %ProgramFiles% directory. This is by design. If it was possible to save files to this directory, then multiple users sharing the same PC (with different accounts) would overwrite each other's settings file.
Adjust your code to save it's settings to the %LOCALAPPDATA% directory. Use SHGetKnownFolderPath API to get this directory path.

log4net writing to file. How to open up permissions

I was happily using log4net with my WPF program on an XP machine and happily using a fileAppender FileAppender to write log messages to c:\log.txt. All was well. However, it does not work on a Windows 7 machine. No error or anything, just that the file isn't created, much less logged to. A little research reveals that it's a file permissions problem (UAC) with Windows 7, and in fact it works if I run the executable as administrator. It doesn't work if I just click on it (even though I'm logged on as administrator) and it doesn't work when I launch from Visual Studio.
Questions:
1. Can someone point me to an example where I ask for permission to write to one and only one file (C:\log.txt). I've seen some examples of where the app.config is configured to ask that the whole program is run with admin privileges. This seems like overkill but I guess it would work.
2. Is there as better way to send the information to a log file? After all, perhaps C: does not exist on user machine. I think I recall the idea of a "user partition" in Windows 7, but whatever I do has to work on XP and Vista.
Thanks a ton,
Dave
You should not be trying to write directly to the root folder. Under windows 7, you will either have to run as administrator or disable UAC for that to work and neither are recommended.
Instead you can write to a folder in the 'application data' area
If you are using a .config file to configure log, you can use something like
<file value="${ALLUSERSPROFILE}\CompanyName\ProductName\Log.txt" />
or
<file value="${APPDATA}\CompanyName\ProductName\Log.txt" />
depending on whether you want the log files to be specific to a user or not.
(Obviously you replace CompanyName and ProductName with your own details).
This should work on Xp/Vista/W7.
You have 3 options in my eyes:
like mentioned always run your app as admin altough thats not a brilliant solution
Use the local path of the executing app to store your log - I always prefer this method as I always know where my logs are ( AppDomain.CurrentDomain.BaseDirectory will help you)
Use "My Documents" or some similar special folders - a quick google gives us: special folders
I hope this helps.

Understanding UAC on windows vista / 7

I don't really understand windows UAC...
I need for my program to be able to update and add files to a specific directory belonging to a program. This directory may be a subdirectory of an application in Program Files, for example c:\Program Files\MyApp\Data or it may be installed elsewhere.
I believe that if it's under Program Files then my program will be prevented from writting there unless it is running as an administrator AND has elevated it's access rights. Is that correct?
I need to be able to update files in that directory preferable without invoking elevated privileges and with the main application still "protected", just allow access to that one directory. I can't move the Data folder elsewhere as this as it's a 3rd party application I need to interface with.
How is it determined that UAC is needed for folders in Program Files? Is Program Files special in some way or is just permissions? If I were to adjust the permissions on that Data subdirectory so that the user account running the program had write access would that allow my application to update files in that directory without special privileges?
Or is there a better way to achieve this that I'm not thinking of? My update program needs to be in java so getting elevated privileges is a pain. I imagine I'll need to write a C++ wrapper to run the java VM so that i can give that wrapper an appropriate manifest. Not impossible but I don't really want to have to do this.
Try changing your application's directory security settings on-install to allow "Authenticated Users" write permissions.
Usually, when you need both protected and unprotected UAC modes you do the following.
Create two executable (one should be the main one and not require privileges for any operation, the second one should be able to perform privileges operations).
Start the first (main) one using limited privileges.
When you need to perform an privileged operation, create a new process with administrative rights (will pop the UAC window) and start the second application in it.
When done with the second application close it and you'll be back to limited mode.
This is how VMWare Workstation does when you change global settings.
Edit: Changing the permissions on a folder is not a good approach. Is just a dirty hack because anybody can write to that folder and this will just invalidate the role of UAC - after all this is the role of UAC: to prevent unprivileged changes in special folders.

How to allow a user to edit data in a separate app from the terminal?

I am writing a terminal-based application, but I want the user to be able to edit certain text data in a separate editor. For example, if the user chooses to edit the list of current usernames, the list should open as a text file in the user's favorite editor (vim, gedit, etc.). This will probably be an environment variable such as $MYAPPEDITOR. This is similar to the way commit messages work in svn.
Is the best way to do this to create a temporary file in /tmp, and read it in when the editor process is terminated? Or is there a better way to approach this problem?
There's already a $EDITOR variable, which is extremely standard and I have seen it working on a wide variety of unixes. Also, vi is always an option on any flavor of unix.
Debian has a sensible-editor command that invokes $EDITOR if it can, or falls back to some standard ones otherwise. Freedesktop.org has an xdg-open command that will detect which desktop environment is running and open the file with the associated application. As far as I know, sensible-editor doesn't exist on other distributions, and of course xdg-open will fail in a text-only environment, but it couldn't hurt to try as many options as possible, if you think it's important that a desktop user can see their happy shiny gedit or kate instead of scary old vi or nano. ;)
The way crontab and sudoedit work is also by making a file in /tmp. git puts it under .git, and svn actually puts it in the current directory (not /tmp).
The way svn and mercurial do it is by making a file in /tmp.
BTW, you don't need a MYAPPEDITOR, on nix there's EDITOR already present.
Since you mention svn in your post, why not just follow the same methodology? svn opens a file with a particular name with whatever $EDITOR (or $SVN_EDITOR) contains - this might actually require some work on your part; determining the parameters to each supported editor. In either case, you have the name of the file that was saved (or the error code of the application if something failed) and you can just use that.

Resources