I have a file name and I want to check whether it can be executed or not on windows through c++. I found _access and _access_s, but they only check for read/write.
My problem is that when I download a bat file for example, the windows blocks it as a security measure. When I run my program and try to execute it, windows blocks my program and asks user if he wants to continue anyway, because the file is risky. I want to avoid that by checking the file rights before executing it.
The windows filesystem, NTFS, does not support an executable attribute in the way you might expect if you have used a Unix based OS.
What you are seeing here is the shell reacting to an extra stream that was added to the file. And streams are a feature of NTFS.
Microsoft has some sample code showing how to access streams in a file:
How to use NTFS Alternate Data Streams
In the case of files downloaded from the internet, Microsofts browsers (IE and Edge) add a stream called "Zone.Identifier", which ShellExecute and related APIs check for when asked to execute a file to present the user with a security prompt.
To cleanse the file so that the security prompt does not appear it is necessary to erase the stream.
BOOL didDeleteZoneIdentifier = DeleteFile(TEXT("Path To Batch File.bat:Zone.Idenfier"));
if(!didDeleteZoneIdentifier){
int errorCode = GetLastError();
....
Related
I'm using Visual Studio 2015 to create a simple send mail program using EA Sendmail library.
I try to send "D:\tmp\pic.jpg", after send success I would delete it by command
remove("D:\\tmp\\pic.jpg") from #include<stdio.h>. But this file still there? What is my mistake?
If that's Windows, three things can happen:
1. File still blocked by delayed operation of sending mail.
2. File was blocked by antivirus, while it may hook on ffile open activities, some AV just block file deletion\file movement.
3. Permissions issue. You're using non-standard folder, in root directory of disk..it inherited permission from the root directory, most likely. In your particular case you program runneth with insufficient (unelevated?)priveleges.
4. UTF-16 path issue. IS that real path you offer?
You're using remove() from standard library? that one based on POSIX "emulation" layer of Windows API that is lacking of Window-specific features.. you can't determine actual reasons and can't manipulate ACL\permissions and supports only Latin1 in path. Windows supports Unicode(UTF-16) on NTFS, but to use it, you need call functions from "native" API that accepts widechar strings (DeleteFileW). Windows API allows to get more error code states than POSIX. Also Windows got mechanisms to monitor\wait for file being if it is open by other operation, but that one available only to Elevated users, sadly, that's a kernel-level driver for taskmgr.
Read a file using a program like Notepad while the file is being written to by another program?
I've created a Windows Service application that logs continuously.
I want to inspect the current events of the service without closing it. To do this I open the log.txt in Notepad, but gets the message
The process cannot access the file because it is being used by another
process
How can I read the log file without closing the service? After the service is closed, I can readily inspect every log entry in the file.
The file is being written by calls to fopen_s and fprintf, if that should be of any interest. Also, the service is programmed in C/C++ on Windows 10 64-bit, running under SCM with default priviledges i.e. LocalSystem.
https://msdn.microsoft.com/en-us/library/z5hh6ee9.aspx and then Remarks:
Files that are opened by fopen_s and _wfopen_s are not sharable. If you require that a file be sharable, use _fsopen, _wfsopen with the appropriate sharing mode constant—for example, _SH_DENYNO for read/write sharing.
Would that be a solution?
It is easier to explain with example.
When 2 text editors edit the same text file in the same time, when one editor saves the file, the other one understands that it was modified and asks to do smth.
How is it possible to get a signal that a file was modified outside the program?
I am working with c++ (though I think it isn't important) and on linux. (solution for windows would be good too)
ISO-C++ does not offer this functionality, so you have to stick with what the operating system provides.
On Linux that would be inotify, on Windows you would use directory change notifications.
① Check the timestamp of the file as close as possible before writing. If it is not what it was when you last opened this file for reading, then beware!
② You can build a checksum of the file and compare this to one you built earlier.
③ Register to a system service which informs you about file activities. This depends on the goodwill of the OS you are using; if this notification service isn't working properly, your stuff will fail. On Linux have a look at Inotify.
I wrote this C++ application that needs to check an INI file (“preference.ini”), and eventually modify it (e.g. if the user does not want to see the introduction form anymore). I created it in WinXP, and it works fine on the system where I compiled it (in many locations, including “Program Files”).
Problem:
In Win 7, it works fine if I put the complete program folder under “C”:\” (e.g. “C:\MyProgram”), but if I put it in “C:\Program Files (x86)\MyProgram”, it just retrieves some mysterious data (values not present in my INI file). When I change some settings and save them to file, it (apparently) save the changes (get no errors, but the changes are not there when I go and open the file...
I had some similar issue on a system with another WinXP system (not the one where I compiled it.
I used 'getcwd' to define the path at runtime, and I verified that it is getting it right, even under "Program Files (x86)":
char currentPath[MAXPATH];
getcwd(currentPath, MAXPATH);
std::string licensePath(currentPath);
licensePath.append("\\dat\\preference.ini");'
Any ideas? Thanks in advance for your help.
The answer is as #Kirill has already said - Win7 won't let you write data into Program Files unless you have higher than normal permissions (Run as Administrator). In this case it may be redirecting your file writes so that they still apear to work, but the data itself is not stored in Progam Files.
To add to his answer: In general (unless you want to run your app as an administrator), you should not write any program data to the Program Files folder.
Application settings should be stored in one of the AppData folders. You can get to your user's appdata manually by going to your start menu Search box (Vista/Win7) and typing %appdata%.
To find this location in your code, use SHGetFolderPath with CSIDL_APPDATA (current user) or CSIDL_COMMON_APPDATA (all users).
It could be related to that Windows use virtualization of the file system. You could read here about it. Check if your INI file is located in <root>\Users\<User_name>\AppData\Local\VirtualStore.
Seems to me that the licensePath: getcwd() + "\\dat\\preference.ini" is not what you would expect.
Log this value (console or in a log file) and see what exactly is the value of licencePath is when running you program from different folders.
This article is about game development but has the best description of how and why this happens that I've been able to find
http://msdn.microsoft.com/en-us/library/ee419001(VS.85).aspx
This paragraph from the article describes what is happening most likely -
Attempting to create or write a file
or directory under a folder which does
not grant write permission to the
process will fail under Windows Vista
if the application does not have
administrative privileges. If your
32-bit game executable is running in
legacy mode, because it did not
declare a requested execution level,
its write operations will succeed, but
they will be subjected to
virtualization as described in the
section "UAC Compatibility with Older
Games" later in this article.
I'm trying to make a small program that could intercept the open process of a file.
The purpose is when an user double-click on a file in a given folder, windows would inform to the software, then it process that petition and return windows the data of the file.
Maybe there would be another solution like monitoring Open messages and force Windows to wait while the program prepare the contents of the file.
One application of this concept, could be to manage desencryption of a file in a transparent way to the user.
In this context, the encrypted file would be on the disk and when the user open it ( with double-click on it or with some application such as notepad ), the background process would intercept that open event, desencrypt the file and give the contents of that file to the asking application.
It's a little bit strange concept, it could be like "Man In The Middle" network concept, but with files instead of network packets.
Thanks for reading.
The best way to do it to cover all cases of opening from any program would be via a file system filter driver. This may be too complex for your needs though.
You can use the trick that Process Explorer uses to replace itself with task manager. Basically create a key like this:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe
Where you replace 'taskmgr.exe' with the name of the process to intercept. Then add a string value called 'Debugger' that has the path to your executable. E.g:
Debugger -> "C:\windows\system32\notepad.exe"
Every a process is run that matches the image name your process will actually be called as a debugger for that process with the path to the actual process as an argument.
You could use code injection and API redirection. You'd start your target process and then inject a DLL which hooks the windows API functions that you want to intercept. You then get called when the target process thinks it's calling OpenFile() or whatever and you can do what you like before passing the call on to the real API.
Google for "IAT hooking".
Windows has an option to encrypt files on the disk (file->properties->advanced->encrypt) and this option is completely transparent to the applications.
Maybe to encrypt decrypt file portions of a disk you should consider softwares like criptainer?
There is this software as well http://www.truecrypt.org/downloads (free and open source) but I haven't tried it.
Developing a custom solution sounds very difficult.