The MASM Forum

General => The Workshop => Topic started by: jimg on February 11, 2013, 04:09:57 PM

Title: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 11, 2013, 04:09:57 PM
I stopped programming a few years ago for various reasons, but now I am trying to get an old program of mine working.  It works on windows XP, but I cannot figure out how to get it to work on Windows 7, 64 bit.

The attached test code was extracted from the program I'm trying to fix.  It finds the windows desktop listview, and prints out the position and caption of each item on the desktop.  On Windows 7 64bit, it prints the correct handles as determined by winspy, and the correct number of icons, and their correct positions, so I'm fairly sure I'm finding the listview properly, but for some reason LVM_GETITEMTEXT always return zero.

This is a console program.

Any help with this will be greatly appreciated.

Update:    See http://masm32.com/board/index.php?topic=1464.msg15440#msg15440 (http://masm32.com/board/index.php?topic=1464.msg15440#msg15440) for solution.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: dedndave on February 11, 2013, 04:47:22 PM
that'll teach ya to leave   :P

the only thing that comes to mind is the difference in window hierarchy for controls under win7
but, if you've looked at it with spy++, i would think you have already noticed that
maybe take a snapshot of the windows in one os and do a side-by-side comparison
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 11, 2013, 05:08:08 PM
The order is strange in win7, here's how I find the listview

.const
workerw BYTE 'WorkerW',0
shellv  BYTE 'SHELLDLL_DefView',0
lview   BYTE 'SysListView32',0

.code
gethandle proc uses ebx esi ;returns EAX=handle else 0
sub esi,esi
   @@:  INVOKE FindWindowEx,0,esi,offset workerw,0
        test eax,eax
        jz @f
        mov esi,eax
        INVOKE FindWindowEx,eax,0,offset shellv,0
        test eax,eax
        jz @b
        INVOKE FindWindowEx,eax,0,offset lview,0
@@: ret
gethandle endp

Unfortunately there is also something called "desktop isolation" (or similar) which means not all info is available.
I think I can get icon positions but not text - can't remember, just gave up :(
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 11, 2013, 08:23:56 PM

I didn't test it, but there's a bug in the code: you may not assume that member pszText in LV_ITEM keeps the initial value - it may be changed by Windows - and further calls with this changed value have a high risk to fail.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 11, 2013, 08:42:54 PM
Quote from: japheth on February 11, 2013, 08:23:56 PM

I didn't test it, but there's a bug in the code: you may not assume that member pszText in LV_ITEM keeps the initial value - it may be changed by Windows - and further calls with this changed value have a high risk to fail.
I found that out the hard way, here's what I do, works in XP but not Vista+

gettext PROC USES EBX ESI EDI hwnd:DWORD,hprocess:DWORD,hprocessmem:DWORD,upto:DWORD,buff:DWORD
    LOCAL item:LVITEM

    INVOKE RtlZeroMemory,ADDR item,SIZEOF item
    mov esi,hprocessmem
    mov ebx,hprocess

    lea eax,[esi+SIZEOF item]
    push 1
    pop item._mask
    push upto
    pop item.iItem
    mov item.pszText,eax
    push 260
    pop item.cchTextMax

    INVOKE WriteProcessMemory,ebx,esi,ADDR item,SIZEOF item,0
    INVOKE SendMessage,hwnd,LVM_GETITEMTEXT,upto,esi
    mov edi,eax
    INVOKE ReadProcessMemory,ebx,item.pszText,buff,eax,0
    mov eax,edi
    ret
gettext endp

Even as admin I get a null string, same code worked OK in XP.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 11, 2013, 10:19:23 PM
Quote from: sinsi on February 11, 2013, 08:42:54 PM
I found that out the hard way, here's what I do, works in XP but not Vista+

I see. However, in your code, shouldn't you first read the LV_ITEM structure back and THEN use the pszText member?

Btw, I found, at second glance, that Jimg does check in his code the "pszText has been changed"-case. Never mind.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 11, 2013, 10:45:55 PM
Quote from: japheth on February 11, 2013, 10:19:23 PM
I see. However, in your code, shouldn't you first read the LV_ITEM structure back and THEN use the pszText member?
Thanks for spotting that. I guess I have been lucky in that Windows doesn't change it.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 12, 2013, 12:50:11 PM
I've finally figured out what the problem is, but not the solution.  Using Spy++ I found that the style of the desktop listview on windows 7 64 bit is LVS_OWNERDATA.   Microsoft specifically says "LVM_GETITEMTEXT is not supported under the LVS_OWNERDATA style."  This means it's a virtual listview, and doesn't keep the info around but asks the parent for it if it needs it.  Microsoft doesn't say anything about what to use instead.  I guess the only way would be to ask the parent ("SHELLDLL_DefView") for the info but have no idea how to get it to send to me instead of the listview.

