.NET Framework Bookmark and Share   
 index > 64-Bit .NET Framework Development > Reasons Why API Returns on 32-bit Systems, but not 64-bit
 

Reasons Why API Returns on 32-bit Systems, but not 64-bit

Hello,

I have an unmanaged API function and it's working great, just like it's suppose to return values. However, the API function only seems to be returning Strings in 32-bit versions of Windows. If I use the exact same API function and same code for calling the functions, it fails to return a String back in 64-bit Windows, even if I compile it with VS2008 on the 64-bit machine.The32-bit computer is Vista (NT 6), the 64-bit is Windows Server 2008 (NT 6). What are some possible reasons of why an API can return on one system, but not the other?

Regards,
Adjutor
Adjutor

Hi Adjutor,

Maybe, the unmanaged API is not supported in 64-bit machine. However, a 32-bit application can run under WOW64 mode on 64-bit machine.

In order to make your 32-bit application work on a 64 bit system, the processor must be an X86.

Thus, please try the following settings:

Go to Project menu -> Properties -> Compile tab -> Select "Advanced Compile Options" -> Select "x86" instead of "AnyCPU"

Or go toBuild menu -> Configuration Manager -> Change Build Platform to X86.
Then it will compile your project for 32-bit platform.
Case:
http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/22a7474c-b54d-4be0-928b-acc8b0a5a091


WOW64 is the x86 emulator that allows 32-bit Windows-based applications to run seamlessly on 64-bit Windows.
Tutorial: http://msdn.microsoft.com/en-us/library/aa384249(VS.85).aspx


FAQ: Can I run 32-bit programs on a 64-bit computer?
Most programs designed for a computer running a 32-bit version of Windows will work on a computer running 64-bit versions of Windows. Notable exceptions are many antivirus programs, and some hardware drivers.

Drivers designed for 32-bit versions of Windows do not work on computers running a 64-bit version of Windows. If you're trying to install a printer or other device that only has 32-bit drivers available, it won't work correctly on a 64-bit version of Windows. If you are unsure whether there is a 64-bit driver available for your device, go online to the Windows Vista Compatibility Center.
Check this link about more 32-bit and 64-bit FAQs:
http://windowshelp.microsoft.com/Windows/en-US/help/41531554-d5ef-4f2c-8fb9-149bdc5c8a701033.mspx


Best regards,
Martin Xie


Please remember to mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback on our support, please contact msdnmg@microsoft.com
Martin Xie - MSFT
Hello Martin!,

Thank you for the reply. I tried "Go to Project menu -> Properties -> Compile tab -> Select "Advanced Compile Options" -> Select "x86" instead of "AnyCPU"", doing this made the application get the returned values with API on x64! However, let's say I want this to be a 64-bit specific application, can I make my API work then? The API flag I am using is "LVM_GETITEMTEXT", is this x86 only?

Regards,
Adjutor
Adjutor
That requires a declaration for the LVITEM structure. You probably got it wrong, pointers are 8 bytes instead of 4 on x64. Post your code.

Hans Passant.
nobugz
Hello nobugz!,

Thanks for the reply. Here is the code that I am using, it adds the text from a ListView into a TextBox named "info":

