1

I'm trying to use the code from the most popular answer to this question: Using C#, how does one figure out what process locked a file?

I'm testing this code in Windows 7 x64 using VS2010 and .NET v4.

I'm finding that the code excerpt...

var baTemp = new byte[nLength];
try
{
    Marshal.Copy(ipTemp, baTemp, 0, nLength);
    strObjectName = Marshal.PtrToStringUni(Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()));
}
catch (AccessViolationException)
{
    return null;
}
finally
{
    Marshal.FreeHGlobal(ipObjectName);
    Win32API.CloseHandle(ipHandle);
}

is what is causing my problems. The Marshal.Copy can fail when the address created earlier is not valid. The code creating the address in x64 systems...

if (Is64Bits())
{
    ipTemp = new IntPtr(Convert.ToInt64(objObjectName.Name.Buffer.ToString(), 10) >> 32);
}

in one instance of my noted failures starts with a buffer string representation of 20588995036390572032 that translates to x1C92AA2089E00000. The code appears to strip the low order word leaving x1C92AA20 as the usaable address.

Question 1: Why would we not simply use the 64bit address provided by the buffer object rather than shift out the low order word and use just the high order word in a 64bit app running on a 64bit OS?

Question 2: Should the try/catch/finally block include more than just AccessViolationException?

Community
  • 1
  • 1
  • `ipTemp` is already an `IntPtr`. This `Is64Bits() ? new IntPtr(ipTemp.ToInt64()) : new IntPtr(ipTemp.ToInt32()` is useless. Simply use `ipTemp` – xanatos Aug 08 '13 at 15:54
  • If its cutting off 89E0000 thats seems to indicate the address being return is 32-bit instead of 64-bit. Verify the system is 32-bit or 64-bit BEFORE you attempt do a copy..The accepted answer actually does this. – Security Hound Aug 08 '13 at 16:03
  • The original code seems to be buggy even on 32 bits... On Win8 64 (but the program is in 32bit mode) once every three times it crashes in Visual Studio... At 64 bits it crashes every time – xanatos Aug 08 '13 at 16:04
  • Object_Pointer is for example wrong. It should be a PVOID, so an IntPtr, not an int – xanatos Aug 08 '13 at 16:06

1 Answers1

0

Read the comments on that article. Unworkable code. Doesn't work. Don't use. Even the "suggested" corrected version is broken (and it doesn't work on my Win8 64bits) and in the words of its author:

The following was produced based on Iain Ballard's code dump. It is broken: it will occasionally lock up when you retrieve the handle name. This code doesn't contain any work-arounds for that issue, and .NET leaves few options: Thread.Abort can no longer abort a thread that's currently in a native method.

Community
  • 1
  • 1
xanatos
  • 109,618
  • 12
  • 197
  • 280