I am facing some issues with this function GetFileAttributes().
I am using C++ to get windows OS notifications and process them. For a particular case of frequent rename action on a single file, some times we are getting FILE_ATTRIBUTE_HIDDEN for those file. I am using Windows 7 Profession Service Pack 1.
Assume I have a pdf file say test.pdf. We are monitoring a directory say (D:\Test) using automatic directory monitoring in windows os. I am renaming the file (D:\Test\test.pdf) frequently as test1.pdf, test12.pdf, test123.pdf and so on.
I got rename notifications for each of the above actions. We used to check the file attributes for each notifications and if it is hidden file, we won't process further. While checking the file attributes, some times it shows as FILE_ATTRIBUTE_HIDDEN for the file. Is there any known issue with GetFileAttributes() ?
Is there any other thing I could try instead of GetFileAttributes ?
Related
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();
....
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.
In the Windows API, when you monitor a directory, the callback provides what changed. How do I accomplish the same for Mac OS X?
I looked at the File System Events API and the Kernel Events API and it seems like they both watch a file descriptor and return what changes happened to that file descriptor. This is inconvenient because now I have to open watchers on the entire file structure and remember the previous names (in case of a rename).
Is there a better way (that doesn't involve a library)?
FSEvents watches a directory hierarchy (or multiple hierarchies), not a file descriptor. So you only need one watcher. But you will need to scan the directories to find out which files changed. There is no better way (that doesn't involve a library).
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.