How to get access rights on an open win32 HANDLE - windows

When you call CreateFile, you pass in dwDesiredAccess to determine if the handle should be writeable/readable/deleteable/etc.
If I'm passed an open handle, how do I recover these access rights? Specifically, I'm interested in whether the handle is writeable (... without actually writing to the handle).
Even more specifically, I'm getting 'access denied' errors on FlushFileBuffers(), and I'm guessing it's because they weren't opened with GENERIC_WRITE, would like to ignore those errors if that's the cause.

for this exist function NtQueryObject with ObjectBasicInformation ObjectInformationClass
OBJECT_BASIC_INFORMATION obi;
if (0 <= NtQueryObject(h, ObjectBasicInformation, &obi, sizeof(obi),0))
{
// use obi.GrantedAccess;
}

Related

CreateFile on Directory in NTFS fails on ReadFile

Supposedly it is possible to actually open and read directories on NTFS volumes. However, my code to try this wasn't working, so I tried google, which found me this.
The key observation there seems to be that you must use FILE_FLAG_BACKUP_SEMANTICS. So, trimming that down, I basically get:
HANDLE hFile = CreateFile(L"C:\\temp", GENERIC_READ, FILE_SHARE_READ,
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
DWORD dwFileSize = GetFileSize(hFile, 0);
char* buf = new char[dwFileSize];
DWORD dwBytesRead = 0;
BOOL b = ReadFile(hFile, buf, dwFileSize, &dwBytesRead, 0);
Seems pretty straight-forward. Unfortunately, it doesn't work.
The CreateFile and GetFileSize both work (handle is not INVALID_HANDLE_VALUE, non-zero and plausible file size), but the ReadFile returns FALSE, dwBytesRead is zero, and GetLastError returns 1 ("Incorrect function"). Huh.
While I was typing this question, the 'Similar Questions' prompt showed me this. That business about using AdjustTokenPrivileges made a lot of sense. However, it didn't help. Adding ReadFile (and using c:\temp) to that example gives the same behavior. A closer reading of the CreateFile docs shows that even without the SE_BACKUP_NAME privilege, I should be able to open the file due to admin privileges.
I've tried a number of permutations:
Different ways of specifying the directory name (c:\temp, c:\temp\, \\.\c:\temp, \\?\c:\temp\, etc).
Different directories
Different drives
Different share options (0, FILE_SHARE_READ, FILE_SHARE_READ | FILE_SHARE_WRITE)
Different access permissions (GENERIC_READ, FILE_LIST_DIRECTORY, FILE_LIST_DIRECTORY + FILE_READ_EA + FILE_READ_ATTRIBUTES, FILE_LIST_DIRECTORY + FILE_READ_EA + FILE_READ_ATTRIBUTES + FILE_TRAVERSE)
I can't see any flags that might apply other than FILE_FLAG_BACKUP_SEMANTICS (which I assume is required), but I tried FILE_FLAG_NO_BUFFERING and a 4096 byte aligned buffer. Nope.
I'm (currently) trying 152 permutations, and none of the ReadFiles are working. What am I missing?
Is my original assumption here incorrect? Is it not really possible to 'read' from a directory? Or is there just some trick I'm still missing?
What else should I mention?
I'm running as an admin, and can do a CreateFile on the volume.
My program is 64bit, built for unicode.
Windows 7 x64
NTFS 3.1 volume
It's cloudy outside (Hey, you never know what might matter...)
If you want to open a stream then you need to include the stream name and/or type as part of the path:
c:\foo:bar A.K.A. c:\foo:bar:$DATA
c:\foo::$INDEX_ALLOCATION
The default $DATA stream is used if you don't specify a stream. $DATA stores a files "normal data".
If you want the list of files in the directory then you can use GetFileInformationByHandleEx(FileIdBothDirectoryInfo) (and NtQueryDirectoryFile on older systems).
It looks like Jonathan Potter has given the correct answer. Despite prompting, he has elected not to post his comments as an answer. So I'm going to create one based on his responses in order to close the question.
In short: "You can open a handle to a directory to do certain things, but calling ReadFile on it isn't one of them."
What things? These things. This list includes:
BackupRead
BackupSeek
BackupWrite
GetFileInformationByHandle
GetFileSize
GetFileTime
GetFileType
ReadDirectoryChangesW
SetFileTime
In summary: While you can "open" directories and "read" certain information about them, you can't actually use ReadFile. If you want to read the DirName::$INDEX_ALLOCATION information, you'll have to use a different approach.

How to get process memory usage WINAPI

I have the problem . I am trying to get process memory usage , but unfortunatly some process always returning the same value in my case - 3276. How can I get the real amount of memory using by the process. Thanks in advance.
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
PROCESS_MEMORY_COUNTERS memCounter;
BOOL result = GetProcessMemoryInfo(hProcess,
&memCounter,
sizeof( memCounter ));
char procID[20];
char procMem[100];
sprintf_s(procMem, "%d",(memCounter.WorkingSetSize/1024/1024));
if (!(strcmp(procMem,"3276"))) {
strcpy(procMem, "<unavaliable>");
}
sprintf_s(procID, "%d",entry.th32ProcessID);
You are not checking the return values for errors. You simply must do that. Clearly one of them is failing. Is it OpenProcess, or is it GetProcessMemoryInfo? How can we tell without any error checking. Read the documentation for the function and follow the instructions there given to check for errors.
Once you identify which function is failing you can try to work out why. In case of failure, both of these functions will set the last error value and so you can call GetLastError to discern what went wrong.
Quite possibly OpenProcess is failing because you are asking for too many access rights. All you need is PROCESS_QUERY_INFORMATION | PROCESS_VM_READ. Another possible failure mode is that some system processes will not give up this information. Ultimately you need to perform error checking to diagnose the specific problem.

CreateFile Returns negative handle

Any ideas why the createfile() function would be returning -1.
Handle = CreateFile(filename, &H80000000, 0, 0, 3, &H80, 0)
This is run a few times. I was thinking perhaps maybe the file is not being closed properly?
EDIT
Err.LastllError returns 32.
You are probably right about not closing the file someplace. I would start by looking where I am opening the file and making sure I have an error handling routine in place. In the error handler I would check the value of "Handle" and if it's valid call CloseHandle(Handle). Also, since you are opening the file for read access, you could change you dwShareMode parameter to 1 to allow subsequent open for read operations on the same file.
Error 32 is ERROR_SHARING_VIOLATION (reference) which means some other process still has the file open.

DuplicateHandle in WINAPI returns ERROR_ACCESS_DENIED

I have two anonymous pipe handles. I want to pass one of them to a child process.
It works correctly if I call DuplicateHandle to make the handle inheritable for a write handle of the pipe like:
DuplicateHandle(myHandle, fdCP[1], myHandle, &fdCP[1], DUPLICATE_SAME_ACCESS, 1, DUPLICATE_CLOSE_SOURCE);
However when doing it for a read handle of another pipe I get a 0x00000000 value in the result handle.
GetLastError in this case is 5 (ERROR_ACCESS_DENIED). I tried to provide SECURITY_ATTRIBUTES of GENERIC_ALL|SPECIFIC_RIGHTS_ALL when created the pipe. However it didn't help.
I noted that DuplicateHandle works as expected if called in on the read handle as follows:
DuplicateHandle(myHandle, fdPC[0], myHandle, &fdPC[0], 0, 1, DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS);
In both cases myHandle is GetCurrentProcess().
So the question is this an error in WINAPI? And is this a correct workaround?

CreateFile not returning a proper Handle - devices in Delphi

Hoping to find somebody that has experience with services in windows.
I am trying to use the NdisProt driver for ethernet adapters in Delphi
my_Handle := CreateFile(PChar('\\.\NdisProt'),
GENERIC_WRITE or GENERIC_READ, 0, nil,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
(have tried with \\.\\NdisProt too)
After execution my_Handle always has the value '4008' decimal and GetLastError always returns 0
If I try to read or write to the file I get acces violation, anybody knows why I'm getting this unwanted behavior?
If CreateFile doesn't return Invalid_Handle_Value, then it has given you a valid handle, or else the driver for that device is severely buggy. Assume the former.
An access violation has nothing to do with your handle value. It means you're accessing memory that doesn't belong to your process (such as by dereferencing a null pointer, an uninitialized pointer, a non-pointer, or an already freed pointer). Your problem lies elsewhere, perhaps in the reading or writing code that you neglected to show here.
The code in your question is not an assignment statement. It's a comparison expression. You should have gotten a warning from the compiler that the variable's value is undefined. If it always has the value 4008 after executing that code, then you should check whether it also had that value before executing that code. It could simply be that CreateFile is returning a valid handle value, but you're not using the value it returns.
If 4008 isn't the value CreateFile returns, then it's probable that 4008 isn't a valid handle value. If the OS treats handles as pointers (or if it performs some kind of transform on handles to generate pointers), then it could be that the pointer corresponding to that "handle" is not a valid address in your process; that would explain the access violation.

Resources