#if (_WIN32_IE >= 0x0400)

    lpnmia = (LPNMITEMACTIVATE)lParam;

#else

    lpnm = (LPNMHDR)lParam;

#endif

I'm writing an app that opens a handle to another process. I was thinking of declaring the HANDLE var globally and setting it from an initialization function. I'm wondering what would be the easiest way to verify the handle is still good (i.e. the process is still running) without calling OpenProcess and CloseHandle every time I want to access the other process. I can't find any predefined functions for this purpose. Maybe checking the return from GetProcessId or something would suit my purpose? I'm keeping the ID I get a handle to as well, so maybe:

[code]If (GetProcessId(processhandle) != processid) [/code]

BOOL CALLBACK ListProcesses(HWND ewHwnd, LPARAM lParam)
{
    char szProcessName[500], szProcessPath[500];
    char szProcessID[20], szProcessSize[20], szProcessTitle[1024];
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS szProcessMemory; memset(&szProcessMemory,0,sizeof(PROCESS_MEMORY_COUNTERS));
    GetModuleBaseName( ewHwnd, NULL, szProcessName, 500 );
    GetWindowText(ewHwnd, szProcessTitle, sizeof(szProcessTitle));
//    if (strlen(szProcessTitle) > 2) { MessageBox(NULL,szProcessTitle,"Debug",0); }
    ListViewAddRow(hProcList, 5, szProcessName, szProcessTitle, szProcessID, szProcessSize, szProcessPath);
    CloseHandle( hProcess );
    return TRUE;
}

        case WM_PASTE:
        {
            char* txtClip;
            if (OpenClipboard(NULL)) {
                txtClip = GetClipboardData(CF_TEXT);
//                MessageBox(NULL,txtClip,"Debug",0);
                if (isHex(txtClip)) { CloseClipboard(); break; }
                CloseClipboard();
                return 0;
            }
//            MessageBox(NULL,"Handle pasting in hex edit boxes!","Debug",0);
//            if (!isHexWindow(hwnd)) { return 0; }
        } break;


u32 DumpRAM(char* DumpName, u8 **ramdata)
{
    u32 filesize = 0;
    u32 chunksize = 0x100000;
    DWORD bytesread;
    u8 *buffer = NULL;
    u32 RamStart;
    u32 i;
    char *CopyAddr;
    if (!VerifyHook()) {
        MessageBox(NULL,"ProcessID no longer valid. Unable to read memory (DumpRAM, 1)", "Error", MB_OK);
        return 0;
    }
    HMODULE hModule;
    MODULEINFO ModuleInfo;
    DWORD cbNeeded;
    if (Settings.Hook.sType == RAM_POINTER) {
        if (ReadProcessMemory(HookedProcess.hProcess, (void*)Settings.Hook.rOffset, &RamStart, 4, &bytesread) == 0) {
            return 0;
        }

    } else { RamStart = Settings.Hook.rOffset; }
    if ((Settings.Hook.AutoRam == BST_UNCHECKED) && (Settings.Hook.MaxRamSize)) {
        chunksize = Settings.Hook.MaxRamSize;
    } else {
        EnumProcessModules(HookedProcess.hProcess, &hModule, sizeof(hModule), &cbNeeded);
        GetModuleInformation(HookedProcess.hProcess, hModule, &ModuleInfo, sizeof(MODULEINFO));
        RamStart = (DWORD)ModuleInfo.lpBaseOfDll;
        chunksize = ModuleInfo.SizeOfImage;
    }
    if (*ramdata) { free(*ramdata); *ramdata = NULL; }
    if (!(*ramdata = (unsigned char*)malloc(chunksize+1))) {
        MessageBox(NULL, "Unable to allocate ramdata memory (DumpRAM,1).", "Error", MB_OK);
        return 0;
    }
    if (ReadProcessMemory(HookedProcess.hProcess, (void*)RamStart, *ramdata, chunksize, &bytesread) == 0) {
        sprintf(ErrTxt, "%x,%x,%x, %u", RamStart, chunksize, sizeof(buffer), GetLastError());
        MessageBox(NULL,ErrTxt,"Error",0);
    }
    sprintf(ErrTxt, "%X", (DWORD)ModuleInfo.lpBaseOfDll);
    MessageBox(NULL,ErrTxt,"Debug",0);
free(*ramdata); *ramdata = NULL;
    return 0;
}


