| 1 | /* $Id: k32ProcessReadWrite.cpp,v 1.2 2001-02-10 11:11:44 bird Exp $
|
|---|
| 2 | *
|
|---|
| 3 | * k32ProcessReadWrite - Read or write to another process.
|
|---|
| 4 | *
|
|---|
| 5 | * Copyright (c) 2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
|
|---|
| 6 | *
|
|---|
| 7 | * Project Odin Software License can be found in LICENSE.TXT
|
|---|
| 8 | *
|
|---|
| 9 | */
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 | /*******************************************************************************
|
|---|
| 13 | * Defined Constants And Macros *
|
|---|
| 14 | *******************************************************************************/
|
|---|
| 15 | #define INCL_DOSMEMMGR
|
|---|
| 16 | #define INCL_DOSERRORS
|
|---|
| 17 |
|
|---|
| 18 | #define INCL_OS2KRNL_TK
|
|---|
| 19 | #define INCL_OS2KRNL_PTDA
|
|---|
| 20 | #define INCL_OS2KRNL_VM
|
|---|
| 21 | #define INCL_OS2KRNL_SEM
|
|---|
| 22 | #define INCL_OS2KRNL_LDR
|
|---|
| 23 | #define NO_WIN32K_LIB_FUNCTIONS
|
|---|
| 24 |
|
|---|
| 25 | /*******************************************************************************
|
|---|
| 26 | * Header Files *
|
|---|
| 27 | *******************************************************************************/
|
|---|
| 28 | #include <os2.h>
|
|---|
| 29 |
|
|---|
| 30 | #include "devSegDf.h" /* Win32k segment definitions. */
|
|---|
| 31 | #include "OS2Krnl.h"
|
|---|
| 32 | #include "win32k.h"
|
|---|
| 33 | #include "k32.h"
|
|---|
| 34 | #include "options.h"
|
|---|
| 35 | #include "dev32.h"
|
|---|
| 36 | #include "log.h"
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 | /**
|
|---|
| 40 | * Reads or write memory in another process.
|
|---|
| 41 | * @returns OS2 returncode.
|
|---|
| 42 | * @param pid Process ID which is to be written to.
|
|---|
| 43 | * @param cb Number of bytes to write.
|
|---|
| 44 | * @param pvSource Pointer to data to read.
|
|---|
| 45 | * @param pvTarget Pointer to where to write.
|
|---|
| 46 | * @param fRead TRUE: pvSource is within pid while pvTarget is ours.
|
|---|
| 47 | * FALSE: pvTarget is within pid while pvSource is ours.
|
|---|
| 48 | * @status completely implelemented.
|
|---|
| 49 | * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
|
|---|
| 50 | * @remark
|
|---|
| 51 | */
|
|---|
| 52 | APIRET k32ProcessReadWrite(PID pid, ULONG cb, PVOID pvSource, PVOID pvTarget, BOOL fRead)
|
|---|
| 53 | {
|
|---|
| 54 | ULONG ulAddrAlias;
|
|---|
| 55 | ULONG cbAlias;
|
|---|
| 56 | APIRET rc;
|
|---|
| 57 | PPTDA pPTDA;
|
|---|
| 58 | HPTDA hPTDA;
|
|---|
| 59 | VMAC vmac;
|
|---|
| 60 |
|
|---|
| 61 | /*
|
|---|
| 62 | * Find alias address and size and validate them a little.
|
|---|
| 63 | */
|
|---|
| 64 | ulAddrAlias = (ULONG)(fRead ? pvSource : pvTarget) & ~0xfffUL;
|
|---|
| 65 | cbAlias = (cb + 0xfffUL) & ~0xfffUL;
|
|---|
| 66 | if (cbAlias - 1 + ulAddrAlias < ulAddrAlias)
|
|---|
| 67 | return ERROR_INVALID_ACCESS;
|
|---|
| 68 |
|
|---|
| 69 | /*
|
|---|
| 70 | * Find the PTDA for the given PID.
|
|---|
| 71 | */
|
|---|
| 72 | pPTDA = NULL;
|
|---|
| 73 | rc = TKPidToPTDA(pid, (PPPTDA)SSToDS(&pPTDA));
|
|---|
| 74 | if (rc != NO_ERROR || pPTDA == NULL ||
|
|---|
| 75 | (hPTDA = ptdaGet_ptda_handle(pPTDA)) == 0 || hPTDA == (USHORT)-1
|
|---|
| 76 | )
|
|---|
| 77 | {
|
|---|
| 78 | kprintf(("k32ProcessReadWrite: Failed with invalid PID.\n"));
|
|---|
| 79 | return rc != NO_ERROR ? rc : ERROR_INVALID_PARAMETER;
|
|---|
| 80 | }
|
|---|
| 81 |
|
|---|
| 82 | /*
|
|---|
| 83 | * Take loader semaphore before calling VMMapDebugAlias.
|
|---|
| 84 | */
|
|---|
| 85 | rc = LDRRequestSem();
|
|---|
| 86 | if (rc != NO_ERROR)
|
|---|
| 87 | {
|
|---|
| 88 | kprintf(("k32ProcessReadWrite: LDRRequestSem failed with rc=%d\n", rc));
|
|---|
| 89 | return rc;
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 | /*
|
|---|
| 93 | * Allocate alias.
|
|---|
| 94 | */
|
|---|
| 95 | rc = VMMapDebugAlias(VMMDA_ARENASYSTEM | (fRead ? VMMDA_READONLY : 0),
|
|---|
| 96 | ulAddrAlias,
|
|---|
| 97 | cbAlias,
|
|---|
| 98 | hPTDA,
|
|---|
| 99 | (PVMAC)SSToDS(&vmac));
|
|---|
| 100 | LDRClearSem();
|
|---|
| 101 | if (rc != NO_ERROR)
|
|---|
| 102 | {
|
|---|
| 103 | kprintf(("k32ProcessReadWrite: VMMapDebugAlias failed with rc=%d\n"));
|
|---|
| 104 | return rc;
|
|---|
| 105 | }
|
|---|
| 106 |
|
|---|
| 107 | /*
|
|---|
| 108 | * Copy data.
|
|---|
| 109 | */
|
|---|
| 110 | if (fRead)
|
|---|
| 111 | pvSource = (PVOID)(vmac.ac_va + ((ULONG)pvSource & 0xfff));
|
|---|
| 112 | else
|
|---|
| 113 | pvTarget = (PVOID)(vmac.ac_va + ((ULONG)pvTarget & 0xfff));
|
|---|
| 114 | rc = TKSuFuBuff(pvTarget,
|
|---|
| 115 | pvSource,
|
|---|
| 116 | cb,
|
|---|
| 117 | TK_FUSU_NONFATAL | TK_FUSU_USER_SRC | TK_FUSU_USER_DST);
|
|---|
| 118 | if (rc != NO_ERROR)
|
|---|
| 119 | kprintf(("k32ProcessReadWrite: TKSuFuBuff failed with rc=%d\n"));
|
|---|
| 120 |
|
|---|
| 121 | /*
|
|---|
| 122 | * Cleanup and exit.
|
|---|
| 123 | */
|
|---|
| 124 | pPTDA = ptdaGetCur();
|
|---|
| 125 | if (pPTDA == NULL || (hPTDA = ptdaGet_ptda_handle(pPTDA)) == 0 || hPTDA == (USHORT)-1)
|
|---|
| 126 | kprintf(("k32ProcessReadWrite: Failed to get hPTDA of current process\n"));
|
|---|
| 127 | if (VMFreeMem(vmac.ac_va, hPTDA, 0))
|
|---|
| 128 | kprintf(("k32ProcessReadWrite: VMFreeMem failed!\n"));
|
|---|
| 129 |
|
|---|
| 130 | return rc;
|
|---|
| 131 | }
|
|---|
| 132 |
|
|---|
| 133 |
|
|---|