bool FUNCMESSAGEFIX::execute(void) { VPVOID scriptaddr; VMREGTYPE addr; const char* str; USHORT mboxhdr[2]; int len = 0; unsigned char buttonlen = 0; unsigned char buttoncount = 0; // we want to modify the real script SCDT info scriptaddr = (VPVOID)machine.GetScript(); if (!GetOffsetData(machine, scriptaddr, OFFSET_SCDT, (ULONG*)&scriptaddr)) return false; scriptoffset += (ULONG)scriptaddr; // must be followed by messagebox opcode and length machine.ReadMem(scriptoffset,(VPVOID)mboxhdr,sizeof(mboxhdr)); scriptoffset += sizeof(mboxhdr); if ( mboxhdr[0] != ORIG_MESSAGEBOX ) return false; // get the parameter matching the main message string if (!machine.pop(addr)) return false; str = machine.GetString((VPVOID)addr); if ( str && *str ) { // can skip the substitution if the string is empty or nonexistant bool suppress_null = false; std::string bad_codes; std::string const new_string = interpolate(str, &machine, &suppress_null, &bad_codes); if (bad_codes != "") { cLog::mLogMessage( "xMessageFix: bad format \"%s\" in \"%s\" generating \"%s\"\n", bad_codes.c_str(), str, new_string.c_str()); } if (mboxhdr[1] < new_string.length()) { len = mboxhdr[1]; } else { len = new_string.length() + 1; } if (suppress_null) --len; machine.WriteMem(scriptoffset,(VPVOID)new_string.c_str(), len); } scriptoffset += mboxhdr[1]; // find the null after the orignal message string // (the "%.0f" style formatting is not allowed for the MessageBox, xMessageFix handles it here) machine.ReadMem(scriptoffset,(VPVOID)&buttoncount,1); // using buttoncount as a temporary scriptoffset += 1; if (buttoncount != 0) return false; // next is the number of buttons to replace machine.ReadMem(scriptoffset,(VPVOID)&buttoncount,1); scriptoffset += 1; // for each button, replace it with string from the stack while (buttoncount != 0) { // find the amount of space available machine.ReadMem(scriptoffset,(VPVOID)&buttonlen,1); scriptoffset += 1; // get the replacement string if (!machine.pop(addr)) return false; str = machine.GetString((VPVOID)addr); if ( str && *str ) { // can skip the substitution if the string is empty or nonexistant bool suppress_null = false; std::string bad_codes; std::string const new_string = interpolate(str, &machine, &suppress_null, &bad_codes); if (bad_codes != "") { cLog::mLogMessage( "xMessageFix: bad format \"%s\" in \"%s\" generating \"%s\"\n", bad_codes.c_str(), str, new_string.c_str()); } if (buttonlen < new_string.length()) { len = buttonlen - 1; } else { len = new_string.length() + 1; } if (suppress_null) --len; machine.WriteMem(scriptoffset,(VPVOID)new_string.c_str(), len); } scriptoffset += buttonlen; // next button buttoncount--; } return true; }
bool FUNCMESSAGEFIX::execute(void) { VPVOID scriptaddr; VMREGTYPE addr; const char* str; USHORT mboxhdr[2]; int len = 0; unsigned char buttonlen = 0; unsigned char buttoncount = 0; // we want to modify the real script SCDT info scriptaddr = (VPVOID)machine.GetScript(); if (!GetOffsetData(machine, scriptaddr, OFFSET_SCDT, (ULONG*)&scriptaddr)) return false; scriptoffset += (ULONG)scriptaddr; // must be followed by messagebox opcode and length machine.ReadMem(scriptoffset,(VPVOID)mboxhdr,sizeof(mboxhdr)); scriptoffset += sizeof(mboxhdr); if ( mboxhdr[0] != ORIG_MESSAGEBOX ) return false; // Calculate a maximum size and create a buffer for the interpreted strings //Timeslip: need to make this a pointer char* buffer=new char[64 + (mboxhdr[1]>256?mboxhdr[1]:256)]; // a little extra temporary work space // get the parameter matching the main message string if (!machine.pop(addr)) { delete buffer; //Timeslip: Need to clean up since it is no longer freed implicetly return false; } str = machine.GetString((VPVOID)addr); if ( str && *str ) // can skip the substitution if the string is empty or nonexistant { len = mboxhdr[1]; // 2005-06-28 CDC Improved processing in interpolate if ( interpolate(machine, str, buffer, len) < 0 ) len--; // 2005-07-03 skip printing the null, showing the rest of the original string machine.WriteMem(scriptoffset,(VPVOID)buffer, len); } scriptoffset += mboxhdr[1]; // find the null after the orignal message string // (the "%.0f" style formatting is not allowed for the MessageBox, xMessageFix handles it here) machine.ReadMem(scriptoffset,(VPVOID)&buttoncount,1); // using buttoncount as a temporary scriptoffset += 1; if (buttoncount != 0) { delete buffer; //Timeslip: Need to clean up since it is no longer freed implicetly return false; } // next is the number of buttons to replace machine.ReadMem(scriptoffset,(VPVOID)&buttoncount,1); scriptoffset += 1; // for each button, replace it with string from the stack while (buttoncount != 0) { // find the amount of space available machine.ReadMem(scriptoffset,(VPVOID)&buttonlen,1); scriptoffset += 1; // get the replacement string if (!machine.pop(addr)) { delete[] buffer; //Timeslip: Need to clean up since it is no longer freed implicetly return false; } str = machine.GetString((VPVOID)addr); if ( str && *str ) // can skip the substitution if the string is empty or nonexistant { len = buttonlen; interpolate(machine, str, buffer, len); // 2005-06-28 CDC Improved processing in interpolate machine.WriteMem(scriptoffset,(VPVOID)buffer, len); } scriptoffset += buttonlen; // next button buttoncount--; } delete[] buffer; //Timeslip: Need to clean up since it is no longer freed implicetly return true; }