Anyone have any ideas?  Anyone heard from Donkey lately?  He seems to be very proficient at figuring out this type of stuff.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: dedndave on February 12, 2013, 01:10:15 PM
you can determine the "worker" control window handles
but, that's probably not necessary

it seems to me that the window would be sent a notification message of some sort
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: dedndave on February 12, 2013, 01:14:20 PM
a little different issue, but similar with regard to window hierarchy....

we wanted a GetOpenFileName dialog to appear in a specific position
because the hierarchy is different, i wrote some code to get the handles
as far as i know it works under win 7 - noone ever said that it didn't - lol

maybe you can get some ideas

http://www.masmforum.com/board/index.php?topic=16931.msg154917#msg154917 (http://www.masmforum.com/board/index.php?topic=16931.msg154917#msg154917)
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jj2007 on February 12, 2013, 04:54:30 PM
Quote from: jimg on February 12, 2013, 12:50:11 PMhow to get it to send to me instead of the listview.

Subclassing & intercepting the appropriate message?
You might google for LVS_OWNERDATA LVM_GETITEMTEXT LVN_GETDISPINFO
... or check the NMLVDISPINFO structure (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780%28v=vs.85%29.aspx):

If the LVITEM structure is receiving item text, the pszText and cchTextMax members specify the address and size of a buffer.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 12, 2013, 06:24:02 PM
Quote from: jimg on February 12, 2013, 12:50:11 PM
Anyone have any ideas?

The "official" way to talk with the Windows shell is surely not to use Read/WriteProcessMemory or SendMessage.

There's a bunch of COM interfaces that are supposed to be used. The problem is that  not everything is well documented.

However, to get the text of folder items is simple:


;--- list the items on the desktop folder

.386
.model flat, stdcall
option casemap:none

.nolist
.nocref
include \wininc\include\windows.inc
include \wininc\include\shlobj.inc
include \wininc\include\shobjidl.inc
include \wininc\include\stdio.inc
.list
.cref

includelib kernel32.lib
includelib user32.lib
includelib gdi32.lib
includelib ole32.lib
includelib shell32.lib
includelib msvcrt.lib

CStr macro x:vararg
local xxx
.const
xxx db x,0
.code
exitm <offset xxx>
endm

.code

main proc

local sf:ptr IShellFolder
local il:ptr IEnumIDList
local iil:ptr ITEMIDLIST
local sr:STRRET

invoke SHGetDesktopFolder, addr sf
.if ( eax != S_OK )
invoke printf, CStr("SHGetDesktopFolder() failed [%X]",10), eax
ret
.endif

invoke vf( sf, IShellFolder, EnumObjects_ ), NULL, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS, addr il
.if ( eax != S_OK )
invoke printf, CStr("IShellFolder:EnumObjects() failed [%X]",10), eax
invoke vf( sf, IUnknown, Release )
ret
.endif

.while 1
invoke vf( il, IEnumIDList, Next ), 1, addr iil, NULL
.break .if ( eax == S_FALSE )
.if ( eax != S_OK )
invoke printf, CStr("IEnumIDList:Next() failed [%X]",10), eax
.break
.endif
invoke vf( sf, IShellFolder, GetDisplayNameOf ), iil, SHGDN_NORMAL, addr sr
.if ( eax == S_OK )
.if ( sr.uType == STRRET_CSTR )
invoke printf, CStr("Item: %s",10), addr sr.cStr
.elseif ( sr.uType == STRRET_WSTR )
invoke printf, CStr("Item: %S",10), sr.pOleStr
invoke CoTaskMemFree, sr.pOleStr
.else
invoke printf, CStr("IShellFolder:GetDisplayNameOf() returned unexpected uType=%u",10), sr.uType
.endif
.else
invoke printf, CStr("IShellFolder:GetDisplayNameOf() failed [%X]",10), eax
.endif
invoke CoTaskMemFree, iil
.endw