u32 DumpRAM(char* DumpName, u8 **ramdata)
{
    u32 filesize = 0;
//    u32 chunksize = 0x100000;
    u32 chunksize = 0;
    DWORD bytesread;
    u8 *buffer = NULL;
    u32 RamStart = Settings.Hook.rOffset;
    u32 i;
    char *CopyAddr;

    HEAPENTRY32 HeapEntry; memset(&HeapEntry,0,sizeof(HEAPENTRY32));
    HEAPLIST32 HeapList; memset(&HeapList,0,sizeof(HEAPLIST32));

    if (!VerifyHook()) {
        MessageBox(NULL,"ProcessID no longer valid. Unable to read memory (DumpRAM, 1)", "Error", MB_OK);
        return 0;
    }
    if (Settings.Hook.sType == RAM_POINTER) {
        if (ReadProcessMemory(HookedProcess.hProcess, (void*)Settings.Hook.rOffset, &RamStart, 4, &bytesread) == 0) {
            return 0;
        }

    } else { RamStart = Settings.Hook.rOffset; }
    if (Settings.Hook.MaxRamSize) {
        chunksize = Settings.Hook.MaxRamSize;
        //grab and return?
    }
    HANDLE hHeapSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, HookedProcess.dwProcessId);
    if (hHeapSnapshot == INVALID_HANDLE_VALUE)
    {
        MessageBox(NULL,"CreateToolhelp32Snapshot failed. (DumpRAM, 1)", "Error", MB_OK);
        return 0;
    }
    HeapList.dwSize = sizeof(HEAPLIST32);
    if (Heap32ListFirst(hHeapSnapshot, &HeapList) == FALSE)
    {
        MessageBox(NULL,"Heap32ListFirst failed. (DumpRAM, 1)", "Error", MB_OK);
        return 0;
    }
    FILE *BAH;
    BAH = fopen("bah.txt", "wt");
    if (!(BAH)) { MessageBox(NULL,"Unable to open file (LoadFile,1).","Error",0); return 0; }
    do
    {
        HeapEntry.dwSize = sizeof(HEAPENTRY32);
        if (Heap32First(&HeapEntry, HeapList.th32ProcessID, HeapList.th32HeapID) != FALSE)
        {
            do
            {
        sprintf(ErrTxt, "%x,%x", HeapEntry.dwAddress, HeapEntry.dwBlockSize);
        fprintf(BAH, "%s\n", ErrTxt);
//        MessageBox(NULL,ErrTxt,"debug",0);
//                ReadTheMemory(buffer, HeapEntry);
            } while (Heap32Next(&HeapEntry) != FALSE);
        }
        else
        {
            break; //error
        }
    } while (Heap32ListNext(hHeapSnapshot, &HeapList) != FALSE);
fclose(BAH);
//    } else {

//        EnumProcessModules(HookedProcess.hProcess, &hModule, sizeof(hModule), &cbNeeded);
//        GetModuleInformation(HookedProcess.hProcess, hModule, &ModuleInfo, sizeof(MODULEINFO));
//        RamStart = (DWORD)ModuleInfo.lpBaseOfDll;
//        chunksize = ModuleInfo.SizeOfImage;
//    }
/*
    if (*ramdata) { free(*ramdata); *ramdata = NULL; }
    if (!(*ramdata = (unsigned char*)malloc(chunksize+1))) {
        MessageBox(NULL, "Unable to allocate ramdata memory (DumpRAM,1).", "Error", MB_OK);
        return 0;
    }
    if (ReadProcessMemory(HookedProcess.hProcess, (void*)RamStart, *ramdata, chunksize, &bytesread) == 0) {
        sprintf(ErrTxt, "%x,%x,%x, %u", RamStart, chunksize, sizeof(buffer), GetLastError());
        MessageBox(NULL,ErrTxt,"Error",0);
    }
//    sprintf(ErrTxt, "%X", (DWORD)ModuleInfo.lpBaseOfDll);
    MessageBox(NULL,ErrTxt,"Debug",0);
free(*ramdata); *ramdata = NULL;
*/
    return 0;
}

/*
    if (!GetProcessMemoryInfo(HookedProcess.hProcess, &szProcessMemory, sizeof(PROCESS_MEMORY_COUNTERS))) {
        sprintf(ErrTxt, "GetProcessMemoryInfo failed (DumpRAM, 1) -- Error %u", GetLastError());
        MessageBox(NULL, ErrTxt, "Error", MB_OK);
        return 0;
    }
*/
FILE *BAH = fopen("bah.txt", "wt");
if (!(BAH)) { MessageBox(NULL,"Unable to open file (LoadFile,1).","Error",0); return 0; }

    PSAPI_WORKING_SET_INFORMATION wsInfo[20000];
    if (QueryWorkingSet(HookedProcess.hProcess, wsInfo, 20000*sizeof(PSAPI_WORKING_SET_INFORMATION)))
    {
        qsort( (void *)wsInfo->WorkingSetInfo[0].VirtualPage, wsInfo->NumberOfEntries, sizeof( ULONG_PTR ), compare4sort );
        for(i = 0; i < wsInfo->NumberOfEntries; i++)
        {
            sprintf(ErrTxt, "%08X", wsInfo->WorkingSetInfo[i].VirtualPage << 12);
        fprintf(BAH, "%s\n", ErrTxt);
        }
    }
fclose(BAH);
/*
    do
    {
        if (Heap32First(&HeapEntry, HeapList.th32ProcessID, HeapList.th32HeapID) != FALSE)
        {
            do
            {
        sprintf(ErrTxt, "%x,%x", HeapEntry.dwAddress, HeapEntry.dwBlockSize);
        fprintf(BAH, "%s\n", ErrTxt);
//        MessageBox(NULL,ErrTxt,"debug",0);
//                ReadTheMemory(buffer, HeapEntry);
            } while (Heap32Next(&HeapEntry) != FALSE);
        }
        else
        {
            break; //error
        }
    } while (Heap32ListNext(hHeapSnapshot, &HeapList) != FALSE);
*/

//    } else {

