All pastes #1995927 Raw Edit

get kl0wned3

public text v1 · immutable
#1995927 ·published 2010-11-18 23:48 UTC
rendered paste body
// ImgBurnProg.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include <Strsafe.h>
#include <Windows.h>
#include <psapi.h>
#include <stdlib.h>

#define maxLine 500
#define maxWndName 512

HANDLE hFileMap;
LPSTR mData;
int wndFound;

char ProcessName[MAX_PATH] = "ImgBurn.exe";
char ProgWndName[] = "% - ImgBurn";
char DestWndName[] = "Destination";
char TextBuffer[maxLine];

DWORD IbPid = 0;
DWORD BurnStatus;
bool StopSearching;

int CheckProcessName(DWORD processID, char *checkProcessName)
{
    char processName[MAX_PATH];

    // Get a handle to the process.
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);

    // Get the process name.
    if (NULL != hProcess)
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
            GetModuleBaseNameA(hProcess, hMod, processName, sizeof(processName)/sizeof(char));
    }

    CloseHandle(hProcess);
    
    return !_strnicmp(processName, checkProcessName, MAX_PATH);
}

// call this function first to get the ImgBurn PID
// that way we can search only windows owned by ImgBurn
int GetImgBurnPid()
{
	DWORD pProcessIds[1024], foundID = 0;
	DWORD pBytesReturned;

	if (!EnumProcesses(pProcessIds, sizeof(pProcessIds), &pBytesReturned))
		return 0;

	DWORD numProcesses = pBytesReturned / sizeof(DWORD);

	for (int i = 0; i < numProcesses; i++)
	{
		if(pProcessIds[i] != 0)
		{
			if (CheckProcessName(pProcessIds[i], ProcessName))
			{
				IbPid = pProcessIds[i];
				break;
			}
		}
	}
}

// if lParam == 0 then copy the first available text
// otherwise when we find text which matches what lparam points to and get the first text below that
// the point was to get the text of the filename for the iso being created
// so i searched for a dialog item named "Destination" and its first child is the filename
// you really want to find the filename being burned, but I was testing by creating ISO files
BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
{
	char buf[512];
	char *foo = (char*)lParam;

	if (lParam == 0)
	{
		if (SendMessageTimeoutA(hwnd, WM_GETTEXT, sizeof(TextBuffer)/sizeof(char), (LPARAM)(void*)TextBuffer, SMTO_ABORTIFHUNG, 1000, 0))
		{
			StopSearching = true;
			return 0;
		}
	}
	else if (SendMessageTimeoutA(hwnd, WM_GETTEXT, sizeof(buf)/sizeof(char), (LPARAM)(void*)buf, SMTO_ABORTIFHUNG, 1000, 0) && !strncmp(buf, (char*)lParam, 512))
	{
			EnumChildWindows(hwnd, EnumChildProc, 0);
			return 0;
	}

	return 1;
}

// call this to see if the completed dialog is up (caaled from FindDoneWndProc()
// should also be able to add checks for other messages like a failed burn
// set BurnStatus to some unigue number for sucess, fail, etc and that number will be returned to mirc
BOOL CALLBACK EnumChildGetSAtatusProc(HWND hwnd, LPARAM lParam)
{
	char buf[512];

	if (SendMessageTimeoutA(hwnd, WM_GETTEXT, sizeof(buf)/sizeof(char), (LPARAM)(void*)buf, SMTO_ABORTIFHUNG, 1000, 0))
	{
		if (!strncmp(buf, "Operation Successfully Completed!", sizeof("Operation Successfully Completed!")))
		{
			BurnStatus = 1;
			return 0;
		}
	}

	return 1;
}

// checks that the window is ImgBurn's then looks for the complete messagebox
BOOL CALLBACK FindDoneWndProc(HWND hwnd, LPARAM lParam)
{
	DWORD pid;

	if (GetWindowThreadProcessId(hwnd, &pid) && pid == IbPid)
	{
		EnumChildWindows(hwnd, EnumChildGetSAtatusProc, 0);
		// if not -1 then something changed BurnStatus, so we're done
		if (BurnStatus != -1)
			return 0;
	}
	return 1;
}

// find a child window with the name pointed to by lParam
BOOL CALLBACK FindWndProc(HWND hwnd, LPARAM lParam)
{
	DWORD pid;

	if (GetWindowThreadProcessId(hwnd, &pid) && pid == IbPid)
	{
		EnumChildWindows(hwnd, EnumChildProc, lParam);
		if (StopSearching == true)
			return 0;
	}
	return 1;
}

// looks for the progress window then copies the percentage number (without the '%')
BOOL CALLBACK FindProgWndProc(HWND hwnd, LPARAM lParam)
{
	char buf[512];
	char *p;
	DWORD pid;

	if (GetWindowThreadProcessId(hwnd, &pid) && pid == IbPid)
	{
		if (SendMessageTimeoutA(hwnd, WM_GETTEXT, sizeof(buf)/sizeof(char), (LPARAM)(void*)buf, SMTO_ABORTIFHUNG, 1000, 0)
								&& strstr(buf, ProgWndName))
		{

			if (p = strchr(buf, L'%'))
			{
				*p = 0;
				strncpy((char*)lParam, buf, maxLine / sizeof(TCHAR));
			}
			return 0;
		}
	}
	return 1;
}

extern "C"
{
	void WINAPI LoadDll(void*)
	{
		//create file mapping
		hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE,0,PAGE_READWRITE,0,4096,L"mIRC");	
		mData = (LPSTR)MapViewOfFile(hFileMap,FILE_MAP_ALL_ACCESS,0,0,0);
	}

	int WINAPI UnloadDll(int timeout)
	{
		if (!timeout)
		{
			//close file mapping
			UnmapViewOfFile(mData);
			CloseHandle(hFileMap);
		}
		return 0;
	}

	// these functions simply return a string which can be processed however the user wants
	// in an mirc script

	// $dll(imgburnprog.dll, getprogress,0)
	int WINAPI getprogress(HWND mWnd, HWND aWnd, char *data, char *parms, 
		BOOL show, BOOL nopause)
	{

		if (GetImgBurnPid())
			EnumWindows(FindProgWndProc, (LPARAM)(void*)data);

		return 3;

	}

	// $dll(imgburnprog.dll, getstatus,0)
	// we can't just wait until it says 100% because that window goes away
	// when the process is finished, so look for the message box that says
	// success/fail/whatever
	int WINAPI getstatus(HWND mWnd, HWND aWnd, char *data, char *parms, 
		BOOL show, BOOL nopause)
	{
		BurnStatus = -1;

		if (!GetImgBurnPid())
			return 3;

		EnumWindows(FindDoneWndProc, 0);

		_ltoa_s(BurnStatus, data, 4, 10);

		return 3;
	}

	// $dll(imgburnprog.dll, getfile,0)
	int WINAPI getfile(HWND mWnd, HWND aWnd, char *data, char *parms, 
		BOOL show, BOOL nopause)
	{
		if (!GetImgBurnPid())
			return 3;

		StopSearching = false;		
		EnumWindows(FindWndProc, (LPARAM)(void*)"Source");

		strncpy(data, TextBuffer, sizeof(TextBuffer));

		return 3;
	}

}