invoke vf( il, IUnknown, Release )
invoke vf( sf, IUnknown, Release )
ret
align 4

main endp

start:
invoke main
invoke ExitProcess, eax

end start


It's more difficult to get "UI-related" things like icon positions, because you'll need UI-related interfaces like IShellBrowser ( which, AFAICS, is only accessible for shell extensions ) or IFolderView.

Please be aware that the sample code doesn't use Masm32!
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 12, 2013, 06:27:32 PM
I tried using SendMessage with LVM_EDITLABEL which is supposed to return the edit hwnd but got error 36B7 "The requested lookup key was not found in any active activation context."
Do I need a manifest or something? BTW, this is win8 but I had the same problem in win7.

Might play around with LVN_BEGINLABELEDIT, GetWindowText and LVN_ENDLABELEDIT.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jj2007 on February 12, 2013, 06:53:07 PM
Quote from: japheth on February 12, 2013, 06:24:02 PM
However, to get the text of folder items is simple:

Provided you add somewhere
   includelib \WinInc\Lib\UUID.Lib
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 12, 2013, 07:13:31 PM
Quote from: jj2007 on February 12, 2013, 06:53:07 PM
Provided you add somewhere
   includelib \WinInc\Lib\UUID.Lib

Actually, that's a Masm bug: sometimes, when 2 or more externdefs ( or prototypes ) of the very same symbol name are found in the source, it assumes that it's a true external - although it is not at all referenced in the source.

If you use jwasm, the link error should disappear.

Quote
IShellBrowser ( which, AFAICS, is only accessible for shell extensions ) or IFolderView.

I meant IShellView, not IFolderView.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 13, 2013, 08:59:58 AM
Thank you Japheth, I appreciate the code.
After hours of digging through that deranged can of worms that is shell on the microsoft site, I've come to the conclusion that it is not actually what I need.  When I compare the list your code gives me to the actual desktop, it gives me four items that are not on the desktop, and misses one that is.  (It gives me two "control panel"s, a "J" (which is my user name), and a "Libraries".  It misses desktop.ini)
Ultimately, with no way to actually tie the names to the desktop listview, it doesn't help much, but still I appreciate it.