//        EnumProcessModules(HookedProcess.hProcess, &hModule, sizeof(hModule), &cbNeeded);
//        GetModuleInformation(HookedProcess.hProcess, hModule, &ModuleInfo, sizeof(MODULEINFO));
//        RamStart = (DWORD)ModuleInfo.lpBaseOfDll;
//        chunksize = ModuleInfo.SizeOfImage;
//    }
/*
    if (*ramdata) { free(*ramdata); *ramdata = NULL; }
    if (!(*ramdata = (unsigned char*)malloc(chunksize+1))) {
        MessageBox(NULL, "Unable to allocate ramdata memory (DumpRAM,1).", "Error", MB_OK);
        return 0;
    }
    if (ReadProcessMemory(HookedProcess.hProcess, (void*)RamStart, *ramdata, chunksize, &bytesread) == 0) {
        sprintf(ErrTxt, "%x,%x,%x, %u", RamStart, chunksize, sizeof(buffer), GetLastError());
        MessageBox(NULL,ErrTxt,"Error",0);
    }
//    sprintf(ErrTxt, "%X", (DWORD)ModuleInfo.lpBaseOfDll);
    MessageBox(NULL,ErrTxt,"Debug",0);
free(*ramdata); *ramdata = NULL;
*/


/*
int compare4sort(const void *arg1, const void *arg2) {
    if (arg1 > arg2) { return 1; }
    return -1;
}
*/
/*
int DumpHeap(u8 *buffer, HEAPENTRY32 heapentry)
{
//    CString     strLine, strArr, strTemp;
    BYTE        byte;
    DWORD dwBlock = 0, dwOffset, dwBytesRead;
//    BYTE * pBuffer = new BYTE[heapentry.dwBlockSize];
    HANDLE hProcess = NULL;
    if (NULL != pBuffer)
    {
        hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwProcessId);
        if(hProcess == NULL)
        {
            fprintf(outfile, "%s", BuildErrorMessage("OpenProcess"));
            return;
        }
        if (ReadProcessMemory( hProcess, (LPCVOID) heapentry.dwAddress, pBuffer, heapentry.dwBlockSize, &dwBytesRead) == TRUE)
        {
            for (dwBlock = 0; dwBlock < heapentry.dwBlockSize; dwBlock += 16)
            {
//                strLine.Format("[%08x]:  ", heapentry.dwAddress + dwBlock);
//                strArr.Empty();
                // we'll use 16 bytes per line
                for (dwOffset = 0; dwOffset < 16; dwOffset++)
                {
                    byte = *(pBuffer + dwBlock + dwOffset);
                    strLine.Format("%02x ", byte);
                    // account for non-printable characters
                    if (32 <= byte && byte < 127)
                        strArr += byte;
                    else
                        strArr += '';
                }
                if(LF32_FIXED == heapentry.dwFlags)
                    strTemp.Format("%s", "Fixed  ");
                else if(LF32_FREE == heapentry.dwFlags)
                    strTemp.Format("%s", "Free   ");
                else if(LF32_MOVEABLE == heapentry.dwFlags)
                    strTemp.Format("%s", "Movable");
                else    strTemp.Format("%s", "Unknown");

                strLine.Format ("%#x %#x %s %#x (%lu) %s ", heapentry.th32HeapID, heapentry.dwAddress, strTemp,heapentry.dwBlockSize, heapentry.dwBlockSize, strArr);
                 fprintf(outfile, "%s\n", strLine);
            }
        }
        else
        {
            strLine.Format ("%#x %#x %s %#x (%lu) %s ", heapentry.th32HeapID, heapentry.dwAddress, strTemp,heapentry.dwBlockSize, heapentry.dwBlockSize, strArr);if(LF32_FIXED == heapentry.dwFlags)
                strTemp.Format("%s", "Fixed  ");
            else if(LF32_FREE == heapentry.dwFlags)
                strTemp.Format("%s", "Free   ");
            else if(LF32_MOVEABLE == heapentry.dwFlags)
                strTemp.Format("%s", "Movable");
            else    strTemp.Format("%s", "Unknown");
            strLine.Format ("%#x %#x %s %#x (%lu)", heapentry.th32HeapID, heapentry.dwAddress,strTemp ,heapentry.dwBlockSize, heapentry.dwBlockSize);
            fprintf(outfile, " %s ", strLine);
            fprintf(outfile, "%s", BuildErrorMessage("ReadProcessMemory"));
        }
        delete [] pBuffer;
        CloseHandle( hProcess );
    }
}
*/


                                    char tmpstring[50];
                                    sprintf(tmpstring,"%I64u", 0xFFFFFFFFFFFFFFFFLL>>((8-csSize)*8));
                                    


    HANDLE hProcess = GetCurrentProcess(); // or however you get your process handle.

    DWORD Address = 0x10000;  // The first user-land address.

    MEMORY_BASIC_INFORMATION mbi;

    VirtualQueryEx(hProcess, (PVOID)Address, &mbi, sizeof(mbi));

    do

    {

        if (mbi.State != MEM_FREE)

        {

            DWORD page_attr = PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY;

            if (mbi.Protect & page_attr)

            {

                // Do something here.  Export to a file.

                printf("ADDRESS -> 0x%.8X\n\r", mbi.BaseAddress);

            };

        };

        Address += mbi.RegionSize;

    } while(VirtualQueryEx(hProcess, (PVOID)Address, &mbi, sizeof(mbi))); 




