#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include HV* lvGetItem ( SV* handle, SV* item, SV* subitem ) { /* Var */ HWND ihandle; int iItem; int iSubItem; int textlength; BOOL Success; HANDLE hProcess; DWORD dwProcessId; LV_ITEM* plvi; LV_ITEM lvi; TCHAR text[100]; DWORD* bytes; SV* sv; HV* hv; /* Process Arguments, get handle */ ihandle = (HWND) SvIV(handle); iItem = SvIV ( item); iSubItem = SvIV ( subitem); #ifdef DEBUG_CHECK printf ("Made it to GetItem handle %d\n", ihandle); #endif /* Open a handle to the remote process's kernel object '*/ if ( GetWindowThreadProcessId( ihandle, &dwProcessId) == NULL ) { croak ("Got a NULL reference for the process or thread handles\n"); } hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcessId); /* check that we got a valid process handle */ if ( hProcess == NULL ) { croak ("Got a NULL reference for the process handle\n"); } #ifdef DEBUG_CHECK printf ("Successfully Received a Process handle and readied the process for a memory operation.\n"); #endif /* Allocate memory in the remote process's address space.'*/ plvi = (LV_ITEM*) VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); #ifdef DEBUG_CHECK printf ("Successfully Allocated Memory%d.\n",(long)plvi); #endif /* Initialize a local LV_ITEM structure */ lvi.mask = LVIF_TEXT; lvi.iItem = iItem; lvi.iSubItem = iSubItem; /* NOTE: The text data immediately follows the LV_ITEM structure */ /* in the memory block allocated in the remote process. */ lvi.pszText = (LPTSTR) (plvi + sizeof(lvi)+1); lvi.cchTextMax = 100; /* Write the local LV_ITEM structure to the remote memory block */ Success = WriteProcessMemory(hProcess, plvi, &lvi, sizeof(lvi), NULL); if ( ! Success ) { croak ("Did Not write request to memory\n"); } #ifdef DEBUG_CHECK else { printf ("Successfully copied local structure\n"); printf ("The size of an lvi struct is %d bytes \n", sizeof(lvi)); } #endif /* Tell the ListView control to fill the remote LV_ITEM structure */ Success = ListView_GetItem( ihandle, plvi); if (!Success) { croak ("The remote process failed to fill the LV structure\n"); } #ifdef DEBUG_CHECK else { printf("The remote Process has filled the LV_ITEM STRUCTURE\n"); } #endif /* Get the Text */ memset(text, 0, 100); Success = ReadProcessMemory(hProcess, (plvi + sizeof(lvi) + 1) , text, 100, &textlength ); if (!Success) { printf("Last Error was error:%d\n", GetLastError() ); croak ("ReadProcess Memory Failed!!!!\n"); } #ifdef DEBUG_CHECK printf ("Got '%s' of length %d for Item %d, %d\n", text,textlength, iItem,iSubItem); #endif /* Free the memory in the remote process's address space'*/ Success = VirtualFreeEx (hProcess, plvi, 0, MEM_RELEASE); if (!Success) { printf("Last Error was error:%d\n", GetLastError() ); croak ("Free Memory Failed!!!!\n"); } #ifdef DEBUG_CHECK else { printf("Freed foreign process memory block\n"); } #endif /* Cleanup */ CloseHandle(hProcess); /* put result on perlstack */ textlength = strlen ( text); sv = newSVpvn(text,textlength); hv = newHV(); hv_store (hv,"-text",5,sv, 0); /* Need to return state and image index as well to be equive to Win32::Gui version */ return (hv); } int lvSelectItem( SV * hw, SV * in){ /* SelectItem macro uses a pointer address so needs a cross-process set-up */ /* Var */ HWND ihandle; int iItem; int textlength; BOOL Success; HANDLE hProcess; DWORD dwProcessId; LV_ITEM* plvi; LV_ITEM lvi; NM_LISTVIEW* plvnm; NM_LISTVIEW lvnm; TCHAR text[100]; DWORD* bytes; SV* sv; HV* hv; /* Process Arguments, get handle */ ihandle = (HWND) SvIV(hw); iItem = (int) SvIV ( in); #ifdef DEBUG_CHECK printf ("Made it to Select Item handle %d\n", ihandle); #endif /* Open a handle to the remote process's kernel object '*/ if ( GetWindowThreadProcessId( ihandle, &dwProcessId) == NULL ) { croak ("Got a NULL reference for the process or thread handles\n"); } hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcessId); /* check that we got a valid process handle */ if ( hProcess == NULL ) { croak ("Got a NULL reference for the process handle\n"); } #ifdef DEBUG_CHECK printf ("Successfully Received a Process handle and readied the process for a memory operation.\n"); #endif /* Allocate memory in the remote process's address space.'*/ plvi = (LV_ITEM*) VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); #ifdef DEBUG_CHECK printf ("Successfully Allocated Memory%x.\n",(long)plvi); #endif /* Initialize a local LV_ITEM structure */ lvi.mask = LVIF_STATE; lvi.state = LVIS_FOCUSED | LVIS_SELECTED; lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvi.iItem = iItem; lvi.iSubItem = 0; /* NOTE: The text data immediately follows the LV_ITEM structure */ /* in the memory block allocated in the remote process. */ lvi.pszText = (LPTSTR) (plvi + sizeof(lvi)+1); lvi.cchTextMax = 100; /* Write the local LV_ITEM structure to the remote memory block */ Success = WriteProcessMemory(hProcess, plvi, &lvi, sizeof(lvi), NULL); if ( ! Success ) { croak ("Did Not write request to memory\n"); } #ifdef DEBUG_CHECK else { printf ("Successfully copied local structure\n"); printf ("The size of an lvi struct is %d bytes \n", sizeof(lvi)); } #endif /* SetItemState(nItem, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED) /* Tell the ListView control to fill the remote LV_ITEM structure */ Success = SendMessage ( ihandle, LVM_SETITEMSTATE, iItem, plvi ); #ifdef DEBUG_CHECK if (Success) { printf("Selected Item %d \n",iItem); } else { printf("Failed to select Item %d\n",iItem); return (0); } #endif /* Free the memory in the remote process's address space'*/ Success = VirtualFreeEx (hProcess, plvi, 0, MEM_RELEASE); if (!Success) { printf("Last Error was error:%d\n", GetLastError() ); croak ("Free Memory Failed!!!!\n"); } #ifdef DEBUG_CHECK else { printf("Freed foreign process memory block\n"); } #endif /* At this point the item should display its new state... but we have to tell mom about the change. */ /* Cleanup */ CloseHandle(hProcess); return (1); } MODULE = ListViewEx PACKAGE = ListViewEx HV* lvGetItem ( handle, item, subitem ) SV* handle SV* item SV* subitem OUTPUT: RETVAL int lvSelectItem( hw, in) SV * hw SV * in OUTPUT: RETVAL