My ultimate goal is to fix my desktop icon positioner program  http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324 (http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324)  to work with windows 7.  It works, I can move icons around, but without the name or icon it really is not very useful.

Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jj2007 on February 13, 2013, 09:18:45 AM
Quote from: jimg on February 13, 2013, 08:59:58 AMMy ultimate goal is to fix my desktop icon positioner program  http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324 (http://www.masmforum.com/board/index.php?topic=2704.msg21324#msg21324)  to work with windows 7.  It works, I can move icons around, but without the name or icon it really is not very useful.

Jim,
Any chance hooking WM_NOTIFY and getting the text via the NMLVDISPINFO structure? Or is that a dead end street?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 13, 2013, 12:04:47 PM
That's what I'm working on right now.  I don't know that I need to hook WM_NOTIFY, but I need to be able to send a notify to the listviews parent with a NMLVDISPINFO message.  I already have space alloted in the listviews memory, so I should be able to read the return if the parent responds properly.  Have a few more things to check out before I try it.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 13, 2013, 01:53:27 PM
Quote from: jimg on February 13, 2013, 08:59:58 AM
When I compare the list your code gives me to the actual desktop, it gives me four items that are not on the desktop, and misses one that is.

Well, it's a sample, to demonstrate the basics, not a "solution". One might have to adjust the code to get exactly what you want.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 13, 2013, 04:18:26 PM
Yes, thank you.  Didn't mean to seem ungrateful.  Sorry.  Reading about shell made me a little verrückt.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 13, 2013, 10:43:18 PM
Just in case: on this site is a nice example about shell objects: http://wiki.winehq.org/Shell32 (http://wiki.winehq.org/Shell32)

if you study the items and their differences you should be able to see what flags have to be set to get the items you are interested in.

Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 14, 2013, 01:41:52 PM
Status update:

I found out the while LVM_GETITEMTEXT is not supposed to work and indeed doesn't work on a virtual listview,  LVM_GETITEM is supposed to work, but doesn't.  In fact, it looks like all the straight functions work, but those that require LVITEM or another structure be passed don't work.  I'm now thinking it has to be a 64 bit application to talk to the 64 bit desktop.  I don't have any idea how to write 64 bit apps, so it will probably be awhile before I'm back with more info.  Perhaps the LVITEM looks different for 64 bit apps?  Qwords instead of Dwords?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jj2007 on February 14, 2013, 05:10:28 PM
Quote from: jimg on February 14, 2013, 01:41:52 PMPerhaps the LVITEM looks different for 64 bit apps?  Qwords instead of Dwords?

Possible. By the way: Does GetLastError show anything interesting?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 14, 2013, 05:54:27 PM
No errors, it thinks it worked.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 14, 2013, 06:33:14 PM
I converted my code to 64-bit and Lo and Behold! it gets labels, and that's using LVM_GETITEMTEXT.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 14, 2013, 07:48:55 PM
Quote from: sinsi on February 14, 2013, 06:33:14 PM
I converted my code to 64-bit and Lo and Behold! it gets labels, and that's using LVM_GETITEMTEXT.

Yes, it works in 64-bit.


    option win64:3
    option frame:auto

    option casemap:none
    include windows.inc
    include commctrl.inc
    include stdio.inc

    includelib <kernel32.lib>
    includelib <user32.lib>
    includelib <comctl32.lib>
    includelib <msvcrt.lib>

CStr macro x:vararg
local xxx
    .const
xxx db x,0
    .code
    exitm <offset xxx>
endm

inv  equ INVOKE
soff equ SADD
nl   equ 13,10

.data?
    hProgMan   dq ?
    hParent    dq ? ; to get desktop listview handle
    hListView  dq ? ; desktop listview
.data
    progman      db "Progman",0
    defview      db "SHELLDLL_defVIEW", 0
    syslistview  db "SysListView32", 0

.code

Program proc frame

    inv InitCommonControls

    invoke printf, CStr("Desktop Icon Info Test",10,10)

    mov rbx, offset progman
    inv FindWindow,rbx,0 ; search for desktop listview
    or  rax,rax
    jz ErrorExit
    mov hProgMan,rax
    invoke printf, CStr("hProgman=%p",10), hProgMan
    mov rbx,offset defview
    inv FindWindowEx, hProgMan, 0, rbx, 0
    or  rax,rax
    jz ErrorExit
    mov hParent,rax
    invoke printf, CStr("  hParent=%p"), hParent
    mov rbx,offset syslistview
    inv FindWindowEx,hParent, 0, rbx, 0
    or  rax,rax
    jz ErrorExit
    mov hListView,rax
    invoke printf, CStr("  hListView=%p",10), hListView
    Call GetDesktopIconInfo ; go fill listview
    jmp @f

ErrorExit:
    inv MessageBox, 0, rbx, CStr("Unable to get"),0
@@:
;    inkey "Press any key to exit..."
    invoke ExitProcess, 0
;    exit 

Program endp

GetErrDescriptionconsole proc frame uses rbx rdi Routine:ptr BYTE
LOCAL hLocal:QWORD
.data
ErrMsgTmpl  db 10,'%s failed, Error Code %Xh',10,'%s',0
Unknown     db 'UnKnown Error',0
.code
    invoke GetLastError
    mov edi,eax
    invoke FormatMessage,FORMAT_MESSAGE_ALLOCATE_BUFFER or FORMAT_MESSAGE_FROM_SYSTEM,
                         0,             ; GetItFromSystem
                         edi,0,         ; ErrNum,Default language
                         addr hLocal,   ; where to send the address of string from system
                         0,0            ; any size, no arguments
    mov rbx,offset Unknown
    .if eax!=0
        invoke LocalLock,hLocal
        mov rbx,rax
    .endif
    invoke printf, offset ErrMsgTmpl, Routine, edi, rbx
;    invoke MessageBox,0,addr Bufferx,0,0
    mov rax, offset Unknown
    .if rbx!=rax
        inv LocalFree,hLocal
    .endif
    ret
GetErrDescriptionconsole endp

GetDesktopIconInfo proc frame; get the names and positions of the desktop icons from the desktop listview
Local I:DWord,J:DWord

.data?
pid          dd ?
IconCount    dd ?
NumBytes     dq ?
hProcess1    dq ?
SharedMem1   dq ?   ; space for LV_ITEM and position data
SharedMem2   dq ?   ; space for caption or title
SharedMem3   dq ?   ; space for the position
PLen         dd ?
vmemsize     dq ?

LV_ITEMx STRUCT 8
  imask         DWORD      ?
  iItem         DWORD      ?
  iSubItem      DWORD      ?
  state         DWORD      ?
  stateMask     DWORD      ?
  pszText       QWORD      ?
  cchTextMax    DWORD      ?
  iImage        DWORD      ?
  lParam        QWORD      ?
  iIndent       DWORD      ?
  iGroupId      DWORD      ?
  puColumns     DWORD      ?
  piColFmt      DWORD      ?
  iGroup        DWORD      ?
LV_ITEMx ENDS

objItem LV_ITEMx <?>
objOut  LV_ITEMx <?>
MaxName     equ 225 ; maximum text description length for an icon  (actually, its about 212)

IconTitle        db  MaxName dup (?)

TPos    POINT   <>

.code
    inv SendMessage,hListView, LVM_GETITEMCOUNT, 0, 0   ; ask the desktop the number of icons present
    mov IconCount,eax
    or  eax,eax
    jz  Done    ; no icons???
    sub eax,1
    invoke printf, CStr("%u icons found",10), eax

    mov vmemsize,sizeof LV_ITEMx + sizeof POINT + MaxName
    mov PLen,sizeof TPos
    inv GetWindowThreadProcessId,hListView, Addr pid
    inv OpenProcess,PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, pid  ; common usage
    mov hProcess1,rax
    inv VirtualAllocEx, rax, 0, vmemsize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE  ; get memory within desktop process
    mov SharedMem1,rax          ; save location within Desktop Listview process to write LV_ITEM
    add rax,sizeof POINT
    mov SharedMem3,rax
    add rax,sizeof LV_ITEMx     
    mov SharedMem2,rax          ; save location of text output

    mov I,0
    Loop1:      ; get length of all titles to reserve storage space
        invoke printf, CStr("#%u "), I
        mov eax, I
        inv SendMessage, hListView, LVM_GETITEMPOSITION, rax, SharedMem1   ; ask for position of Item I (send msg to explorer listview (desktop))
        mov ebx, PLen
        inv ReadProcessMemory,hProcess1, SharedMem1, addr TPos, rbx, addr NumBytes  ; read it into TPos
        .if ( !eax )
            invoke GetErrDescriptionconsole, CStr("ReadProcessMemory")
            jmp Done3
        .endif
        invoke printf, CStr("x=%u y=%u "), TPos.x, TPos.y
        mov objItem.imask, LVIF_TEXT
        mov eax, I
        mov objItem.iItem, eax
        mov objItem.iSubItem, 0
        mov rax, SharedMem2
        mov objItem.pszText, rax
        mov objItem.cchTextMax,MaxName
        inv WriteProcessMemory, hProcess1, SharedMem1, ADDR objItem, sizeof LV_ITEMx, ADDR NumBytes ;copy LV_ITEM structure to memory
        .if ( !eax )
            invoke GetErrDescriptionconsole, CStr("WriteProcessMemory")
            jmp Done3
        .endif
;************************  this is the malfunctioning call
        inv SendMessage, hListView, LVM_GETITEM, 0, SharedMem1 ; send msg to explorer listview (desktop), ask for title, returns length in eax

        inv ReadProcessMemory, hProcess1, SharedMem1, addr objItem, sizeof LV_ITEMx, addr NumBytes
        inv ReadProcessMemory, hProcess1, objItem.pszText, addr IconTitle, 40, addr NumBytes
        mov byte ptr [IconTitle+40],0  ; **** truncate long names for test
        invoke printf, CStr("Title %s",10), addr IconTitle

        inc I
        mov eax,IconCount
        cmp I,eax
        jb Loop1
    ;Loop1 ends

Done3:
    inv VirtualFreeEx, hProcess1, SharedMem1, vmemsize, MEM_RELEASE
Done2:
    inv CloseHandle,hProcess1

Done:
    ret
GetDesktopIconInfo Endp

End Program


Since it works in Win 7 64-bit, the 32-bit version should work in Win 7 32-bit as well, shouldn't it?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jj2007 on February 14, 2013, 08:10:36 PM
Quote from: jimg on February 14, 2013, 05:54:27 PM
No errors, it thinks it worked.

I like that one :biggrin:

Have you tried LVM_GETITEMTEXTW? I know one case (with ToolTips) where only the Unicode version worked:

  .if uMsg==WM_NOTIFY
      mov ecx, lParam
      .if [ecx.NMHDR.code]==TTN_GETDISPINFO
         MsgBox 0, "Never seen!", "Hi", MB_OK
      .endif
      .if [ecx.NMHDR.code]==TTN_GETDISPINFOW
         mov eax, [ecx.NMTTDISPINFOW.lpszText]
         invoke MessageBoxW, 0, eax, 0, MB_OK
      .endif

Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 15, 2013, 04:06:38 AM
Thank guys, at least I have a direction to go now :)  Is there an Idiots guide to 64 bit assembly programming anywhere?  This is going to be painful to convert.  I've become too dependent upon the masm32 macros. (Is there an msvcrt equivalent to inkey for pausing?)

