Index: reactos/ntoskrnl/kdbg/kdb_cli.c =================================================================== --- reactos/ntoskrnl/kdbg/kdb_cli.c (revision 74444) +++ reactos/ntoskrnl/kdbg/kdb_cli.c (working copy) @@ -67,6 +67,7 @@ static BOOLEAN KdbpCmdEvalExpression(ULONG Argc, PCHAR Argv[]); static BOOLEAN KdbpCmdDisassembleX(ULONG Argc, PCHAR Argv[]); +static BOOLEAN KdbpCmdWriteMem(ULONG Argc, PCHAR Argv[]); static BOOLEAN KdbpCmdRegs(ULONG Argc, PCHAR Argv[]); static BOOLEAN KdbpCmdBackTrace(ULONG Argc, PCHAR Argv[]); @@ -139,6 +140,7 @@ { "?", "? expression", "Evaluate expression.", KdbpCmdEvalExpression }, { "disasm", "disasm [address] [L count]", "Disassemble count instructions at address.", KdbpCmdDisassembleX }, { "x", "x [address] [L count]", "Display count dwords, starting at addr.", KdbpCmdDisassembleX }, + { "w", "w address V value", "Write byte value at addr..", KdbpCmdWriteMem }, { "regs", "regs", "Display general purpose registers.", KdbpCmdRegs }, { "cregs", "cregs", "Display control registers.", KdbpCmdRegs }, { "sregs", "sregs", "Display status registers.", KdbpCmdRegs }, @@ -3782,3 +3784,88 @@ /* Return the length */ return i; } + +/*!\brief Writes 1 byte to memory at given address. + */ +static BOOLEAN +KdbpCmdWriteMem(ULONG Argc, PCHAR Argv[]) +{ + ULONG Value=0; + ULONG ul=0; + ULONGLONG Result = 0; + ULONG_PTR Address; + + + /* Evaluate the value expression */ + if (Argc >= 2) + { + /* Check for [V value] part with space after 'v' */ + if ((strcmp(Argv[Argc-2], "V") == 0) || (strcmp(Argv[Argc-2], "v") == 0)) + { + ul = strtoul(Argv[Argc-1], NULL, 0); + Value = ul; + Argc -= 2; + } + /* Check for [Vvalue] part with no space after 'v' */ + else if ((Argv[Argc-1][0] == 'V') || (Argv[Argc-1][0] == 'v')) + { + ul = strtoul(Argv[Argc-1] + 1, NULL, 0); + Value = ul; + Argc--; + } + else + /* there must not have been a 'v' or 'V' and we need a value */ + { + KdbpPrint("Warning: v: Value argument required.\n"); + return TRUE; + } + + + /* Put the remaining arguments back together */ + Argc--; + for (ul = 1; ul < Argc; ul++) + { + Argv[ul][strlen(Argv[ul])] = ' '; + } + Argc++; + } + + /* Evaluate the address expression */ + if (Argc > 1) + { + if (!KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result)) + return TRUE; + + if (Result > (ULONGLONG)(~((ULONG_PTR)0))) + KdbpPrint("Warning: Address %I64x is being truncated\n",Result); + + Address = (ULONG_PTR)Result; + } + else + /* there must not have been an address expression */ + { + KdbpPrint("Warning: w: Address argument required.\n"); + return TRUE; + } + + /* make sure that our value to write is only byte sized */ + if (Value > 0xFF) + { + KdbpPrint("Warning: Value %x was truncated to %#04x\n", Value, (Value & 0xFF)); + Value = Value & 0xff; + } + + /* address of where to write byte */ + if (!KdbSymPrintAddress((PVOID)Address, NULL)) + KdbpPrint("<%x>:", Address); + else + KdbpPrint(":"); + + /* Write byte */ + if (!(KdpSafeWriteMemory((ULONG_PTR)Address, 1, Value))) + KdbpPrint(" ????????\n"); + else + KdbpPrint("Writing %08x with %#04x\n", Address, Value); + + return TRUE; +}