How to open a file when file handle number is known?

試著忘記壹切 提交于 2020-01-03 05:19:35

问题


I open a file in C# with FileStream, and I got the file handle number with this line:

IntPtr file_handle = fs.SafeFileHandle.DangerousGetHandle();

Now I want to pass this handle to C++ code and use this handle value to access the file. Is this possible? How to open a file with merely a file handle in C++?

Thanks.

Update

I use C# to P/Invoke into a C++ Win32 DLL(not a COM DLL). I open the file in C# as FileStream, and pass the handle to the C++. Here is some of my code in the C++ DLL:

extern "C" __declspec(dllexport)void read_file(HANDLE file_handle)
{
    char buffer[64];
    ::printf("\nfile = %d\n",file_handle);

    if(::ReadFile(file_handle,buffer,32,NULL,NULL))
    {
        for(int i=0;i<32;i++)
            cout<<buffer[i]<<endl;
    }
    else
        cout<<"error"<<endl;
}

And here is my C# code:

    [DllImport("...",EntryPoint = "read_file", CharSet = CharSet.Auto)]
    public static extern void read_file(IntPtr file_handle_arg);

But I get this error:

Unhandled Exception: System.AccessViolationException: Attempted to read or write
 protected memory. This is often an indication that other memory is corrupt.

Thanks.


回答1:


You can use win32 calls, the same way the filestream/file constructors do (via p/invoke).

Cracking it open in .NET Reflector, it looks like it is using this function:

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern SafeFileHandle CreateFile(
  string lpFileName,
  int dwDesiredAccess,
  FileShare dwShareMode,
  SECURITY_ATTRIBUTES securityAttrs,
  FileMode dwCreationDisposition,
  int dwFlagsAndAttributes,
  IntPtr hTemplateFile);

Here is an official reference:

http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

This is just to open the file, though, as you asked when you said:

How to open a file with merely a file handle in C++

If you want to read an already open file, you might have more trouble. I'm not sure. You might be able to use this function:

[DllImport("kernel32.dll", SetLastError=true)]
internal static extern unsafe int ReadFile(
  SafeFileHandle handle,
  byte* bytes,
  int numBytesToRead,
  IntPtr numBytesRead_mustBeZero,
  NativeOverlapped* overlapped
);

http://msdn.microsoft.com/en-us/library/aa365467(v=VS.85).aspx




回答2:


That entirely depends -- but it's unlikely that you will be able to do this. I'm assuming that your C# code and C++ code are running in different processes -- if you're in the same process you should just be able to marshall over the IntPtr over as a HANDLE.

The problem is that file handles are specific to a process -- you won't be able to use that handle in another process.

That said, you're probably better off:

  • Passing the name of the file to the C++ code and opening it there
  • Passing the data actually contained whithin the file to the C++ and dealing with it there.



回答3:


If the C++ code is C++/CLI, then don't bother with the handle at all. Just pass the FileStream object directly to your C++ code.

If the C++ is native code, then you can use the file handle anywhere you'd normally use a Windows HANDLE value for files, such as ReadFile and WriteFile. You wouldn't use the handle to open a file because it's already open. If you want another copy of the handle, or if you want to give the handle to another process, then use DuplicateHandle. If you need to the value with POSIX-like functions like _read and _write, then call _open_osfhandle to get a file descriptor. You can wrap the file descriptor into a C FILE* stream with _fdopen.




回答4:


Turns out the title isn't really what the OP was after.

But if someone ever really needs to do this (say: Re-opening a file with different permissions), you can probably use a combination of GetFileInformationByHandle to get the File ID and OpenFileById.

FWIW.



来源:https://stackoverflow.com/questions/3562513/how-to-open-a-file-when-file-handle-number-is-known

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!