/****************************************		
working method
*****************************************/

    FILE *DumpFile = fopen(DumpName, "wb");
    if (!(DumpFile)) {
        sprintf(ErrTxt, "Unable to open dump file (DumpRAM,1) -- Error %u", GetLastError());
        MessageBox(NULL, ErrTxt, "Error", MB_OK);
        return 0;
    }
    fseek(DumpFile,0,SEEK_SET);

    MEMORY_BASIC_INFORMATION memInfo; memset(&memInfo,0,sizeof(MEMORY_BASIC_INFORMATION));
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    VOID* address = sysInfo.lpMinimumApplicationAddress;
    while (address < sysInfo.lpMaximumApplicationAddress)
	{
		VirtualQueryEx(HookedProcess.hProcess, address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
        address = memInfo.BaseAddress + memInfo.RegionSize;
//		if (memInfo.State != MEM_COMMIT) { continue; }
//		if (memInfo.Type != MEM_PRIVATE) { continue; }
		if (memInfo.State == MEM_FREE) { continue; }
		if ((memInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) == 0) { continue; }
		if (memInfo.Protect & (PAGE_NOACCESS|PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_GUARD)) { continue; }

        if (buffer) { free(buffer); buffer = NULL; }
        if (!(buffer = (unsigned char*)malloc((DWORD)memInfo.RegionSize+1))) {
            sprintf(ErrTxt, "Unable to allocate buffer memory (DumpRAM, 1) -- Error %u", GetLastError());
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            return 0;
        }

        if (ReadProcessMemory(HookedProcess.hProcess, memInfo.BaseAddress, buffer, memInfo.RegionSize, &bytesread) == 0) {
                //fail
            sprintf(ErrTxt, "Unable to dump RAM from process (DumpRAM, 2) -- Error %u\nAddress: %08X\nRegion Size: %X\nProtection: %08X\n State: %X, Type: %X", GetLastError(), memInfo.BaseAddress, memInfo.RegionSize, memInfo.Protect, memInfo.State, memInfo.Type);
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            free(buffer); buffer = NULL;
            fclose(DumpFile);
            return 0;
        }
        fwrite(buffer,1,memInfo.RegionSize,DumpFile);
        filesize += memInfo.RegionSize;
	}
	free(buffer); buffer = NULL;
    fclose(DumpFile);

BOOL CALLBACK GetWindowFromProcessID(HWND hWnd, LPARAM lParam)
{
    static HWND hWnd2Find;
    static DWORD dwMatchProcessID;

    if(lParam != 0){
        dwMatchProcessID = (DWORD)hWnd;
        if(EnumWindows(GetWindowFromProcessID, 0))
            return FALSE;
        *(HWND *)lParam = hWnd2Find;
    }
    else{
        DWORD dwPID = 0;
        GetWindowThreadProcessId(hWnd, &dwPID);
        if(dwMatchProcessID == dwPID)
        {
            hWnd2Find = hWnd;
            return FALSE;
        }
    }
    return TRUE;
}

/*******************************************
Get System CMB (combo index)
********************************************/
int GetSystemCMB(u32 sys)
{
    switch (sys)
    {
        case SYSTEM_PC: { return 0; }
        case SYSTEM_N64: { return 1; }
        case SYSTEM_PS1: { return 2; }
        case SYSTEM_PS2: { return 3; }
        case SYSTEM_GBA: { return 4; }
        case SYSTEM_DS: { return 5; }
    }
    return 0;
}

/**********************************************
Toggle Control - enable/disable a control (1/0)
***********************************************/
int ToggleControl(HWND hControl, int Enable)
{
    DWORD dwStyle = GetWindowLong(hControl, GWL_STYLE);
    if(Enable) { return SetWindowLong(hControl, GWL_STYLE, dwStyle & ~WS_DISABLED); }
    return SetWindowLong(hControl, GWL_STYLE, dwStyle|WS_DISABLED);
}

int CodeFromString(char* code, int start, int length, int size, u32 *value)
{
    char tmpcode[10];
    int i, x = 0;
    for (i = start; i < length; i++)
    {
        if ((code[i] == ' ') || (code[i] == '\n')) { continue; }
        if (!isxdigit(code[i])) { return -1; }
        tmpcode[x] = code[i];
        if (x = (size - 1)) {
            tmpcode[size] = '\0';
            String2Hex(tmpcode, value);
            return i + 1;
        }
        x++;
    }
    if (i > start) { return -1; }
    else { return length; }
}

/**************************************************************
Game List Procedure
/**************************************************************/
LRESULT CALLBACK GameListProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_VSCROLL: case WM_MOUSEWHEEL:
        {
            if (lvGameNameEdit.Status) { SendMessage(hTabDlgs[CHEAT_TAB], WM_COMMAND, LSV_CHEAT_GAME_ENDEDIT, 0); }
        } break;
        case LVM_SETSELECTIONMARK:
        {
            if (lParam <= 0) { SendMessage(GetDlgItem(hTabDlgs[CHEAT_TAB], LSV_CHEAT_CODES), LVM_DELETEALLITEMS, 0, 0); break; }
            u32 GameNum = ListViewGetHex(hwnd, lParam, 1);
            ListCodes(GameNum);
            SetWindowText(GetDlgItem(hTabDlgs[CHEAT_TAB], TXT_CHEAT_CODE), "");
            SetWindowText(GetDlgItem(hTabDlgs[CHEAT_TAB], TXT_CHEAT_NOTE), "");
        } break;
        case WM_LBUTTONDOWN:
        {
            int iGame = ListViewHitTst(hwnd, GetMessagePos(), -1);
            if (iGame <= 0) { SendMessage(GetDlgItem(hTabDlgs[CHEAT_TAB], LSV_CHEAT_CODES), LVM_DELETEALLITEMS, 0, 0); break; }
            u32 GameNum = ListViewGetHex(hwnd, iGame, 1);
            ListCodes(GameNum);
            SetWindowText(GetDlgItem(hTabDlgs[CHEAT_TAB], TXT_CHEAT_CODE), "");
            SetWindowText(GetDlgItem(hTabDlgs[CHEAT_TAB], TXT_CHEAT_NOTE), "");
        } break;
        case WM_LBUTTONDBLCLK:
        {
            if (lvGameNameEdit.Status) { SendMessage(hTabDlgs[CHEAT_TAB], WM_COMMAND, LSV_CHEAT_GAME_ENDEDIT, 0); }
            int iSelected = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
            if (iSelected < 0) { break; }
            SendMessage(hTabDlgs[CHEAT_TAB], WM_COMMAND, LSV_CHEAT_GAME_BEGINEDIT, MAKELPARAM(iSelected, 0));
        } break;
        case WM_NOTIFY:
        {
                if (((NMHDR*)lParam)->code == HDN_BEGINTRACKW) { return TRUE; }
                if (((NMHDR*)lParam)->code == HDN_BEGINTRACKA) { return TRUE; }
        } break;
        case WM_KEYUP:
        {
            if (wParam == VK_DELETE) {
                int iGame = SendMessage(hwnd, LVM_GETSELECTIONMARK, 0, 0);
                if (iGame <= 0) { break; }
                u32 GameNum = ListViewGetHex(hwnd, iGame, 1);
                memset(&CheatDB.Games[GameNum], 0, sizeof(CHEAT_GAME));
                SendMessage(hwnd, LVM_DELETEITEM, iGame, 0);
            }
        } break;
    }
    if (oldGameListProc) { return CallWindowProc (oldGameListProc, hwnd, message, wParam, lParam); }
    else { return DefWindowProc (hwnd, message, wParam, lParam); }
}

