I've been trying to write to a file in the system dir on my computers' but I can't get it to work;what would I do to get the necessary permissions?I need to update the SS without having to manually change the permissions on each and every computer...
var
z: THandle;
...
begin
....
z:=OpenFile('myfile.scr',a,OF_WRITE);
FileWrite(z,buf[16],3124);
FileClose(z);
end;
Most likely this is down the the file system redirector. Assuming you really are running elevated then you will have sufficient rights. But a 32 bit process sees the 32 bit system folder SysWOW64. That's probably where your file is landing.
If you really do need to write to the 64 bit system directory either run a 64 bit process, or write to the sysnative alias.
I'm not quite sure why you are using the legacy OpenFile. It would be normal to use CreateFile. Or even TFileStream.
You could add a manifest to your application as described here:
How to add manifest <requestedPrivileges> info into delphi project
This way, on application startup, Windows UAC will prompt for administrator privileges. The post is about Delphi XE but I've tested the manifest successfully on Delphi 2005.
During development, be sure to start the Delphi IDE with administrator privileges too. Otherwise, it might crash when you try to run/debug the program out of the IDE.
Related
Basically I have some C/C++ code that I need to build and debug on a Linux machine. Unfortunately, my windows laptop doesn't have enough free hard space to install some Linux dist nor does it have enough free RAM to comfortably run VM.
Until now, I dealt with it rather comfortably using WSL, but the scale was rather small. It was easy to edit and debug 2-3 .c files through CLI and gdb, but it became really annoying on a large scale projects.
I want something simple as "edit code in windows IDE [X], compile it on remote Linux/WSL (the project uses Makefiles), and preferably debug it via gdb".
VS has something close to what I want, but it can't deal with existing Linux projects. It needs to create a new configuration which is alien to the project's Makefile.
I know this question is a bit old, but I think the solution is to make a symlink between your WSL folder and the Window's folder. This is how I handled it for a Ubuntu-20.04 WSL:
Access PowerShell in Administrator mode
Type cmd.exe in the PowerShell
Once cmd.exe is opened, type mklink /d C:\<path_to_your_Windows_folder> \\wsl$\Ubuntu-20.04\home\<your_user>\<path_to_your_WSL_folder>
EDIT
This was tested under Windows 10 Version 2004 with WSL2
I'm unsure about C and C++ but it sounds like this is exactly the same as how i work in node and javascript every day.
I checkout my code using git inside WSL to a location like /mnt/c/code/myproject. Then using sublime/VS code/webstorm i edit the files in windows in the location c:\code\myproject this works really well and have been doing this every day for over a year.
Things to be aware of are that you need to ensure that your editor of choice saves files with linux line endings and that all command line operations are done inside WSL.
Please see this article to see the differences between windows and linux files and how this works inside the WSL.
I want something simple as "edit code in windows IDE , compile it on remote linux/WSL
You will have something as simple as that.
Only with Windows 19.03 though:
See "Updated WSL in Windows 10 version 1903 lets you access Linux files from Windows"
Microsoft's Craig Loewen says:
In the past, creating and changing Linux files from Windows resulted in losing files or corrupting data. Making this possible has been a highly requested and long anticipated feature. We're proud to announce you can now easily access all the files in your Linux distros from Windows.
So how does this work? He goes on to explain:
To put it briefly: a 9P protocol file server facilitates file related requests, with Windows acting as the client.
We've modified the WSL init daemon to include a 9P server. This server contains protocols that support Linux metadata, including permissions.
There is a Windows service and driver that acts as the client and talks to the 9P server (which is running inside of a WSL instance).
Client and server communicate over AF_UNIX sockets, since WSL allows interop between a Windows application and a Linux application using AF_UNIX as described in this post.
Warning:
The old rules still apply, you should NOT access your Linux files inside of the AppData folder!
If you try to access your Linux files through your AppData folder, you are bypassing using the 9P server, which means that you will not have access to your Linux files, and you could possibly corrupt your Linux distro.
The following program does not work when compiled with Visual Studio 2010 on Windows 7:
#include <stdio.h>
int main()
{
int status;
status = rename("C:\\Temp\\A.dat","C:\\Temp\\a.dat");
status = rename("C:\\ProgramData\\A.dat","C:\\ProgramData\\a.dat");
return 0;
}
The first rename works, but the second rename does not work. The rename function returns 0 in both cases. What is so special about c:\ProgramData that keeps the case sensitive rename from working?
Just FYI, the program works fine when compiled with cygwin gcc 4.8.3.
C:\ProgramData has has security settings that prevent standard user from writing there. This is not new in Windows 8, Windows 7 was the same, and the equivalent folder on Vista is also secured in this way. Perhaps your Windows 7 environment of UAC has not disabled, or perhaps you have secured C:\ProgramData or C:\ProgramData\MyProgramName to permit write access to standard user.
Somethings you must something about UAC
When Microsoft introduced UAC they needed a way for older applications to continue working, at least for a while. What they came up with was "File and Registry virtualization", where legacy applications that tried to access (now-)verboten System folders or registry entries would be redirected to their own user-specific "virtualized" copy of those resources. As the Wikipedia article on UAC.
To put it straight, ProgramData contains application data that is not user specific. This data which will be available to all users on the computer.
There are a couple of approaches to the use of this folder. Some applications write there only during installation whilst the installer process is running elevated. Then the application itself, which runs as standard user, can read, but never attempts to write.
Another approach is for the installer to create a sub folder of C:\ProgramData that is secured to allow write access for standard user, or whatever user/group that you the developer deem appropriate.
If your program "Run as administrator" privileges then you should be able to avoid this issue.
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.
I have a legacy VB6 system which is installed in C:/Program Files/IronDuke
In the past it has written some files into this directory. I understand that these files are hidden away if the application is installed under Vista or a later OS, but not if they were written under XP or earlier OS.
How can I retrieve a copy of these 'hidden' files when written under Vista or Windows 7 or 8?
You are looking at a feature called UAC Virtualization, this blog posting gives a pretty good rundown on what is happening and where the files are located.
From above article:
For example, if an application attempts to write to C:\Program Files\Contoso\Settings.ini, and the user does not have permissions to write to that directory (the Program Files), the write operation will be redirected to C:\Users\Username\AppData\Local\VirtualStore\Program Files\Contoso\settings.ini. If an application attempts to write to HKEY_LOCAL_MACHINE\Software\Contoso\ in the registry, it will automatically be redirected to HKEY_CURRENT_USER\Software\Classes\VirtualStore\MACHINE\Software\Contoso or HKEY_USERS\UserSID_Classes\VirtualStore\Machine\Software\Contoso.
so in your case if you are trying to find the files you need to look in:
C:\Users\Username\AppData\Local\VirtualStore\Program Files\IronDuke\
You cannot write to Program Files under Windows 7 / 8 - system security prevents programs running as regular users from doing so. One option for you is to write these files to the user's profile folder (you'll have to update the VB6 program for this, although the changes should be pretty small if the program is otherwise well-written). This would be your best option since the updated code would work well in the future without more changes.
You amy be able to get the program running using Compatibility Mode but I doubt it - on my Windows 8 system I don't even get 'Windows XP' as a compatibility option anymore. All other options will likely enforce security.
You can try running your program as administrator but I'd only do this if you don't have the source to make the changes - it's poor practice to run programs with all privileges since it opens up the system for attacks.
I've seen several questions that are the opposite of this; "How do I disable virtualization?" That is not my question. I want to force an application to run with virtualization enabled.
I have an application that ran just fine under Windows XP, but, because it writes its configuration to its working directory (a subfolder of "C:\Program Files (x86)"), it does not work completely under Windows 7. If I use task manager to turn on UAC Virtualization, it saves its config just fine, but of course it then can't load that config.
I do not want to set it to run as administrator, as it does not need those privileges. I want to set it to run with UAC Virtualization enabled.
I found a suggestion that I put some magic in the registry at HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags. For completeness I also put it in Wow6432Node, but neither had any effect.
File system is virtualized in certain scenarios, so is your question how to still turn it on when your application does not qualify? It is unlikely possible, MSDN:
Virtualization is not in option in the following scenarios:
Virtualization does not apply to applications that are elevated and run with a full administrative access token.
Virtualization supports only 32-bit applications. Non-elevated 64-bit applications simply receive an access denied message when they
attempt to acquire a handle (a unique identifier) to a Windows object.
Native Windows 64-bit applications are required to be compatible with
UAC and to write data into the correct locations.
Virtualization is disabled for an application if the application includes an application manifest with a requested execution level
attribute.
this may come way too late now, but I am the author of the suggestion you found to activate UAC virtualization, and there was a mistake in my post. The registry keys to modify are the following:
HKLM\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers\
(notice the "Layers" appended)
so a full example would be:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="RUNASINVOKER"
note that multiple parameters must be separated with space character.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"C:\\Program Files (x86)\\Some Company\\someprogram.exe"="WINXPSP3 RUNASINVOKER"
--
I'm sincerely sorry that you lost a fair amount of time because of my mistake.
And by the way, let me express my disagreement with Ian Boyd's post. There are places where write privileges should not be granted to everyone, such as this one, since it breaks the base security rule of "System-wide writes should be authorised to privileged principals only". Program Files is a system-wide place, not a per-user one.
All rules have exceptions of course, but in the present case, one could imagine a maliciously crafted configuration file making the program exec an arbitrary command as the user running it. On a lighter side, one could imagine a "mistake delete" by another user, which would make the app fail. Back on the heavier side, application executables in Program Files are often run by the admin, sooner or later. Even if you don't want to, uninstalling programs very often run uninstall executables that are in Program Files. Maybe the uninstall procedure will use that config file which could have consequences if it's maliciously crafted.
Of course you may say, this sounds paranoid somehow, agreed. I did modify some NTFS ACLs in Program Files at the times of Win XP and was able to sleep after that, but why take the slightest risk when the tools are available ?
I found one not very well cited condition where UAC Virtualization does NOT work: when the file in Program Files is maked as read-only.
That is, suppose the file C:\Program Files\<whatever>\config.ini is marked as read-only. When the application try to change it, UAC Virtualization will return an access denied error instead of reparsing it to %LOCALAPPDATA%\VirtualStore\<whatever>\config.ini.
Although I did not found this documented, this behavior is probably done by design, since it makes some sense.
The solution is simple: assure that all files that are supposed to be modified by the application are not read-only (or just unflag all files, since the user will not be able to change them anyway).
You have an application, and you want users to be able to modify registry keys or files in locations that by default only Administrators can modify.
If you were running Windows 2000, or Windows XP, or Windows Vista, or Windows 7, or Windows 8, the solution is the same:
grant appropriate permissions to those locations
For example, if your program needs to modify files in:
C:\Program Files\Blizzard\World of Warcraft
Then the correct action is to change permissions on the World of Warcraft folder. This is, in fact, a shim that Microsoft applied to World of Warcraft. (On next run it granted Everyone Full Control to the folder - how else can WoW update itself no matter what user is logged in.)
If you want users to be able to modify files in a location: you have to grant them permission. If you were a standard user trying to run WoW on Windows XP you will get the same problem - and need to apply the same solution.
Your application is writing its configuration to:
C:\Program Files (x86)\Hyperion Pro\preferences.ini
then you, in fact do want to grant Users Full Control to that file:
So your:
application is not set to run as an Administrator
users cannot modify the executable
users can modify Configuration.ini
Granting permissions is not a bad thing; it's how you administer your server.
There are two solutions:
Install to C:\ProgramData\Contoso\Preferences.ini and ACL it at install time
Install to C:\Program Files\Contoso\Preferences.ini and ACL it at install time
And if you look at the guidance of the AppCompat guy at Microsoft:
Where Should I Write Program Data Instead of Program Files?
A common application code update is this: “my application used to write files to program files. It felt like as good a place to put it as any other. It had my application’s name on it already, and because my users were admins, it worked fine. But now I see that this may not be as great a place to stick things as I once thought, because with UAC even Administrators run with standard user-like privileges most of the time. So, where should I put my files instead?”
FOLDERID_ProgramData
The user would never want to browse here in Explorer, and settings changed here should affect every user on the machine. The default location is %systemdrive%ProgramData, which is a hidden folder, on an installation of Windows Vista. You’ll want to create your directory and set the ACLs you need at install time.
So you have two solutions:
create your file at install time, and ACL it so that all users can modify it at runtime
create your file at install time, and ACL it so that all users can modify it at runtime
The only difference is semantic. The Program Files folder is mean for program files. You don't want to store data here.
And it's not because Diego Queiroz has any insight about security.
It's because it's where just the programs go.
Sometimes machines are imaged with the same Program Files over and over. You don't want per-machine data in your image. That data belongs in ProgramData.
And it's not a security issue.
Some people have to learn where the security boundary is.
there are quite some good points in those other answers.
actually i have upvoted all of those.
so let's all combine them together and add some more aspect ...
the OP mentions some "legacy application from the old days".
so we can assume it is x86 (32bit) and also does not include any manifest (and in particular does not specify any "requestedExecutionLevel").
--
Roman R. has good points in his answer regarding x64 and manifest file:
https://stackoverflow.com/a/8853363/1468842
but all those conditions don't seem to apply in this case.
NovHak outlines some AppCompatFlags with RUNASIVOKER in his answer:
https://stackoverflow.com/a/25903006/1468842
Diego Queiroz adds intersting aspect regarding the read-only flag in his answer:
https://stackoverflow.com/a/42934048/1468842
Ian Boyd states that probably you don't even should go for that "virtualization", but instead set according ACL on those files of interest (such as "config.ini"):
https://stackoverflow.com/a/12940213/1468842
and here comes the addtional / new aspect:
one can set a policy to disable all virtualization - system-wide:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"EnableVirtualization"=dword:00000000
actually i'm enforcing this policy on each and every system that i own.
because otherwise it will lead to confusing behaviour on multi-user environments.
where UserA applies some changes and everything goes fine.
but then UnserB does not get the changes done by UserA.
in case some old crappy software fails then it should "fail"!
and not claim that everything went "fine".
IMHO this "Virtualization" thing was the worst design decision by microsoft, ever.
so maybe the system has this policy enabled and that's why virtualization doesn't work for you?
--
so probably the ultimate checklist would be:
is the application x86 or x64?
does the exe have a manifest (including the requestedExecutionLevel)?
have you checked the read-only attribute (e.g. of those INI files)?
is there a policy to force the EnableVirtualization to 0?
have you tried the AppCompatFlags with RUNASIVOKER?
or simply go for ACL instead of virtualization
--
in the end we are discussing how to get on old legacy application to run.
by using whatever workarounds and hacks we can think of.
this should probably better discussed on either superuser or serverfault.
at stackoverflow (targeted for programmers) we all know: it's about time to get all of our own programs compatible with UAC concept and how to implement things the "right" way - the "microsoft" way :)