Private Sub GetListViewText(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim subitem As Integer

        listviewHandle = Int32.Parse(txtHandle.Text)

        Dim itemCount As Integer = SendMessage(listviewHandle, LVM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero)
        ' Aquire the amount of rows in the listview
        Dim headerhandle As IntPtr = SendMessage(listviewHandle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero)
        ' Aquire the handle of the listviews header
        Dim coloumcount As Integer = SendMessage(headerhandle, HDM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero)
        ' Aquire the amount of coloumns in the listview header

        Dim id As Integer = -1
        Dim p As Process

        For Each p In Process.GetProcessesByName("testapplication")
            id = p.Id
        Next

        Dim hProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE Or &H8, False, id)
        For index As Integer = 0 To itemCount - 1
            ' For each of the rows do the following :
            For subitem = 0 To coloumcount
                ' For each of the columns do the following :

                Dim lvi As New LV_ITEM
                lvi.cchTextMax = 260
                lvi.iSubItem = subitem
                lvi.mask = 1
                lvi.iItem = index
                Dim pString As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, 260, MEM_COMMIT, PAGE_READWRITE)
                lvi.pszText = pString
                Dim pLvItem As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, Marshal.SizeOf(lvi), MEM_COMMIT, PAGE_READWRITE)
                Dim success As Boolean = WriteProcessMemory(hProcess, pLvItem, lvi, Marshal.SizeOf(lvi), 0)
                Dim result As Integer = SendMessage(listviewHandle, LVM_GETITEMTEXT, index, pLvItem)
                Dim s As New StringBuilder(260)
                success = ReadProcessMemory(hProcess, pString, s, 260, 0)
                success = ReadProcessMemory(hProcess, pLvItem, lvi, Marshal.SizeOf(lvi), 0)
                success = VirtualFreeEx(hProcess, pString, 0, MEM_RELEASE)
                success = VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE)
                s.AppendLine()
                info.AppendText(s.ToString)

            Next

        Next

        CloseHandle(hProcess)

    End Sub
Regards,
Adjutor
Adjutor
You didn't post the crucial LVITEM declaration. Hacking an old 32-bit program like this with 64-bit code is kinda pointless and cannot work. You are not finding out because you do no error checking at all.

Hans Passant.
nobugz
Hello nobugz,

Alright, I'll post the LV_ITEM declaration:

 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> _
    Public Structure LV_ITEM
        Public mask As UInteger
        Public iItem As Integer
        Public iSubItem As Integer
        Public state As UInteger
        Public stateMask As UInteger
        Public pszText As IntPtr
        Public cchTextMax As Integer
        Public iImage As Integer
        Public lParam As IntPtr
        Public iIndent As Integer
        Public iGroupId As Integer
        Public cColumns As Integer
        Public puColumns As IntPtr
        Public piColFmt As IntPtr
        Public iGroup As Integer
    End Structure
I am not sure how it's "pointless", I need to view text on external application's ListView. If you have a suggestion of a better approach, then please say.

Regards,
Adjutor
Adjutor
It's okay. Check the return value of VirtualAllocEx(), it is probably zero.

Hans Passant.
nobugz
Hello,

Alright, I just checked the return values of both VirtualAllocEx() on lines pString and pLvItem. Both lines I get a value that is greater than 0, in the thousands.

Regards,
Adjutor
Adjutor
Hello nobugz,

Could this be an error in the 64-bit API? I stepped through each line today and it seems I do get valid pointer addresses returned. Does my LV_ITEM Structure need to be changed with Int64's?

Regards,
Adjutor
Adjutor
You shot down ever theory I had, I have none left. Why exactly does this need to be an x64 program?

Hans Passant.
nobugz
Hello nobugz,

The computer that will be running this application is an x64 computer. I could of course compile as a 32-bit application using the WOW64 emulation method of 64-bit Windows as Martin suggested, but I just don't see why an API function that is suppose to be universal across Windows platforms would fail. It seemsI have found a bug in 64-bit API:).

Regards,
Adjutor
Adjutor
Hello nobugz,

Is there anyone else that might know why I get empty Strings back as a returned value?

Regards,
Adjutor
Adjutor

You can use google to search for other answers

Custom Search

More Threads

• COM+ export problem on Windows Server 2003 (64-bit)
• remoted tier dependancies in 64 bit
• .Net 2.0 with Windows 2003 Server
• Plans for supporting .NET v3.5 on Itanium 64-bit machines?
• App config setting to force 32 bit execution for .Net 2.0 apps
• Sending Email is Failuring by Using System.Net.mail
• Corflags /32bit+ with a network account on windows service always runs as 64bit
• Installer for pocket PC
• MODI and .NET 2.0 on Itanium 2
• Difficulty installing asp.net 2.0 ajax