How Make File* from Handle in Winapi

How make FILE* from HANDLE in WinApi?

You can do this but you have to do it in two steps. First, call _open_osfhandle() to get a C run-time file descriptor from a Win32 HANDLE value, then call _fdopen() to get a FILE* object from the file descriptor.

Get FILE stream from File Handle

Use _open_osfhandle() to create a C-style file descriptor from a Win32 HANDLE, and then use _fdopen() to create a FILE* from the file descriptor.

How can we convert a FILE* to a HANDLE?

(HANDLE)_get_osfhandle(_fileno( file ) )

Good luck on 64-bit systems if you're using Visual C++ 2008 or earlier, though, because the return type is long on those. :(

Winapi: Get the process which has specific handle of a file

For this task, starting with Windows Vista special exist FileProcessIdsUsingFileInformation FILE_INFORMATION_CLASS.

So we need open file with FILE_READ_ATTRIBUTES (this is possible even if somebody open file with 0 share mode. of if we have no access to file (by it DACL) but have read access to parent directory). and call NtQueryInformationFile with FileProcessIdsUsingFileInformation. on return we got FILE_PROCESS_IDS_USING_FILE_INFORMATION structure (defined in wdm.h) where list of ProcessId which hold this file(open file handle or mapped section. say if this file is exe/dll - we got process ids where it loaded). good also with this print process name for every id:

volatile UCHAR guz = 0;

NTSTATUS PrintProcessesUsingFile(HANDLE hFile)
{
NTSTATUS status;
IO_STATUS_BLOCK iosb;

ULONG cb = 0, rcb = FIELD_OFFSET(FILE_PROCESS_IDS_USING_FILE_INFORMATION, ProcessIdList[64]);

union {
PVOID buf;
PFILE_PROCESS_IDS_USING_FILE_INFORMATION ppiufi;
};

PVOID stack = alloca(guz);

do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}

if (0 <= (status = NtQueryInformationFile(hFile, &iosb, ppiufi, cb, FileProcessIdsUsingFileInformation)))
{
if (ppiufi->NumberOfProcessIdsInList)
{
PrintProcessesUsingFile(ppiufi);
}
}

rcb = (ULONG)iosb.Information;

} while (status == STATUS_INFO_LENGTH_MISMATCH);

return status;
}

NTSTATUS PrintProcessesUsingFile(POBJECT_ATTRIBUTES poa)
{
IO_STATUS_BLOCK iosb;
HANDLE hFile;
NTSTATUS status;
if (0 <= (status = NtOpenFile(&hFile, FILE_READ_ATTRIBUTES, poa, &iosb, FILE_SHARE_VALID_FLAGS, 0)))
{
status = PrintProcessesUsingFile(hFile);
NtClose(hFile);
}

return status;
}

NTSTATUS PrintProcessesUsingFile(PCWSTR FileName)
{
UNICODE_STRING ObjectName;
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(FileName, &ObjectName, 0, 0);
if (0 <= status)
{
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
status = PrintProcessesUsingFile(&oa);
RtlFreeUnicodeString(&ObjectName);
}

return status;
}

NTSTATUS PrintProcessesUsingFile(PFILE_PROCESS_IDS_USING_FILE_INFORMATION ppiufi)
{
NTSTATUS status;

ULONG cb = 0x8000;

do
{
status = STATUS_INSUFFICIENT_RESOURCES;

if (PVOID buf = new BYTE[cb])
{
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &cb)))
{
union {
PVOID pv;
PBYTE pb;
PSYSTEM_PROCESS_INFORMATION pspi;
};

pv = buf;
ULONG NextEntryOffset = 0;

do
{
pb += NextEntryOffset;

ULONG NumberOfProcessIdsInList = ppiufi->NumberOfProcessIdsInList;

PULONG_PTR ProcessIdList = ppiufi->ProcessIdList;
do
{
if (*ProcessIdList++ == (ULONG_PTR)pspi->UniqueProcessId)
{
DbgPrint("%p %wZ\n", pspi->UniqueProcessId, &pspi->ImageName);
break;
}
} while (--NumberOfProcessIdsInList);

} while (NextEntryOffset = pspi->NextEntryOffset);
}

delete [] buf;
}

} while (status == STATUS_INFO_LENGTH_MISMATCH);

return status;
}

How do I get the file HANDLE from the fopen FILE structure?

Use _fileno followed by _get_osfhandle. Don't forget to _close it when you are done.

EDIT: it's not clear to me that _get_osfhandle is supported on WinCE. However the docs for WinCE _fileno say it returns a "file handle" rather than "descriptor". YMMV but this suggests that you can maybe just use _fileno return value directly as a handle on WinCE.

EDIT: #2 That theory is supported by this person's experience.

"If you take a look at the header files that I posted to the list on Jan 29
you can see how I handled the file creation/handle problem. I didn't have
to replace all FILE* items with HANDLEs. See the following snippet from
fileio.cpp:

#ifndef q4_WCE

FlushFileBuffers((HANDLE) _get_osfhandle(_fileno(_file)));
HANDLE h = ::CreateFileMapping((HANDLE)
_get_osfhandle(_fileno(_file)),
0, PAGE_READONLY, 0, len, 0);
#else

FlushFileBuffers((HANDLE) _fileno(_file));
HANDLE h = ::CreateFileMapping((HANDLE) _fileno(_file),
0, PAGE_READONLY, 0, len, 0);
#endif //q4_WCE

It turns out that _fileno returns a handle. You just have to cast it."

How to get a win32 handle of an open file in python?

I found the answer:

>>> msvcrt.get_osfhandle(a.fileno())
1956 # valid HANDLE

This is actually documented on http://docs.python.org/library/msvcrt.html , no idea how i missed it.

Controlling inheritability of file handles created by C++ std::fstream in Windows

The C runtime creates inheritable handles by default.

ofstream outFile("filename.txt") ;
CreateProcess("program.exe", ..., true, ...) ; //program.exe will inherit the above file handle

So, if you want a handle to be inherited, you don't need to do anything.

If you DO NOT want a handle to be inherited, you have to set the handle's HANDLE_FLAG_INHERIT flag yourself using WinAPI function SetHandleInformation, like this:

FILE* filePtr = fopen("filename.txt", "w") ;
SetHandleInformation( (HANDLE)_get_osfhandle(_fileno(filePtr)), HANDLE_FLAG_INHERIT, 0) ;
ofstream outFile(filePtr) ;

In the third line, above, the constructor ofstream(FILE*) is an extension to the standard that exists in Visual Studio (I don't know about other compilers).

After that constructor, filePtr is now owned by outFile, so calling outFile.close() closes filePtr as well. You can completely forget about the filePtr variable.

Documentation: fopen, _fileno, _get_osfhandle, SetHandleInformation

how to get the name of a file in C++ using Win32 Handle?

For XP+ you can map the file then call GetMappedFileName which will return the name (although not for directories). See Obtaining a File Name From a File Handle.



Related Topics



Leave a reply



Submit