I am writing a program that is using a database library. The library provides me access to the file handle it uses to access my table. I've found a windows API that allows me to retrieve information about the file by handle but I've yet to find any means of determining access mode / permissions of that file. At this point I'm sure I could likely live without knowing this information but being the stubborn cuss that I am I'm not ready to let this one go. Obviously Windows knows this info - so the question is how can coax the info out of it?
The API function that I've found is: GetFileInformationByHandleEx and it takes me close to the watering hole but doesn't let me drink the water.
The reason that the file mode information is useful is that I need to modify the table header information. If the file is already in a proper mode then I won't have to close the table open the file modify the file close the file then re-open the table.
And yes, before I'm told of all the options available to me to achieve my goal - I'm not interested in those. I'm only interesting in the original question - how do I determine the mode of an already opened file. I look forward to any responses and I thank you in advance.
Thanks,
Robert Milligan
I don't know if there is a corresponding Win32 API for this, but if you really need it you can call NtQueryObject(ObjectBasicInformation).
OK. So I finally got this part all figured out - thanks to your direction, a lot of MSDN study and a LOT of trial and error.
There were a couple of tricky points to getting this all figured out.
1) The ACCESS_MASK certainly did not reflect the access modes as I expected. The documentation led me to expect the upper 4 bits to reflect the "GENERIC" modes that I opened the file with - wrong! Those show up in the Specific Rights section. Heck - I still don't have a clue when those upper 4 bits actually get used, but for this exercise I don't need to.
2) Once I got THAT clear in my mind I had to stumble across documentation that let me know that when I opened with GENERIC_READ that was translated into:
FILE_GENERIC_READ
which is made up of:
STANDARD_RIGHTS_READ |
FILE_READ_DATA |
FILE_READ_ATTRIBUTES |
FILE_READ_EA |
SYNCHRONIZE
Understanding this concept made all the rest of it fall into place. Now my understanding correlated with the information that Process Hacker was telling me.
3) I also had a serious error going from my UI to the code (read one constant misplaced), which once figured out made the whole world lay down before my feet.
This is great because I can now figure out what Access Modes were used when the file was opened. Original question answered!
Now I would like to be able to determine the "share" mode the file is in - if possible. Any ideas?
Thanks again for your help
Figured it out maybe? From my reading of the docs, it seems you might be able to discern the original "share mode" of an open handle by calling ReOpenFile with dwDesiredAccess of 0 and dwShareMode for one (or more?) of the modes to query, i.e. FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE. If ReOpenFile returns a valid handle--which you can then close/dispose--then that sharing mode was present on the original file?
Source:
"If dwDesiredAccess is zero (0), the application can query device attributes without accessing the device. This is useful if an application wants to determine the size of a floppy disk drive and the formats it supports without requiring a floppy in the drive."https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-reopenfile
Related
Given I have a list of all file handles of all processes, how could I find out which of these handles are actually locking a file?
From what I understand I could simply try to open the files and try to get all the permissions and if something goes wrong I'd know it is locked. But that sound extremely inefficient. I mean I already have the handles is there no way to check which permissions the handles have?
Preferably I'd like to see a solution that works on Windows XP and above.
I already searched through the GetFileInformationByHandleEx function, but I couldn't find anything about access permissions. :/
Edit:
I don't need real-time information on the file lock. The files that I'm planning to work on will either be locked until certain applications are closed or not be locked at all.
This question is a duplicate of Win32 files locked for reading: how to find out who's locking them.
Also, Hans Passant's commentary is correct: querying the locked state of any Win32 file gives stale information. Disregarding this warning will cause hard-to-find bugs.
If you control all bits of code that you think will access the files, it's better to use a named pipe for interprocess communication, instead of querying locked files.
You can use NtQueryObject API to get information about the handle including the following:
ULONG Attributes;
ACCESS_MASK GrantedAccess;
Or you can access the same information using NtQueryInformationFile using FileModeInformation and FileAccessInformation values for FileInformationClass parameter.
Is there a way to get all opened file handles for a process and arrange it by time files were opened? We have a project, which requires exactly this - we need to determine which files are opened by a Dj software, such as Traktor or Serato. The reason we need to know its order is to determine, which file is in the first deck, and which is in the second one.
Currently we are using Windows internal APIs from the Ntdll.dll (Winternl.h) to determine a list of all opened files for a process. Maybe that's not the best way to do it. Any suggestions are highly appreciated.
We relied on an observed behavior of that APIs on certain OS version and certain Dj software versions, which was that the list of all opened files for a process never get rearranges, i.e. adheres an order. I know that's a bad practice, but it was a "should be" feature from the customer right before the release, so we had to. The problem is now we have a bug when those handles are sometimes randomly rearranged without any particular cause. That brakes everything. I thought maybe there would be a field in those win structures to obtain file's been opened time, but seemingly there are no such things. Docs on that APIs are quite bad.
I thought about some code paste, but it's a function 200 lines long and it uses indirect calls from the dll using function pointers and all structures for WinAPIs are redefined manually, so it's really hard to read it. Actually, the Winternl.h header isn't even included - all stuff is loaded manually too, like that:
GetProcAddress( GetModuleHandleA("ntdll.dll"), "NtQuerySystemInformation" );
It's really a headache for a cross platform application...
P.S. I have posted a related question here about any cross-platform or Qt way to get opened file handles, maybe that stuff will be useful or related.
if it's just to check the behavior in other OS for debug purpose, you can use the technique of creating process in debug mode and intercept in the order all events of dll loading, here's a good article talking about that.
There seems to be two methods of setting and getting a user screensaver parameters on a Windows platform:
1: Via the SystemParametersInfo() API:
//To read
SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, &bScreensaverAcrtive, NULL);
SystemParametersInfo(SPI_GETSCREENSAVETIMEOUT, 0, &nScreensaverTimeout, NULL);
//No API to get the screensaver file used
//To set
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, bScreensaverAcrtive, NULL);
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, 0, nScreensaverTimeout, NULL);
//No API to change the screensaver file
2: Through the system registry keys:
HKCU\Control Panel\Desktop - "ScreenSaveActive"
HKCU\Control Panel\Desktop - "ScreenSaveTimeOut"
HKCU\Control Panel\Desktop - "SCRNSAVE.EXE"
But since there're two competing methods that seem to do the same, what is the recommended way to use?
PS. I highly favor method #2 (or writing directly into registry) due to the following reasons:
A. If you read the explanation of a bug in the SPI_GETSCREENSAVEACTIVE flag, you'll see that MS themselves recommend to use registry.
B. If you read the documentation for the SPI_SETSCREENSAVEACTIVE and SPI_SETSCREENSAVETIMEOUT flags, there's this mystical line that says, "*If the machine has entered power saving mode or system lock state, an ERROR_OPERATION_IN_PROGRESS exception occurs.*" I first ignored this situation until it actually started happening on my test installation of Windows 8. This is the most asinine error, I should tell you. There's absolutely no graceful way of interpreting what it means or do any workaround (except, writing directly into the registry.)
Use the API. Asking that is like asking if you should wait for the traffic light to turn green before crossing the road. I won't call the cops if I see you crossing at red, but if you ask me, I'll tell you you have to wait. And you are the one taking the risk of bad things happening.
The API is documented, the registry locations are not. Microsoft is in no obligation to preserve the registry locations or their functionality.
The SPI_GETSCREENSAVEACTIVE flag affects Windows 2000. If you support Windows 2000 as a target platform, I would apply the registry read to that version only (OSVERSIONINFO.dwMajor=5, .dwMinor=0)
ERROR_OPERATION_IN_PROGRESS I'd try to figure out under what circumstances this happens (e.g. screensaver already active, or system about to enter a power saving state).
Generally, I'd find it questionable if activating / deactivating the screensaver is not at least related to a user action, in which case the system should be ready to accept a change.
What are you trying to achieve? Why do you need to modify screensaver activity? Maybe there's some better method to achieve your goal
Use the API. The registry format changes often.
As for the power state changes, screen savers are really a 20th century feature. Laptops turn off the screen entirely, for obvious reasons. In that power saving state SPI_SETSCREENSAVEACTIVE obviously should fail. Not a lot of interpreting to do.
So, check for GUID_VIDEO_POWERDOWN_TIMEOUT first.
edit
I just realized that Group Policy screensavers are also unlikely to be in the registry, and certainly would override HKCU. Not a real issue for Windows 2000, of course, but today the API method would be even more advisable. Of course, do realize that this is just another reason why SPI_SETSCREENSAVEACTIVE may return an error. Still an improvement over the registry approach, which fails silently in the presence of Group Policy.
"To set" above is incorrect. It should be:
//To set
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, bScreensaverAcrtive, NULL, NULL);
SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, nScreensaverTimeout, NULL, NULL);
I know that one can call the following API to hibernate the system:
SetSuspendState(TRUE, FALSE, FALSE);
But is there any way to find out if "real" hibernation is available for the current Windows user?
Here's what I mean:
If an admin calls:
powercfg.exe /hibernate off
the API above will put system into a Sleep mode. So how do you know (from a C++ program) that this will happen instead of hibernation?
I'm not sure if there's a group policy that can prohibit a user from hibernating a computer connected to an Active Directory?
Edit I am aware of the (dated) IsPwrHibernateAllowed API. I find that it doesn't work: it still returns the same result even if powercfg.exe /hibernate off was called. Am I doing something wrong there? Can someone explain why IsPwrHibernateAllowed doesn't work for me?
Take a look at SYSTEM_POWER_CAPABILITIES structure that can be obtained with CallNtPowerInformation. Specifically, look at HiberFilePresent field.
I'm developing in windows with C/C++ and I want to know is it possible to get an apropriate \\.\SCSI device name by \\.\PhysicalDrive ?..
For example, it's wonderful to know how to get that \\.\PhysicalDrive0 is the same that \\.\SCSI0.
Look at the code which I posted in my answer to the question. The author of the question had changed the text of the question so many time and the last version of text clear nor really what the original problem was.
In the example, which C source code you can download here, I show how to get many kind of information about the local drive using different Windows API. The important thing which you need is that some name conversion like DeviceType and DeviceNumber (received by IOCTL_STORAGE_GET_DEVICE_NUMBER) like the following
DeviceType: 7, DeviceNumber: 5, PartitionNumber: 1
are unique in the operation system and can be used to identify the same devices. The reference to the statement you can find in the documentation of IOCTL_STORAGE_GET_DEVICE_NUMBER control code:
The values in the
STORAGE_DEVICE_NUMBER structure are
guaranteed to remain unchanged until
the device is removed or the system is
restarted. It is not guaranteed to be
persistent across device restarts or
system restarts.
In the way you can compare \\.\SCSI0 devices and \\.\PhysicalDrive0 and find out the correspondence.