EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found

Plug-in and third party software discussion.
Post Reply
Lucas
Posts: 2
Joined: Wed Jul 15, 2020 9:07 am

EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found

Post by Lucas » Wed Jul 15, 2020 9:14 am

in everything_ipc.h, the value EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found.

I tried EVERYTHING_IPC_ID_FILE_COPY_FULL_PATH_AND_NAME successfully, but now I am trying to get the selected file path from Everything without changing user's clipboard.
So is EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME for that, what is the value and how to use it?

NotNull
Posts: 2345
Joined: Wed May 24, 2017 9:22 pm

Re: EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found

Post by NotNull » Wed Jul 15, 2020 10:23 am

Warning: I am not a developer and just guessing here. But maybe it can help you.

It looks to me that the EVERYTHING_IPC routines are for "remote controlling" a running Everything GUI window.

There are also routines to query the Everything database. Those can be found in "Everything.h" in the SDK.
It seems more fitting for your purpose [1]
Examples can be found here and througout the forum.



[1] Although there is a EVERYTHING_IPC_ITEMFILENAMEW

void
Site Admin
Posts: 5746
Joined: Fri Oct 16, 2009 11:31 pm

Re: EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found

Post by void » Wed Jul 15, 2020 10:24 am

The IPC call EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not implemented.

It was planned during development and unfortunately removed due to synchronization issues.
I plan to add something similar in a future release.

For now, you will need to send LVM_GETITEM with a remotely allocated buffer:

Code: Select all

void get_lvitem(HWND everything_listview_hwnd,int index)
{
	wchar_t buf[MAX_PATH];
	DWORD dwProcessID;
	HANDLE hProcess;
	BYTE *lpRemoteBuffer;
	LVITEM lvItem = {0};

	// Get the process id owning the window
	GetWindowThreadProcessId( everything_listview_hwnd, &dwProcessID );

	// Open the process wih all access (You may not have the rights to do this)
	hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, dwProcessID );
	if (hProcess)
	{
		// Allocate a buffer in the remote process
		lpRemoteBuffer = (BYTE*)VirtualAllocEx( hProcess, NULL, sizeof(LVITEM) + (MAX_PATH * sizeof(wchar_t)),MEM_COMMIT, PAGE_READWRITE );
		if (lpRemoteBuffer)
		{
			SIZE_T num_bytes_written;
			
			// Fill in the LVITEM struct, this is in your own process
			// Set the pszText member to somewhere in the remote buffer,
			// For the example I used the address imediately following the LVITEM stuct
			lvItem.mask = LVIF_TEXT | LVIF_STATE | LVIF_STATE | LVIF_IMAGE;
			lvItem.stateMask = 0xffffffff;
			lvItem.iItem = index;
			lvItem.iSubItem = 0;
			lvItem.cchTextMax = MAX_PATH;

			// Point to after LVITEM in the remote buffer
			lvItem.pszText = (LPTSTR)(lpRemoteBuffer + sizeof( LVITEM )); 

			// Copy the local LVITEM to the remote buffer
			if (WriteProcessMemory( hProcess, (LPVOID)lpRemoteBuffer, &lvItem, sizeof(LVITEM), &num_bytes_written ))
			{
				if (num_bytes_written == sizeof(LVITEM))
				{
//					printf("lpRemoteBuffer %p %p\n",lpRemoteBuffer,lvItem.pszText);

					// Send the message
					if (SendMessage( everything_listview_hwnd, LVM_GETITEMW, 0, (LPARAM)lpRemoteBuffer))
					{
						// Read the struct back from the remote process into local buffer
						ReadProcessMemory( hProcess, (LPVOID)lpRemoteBuffer, &lvItem, sizeof(LVITEM), NULL );

						ReadProcessMemory( hProcess, (LPVOID)(lpRemoteBuffer + sizeof(LVITEM)), buf, (MAX_PATH * sizeof(wchar_t)), NULL );

						//Fix pszText to point to same offset in local buffer
						lvItem.pszText = buf;
						
						printf("Item %d: %08x %S\n",index,lvItem.state,lvItem.pszText);
					}
				}
				else
				{
					printf("WriteProcessMemory bad write %d\n",num_bytes_written);
				}
			}
			else
			{
				printf("WriteProcessMemory failed %d\n",GetLastError());
			}
			
			// Clean-up
			VirtualFreeEx( hProcess, (LPVOID)lpRemoteBuffer, 0, MEM_RELEASE ); 
		}
		else
		{
			printf("virtualalloc failed %d\n",GetLastError());
		}
		
		CloseHandle( hProcess );
	}
	else
	{
		printf("OpenProcess failed %d\n",GetLastError());
	}

}
This will get the Name, use iSubItem=1 to get the parent folder location and combine them to get the full path.
Make sure you compile as x64 for x64 OSes.

Lucas
Posts: 2
Joined: Wed Jul 15, 2020 9:07 am

Re: EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found

Post by Lucas » Wed Jul 15, 2020 11:27 am

Thank you~
I just tried, it worked perfectly.

Actually, I emailed you for the same question almost five years ago. But I was not able to implement it because of my lack of programming skill. :D :D
However, I am so glad it is solved now.
Last edited by Lucas on Thu Jul 16, 2020 2:12 am, edited 1 time in total.

NotNull
Posts: 2345
Joined: Wed May 24, 2017 9:22 pm

Re: EVERYTHING_IPC_WM_QUERY_GET_SELECTION_FULL_PATH_AND_NAME is not found

Post by NotNull » Wed Jul 15, 2020 1:31 pm

void wrote:
Wed Jul 15, 2020 10:24 am
some magic spells
Yes, that is *exactly* what I wanted to say!! ;)



( sorry for creating "noise" )

Post Reply