Japheth-

I finally got JWasm 64 bit installed.  I used these options and it seemed to work, but if you have better suggestions for options to use, I'd appreciate it.

@set INCLUDE=F:\JWasm\WinInc\Include
@set path=%path%;F:\jwasm\bin
@set lib=F:\JWasm\WinInc\Lib64

Jwasm -win64 -Cp -Fo=tst.obj %1
jwlink  format win pe file tst.obj Libpath \WinInc\Lib64


also, I had to download polib to make the libraries using your batch file.  Are you working on a jwlib?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 15, 2013, 04:41:30 AM
Quote from: jimg on February 15, 2013, 04:06:38 AM
I finally got JWasm 64 bit installed.  I used these options and it seemed to work, but if you have better suggestions for options to use, I'd appreciate it.

I used the standard 32-bit JWasm and the normal MS link to create the 64-bit sample - because I wanted to be able to use the 64-bit WinDbg.

Quote
also, I had to download polib to make the libraries using your batch file.  Are you working on a jwlib?

There is a jwlib, but it doesn't understand .def files as of yet.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 15, 2013, 06:12:07 AM
Just to avoid confusion, I used the standard JWasm, I didn't mean to imply that a 64 bit version of JWasm even existed, I just put -win64 in the options.  But I did use the 64 bit libraries.

