SafeHandle vs IntPtr in WinAPIs and CloseHandle in C#
up vote
2
down vote
favorite
I read many articles about SafeHandle
and IDiposable
but I still don't understand whether I should use SafeHandle and CloseHandle or not in C#.
MSDN SafeHandle example
IntPtr, SafeHandle and HandleRef - Explained
https://blog.benoitblanchon.fr/safehandle/.
The first source is similar to my question but however it doesn't answer my question.
Let's say I have the following 3 different examples that I got from Internet:
// Example 1
byte temp = new byte[IntPtr.Size];
fixed (byte* p = temp)
{
IntPtr SectionHandle = new IntPtr(p);
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
SectionHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
}
// Example 2
IntPtr hFile = CreateFile(
path,
GenericRights.GENERIC_READ,
FileFlags.FILE_SHARE_DELETE | FileFlags.FILE_SHARE_READ | FileFlags.FILE_SHARE_WRITE,
IntPtr.Zero,
FileCreationFlags.OPEN_EXISTING,
FileFlags.FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hFile == INVALID_HANDLE_VALUE)
return false;
// Example 3
IntPtr hMap = CreateFileMapping(
hFile,
IntPtr.Zero,
MemoryProtectionConstants.PAGE_READONLY,
0,
0,
IntPtr.Zero);
if (hMap == IntPtr.Zero)
return false;
The examples are Windows APIs, so they are unmanaged. What I don't get is:
1) Should the all 3 examples use SafeHandle over IntPtr because they are unmanaged and if one of them shouldn't, why?
2) I find CloseHandle for a good practice in C/C++ but in C# I don't know if the Garbage Collector closes the handle automatically in the end? Should CloseHandle be used in the above examples and why?
3) The first example uses an unmanaged byte*
to allocate memory on the heap. Can this procedure be done by not using unmanaged pointer? The code below is my guess, what do you think about it?
IntPtr SectionHandle = Marshal.AllocateHGlobal(sizeof(int));
... code ...
Marshal.FreeHGlobal(SectionHandle);
Edit:
Posting the code I edited:
[SecurityCritical]
public sealed class SafeHandleBuffer : SafeBuffer
{
public SafeHandleBuffer()
: base(true)
{
handle = Marshal.AllocHGlobal(IntPtr.Size);
}
public int GetValue() =>
Marshal.ReadInt32(handle);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
return true;
}
}
public sealed class SafeHandleToken : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeHandleToken()
: base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle() =>
CloseHandle(handle);
}
// Including the IDisposable implementation in the class where the next example calls are found
private SafeHandleToken _fileHandle, _mappingHandle;
private SafeHandleBuffer _sectionHandle;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected virtual void Dispose(bool disposing)
{
if (_fileHandle != null && !_fileHandle.IsInvalid)
{
_fileHandle.Dispose();
}
if (_mappingHandle != null && !_mappingHandle.IsInvalid)
{
_mappingHandle.Dispose();
}
if (_sectionHandle != null && !_sectionHandle.IsInvalid)
{
_sectionHandle.Dispose();
}
}
// Example 1
SafeHandleBuffer tempHandle = new SafeHandleBuffer();
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
tempHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
// Example 2
SafeHandleToken tempHandle = CreateFile(
path,
GenericRights.GENERIC_READ,
FileShare.ReadWrite | FileShare.Delete,
IntPtr.Zero,
FileMode.Open,
FileAttributes.Normal,
IntPtr.Zero);
Thread.Sleep(500);
_fileHandle = tempHandle;
if (_fileHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Example 3
tempHandle = CreateFileMapping(
_fileHandle,
IntPtr.Zero,
(uint)MemoryProtectionConstants.PAGE_READONLY | (uint)AllocationTypes.SEC_IMAGE,
0,
0,
IntPtr.Zero);
Thread.Sleep(500);
_mappingHandle = tempHandle;
if (_mappingHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
Do you think I did everything alright? Should SafeHandle
be used on every Windows API like GetModuleHandle
, GetProcAddress
, MapViewOfFile
and some more I don't remember right now. Some of them are returning LPVOID
.
c# intptr safehandle
|
show 2 more comments
up vote
2
down vote
favorite
I read many articles about SafeHandle
and IDiposable
but I still don't understand whether I should use SafeHandle and CloseHandle or not in C#.
MSDN SafeHandle example
IntPtr, SafeHandle and HandleRef - Explained
https://blog.benoitblanchon.fr/safehandle/.
The first source is similar to my question but however it doesn't answer my question.
Let's say I have the following 3 different examples that I got from Internet:
// Example 1
byte temp = new byte[IntPtr.Size];
fixed (byte* p = temp)
{
IntPtr SectionHandle = new IntPtr(p);
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
SectionHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
}
// Example 2
IntPtr hFile = CreateFile(
path,
GenericRights.GENERIC_READ,
FileFlags.FILE_SHARE_DELETE | FileFlags.FILE_SHARE_READ | FileFlags.FILE_SHARE_WRITE,
IntPtr.Zero,
FileCreationFlags.OPEN_EXISTING,
FileFlags.FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hFile == INVALID_HANDLE_VALUE)
return false;
// Example 3
IntPtr hMap = CreateFileMapping(
hFile,
IntPtr.Zero,
MemoryProtectionConstants.PAGE_READONLY,
0,
0,
IntPtr.Zero);
if (hMap == IntPtr.Zero)
return false;
The examples are Windows APIs, so they are unmanaged. What I don't get is:
1) Should the all 3 examples use SafeHandle over IntPtr because they are unmanaged and if one of them shouldn't, why?
2) I find CloseHandle for a good practice in C/C++ but in C# I don't know if the Garbage Collector closes the handle automatically in the end? Should CloseHandle be used in the above examples and why?
3) The first example uses an unmanaged byte*
to allocate memory on the heap. Can this procedure be done by not using unmanaged pointer? The code below is my guess, what do you think about it?
IntPtr SectionHandle = Marshal.AllocateHGlobal(sizeof(int));
... code ...
Marshal.FreeHGlobal(SectionHandle);
Edit:
Posting the code I edited:
[SecurityCritical]
public sealed class SafeHandleBuffer : SafeBuffer
{
public SafeHandleBuffer()
: base(true)
{
handle = Marshal.AllocHGlobal(IntPtr.Size);
}
public int GetValue() =>
Marshal.ReadInt32(handle);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
return true;
}
}
public sealed class SafeHandleToken : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeHandleToken()
: base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle() =>
CloseHandle(handle);
}
// Including the IDisposable implementation in the class where the next example calls are found
private SafeHandleToken _fileHandle, _mappingHandle;
private SafeHandleBuffer _sectionHandle;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected virtual void Dispose(bool disposing)
{
if (_fileHandle != null && !_fileHandle.IsInvalid)
{
_fileHandle.Dispose();
}
if (_mappingHandle != null && !_mappingHandle.IsInvalid)
{
_mappingHandle.Dispose();
}
if (_sectionHandle != null && !_sectionHandle.IsInvalid)
{
_sectionHandle.Dispose();
}
}
// Example 1
SafeHandleBuffer tempHandle = new SafeHandleBuffer();
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
tempHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
// Example 2
SafeHandleToken tempHandle = CreateFile(
path,
GenericRights.GENERIC_READ,
FileShare.ReadWrite | FileShare.Delete,
IntPtr.Zero,
FileMode.Open,
FileAttributes.Normal,
IntPtr.Zero);
Thread.Sleep(500);
_fileHandle = tempHandle;
if (_fileHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Example 3
tempHandle = CreateFileMapping(
_fileHandle,
IntPtr.Zero,
(uint)MemoryProtectionConstants.PAGE_READONLY | (uint)AllocationTypes.SEC_IMAGE,
0,
0,
IntPtr.Zero);
Thread.Sleep(500);
_mappingHandle = tempHandle;
if (_mappingHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
Do you think I did everything alright? Should SafeHandle
be used on every Windows API like GetModuleHandle
, GetProcAddress
, MapViewOfFile
and some more I don't remember right now. Some of them are returning LPVOID
.
c# intptr safehandle
Please always useSafeHandle
in C#. This is the most safe way. Only fall back to unmanaged if it's impossible to use managed API for some reasons. The GC will not close any handles, they will leak if you don't close them.
– dymanoid
Nov 8 at 10:07
Nobody should ever write code like this, already covered by FileStream and MemoryMappedFile. The first snippet is particularly nonsensical, the author did not know how to declare the function correctly. Delete them from your disk/browser cache so they can do no further harm.
– Hans Passant
Nov 8 at 10:08
Does that mean even APIs likeGetModuleHandle
,GetProcAddress
,MapViewOfFile
, etc. that can't beCloseHandle
'd, should be returningSafeHandle
as well? Edit: They basically return also anIntPtr
but not a handle that can be closed. And is_handle.DangerousGetHandle()
safe because let's say I want to have operations like addition, subtraction?
– J. Smith
Nov 8 at 13:54
Cannot edit previous comment. Actually,MapViewOfFile
returnsLPVOID
, does that mean thatSafeHandle
is not useful for it? Does SafeHandle only include handles that can be closed withCloseHandle
such as CreateFile, CreateFileMapping and some more that I don't remember right now.
– J. Smith
Nov 8 at 14:07
Edited my initial post with the code I could manage to edit. The previous questions still remain.
– J. Smith
Nov 8 at 16:22
|
show 2 more comments
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I read many articles about SafeHandle
and IDiposable
but I still don't understand whether I should use SafeHandle and CloseHandle or not in C#.
MSDN SafeHandle example
IntPtr, SafeHandle and HandleRef - Explained
https://blog.benoitblanchon.fr/safehandle/.
The first source is similar to my question but however it doesn't answer my question.
Let's say I have the following 3 different examples that I got from Internet:
// Example 1
byte temp = new byte[IntPtr.Size];
fixed (byte* p = temp)
{
IntPtr SectionHandle = new IntPtr(p);
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
SectionHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
}
// Example 2
IntPtr hFile = CreateFile(
path,
GenericRights.GENERIC_READ,
FileFlags.FILE_SHARE_DELETE | FileFlags.FILE_SHARE_READ | FileFlags.FILE_SHARE_WRITE,
IntPtr.Zero,
FileCreationFlags.OPEN_EXISTING,
FileFlags.FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hFile == INVALID_HANDLE_VALUE)
return false;
// Example 3
IntPtr hMap = CreateFileMapping(
hFile,
IntPtr.Zero,
MemoryProtectionConstants.PAGE_READONLY,
0,
0,
IntPtr.Zero);
if (hMap == IntPtr.Zero)
return false;
The examples are Windows APIs, so they are unmanaged. What I don't get is:
1) Should the all 3 examples use SafeHandle over IntPtr because they are unmanaged and if one of them shouldn't, why?
2) I find CloseHandle for a good practice in C/C++ but in C# I don't know if the Garbage Collector closes the handle automatically in the end? Should CloseHandle be used in the above examples and why?
3) The first example uses an unmanaged byte*
to allocate memory on the heap. Can this procedure be done by not using unmanaged pointer? The code below is my guess, what do you think about it?
IntPtr SectionHandle = Marshal.AllocateHGlobal(sizeof(int));
... code ...
Marshal.FreeHGlobal(SectionHandle);
Edit:
Posting the code I edited:
[SecurityCritical]
public sealed class SafeHandleBuffer : SafeBuffer
{
public SafeHandleBuffer()
: base(true)
{
handle = Marshal.AllocHGlobal(IntPtr.Size);
}
public int GetValue() =>
Marshal.ReadInt32(handle);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
return true;
}
}
public sealed class SafeHandleToken : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeHandleToken()
: base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle() =>
CloseHandle(handle);
}
// Including the IDisposable implementation in the class where the next example calls are found
private SafeHandleToken _fileHandle, _mappingHandle;
private SafeHandleBuffer _sectionHandle;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected virtual void Dispose(bool disposing)
{
if (_fileHandle != null && !_fileHandle.IsInvalid)
{
_fileHandle.Dispose();
}
if (_mappingHandle != null && !_mappingHandle.IsInvalid)
{
_mappingHandle.Dispose();
}
if (_sectionHandle != null && !_sectionHandle.IsInvalid)
{
_sectionHandle.Dispose();
}
}
// Example 1
SafeHandleBuffer tempHandle = new SafeHandleBuffer();
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
tempHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
// Example 2
SafeHandleToken tempHandle = CreateFile(
path,
GenericRights.GENERIC_READ,
FileShare.ReadWrite | FileShare.Delete,
IntPtr.Zero,
FileMode.Open,
FileAttributes.Normal,
IntPtr.Zero);
Thread.Sleep(500);
_fileHandle = tempHandle;
if (_fileHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Example 3
tempHandle = CreateFileMapping(
_fileHandle,
IntPtr.Zero,
(uint)MemoryProtectionConstants.PAGE_READONLY | (uint)AllocationTypes.SEC_IMAGE,
0,
0,
IntPtr.Zero);
Thread.Sleep(500);
_mappingHandle = tempHandle;
if (_mappingHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
Do you think I did everything alright? Should SafeHandle
be used on every Windows API like GetModuleHandle
, GetProcAddress
, MapViewOfFile
and some more I don't remember right now. Some of them are returning LPVOID
.
c# intptr safehandle
I read many articles about SafeHandle
and IDiposable
but I still don't understand whether I should use SafeHandle and CloseHandle or not in C#.
MSDN SafeHandle example
IntPtr, SafeHandle and HandleRef - Explained
https://blog.benoitblanchon.fr/safehandle/.
The first source is similar to my question but however it doesn't answer my question.
Let's say I have the following 3 different examples that I got from Internet:
// Example 1
byte temp = new byte[IntPtr.Size];
fixed (byte* p = temp)
{
IntPtr SectionHandle = new IntPtr(p);
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
SectionHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
}
// Example 2
IntPtr hFile = CreateFile(
path,
GenericRights.GENERIC_READ,
FileFlags.FILE_SHARE_DELETE | FileFlags.FILE_SHARE_READ | FileFlags.FILE_SHARE_WRITE,
IntPtr.Zero,
FileCreationFlags.OPEN_EXISTING,
FileFlags.FILE_ATTRIBUTE_NORMAL,
IntPtr.Zero);
if (hFile == INVALID_HANDLE_VALUE)
return false;
// Example 3
IntPtr hMap = CreateFileMapping(
hFile,
IntPtr.Zero,
MemoryProtectionConstants.PAGE_READONLY,
0,
0,
IntPtr.Zero);
if (hMap == IntPtr.Zero)
return false;
The examples are Windows APIs, so they are unmanaged. What I don't get is:
1) Should the all 3 examples use SafeHandle over IntPtr because they are unmanaged and if one of them shouldn't, why?
2) I find CloseHandle for a good practice in C/C++ but in C# I don't know if the Garbage Collector closes the handle automatically in the end? Should CloseHandle be used in the above examples and why?
3) The first example uses an unmanaged byte*
to allocate memory on the heap. Can this procedure be done by not using unmanaged pointer? The code below is my guess, what do you think about it?
IntPtr SectionHandle = Marshal.AllocateHGlobal(sizeof(int));
... code ...
Marshal.FreeHGlobal(SectionHandle);
Edit:
Posting the code I edited:
[SecurityCritical]
public sealed class SafeHandleBuffer : SafeBuffer
{
public SafeHandleBuffer()
: base(true)
{
handle = Marshal.AllocHGlobal(IntPtr.Size);
}
public int GetValue() =>
Marshal.ReadInt32(handle);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle()
{
Marshal.FreeHGlobal(handle);
return true;
}
}
public sealed class SafeHandleToken : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeHandleToken()
: base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle() =>
CloseHandle(handle);
}
// Including the IDisposable implementation in the class where the next example calls are found
private SafeHandleToken _fileHandle, _mappingHandle;
private SafeHandleBuffer _sectionHandle;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
protected virtual void Dispose(bool disposing)
{
if (_fileHandle != null && !_fileHandle.IsInvalid)
{
_fileHandle.Dispose();
}
if (_mappingHandle != null && !_mappingHandle.IsInvalid)
{
_mappingHandle.Dispose();
}
if (_sectionHandle != null && !_sectionHandle.IsInvalid)
{
_sectionHandle.Dispose();
}
}
// Example 1
SafeHandleBuffer tempHandle = new SafeHandleBuffer();
LARGE_INTEGER MaximumSize = new LARGE_INTEGER();
MaximumSize.LowPart = pNTHeader->OptionalHeader.SizeOfImage;
status = NtCreateSection(
tempHandle,
SectionAccess.SECTION_MAP_EXECUTE | SectionAccess.SECTION_MAP_READ | SectionAccess.SECTION_MAP_WRITE,
IntPtr.Zero,
ref MaximumSize,
MemoryProtectionConstants.PAGE_EXECUTE_READWRITE,
AllocationTypes.SEC_COMMIT,
IntPtr.Zero);
// Example 2
SafeHandleToken tempHandle = CreateFile(
path,
GenericRights.GENERIC_READ,
FileShare.ReadWrite | FileShare.Delete,
IntPtr.Zero,
FileMode.Open,
FileAttributes.Normal,
IntPtr.Zero);
Thread.Sleep(500);
_fileHandle = tempHandle;
if (_fileHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
// Example 3
tempHandle = CreateFileMapping(
_fileHandle,
IntPtr.Zero,
(uint)MemoryProtectionConstants.PAGE_READONLY | (uint)AllocationTypes.SEC_IMAGE,
0,
0,
IntPtr.Zero);
Thread.Sleep(500);
_mappingHandle = tempHandle;
if (_mappingHandle.IsInvalid)
throw new Win32Exception(Marshal.GetLastWin32Error());
Do you think I did everything alright? Should SafeHandle
be used on every Windows API like GetModuleHandle
, GetProcAddress
, MapViewOfFile
and some more I don't remember right now. Some of them are returning LPVOID
.
c# intptr safehandle
c# intptr safehandle
edited Nov 8 at 16:20
asked Nov 8 at 9:26
J. Smith
2116
2116
Please always useSafeHandle
in C#. This is the most safe way. Only fall back to unmanaged if it's impossible to use managed API for some reasons. The GC will not close any handles, they will leak if you don't close them.
– dymanoid
Nov 8 at 10:07
Nobody should ever write code like this, already covered by FileStream and MemoryMappedFile. The first snippet is particularly nonsensical, the author did not know how to declare the function correctly. Delete them from your disk/browser cache so they can do no further harm.
– Hans Passant
Nov 8 at 10:08
Does that mean even APIs likeGetModuleHandle
,GetProcAddress
,MapViewOfFile
, etc. that can't beCloseHandle
'd, should be returningSafeHandle
as well? Edit: They basically return also anIntPtr
but not a handle that can be closed. And is_handle.DangerousGetHandle()
safe because let's say I want to have operations like addition, subtraction?
– J. Smith
Nov 8 at 13:54
Cannot edit previous comment. Actually,MapViewOfFile
returnsLPVOID
, does that mean thatSafeHandle
is not useful for it? Does SafeHandle only include handles that can be closed withCloseHandle
such as CreateFile, CreateFileMapping and some more that I don't remember right now.
– J. Smith
Nov 8 at 14:07
Edited my initial post with the code I could manage to edit. The previous questions still remain.
– J. Smith
Nov 8 at 16:22
|
show 2 more comments
Please always useSafeHandle
in C#. This is the most safe way. Only fall back to unmanaged if it's impossible to use managed API for some reasons. The GC will not close any handles, they will leak if you don't close them.
– dymanoid
Nov 8 at 10:07
Nobody should ever write code like this, already covered by FileStream and MemoryMappedFile. The first snippet is particularly nonsensical, the author did not know how to declare the function correctly. Delete them from your disk/browser cache so they can do no further harm.
– Hans Passant
Nov 8 at 10:08
Does that mean even APIs likeGetModuleHandle
,GetProcAddress
,MapViewOfFile
, etc. that can't beCloseHandle
'd, should be returningSafeHandle
as well? Edit: They basically return also anIntPtr
but not a handle that can be closed. And is_handle.DangerousGetHandle()
safe because let's say I want to have operations like addition, subtraction?
– J. Smith
Nov 8 at 13:54
Cannot edit previous comment. Actually,MapViewOfFile
returnsLPVOID
, does that mean thatSafeHandle
is not useful for it? Does SafeHandle only include handles that can be closed withCloseHandle
such as CreateFile, CreateFileMapping and some more that I don't remember right now.
– J. Smith
Nov 8 at 14:07
Edited my initial post with the code I could manage to edit. The previous questions still remain.
– J. Smith
Nov 8 at 16:22
Please always use
SafeHandle
in C#. This is the most safe way. Only fall back to unmanaged if it's impossible to use managed API for some reasons. The GC will not close any handles, they will leak if you don't close them.– dymanoid
Nov 8 at 10:07
Please always use
SafeHandle
in C#. This is the most safe way. Only fall back to unmanaged if it's impossible to use managed API for some reasons. The GC will not close any handles, they will leak if you don't close them.– dymanoid
Nov 8 at 10:07
Nobody should ever write code like this, already covered by FileStream and MemoryMappedFile. The first snippet is particularly nonsensical, the author did not know how to declare the function correctly. Delete them from your disk/browser cache so they can do no further harm.
– Hans Passant
Nov 8 at 10:08
Nobody should ever write code like this, already covered by FileStream and MemoryMappedFile. The first snippet is particularly nonsensical, the author did not know how to declare the function correctly. Delete them from your disk/browser cache so they can do no further harm.
– Hans Passant
Nov 8 at 10:08
Does that mean even APIs like
GetModuleHandle
, GetProcAddress
, MapViewOfFile
, etc. that can't be CloseHandle
'd, should be returning SafeHandle
as well? Edit: They basically return also an IntPtr
but not a handle that can be closed. And is _handle.DangerousGetHandle()
safe because let's say I want to have operations like addition, subtraction?– J. Smith
Nov 8 at 13:54
Does that mean even APIs like
GetModuleHandle
, GetProcAddress
, MapViewOfFile
, etc. that can't be CloseHandle
'd, should be returning SafeHandle
as well? Edit: They basically return also an IntPtr
but not a handle that can be closed. And is _handle.DangerousGetHandle()
safe because let's say I want to have operations like addition, subtraction?– J. Smith
Nov 8 at 13:54
Cannot edit previous comment. Actually,
MapViewOfFile
returns LPVOID
, does that mean that SafeHandle
is not useful for it? Does SafeHandle only include handles that can be closed with CloseHandle
such as CreateFile, CreateFileMapping and some more that I don't remember right now.– J. Smith
Nov 8 at 14:07
Cannot edit previous comment. Actually,
MapViewOfFile
returns LPVOID
, does that mean that SafeHandle
is not useful for it? Does SafeHandle only include handles that can be closed with CloseHandle
such as CreateFile, CreateFileMapping and some more that I don't remember right now.– J. Smith
Nov 8 at 14:07
Edited my initial post with the code I could manage to edit. The previous questions still remain.
– J. Smith
Nov 8 at 16:22
Edited my initial post with the code I could manage to edit. The previous questions still remain.
– J. Smith
Nov 8 at 16:22
|
show 2 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53204780%2fsafehandle-vs-intptr-in-winapis-and-closehandle-in-c-sharp%23new-answer', 'question_page');
}
);
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Please always use
SafeHandle
in C#. This is the most safe way. Only fall back to unmanaged if it's impossible to use managed API for some reasons. The GC will not close any handles, they will leak if you don't close them.– dymanoid
Nov 8 at 10:07
Nobody should ever write code like this, already covered by FileStream and MemoryMappedFile. The first snippet is particularly nonsensical, the author did not know how to declare the function correctly. Delete them from your disk/browser cache so they can do no further harm.
– Hans Passant
Nov 8 at 10:08
Does that mean even APIs like
GetModuleHandle
,GetProcAddress
,MapViewOfFile
, etc. that can't beCloseHandle
'd, should be returningSafeHandle
as well? Edit: They basically return also anIntPtr
but not a handle that can be closed. And is_handle.DangerousGetHandle()
safe because let's say I want to have operations like addition, subtraction?– J. Smith
Nov 8 at 13:54
Cannot edit previous comment. Actually,
MapViewOfFile
returnsLPVOID
, does that mean thatSafeHandle
is not useful for it? Does SafeHandle only include handles that can be closed withCloseHandle
such as CreateFile, CreateFileMapping and some more that I don't remember right now.– J. Smith
Nov 8 at 14:07
Edited my initial post with the code I could manage to edit. The previous questions still remain.
– J. Smith
Nov 8 at 16:22