0

I have the following code used to create a valid handle using CreateFile working on a 32 bit XP OS. When testing the same code on a 64 bit Vista and Windows 7 computer, CreateFile returns an invalid handle value. I can not seem to figure out what is going on.

Here is the dll import:

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateFile(
     string FileName,
     uint DesiredAccess,
     uint ShareMode,
     IntPtr SecurityAttributes,
     uint CreationDisposition,
     uint FlagsAndAttributes,
     IntPtr hTemplateFile
     );

And the call:

drive = CreateFile(devicePath,
           GENERIC_READ | GENERIC_WRITE,
           FILE_SHARE_READ | FILE_SHARE_WRITE,
           IntPtr.Zero,
           OPEN_EXISTING,
           FILE_FLAG_DELETE_ON_CLOSE,
           IntPtr.Zero);

devicePath is a valid path to the usb. This returns a valid handle on a 32 bit OS and an invalid value on a 64 bit OS. I have searched and searched and found nothing. If anyone could help or share some information I would be thankful. Regards.

PhilMY
  • 2,621
  • 21
  • 29
daniel
  • 75
  • 2
  • 9
  • @pstrjds Compiling for x86 is the opposite of what he should be doing. `CreateFile` returns `HANDLE`, which is `PVOID`, also known as `void*`. On a 64-bit OS, the returned value should be 64-bit. – Polynomial Aug 01 '12 at 15:37
  • @Polynomial - Yeah, I realized that I had inverted my logics after I typed it, which is why I deleted my comment :) – pstrjds Aug 01 '12 at 15:49
  • In the 64 bit OS when you are getting a -1, have you checked what the last error was. Maybe you are running into some UAC permission type issue on your 64 bit OS. – pstrjds Aug 01 '12 at 15:56
  • that seems to be the case, thank you. I get error code 5, access denied – daniel Aug 01 '12 at 16:09

2 Answers2

2

Verify that you're compiling for AnyCPU. If you compilation target is x86, you'll have 32-bit IntPtr types on both 32-bit and 64-bit operating systems. Compiling for AnyCPU allows the IntPtr data type to reflect the size of a pointer.

The CreateFile API returns HANDLE, which is an alias for PVOID (a.k.a. void*), so it'll be 64 bits long on a 64-bit OS, and 32 bits long on a 32-bit OS.

When you compile for x86, the code expects a 32-bit value to be returned by the API. Since it's actually 64-bit, you lose half of it, giving you an invalid pointer.

Community
  • 1
  • 1
Polynomial
  • 27,674
  • 12
  • 80
  • 107
0

It's worth mentioning (since so many people get it wrong) that on 64-bit Windows, handles may safely be truncated to 32 bits.

This allows the handles to be compatible with 32-bit applications (but not 16-bit applications) without special "handle transform" thunking.

Going the other way, truncated 32 bit handles may be safely sign extended to 64 bits. (The invalid handle -1 must by sign extended)

MSDN "Running 32-bit Applications" "handles have 32 significant bits on 64-bit Windows."

david
  • 2,435
  • 1
  • 21
  • 33