/**************************************************************
Game Name Edit Procedure
/**************************************************************/
LRESULT CALLBACK GameNameEditProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_CHAR:
        {
            if ((wParam == VK_BACK) || (wParam == 24) || (wParam == 3) || (wParam == 22) || (wParam == VK_RETURN) || (wParam == VK_SPACE)) { break; } //cut/copy/paste/backspace
            if (wParam == 1) { SendMessage(hwnd, EM_SETSEL, 0, -1); } //select all
        } break;
        case WM_KILLFOCUS:
        {
            SendMessage(hTabDlgs[CHEAT_TAB], WM_COMMAND, LSV_CHEAT_GAME_ENDEDIT, 0);
        } return 0;
        case WM_KEYDOWN:
        {
            if (wParam == VK_RETURN) { SendMessage(hTabDlgs[CHEAT_TAB], WM_COMMAND, LSV_CHEAT_GAME_ENDEDIT, 1); }
            if (wParam == VK_ESCAPE) { SendMessage(hTabDlgs[CHEAT_TAB], WM_COMMAND, LSV_CHEAT_GAME_ENDEDIT, 0); }
        } break;
    }
    if (oldGameNameEditProc) { return CallWindowProc (oldGameNameEditProc, hwnd, message, wParam, lParam); }
    else { return DefWindowProc (hwnd, message, wParam, lParam); }
}

                case LSV_CHEAT_GAME_BEGINEDIT:
                {
                    //remember if codes are on/off
//			        if (lvGameNameEdit.Status) { MessageBox(NULL,"Already editing. WTF? (LSV_CHEAT_GAME_BEGINEDIT)","Error",0); break; }
			        lvGameNameEdit.iItem = LOWORD(lParam);
			        lvGameNameEdit.iSubItem = HIWORD(lParam);
			        RECT lvEditRect; memset(&lvEditRect,0,sizeof(RECT));
			        lvEditRect.top = 0;
			        lvEditRect.left = LVIR_LABEL;
			        SendMessage(hGameList, LVM_GETSUBITEMRECT, lvGameNameEdit.iItem, (LPARAM)&lvEditRect);
			        char txtGameName[CODE_MAX_GAME_NAME];
			        ListViewGetText(hGameList, lvGameNameEdit.iItem, lvGameNameEdit.iSubItem, txtGameName, CODE_MAX_GAME_NAME);
			        SetWindowText(hGameName, txtGameName);
			        WINDOWPLACEMENT lvPlace; memset(&lvPlace,0,sizeof(WINDOWPLACEMENT));
			        lvPlace.length = sizeof(WINDOWPLACEMENT);
			        GetWindowPlacement(hGameList, &lvPlace);
			        POINT lvPos;
			        lvPos.x = lvPlace.rcNormalPosition.left;
			        lvPos.y = lvPlace.rcNormalPosition.top;
			        SetWindowPos(hGameName,HWND_TOP,lvPos.x+lvEditRect.left+3,lvPos.y+lvEditRect.top+1,(lvEditRect.right-lvEditRect.left),(lvEditRect.bottom-lvEditRect.top)+1,SWP_SHOWWINDOW);
			        SetFocus(hGameName);
			        SendMessage(hGameName, EM_SETSEL, 0, -1);
			        lvGameNameEdit.Status = 1;
                } break;
                case LSV_CHEAT_GAME_ENDEDIT:
                {
			        if ((!lvGameNameEdit.Status) || (!lParam)) {
			            SetWindowPos(hGameName,HWND_BOTTOM,0,0,0,0,SWP_HIDEWINDOW);
			            lvGameNameEdit.Status = 0;
			            SetFocus(hGameList); break;
                    }
                    lvGameNameEdit.Status = 0;
                    SetWindowPos(hGameName,HWND_BOTTOM,0,0,0,0,SWP_HIDEWINDOW);
                    SetFocus(hGameList);
                    u32 GameNum = ListViewGetHex(hGameList, lvGameNameEdit.iItem, 1);
                    if (GameNum == CODE_MAX_GAMES) {
                        GameNum = FindEmptyGame();
                        if (GameNum == CODE_MAX_GAMES) { break; }
                    }
			        char txtGameNum[9]; sprintf(txtGameNum, "%x", GameNum);
			        GetWindowText(hGameName, CheatDB.Games[GameNum].Name, CODE_MAX_GAME_NAME);
			        if (lvGameNameEdit.iItem) {
                        ListViewSetRow(hGameList, lvGameNameEdit.iItem, lvGameNameEdit.iSubItem, 1, CheatDB.Games[GameNum].Name);
                    } else {
                        ListViewAddRow(hGameList, 2, CheatDB.Games[GameNum].Name, txtGameNum);
                        SendMessage(hGameList, LVM_SETSELECTIONMARK, 0, SendMessage(hGameList, LVM_GETITEMCOUNT, 0, 0)-1);
                        ListView_SetItemState(hGameList, SendMessage(hGameList, LVM_GETITEMCOUNT, 0, 0)-1, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
                    }
                    Settings.Cheat.dbModified = 1;
                } break;

/**************************************************************
ListCodes - fill the code list with codes for GameNum
/**************************************************************/
int ListCodes()
{
    HWND hCodeList = GetDlgItem(hTabDlgs[CHEAT_TAB], LSV_CHEAT_CODES);
    SendMessage(hCodeList,LVM_DELETEALLITEMS,0,0);
    char txtCodeNum[9];
    sprintf(txtCodeNum, "%x", CODE_MAX_PER_GAME);
    ListViewAddRow(hCodeList, 2, "New Code", txtCodeNum);
    int i, count = 0;
    for (i = 0; i < CODE_MAX_PER_GAME; i++)
    {
        if ((CheatDB.Games[GameNum].Codes[i].Address[0]) && (strlen(CheatDB.Games[GameNum].Codes[i].Name))) {
            sprintf(txtCodeNum, "%x", i);
            ListViewAddRow(hCodeList, 2, CheatDB.Games[GameNum].Codes[i].Name, txtCodeNum);
            count++;
        }
    }
    return 1;
}

/**************************************************************
FindEmptyGame - Finds the first empty game entry in the list
/**************************************************************/
u32 FindEmptyGame()
{
    int i;
    for (i = 0; i < CODE_MAX_GAMES; i++)
    {
        if (!strlen(CheatDB.Games[i].Name)) { return i; }
    }
    return CODE_MAX_GAMES;
}

/**************************************************************
Is Code String - may not be needed
/**************************************************************/
int IsCodeString(char *Code, int length)
{
    int i;
    for (i = 0; i < length; i++)
    {
        if ((!isxdigit(Code[i])) && (Code[i] != ' ') && (Code[i] != '\n') && (Code[i] != '\r')) { return 0; }
    }
    return 1;
}

/**************************************************************
Copy Bytes
/**************************************************************/
int CopyBytesCode(u32 source, u32 dest, u32 bytes, endian)
{
    int i;
    u64 tmpValue;
    
    {
        if (ReadRAM(source, &tmpValue, 1, endian)) { WriteRAM(dest, tmpValue, 1, endian); }
    }
}

#if (EMU_INTEGRATE == 1) //Mupen
void NOTCOMPILED();
typedef struct _reg_cache_struct
{
   int need_map;
   void *needed_registers[8];
   unsigned char jump_wrapper[62];
   int need_cop1_check;
} reg_cache_struct;
typedef struct _precomp_instr
{
   void (*ops)();
   union
     {
	struct
	  {
	     long long int *rs;
	     long long int *rt;
	     short immediate;
	  } i;
	struct
	  {
	     unsigned long inst_index;
	  } j;
	struct
	  {
	     long long int *rs;
	     long long int *rt;
	     long long int *rd;
	     unsigned char sa;
	     unsigned char nrd;
	  } r;
	struct
	  {
	     unsigned char base;
	     unsigned char ft;
	     short offset;
	  } lf;
	struct
	  {
	     unsigned char ft;
	     unsigned char fs;
	     unsigned char fd;
	  } cf;
     } f;
   unsigned long addr;
   unsigned long local_addr;
   reg_cache_struct reg_cache_infos;
} precomp_instr;
typedef struct _precomp_block
{
   precomp_instr *block;
   unsigned int start;
   unsigned int end;
   unsigned char *code;
   unsigned int code_length;
   unsigned int max_code_length;
   void *jumps_table;
   int jumps_number;
   //unsigned char md5[16];
   unsigned long adler32;
} precomp_block;
#endif


/**********************************************
Find NDS RAM - working method, but the hex string appears at both start of RAM and ROM
***********************************************/
u32 FindNDSRAM()
{
    u32 i;
    u8 *buffer = NULL;
    DWORD bytesread;
    MEMORY_BASIC_INFORMATION memInfo; memset(&memInfo,0,sizeof(MEMORY_BASIC_INFORMATION));
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    VOID* address = (VOID*)0x11000;

    while (address < sysInfo.lpMaximumApplicationAddress) //stop during map lookup???
	{
        VirtualQueryEx(HookedProcess.hProcess, address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
        address = memInfo.BaseAddress + memInfo.RegionSize;
//        if (memInfo.BaseAddress == ModuleInfo.lpBaseOfDll) { continue; }
//		if (memInfo.State != MEM_COMMIT) { continue; }
//		if (memInfo.Type != MEM_PRIVATE) { continue; }
		if (memInfo.State == MEM_FREE) { continue; }
		if ((memInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) == 0) { continue; }
		if (memInfo.Protect & (PAGE_NOACCESS|PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_GUARD)) { continue; }

        if (buffer) { free(buffer); buffer = NULL; }
        if (!(buffer = (unsigned char*)malloc((DWORD)memInfo.RegionSize+1))) {
            sprintf(ErrTxt, "Unable to allocate buffer memory (DumpRAM, 2) -- Error %u", GetLastError());
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            return 0;
        }
        if (ReadProcessMemory(HookedProcess.hProcess, memInfo.BaseAddress, buffer, memInfo.RegionSize, &bytesread) == 0) {
                //fail
            sprintf(ErrTxt, "Unable to dump RAM from process (DumpRAM, 3) -- Error %u\nAddress: %08X\nRegion Size: %X\nProtection: %08X\n State: %X, Type: %X", GetLastError(), memInfo.BaseAddress, memInfo.RegionSize, memInfo.Protect, memInfo.State, memInfo.Type);
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            free(buffer); buffer = NULL;
            return 0;
        }
        for (i = 0; i < memInfo.RegionSize; i += 4)
        {
            if ((*(u32*)(&buffer[i]) == 0xE7FFDEFF) && (*(u32*)(&buffer[i + 4]) == 0xE7FFDEFF) && (*(u32*)(&buffer[i + 8]) == 0xE7FFDEFF)) {
                Settings.Hook.StartAddress = (DWORD)memInfo.BaseAddress + i;
                return Settings.Hook.StartAddress;
            }
        }
        
//fprintf(BAH, "%08X, %X\n", (DWORD)memInfo.BaseAddress, memInfo.RegionSize);
//        putw(filesize,MapFile);
	}
//fclose(BAH);
	free(buffer); buffer = NULL;

//sprintf(ErrTxt, "%08X, %08X, %08X, %08X", address, memInfo.BaseAddress, memInfo.RegionSize, memInfo.State);
//sprintf(ErrTxt, "%u", NumEntries);
//MessageBox(NULL, ErrTxt, "Error", MB_OK);
    return 0;
}


/**********************************************
Find NDS RAM - junk
***********************************************/
u32 FindNDSRAM()
{
    u32 i, e;
    u8 *buffer = NULL;
    u32 HeadersFound[10]; memset(&HeadersFound, 0, sizeof(HeadersFound));
    char HeaderCount = 0;
    char pass = 0;
    DWORD bytesread;
    MEMORY_BASIC_INFORMATION memInfo; memset(&memInfo,0,sizeof(MEMORY_BASIC_INFORMATION));
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    VOID* address = (VOID*)0x11000;
    for (pass = 0; pass < 2; pass++)
    {
    while (address < sysInfo.lpMaximumApplicationAddress) //stop during map lookup???
	{
        VirtualQueryEx(HookedProcess.hProcess, address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
        address = memInfo.BaseAddress + memInfo.RegionSize;
//        if (memInfo.BaseAddress == ModuleInfo.lpBaseOfDll) { continue; }
//		if (memInfo.State != MEM_COMMIT) { continue; }
//		if (memInfo.Type != MEM_PRIVATE) { continue; }
		if (memInfo.State == MEM_FREE) { continue; }
		if ((memInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) == 0) { continue; }
		if (memInfo.Protect & (PAGE_NOACCESS|PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_GUARD)) { continue; }

        if (buffer) { free(buffer); buffer = NULL; }
        if (!(buffer = (unsigned char*)malloc((DWORD)memInfo.RegionSize+1))) {
            sprintf(ErrTxt, "Unable to allocate buffer memory (DumpRAM, 2) -- Error %u", GetLastError());
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            return 0;
        }
        if (ReadProcessMemory(HookedProcess.hProcess, memInfo.BaseAddress, buffer, memInfo.RegionSize, &bytesread) == 0) {
                //fail
            sprintf(ErrTxt, "Unable to dump RAM from process (DumpRAM, 3) -- Error %u\nAddress: %08X\nRegion Size: %X\nProtection: %08X\n State: %X, Type: %X", GetLastError(), memInfo.BaseAddress, memInfo.RegionSize, memInfo.Protect, memInfo.State, memInfo.Type);
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            free(buffer); buffer = NULL;
            return 0;
        }
        for (i = 0; i < memInfo.RegionSize; i += 8)
        {
            if (pass == 0) {
                if ((*(u32*)(&buffer[i]) == 0xE7FFDEFF) && (*(u32*)(&buffer[i + 4]) == 0xE7FFDEFF) && (*(u32*)(&buffer[i + 8]) == 0xE7FFDEFF)) {
                    if (HeaderCount >= 10) { break; }
                    HeadersFound[HeaderCount] = *(u32*)(&buffer[i]);
                    HeaderCount++;
                }
//                Settings.Hook.StartAddress = (DWORD)memInfo.BaseAddress + i;
//                return Settings.Hook.StartAddress;
            } else {
                for (e = 0; e < HeaderCount; e++)
                {
                    if ((*(u32*)(&buffer[i]) <= HeadersFound[e]) && (*(u32*)(&buffer[i+4]) > HeadersFound[e]) &&
                        ((*(u32*)(&buffer[i+4]) - (*(u32*)(&buffer[i]))) == 0x400000)) {
                        bytesread = *(u32*)(&buffer[i]);
                    }
                }
            }
        }
	}
	}
//fclose(BAH);
	free(buffer); buffer = NULL;

//sprintf(ErrTxt, "%08X, %08X, %08X, %08X", address, memInfo.BaseAddress, memInfo.RegionSize, memInfo.State);
//sprintf(ErrTxt, "%u", NumEntries);
//MessageBox(NULL, ErrTxt, "Error", MB_OK);
    return 0;
}

//NDS Specific checks
    if (Settings.Hook.System == SYSTEM_NDS) {
        u32 NDSCheck = 0;
        ReadProcessMemory(HookedProcess.hProcess, (void*)Settings.Hook.StartAddress, &NDSCheck, 4, &bytesread);
        if (NDSCheck == 0xE7FFDEFF) {
            RamStart = Settings.Hook.StartAddress - Settings.Hook.EntryOffset;
        } else {
            if (!(RamStart = FindNDSRAM())) {
                sprintf(ErrTxt, "Unable to verify NDS RAM start location (DumpRAM, 1) -- Error %u", GetLastError());
                MessageBox(NULL, ErrTxt, "Error", MB_OK);
                return 0;
            }
        }
    }
//NDS Specific checks

/**********************************************
Find NDS RAM - working method, but the hex string appears at both start of RAM and ROM
***********************************************/
u32 FindNDSRAM()
{
    u32 i;
    u8 *buffer = NULL;
    DWORD bytesread;
    u32 NDSCheck = 0;
    //update this to include the offset and/or pointers
    ReadProcessMemory(HookedProcess.hProcess, (void*)Settings.Hook.StartAddress, &NDSCheck, 4, &bytesread);
    if (NDSCheck == 0xE7FFDEFF) {
        return Settings.Hook.StartAddress - Settings.Hook.EntryOffset;
    }
    MEMORY_BASIC_INFORMATION memInfo; memset(&memInfo,0,sizeof(MEMORY_BASIC_INFORMATION));
    SYSTEM_INFO sysInfo;
    GetSystemInfo(&sysInfo);
    VOID* address = (VOID*)0x11000;

    while (address < sysInfo.lpMaximumApplicationAddress) //stop during map lookup???
	{
        VirtualQueryEx(HookedProcess.hProcess, address, &memInfo, sizeof(MEMORY_BASIC_INFORMATION));
        address = memInfo.BaseAddress + memInfo.RegionSize;
//        if (memInfo.BaseAddress == ModuleInfo.lpBaseOfDll) { continue; }
//		if (memInfo.State != MEM_COMMIT) { continue; }
//		if (memInfo.Type != MEM_PRIVATE) { continue; }
		if (memInfo.State == MEM_FREE) { continue; }
		if ((memInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)) == 0) { continue; }
		if (memInfo.Protect & (PAGE_NOACCESS|PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_GUARD)) { continue; }

        if (buffer) { free(buffer); buffer = NULL; }
        if (!(buffer = (unsigned char*)malloc((DWORD)memInfo.RegionSize+1))) {
            sprintf(ErrTxt, "Unable to allocate buffer memory (DumpRAM, 2) -- Error %u", GetLastError());
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            return 0;
        }
        if (ReadProcessMemory(HookedProcess.hProcess, memInfo.BaseAddress, buffer, memInfo.RegionSize, &bytesread) == 0) {
                //fail
            sprintf(ErrTxt, "Unable to dump RAM from process (DumpRAM, 3) -- Error %u\nAddress: %08X\nRegion Size: %X\nProtection: %08X\n State: %X, Type: %X", GetLastError(), memInfo.BaseAddress, memInfo.RegionSize, memInfo.Protect, memInfo.State, memInfo.Type);
            MessageBox(NULL, ErrTxt, "Error", MB_OK);
            free(buffer); buffer = NULL;
            return 0;
        }
        for (i = 0; i < memInfo.RegionSize; i += 4)
        {
            if ((*(u32*)(&buffer[i]) == 0xE7FFDEFF) && (*(u32*)(&buffer[i + 4]) == 0xE7FFDEFF) && (*(u32*)(&buffer[i + 8]) == 0xE7FFDEFF)) {
                Settings.Hook.StartAddress = (DWORD)memInfo.BaseAddress + i;
                Settings.Hook.StartType = RAM_STATIC;
                SendMessage(hTabDlgs[HOOK_TAB], WM_COMMAND, VCMD_HOOK_SHOW_SETTS, 0);
                return Settings.Hook.StartAddress;
            }
        }
	}
	free(buffer); buffer = NULL;

    return 0;
}
