Beispiel #1
0
BOOL __stdcall ProcessRequest(HWND hwnd, LPARAM param)
{
	char szBuf[MAX_PATH];

	TEnumData *lParam = (TEnumData*)param;
	DWORD pid = 0;
	GetWindowThreadProcessId(hwnd, &pid);
	if (pid != 0) {
		// old system would get a window's pid and the module handle that created it
		// and try to OpenEvent() a event object name to it (prefixed with a string)
		// this was fine for most Oses (not the best way) but now actually compares
		// the class string (a bit slower) but should get rid of those bugs finally.
		HANDLE hMirandaWorkEvent = OpenEventA(EVENT_ALL_ACCESS, false, CreateProcessUID(pid, szBuf, sizeof(szBuf)));
		if (hMirandaWorkEvent != 0) {
			GetClassNameA(hwnd, szBuf, sizeof(szBuf));
			if ( lstrcmpA(szBuf, MIRANDACLASS) != 0) {
				// opened but not valid.
				logA("ProcessRequest(%d, %p): class %s differs from %s\n", pid, hwnd, szBuf, MIRANDACLASS);
				CloseHandle(hMirandaWorkEvent);
				return true;
			}
		}
		// if the event object exists,  a shlext.dll running in the instance must of created it.
		if (hMirandaWorkEvent != 0) {
			logA("ProcessRequest(%d, %p): window found\n", pid, hwnd);
			// prep the request
			ipcPrepareRequests(IPC_PACKET_SIZE, lParam->ipch, REQUEST_ICONS | REQUEST_GROUPS | REQUEST_CONTACTS | REQUEST_NEWICONS);

			// slots will be in the order of icon data, groups  contacts, the first
			// slot will contain the profile name
			DWORD replyBits = ipcSendRequest(hMirandaWorkEvent, lParam->hWaitFor, lParam->ipch, 1000);

			// replyBits will be REPLY_FAIL if the wait timed out, or it'll be the request
			// bits as sent or a series of *_NOTIMPL bits where the request bit were, if there are no
			// contacts to speak of,  don't bother showing this instance of Miranda }
			if (replyBits != REPLY_FAIL && lParam->ipch->ContactsBegin != NULL) {
				logA("ProcessRequest(%d, %p): IPC succeeded\n", pid, hwnd);
				// load the address again, the server side will always overwrite it
				lParam->ipch->pClientBaseAddress = lParam->ipch;
				// fixup all the pointers to be relative to the memory map
				// the base pointer of the client side version of the mapped file
				ipcFixupAddresses(lParam->ipch);
				// store the PID used to create the work event object
				// that got replied to -- this is needed since each contact
				// on the final menu maybe on a different instance and another OpenEvent() will be needed.
				lParam->pid = pid;
				// check out the user options from the server
				lParam->bShouldOwnerDraw = (lParam->ipch->dwFlags & HIPC_NOICONS) == 0;
				// process the icons
				BuildSkinIcons(lParam);
				// process other replies
				BuildMenus(lParam);
			}
			// close the work object
			CloseHandle(hMirandaWorkEvent);
		}
	}
	return true;
}
Beispiel #2
0
void __cdecl ThreadServer(HANDLE hMainThread)
{
	char szBuf[100];
	HANDLE hEvent = CreateEventA(NULL, false, false, CreateProcessUID(GetCurrentProcessId(), szBuf, sizeof(szBuf)));
	while (true) {
		int retVal = WaitForSingleObjectEx(hEvent, INFINITE, true);
		if (retVal == WAIT_OBJECT_0)
			QueueUserAPC(ipcService, hMainThread, 0);

		if (CallService(MS_SYSTEM_TERMINATED, 0, 0) == 1)
			break;
	}
	CloseHandle(hEvent);
	CloseHandle(hMainThread);
}
Beispiel #3
0
HRESULT RequestTransfer(TShellExt *Self, int idxCmd)
{
	// get the contact information
	MENUITEMINFOA mii = { 0 };
	mii.cbSize = sizeof(mii);
	mii.fMask = MIIM_ID | MIIM_DATA;
	if ( !GetMenuItemInfoA(Self->hRootMenu, Self->idCmdFirst + idxCmd, false, &mii))
		return E_INVALIDARG;

	// get the pointer
	TMenuDrawInfo *psd = (TMenuDrawInfo*)mii.dwItemData;
	// the ID stored in the item pointer and the ID for the menu must match
	if (psd == NULL || psd->wID != mii.wID)
		return E_INVALIDARG;

	// is there an IDataObject instance?
	HRESULT hr = E_INVALIDARG;
	if (Self->pDataObject != NULL) {
		// OpenEvent() the work object to see if the instance is still around
		char szBuf[100];
		HANDLE hTransfer = OpenEventA(EVENT_ALL_ACCESS, false, CreateProcessUID(psd->pid, szBuf, sizeof(szBuf)));
		if (hTransfer != 0) {
			// map the ipc file again
			HANDLE hMap = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, IPC_PACKET_SIZE, IPC_PACKET_NAME);
			if (hMap != 0 && GetLastError() != ERROR_ALREADY_EXISTS) {
				// map it to process
				THeaderIPC *pipch = (THeaderIPC*)MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
				if (pipch != NULL) {
					// create the name of the object to be signalled by the ST
					lstrcpyA(pipch->SignalEventName, CreateUID(szBuf, sizeof(szBuf)));
					// create it
					HANDLE hReply = CreateEventA(NULL, false, false, pipch->SignalEventName);
					if (hReply != 0) {
						if (psd->fTypes & dtCommand) {
							if (psd->MenuCommandCallback) 
								hr = psd->MenuCommandCallback(pipch, hTransfer, hReply);
						}
						else {
							// prepare the buffer
							ipcPrepareRequests(IPC_PACKET_SIZE, pipch, REQUEST_XFRFILES);
							// get all the files into the packet
							if (ipcGetFiles(pipch, Self->pDataObject, psd->hContact) == S_OK) {
								// need to wait for the ST to open the mapping object
								// since if we close it before it's opened it the data it
								// has will be undefined
								int replyBits = ipcSendRequest(hTransfer, hReply, pipch, 200);
								if (replyBits != REPLY_FAIL) // they got the files!
									hr = S_OK;
							}
						}
						// close the work object name
						CloseHandle(hReply);
					}
					// unmap it from this process
					UnmapViewOfFile(pipch);
				}
				// close the map
				CloseHandle(hMap);
			}
			// close the handle to the ST object name
			CloseHandle(hTransfer);
		}
	}
	return hr;
}