I just tried again using the 32bit libraries, and it assembled, but I got a lot of errors trying to link with jwlink.  eg.

Error! E2028: __imp_LocalFree is an undefined reference
Error! E2028: __imp_VirtualAllocEx is an undefined reference
Error! E2028: InitCommonControls is an undefined reference
Error! E2028: printf is an undefined reference
creating a 64-bit PE executable
file tst.obj(F:\JWasm\Progs\dip64\ec.asm): undefined symbol InitCommonControls
file tst.obj(F:\JWasm\Progs\dip64\ec.asm): undefined symbol printf
file tst.obj(F:\JWasm\Progs\dip64\ec.asm): undefined

etc.

So I obviously have a lot of learning to do yet.

What version of MS link did you use?  What were the options?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 15, 2013, 05:57:16 PM
Quote from: jimg on February 15, 2013, 06:12:07 AM
What version of MS link did you use?  What were the options?

I used the one included in VC++ 2003 Toolkit, but I assume any MS linker since 2001 should do.

used for debug build:

jwasm -win64 -Zi -Ic:\wininc\include ec.asm
link /debug /subsystem:console /libpath:c:\wininc\lib64 ec.obj
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 16, 2013, 01:48:04 AM
Thank you sir,  I misread your previous post.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 18, 2013, 04:36:04 AM
So, after screwing around for days, I learned I'm not ready for 64-bit assembly yet.

But, the solution did not have to be 64 bit, it only needed an LV_ITEM designed for a 64 bit listview, as Japheth did in his 64 bit program.  I couldn't find any official Microsoft 64 bit layout, so I just fudged and added some extra space at the end in case some of the last five items are actually qwords.

Here is my 32-bit test program.  It seems to work fine on both XP and 64 bit windows 7.  I used the 64 bit layout as default, and if I needed the 32 bit instead, just converted it by copying the affected items.


update: fixed error: added cColumn to structure
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: Don57 on February 18, 2013, 05:22:26 AM
Vey nice. Runs fine on my 64bit system. :t
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jj2007 on February 18, 2013, 05:31:22 AM
Congrats, Jim - works like a charm on XP-32, too :t
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 18, 2013, 05:39:14 AM
And nearly as soon as I posted it I noticed that cColumns was missing from the structure.  Shouldn't have had any serious effect on what I was doing, but I'll update it in a bit.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 18, 2013, 11:08:14 AM
Windows 8 Pro x64 gives me: Unable to get SHELLDLL_defView
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 18, 2013, 12:07:28 PM
Ugh.    If you look at the desktop with spy++, what is the name of the item between progman and the listview?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 18, 2013, 12:34:20 PM
Progman is a sibling window to this window class - #32769 (Desktop window).
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: dedndave on February 18, 2013, 12:48:52 PM
under xp sp3, also
SHELLDLL_DefView
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 19, 2013, 02:23:59 AM
Quote from: jimg on February 18, 2013, 04:36:04 AM
But, the solution did not have to be 64 bit, it only needed an LV_ITEM designed for a 64 bit listview, as Japheth did in his 64 bit program. 

Nice find. Does that mean that the former assumption:

Quote
I found out the while LVM_GETITEMTEXT is not supposed to work and indeed doesn't work on a virtual listview,

was premature or that the Win7 64-bit explorer doesn't use virtual listviews?
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 19, 2013, 01:34:59 PM
If you can trust Spy++, it says that the listview has the property style LVS_OWNERDATA, which means it is a virtual listview.

  Apparently, either it's not supposed to work, but does for some unknown reason and can't be trusted, or Microsoft screwed up the documentation.  It clearly says "LVM_GETITEMTEXT is not supported under the LVS_OWNERDATA style" here http://msdn.microsoft.com/en-us/library/windows/desktop/bb761055%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/bb761055%28v=vs.85%29.aspx)

Perhaps "not supported" means...    we meant for it to work, but sometimes it doesn't, so no guarantee, and we're not talking to you about it.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: dedndave on February 19, 2013, 01:52:17 PM
i have minimal experience with virtual listview controls, but....

if i understand the documentation, it is designed to allow you to manage the data
http://msdn.microsoft.com/en-us/library/windows/desktop/bb774735%28v=vs.85%29.aspx#Virtual_ListView_Style (http://msdn.microsoft.com/en-us/library/windows/desktop/bb774735%28v=vs.85%29.aspx#Virtual_ListView_Style)

so, i am having a hard time understanding why you are trying to use LVM_GETITEMTEXT   :P

QuoteThe following messages are not supported under the LVS_OWNERDATA style:
LVM_ENABLEGROUPVIEW, LVM_GETITEMTEXT, LVM_SETTILEINFO, and LVM_MAPIDTOINDEX.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 19, 2013, 04:30:41 PM
The text is the text that appears under the icon on your desktop.  Why Microsoft switched to a virtual listview for the desktop is beyond me.  But you do see why I wanted the text of the icon, right?  Or did I misunderstand the question or intended humor of the question?   I now use LVM_GETITEM to get the text purely because of the quote.  It wasn't working either until we found the right layout for the structure, but at least it isn't specifically "not supported".  (and I still think the word "supported" is really ambiguous in this case)
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: sinsi on February 19, 2013, 04:49:41 PM
Using LVM_GETITEMTEXT I can get the text from 64-bit code and using the 64-bit LVITEM structure I can get the text from 32-bit code, again using LVM_GETITEMTEXT.
Looks like you can send a message to a 64-bit program from 32-bit land, assuming you use 64-bit parameters (which they would expect).

Two questions:
1) VirtualAllocEx returns a 32-bit pointer (in my 32-bit code) into a 64-bit process, luck? Or Windows?
2) Why does LVM_GETITEMTEXT work?

Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: japheth on February 19, 2013, 06:04:41 PM

I also checked my old COMView source - written 10 years ago - which uses LVS_OWNERDATA. There's no problem with the LVM_GETITEMTEXT message. AFAICS, to support certain features of the standard listview, one may have to use ListView_SetCallbackMask(); but it's not necessary for LVM_GETITEM(TEXT).

So the MS documentation is probably wrong - surely not the first time.
Title: Re: LVM_GETITEMTEXT working in XP but not windows 7
Post by: jimg on February 21, 2013, 02:43:12 AM
http://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/aa384203%28v=vs.85%29.aspx)
Quote64-bit versions of Windows use 32-bit handles for interoperability. When sharing a handle between 32-bit and 64-bit applications, only the lower 32 bits are significant, so it is safe to truncate the handle (when passing it from 64-bit to 32-bit) or sign-extend the handle (when passing it from 32-bit to 64-bit).