diff options
Diffstat (limited to 'SrcShared/Patches')
-rw-r--r-- | SrcShared/Patches/EmPatchIf.h | 150 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchLoader.cpp | 129 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchLoader.h | 74 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchMgr.cpp | 1203 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchMgr.h | 103 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModule.cpp | 318 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModule.h | 118 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleHtal.cpp | 89 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleHtal.h | 30 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleMap.cpp | 146 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleMap.h | 100 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleMemMgr.cpp | 1902 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleNetLib.cpp | 4100 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleNetLib.h | 27 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleSys.cpp | 3217 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleSys.h | 271 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchModuleTypes.h | 94 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchState.cpp | 1034 | ||||
-rw-r--r-- | SrcShared/Patches/EmPatchState.h | 264 |
19 files changed, 13369 insertions, 0 deletions
diff --git a/SrcShared/Patches/EmPatchIf.h b/SrcShared/Patches/EmPatchIf.h new file mode 100644 index 0000000..e6e1d41 --- /dev/null +++ b/SrcShared/Patches/EmPatchIf.h @@ -0,0 +1,150 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + + +#ifndef EmPatchIf_h +#define EmPatchIf_h + +#include "EcmIf.h" + + +enum +{ + kPatchErrNone, + kPatchErrNotImplemented, + kPatchErrInvalidIndex +}; + + +enum CallROMType +{ + kExecuteROM, + kSkipROM +}; + + +// Function types for head- and Tailpatch functions. + +typedef CallROMType (*HeadpatchProc)(void); +typedef void (*TailpatchProc)(void); + + +// ============================================================================== +// * BEGIN IEmPatchLoader +// ============================================================================== + +const EcmIfName kEmPatchLoaderIfn = "loader.patchmodule.i.ecm"; + +ecm_interface IEmPatchLoader : ecm_extends IEcmComponent +{ + virtual Err InitializePL (void) = 0; + virtual Err ResetPL (void) = 0; + virtual Err DisposePL (void) = 0; + + virtual Err ClearPL (void) = 0; + virtual Err LoadPL (void) = 0; + + virtual Err LoadAllModules (void) = 0; + virtual Err LoadModule (const string& url) = 0; +}; + +// ============================================================================== +// * END IEmPatchLoader +// ============================================================================== + + + +// ============================================================================== +// * BEGIN IEmPatchContainer +// ============================================================================== + +const EcmIfName kEmPatchContainerIfn = "container.patchmodule.i.ecm"; + +ecm_interface IEmPatchContainer : ecm_extends IEcmContainer +{ +}; + + +// ============================================================================== +// * END IEmPatchContainer +// ============================================================================== + + + +// ============================================================================== +// * BEGIN IEmPatchDllTempHacks +// ============================================================================== + +const EcmIfName kEmPatchDllTempHacksIfn = "hacks.dll.patchmodule.i.ecm"; + +ecm_interface IEmPatchDllTempHacks : ecm_extends IEcmComponent +{ + virtual Err GetGlobalMemBanks(void** membanksPP)=0; + virtual Err GetGlobalRegs(void** regsPP)=0; +}; + +// ============================================================================== +// * END IEmPatchDllTempHacks +// ============================================================================== + + + + +// =========================================================================== +// IEmPatchModule interface exposed by all patch modules. +// this is how all patch modules appear to the patching sub-system +// =========================================================================== + +const EcmIfName kEmPatchModuleIfn = "patchmodule.i.ecm"; + +ecm_interface IEmPatchModule : ecm_extends IEcmComponent +{ + virtual Err Initialize(IEmPatchContainer &containerIP) = 0; + virtual Err Reset() = 0; + virtual Err Dispose() = 0; + + virtual Err Clear () = 0; + virtual Err Load () = 0; + + virtual const string &GetName() = 0; + + virtual Err GetHeadpatch (uint16 index, HeadpatchProc &procP) = 0; + virtual Err GetTailpatch (uint16 index, TailpatchProc &procP) = 0; +}; + + + + +// =========================================================================== +// IEmPatchModuleMap interface supporting a collection of PatchModules +// Basically there is one component which maintains the list of all +// installed patch modules, and it is accessed using IEmPatchModuleMap +// =========================================================================== + +const EcmIfName kEmPatchModuleMapIfn = "map.patchmodule.i.ecm"; + +ecm_interface IEmPatchModuleMap : ecm_extends IEcmComponent +{ + virtual Err InitializeAll(IEmPatchContainer &containerI) = 0; + virtual Err ResetAll() = 0; + virtual Err DisposeAll() = 0; + + virtual Err ClearAll () = 0; + virtual Err LoadAll () = 0; + + virtual Err AddModule (IEmPatchModule *moduleIP) = 0; + + virtual Err GetModuleByName (const string &nameStr, IEmPatchModule *& moduleIP) = 0; +}; + +#endif // EmPatchIf_h diff --git a/SrcShared/Patches/EmPatchLoader.cpp b/SrcShared/Patches/EmPatchLoader.cpp new file mode 100644 index 0000000..01c6f2d --- /dev/null +++ b/SrcShared/Patches/EmPatchLoader.cpp @@ -0,0 +1,129 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchLoader.h" + +#include "EmPatchMgr.h" +#include "EmPatchModule.h" +#include "EmPatchModuleHtal.h" +#include "EmPatchModuleMap.h" +#include "EmPatchModuleNetLib.h" +#include "EmPatchModuleSys.h" +#include "EmPatchState.h" + + +// ====================================================================== +// This is where you might say all the good stuff actually happens... +// +// we create the instances of all the relevant objects +// we create the instances of all the statically linked patch modules +// we add the statically linked patch modules to the PatchMap +// +// NOTE: +// If USE_HOST_SPECIFIC_LOADER is defined no EmPatchLoader object is +// created here, a derived object will be created for the Host specific +// implementation. +// +// Either way the EmPatchLoader will be exposed globally through the +// global public interface pointer "gTheLoaderIP" +// ====================================================================== + + +// ====================================================================== +// Private Object instances +// ====================================================================== +// +static EmPatchMgr gPatchManager; +static EmPatchModuleMap gPatchMap; + +#ifndef USE_HOST_SPECIFIC_LOADER +static EmPatchLoader gLoader; +#endif //USE_HOST_SPECIFIC_LOADER + + +// ====================================================================== +// Static linked PatchModule instances +// ====================================================================== + +static EmPatchModuleHtal gPatchModuleHtal; +static EmPatchModuleSys gPatchModuleSys; +static EmPatchModuleNetLib gPatchModuleNetLib; + + +// ====================================================================== +// Global Public interfaces +// ====================================================================== + +IEmPatchModuleMap* gPatchMapIP = &gPatchMap; +IEmPatchContainer* gPatchContainerIP = &gPatchManager; + +#ifndef USE_HOST_SPECIFIC_LOADER + +IEmPatchLoader* gTheLoaderIP = &gLoader; + +#endif //USE_HOST_SPECIFIC_LOADER + + + + +// ============================================================================== +// * BEGIN IEmPatchLoader +// ============================================================================== + +Err EmPatchLoader::InitializePL (void) +{ + return kPatchErrNone; +} + +Err EmPatchLoader::ResetPL (void) +{ + return kPatchErrNone; +} + +Err EmPatchLoader::DisposePL (void) +{ + return kPatchErrNone; +} + +Err EmPatchLoader::ClearPL (void) +{ + return kPatchErrNone; +} + +Err EmPatchLoader::LoadPL (void) +{ + return kPatchErrNone; +} + + +Err EmPatchLoader::LoadAllModules(void) +{ + gPatchMap.AddModule (&gPatchModuleSys); + gPatchMap.AddModule (&gPatchModuleNetLib); + gPatchMap.AddModule (&gPatchModuleHtal); + + gPatchMap.InitializeAll (*gPatchContainerIP); + + return kPatchErrNone; +} + + +Err EmPatchLoader::LoadModule (const string& /*url*/) +{ + return kPatchErrNotImplemented; +} + +// ============================================================================== +// * END IEmPatchLoader +// ============================================================================== diff --git a/SrcShared/Patches/EmPatchLoader.h b/SrcShared/Patches/EmPatchLoader.h new file mode 100644 index 0000000..05a1ad8 --- /dev/null +++ b/SrcShared/Patches/EmPatchLoader.h @@ -0,0 +1,74 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + + +#ifndef EmPatchLoader_h +#define EmPatchLoader_h + +#include "EcmObject.h" +#include "EmPatchIf.h" + + +// =========================================================================== +// EmPatchLoader +// =========================================================================== + +class EmPatchLoader : public EcmObject, + ecm_implements IEmPatchLoader +{ + public: + +// ============================================================================== +// * constructors +// ============================================================================== + + EmPatchLoader() + { + } + + +// ============================================================================== +// * interface implementations +// ============================================================================== +// ============================================================================== +// * BEGIN IEmPatchLoader +// ============================================================================== + + virtual Err InitializePL(); + virtual Err ResetPL(); + virtual Err DisposePL(); + virtual Err ClearPL(); + virtual Err LoadPL(); + + virtual Err LoadAllModules(); + virtual Err LoadModule(const string &url); + +// ============================================================================== +// * END IEmPatchLoader +// ============================================================================== + + +// ============================================================================== +// * BEGIN IEmPatchContainer +// ============================================================================== + + +// ============================================================================== +// * END IEmPatchContainer +// ============================================================================== + + private: +}; + + +#endif // EmPatchLoader_h diff --git a/SrcShared/Patches/EmPatchMgr.cpp b/SrcShared/Patches/EmPatchMgr.cpp new file mode 100644 index 0000000..4a8f844 --- /dev/null +++ b/SrcShared/Patches/EmPatchMgr.cpp @@ -0,0 +1,1203 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchMgr.h" + +#include "EmPatchModule.h" +#include "EmPatchModuleMap.h" +#include "EmPatchState.h" +#include "EmPatchLoader.h" + +#include "CGremlinsStubs.h" // StubAppEnqueueKey +#include "DebugMgr.h" // Debug::ConnectedToTCPDebugger +#include "EmEventPlayback.h" // EmEventPlayback::ReplayingEvents +#include "EmHAL.h" // EmHAL::GetLineDriverState +#include "EmLowMem.h" // EmLowMem::GetEvtMgrIdle, EmLowMem::TrapExists, EmLowMem_SetGlobal, EmLowMem_GetGlobal +#include "EmPalmFunction.h" // IsSystemTrap +#include "EmRPC.h" // RPC::SignalWaiters +#include "EmSession.h" // GetDevice +#include "Hordes.h" // Hordes::IsOn, Hordes::PostFakeEvent, Hordes::CanSwitchToApp +#include "Logging.h" // LogEvtAddEventToQueue, etc. +#include "MetaMemory.h" // MetaMemory mark functions +#include "PreferenceMgr.h" // Preference (kPrefKeyUserName) +#include "Profiling.h" // StDisableAllProfiling +#include "ROMStubs.h" // FtrSet, FtrUnregister, EvtWakeup, ... +#include "SessionFile.h" // SessionFile +#include "UAE.h" // gRegs, m68k_dreg, etc. + + +#pragma mark - + +// =========================================================================== +// ¥ EmPatchMgr +// =========================================================================== + +// ====================================================================== +// Global Interfaces +// ====================================================================== + + +//Interface to THE collection of all patch modules: + +extern IEmPatchModuleMap* gPatchMapIP; +extern IEmPatchLoader* gTheLoaderIP; + + +// ====================================================================== +// Private globals and constants +// ====================================================================== + +//Table of currently Patched shared libraries +// +static PatchedLibIndex gPatchedLibs; + +//Table of currently installed tail patches +// +static TailPatchIndex gInstalledTailpatches; + + +// Magic number used to identify Htal patch +// See comments in HtalLibSendReply. +// +const UInt16 kMagicRefNum = 0x666; + + + +// ====================================================================== +// Private functions +// ====================================================================== + +void PrvAutoload (void); +void PrvSetCurrentDate (void); + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::Initialize + * + * DESCRIPTION: Standard initialization function. Responsible for + * initializing this sub-system when a new session is + * created. Will be followed by at least one call to + * Reset or Load. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::Initialize (void) +{ + EmAssert (gSession); + + gTheLoaderIP->InitializePL (); + gTheLoaderIP->LoadAllModules (); + + gSession->AddInstructionBreakHandlers ( + InstallInstructionBreaks, + RemoveInstructionBreaks, + HandleInstructionBreak); + + if (gPatchMapIP != NULL) + { + gPatchMapIP->ClearAll (); + gPatchMapIP->LoadAll (); + } + + EmPatchState::Initialize (); +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::Reset + * + * DESCRIPTION: Standard reset function. Sets the sub-system to a + * default state. This occurs not only on a Reset (as + * from the menu item), but also when the sub-system + * is first initialized (Reset is called after Initialize) + * as well as when the system is re-loaded from an + * insufficient session file. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::Reset (void) +{ + gInstalledTailpatches.clear (); + + // Clear the installed lib patches (for "loaded" libraries) + // + gPatchedLibs.clear (); + + EmPatchState::Reset (); +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::Save + * + * DESCRIPTION: Standard save function. Saves any sub-system state to + * the given session file. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::Save (SessionFile& f) +{ + const long kCurrentVersion = 5; + + Chunk chunk; + EmStreamChunk s (chunk); + + s << kCurrentVersion; + + EmPatchState::Save (s, kCurrentVersion, EmPatchState::PSPersistStep1); + +// s << gSysPatchModule; +// s << gNetLibPatchModule; +// s << gPatchedLibs; + + s << (long) gInstalledTailpatches.size (); + + TailPatchIndex::iterator iter2; + for (iter2 = gInstalledTailpatches.begin (); iter2 != gInstalledTailpatches.end (); ++iter2) + { + s << iter2->fContext.fDestPC1; // !!! Need to support fDestPC2, too. But since only fNextPC seems to be used, it doesn't really matter. + s << iter2->fContext.fExtra; + s << iter2->fContext.fNextPC; + s << iter2->fContext.fPC; + s << iter2->fContext.fTrapIndex; + s << iter2->fContext.fTrapWord; + s << iter2->fCount; +// s << iter2->fTailpatch; // Patched up in ::Load + } + + EmPatchState::Save (s, kCurrentVersion, EmPatchState::PSPersistStep2); + + f.WritePatchInfo (chunk); +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::Load + * + * DESCRIPTION: Standard load function. Loads any sub-system state + * from the given session file. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::Load (SessionFile& f) +{ + Chunk chunk; + if (f.ReadPatchInfo (chunk)) + { + long version; + EmStreamChunk s (chunk); + + s >> version; + + if (version >= 1) + { + EmPatchState::Load (s, version, EmPatchState::PSPersistStep1); + + gPatchedLibs.clear (); + gInstalledTailpatches.clear (); + + + long numTailpatches; + s >> numTailpatches; + + int ii; + for (ii = 0; ii < numTailpatches; ++ii) + { + TailpatchType patch; + + s >> patch.fContext.fDestPC1; // !!! Need to support fDestPC2, too. But since only fNextPC seems to be used, it doesn't really matter. + patch.fContext.fDestPC2 = patch.fContext.fDestPC1; + s >> patch.fContext.fExtra; + s >> patch.fContext.fNextPC; + s >> patch.fContext.fPC; + s >> patch.fContext.fTrapIndex; + s >> patch.fContext.fTrapWord; + s >> patch.fCount; + + // Patch up the tailpatch proc. + + HeadpatchProc dummy; + GetPatches (patch.fContext, dummy, patch.fTailpatch); + + gInstalledTailpatches.push_back (patch); + } + } + + EmPatchState::Load (s, version, EmPatchState::PSPersistStep2); + } + else + { + f.SetCanReload (false); + } +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::Dispose + * + * DESCRIPTION: Standard dispose function. Completely release any + * resources acquired or allocated in Initialize and/or + * Load. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::Dispose (void) +{ + gInstalledTailpatches.clear (); + gPatchedLibs.clear (); + + EmPatchState::Dispose (); + + if (gPatchMapIP != NULL) + { + gPatchMapIP->ClearAll (); + } + + if (gTheLoaderIP) + { + gTheLoaderIP->ClearPL (); + } +} + + +Err EmPatchMgr::GetGlobalMemBanks (void** membanksPP) +{ + if (membanksPP != NULL) + *membanksPP = gEmMemBanks; + + return 0; +} + +Err EmPatchMgr::GetGlobalRegs (void** regsPP) +{ + if (regsPP != NULL) + *regsPP = &gRegs; + + return 0; +} + + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::PostLoad + * + * DESCRIPTION: Do some stuff that is normally taken care of during the + * process of resetting the device (autoloading + * applications, setting the device date, installing the + * HotSync user-name, and setting the 'gdbS' feature). + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::PostLoad (void) +{ + if (EmPatchState::UIInitialized ()) + { + // If we're listening on a socket, install the 'gdbS' feature. The + // existance of this feature causes programs written with the prc tools + // to enter the debugger when they're launched. + + if (Debug::ConnectedToTCPDebugger ()) + { + FtrSet ('gdbS', 0, 0x12BEEF34); + } + else + { + FtrUnregister ('gdbS', 0); + } + + // Reconfirm the strict intl checks setting, whether on or off. + + Preference<Bool> intlPref (kPrefKeyReportStrictIntlChecks); + + if (EmPatchMgr::IntlMgrAvailable ()) + { + ::IntlSetStrictChecks (*intlPref); + } + + // Reconfirm the overlay checks setting, whether on or off. + + Preference<Bool> overlayPref (kPrefKeyReportOverlayErrors); + (void) ::FtrSet (omFtrCreator, omFtrShowErrorsFlag, *overlayPref); + + // Install the HotSync user-name. + + // Actually, let's not do that. From Scott Maxwell: + // + // Would it be possible to save the HotSync user name with each session? This + // would be very convenient for working on multiple projects because each + // session could have a different user name. + // + // To which I said: + // I think that what you're seeing is Poser (re-)establishing the user preference + // from the Properties/Preferences dialog box after the session is reloaded. I + // could see this way of working as being valuable, too, so I'm not sure which way + // to go: keep things the way they are or change them. + // + // To which he said: + // + // How about having the preferences dialog grab the name from the Palm RAM? + // That way you could easily maintain it per session. + // + // Sounds good to me... + +// Preference<string> userNamePref (kPrefKeyUserName); +// ::SetHotSyncUserName (userNamePref->c_str ()); + + CEnableFullAccess munge; + + if (EmLowMem::TrapExists (sysTrapDlkGetSyncInfo)) + { + char userName[dlkUserNameBufSize]; + Err err = ::DlkGetSyncInfo (NULL, NULL, NULL, userName, NULL, NULL); + if (!err) + { + Preference<string> userNamePref (kPrefKeyUserName); + userNamePref = string (userName); + } + } + + // Auto-load any files in the Autoload[Foo] directories. + + ::PrvAutoload (); + + // Install the current date. + + ::PrvSetCurrentDate (); + + // Wake up any current application so that they can respond + // to events we pump in at EvtGetEvent time. + + ::EvtWakeup (); + } + + // Re-open any needed transports. This could probably be done + // at the time the session file is loaded, but we put it here + // with the rest of the (deferred) post-load activities for + // consistancy. + + for (EmUARTDeviceType ii = kUARTBegin; ii < kUARTEnd; ++ii) + { + if (EmHAL::GetLineDriverState (ii)) + { + EmTransport* transport = gEmuPrefs->GetTransportForDevice (ii); + + if (transport) + { + transport->Open (); + } + } + } +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::GetLibPatchTable + * + * DESCRIPTION: . + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +IEmPatchModule* EmPatchMgr::GetLibPatchTable (uint16 refNum) +{ + if (refNum >= gPatchedLibs.size ()) + { + gPatchedLibs.resize (refNum + 1); + } + + InstalledLibPatchEntry &libPtchEntry = gPatchedLibs[refNum]; + + if (libPtchEntry.IsDirty () == true) + { + string libName = ::GetLibraryName (refNum); + + IEmPatchModule *patchModuleIP = NULL; + + if (gPatchMapIP != NULL) + { + gPatchMapIP->GetModuleByName (libName, patchModuleIP); + } + + + libPtchEntry.SetPatchTableP (patchModuleIP); + libPtchEntry.SetDirty (false); + } + + return libPtchEntry.GetPatchTableP (); +} + + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::HandleSystemCall + * + * DESCRIPTION: If this is a trap we could possibly have head- or + * tail-patched, handle those cases. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType EmPatchMgr::HandleSystemCall (const SystemCallContext& context) +{ + EmAssert (gSession); + if (gSession->GetNeedPostLoad ()) + { + gSession->SetNeedPostLoad (false); + EmPatchMgr::PostLoad (); + } + + HeadpatchProc hp; + TailpatchProc tp; + EmPatchMgr::GetPatches (context, hp, tp); + + CallROMType handled = EmPatchMgr::HandlePatches (context, hp, tp); + + return handled; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::GetPatches + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::GetPatches ( const SystemCallContext& context, + HeadpatchProc& hp, + TailpatchProc& tp) +{ + IEmPatchModule* patchModuleIP = NULL; + + // If this is in the system function range, check our table of + // system function patches. + + if (::IsSystemTrap (context.fTrapWord)) + { + static IEmPatchModule *sysPatchModuleIP = NULL; + + if (sysPatchModuleIP == NULL && gPatchMapIP != NULL) + { + gPatchMapIP->GetModuleByName (string ("~system"), sysPatchModuleIP); + } + + patchModuleIP = sysPatchModuleIP; + } + + else if (context.fExtra == kMagicRefNum) // See comments in HtalLibSendReply. + { + static IEmPatchModule *htalPatchModuleIP = NULL; + + if (htalPatchModuleIP == NULL && gPatchMapIP != NULL) + { + gPatchMapIP->GetModuleByName (string ("~Htal"), htalPatchModuleIP); + } + + patchModuleIP = htalPatchModuleIP; + } + + // Otherwise, see if this is a call to a patched library + else + { + patchModuleIP = GetLibPatchTable (context.fExtra); + } + + // Now that we've got the right patch table for this module, see if + // that patch table has head- or tailpatches for this function. + + if (patchModuleIP != NULL) + { + patchModuleIP->GetHeadpatch (context.fTrapIndex, hp); + patchModuleIP->GetTailpatch (context.fTrapIndex, tp); + } + else + { + hp = NULL; + tp = NULL; + } +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::HandlePatches + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType EmPatchMgr::HandlePatches (const SystemCallContext& context, + HeadpatchProc hp, + TailpatchProc tp) +{ + CallROMType handled = kExecuteROM; + + // First, see if we have a SysHeadpatch for this function. If so, call + // it. If it returns true, then that means that the head patch + // completely handled the function. + + // !!! May have to mess with PC here in case patches do something + // to enter the debugger. + + if (hp) + { + handled = CallHeadpatch (hp); + } + + // Next, see if there's a SysTailpatch function for this trap. If + // so, install the TRAP that will cause us to regain control + // after the trap function has executed. + + if (tp) + { + if (handled == kExecuteROM) + { + SetupForTailpatch (tp, context); + } + else + { + CallTailpatch (tp); + } + } + + return handled; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::HandleInstructionBreak + * + * DESCRIPTION: Handle a tail patch, if any is registered for this + * memory location. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::HandleInstructionBreak (void) +{ + // Get the address of the tailpatch to call. May return NULL if + // there is no tailpatch for this memory location. + + TailpatchProc tp = RecoverFromTailpatch (gCPU->GetPC ()); + + // Call the tailpatch handler for the trap that just returned. + + CallTailpatch (tp); +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::InstallInstructionBreaks + * + * DESCRIPTION: Set the MetaMemory bit that tells the CPU loop to stop + * when we get to the desired locations. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::InstallInstructionBreaks (void) +{ + TailPatchIndex::iterator iter = gInstalledTailpatches.begin (); + + while (iter != gInstalledTailpatches.end ()) + { + MetaMemory::MarkInstructionBreak (iter->fContext.fNextPC); + ++iter; + } +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::RemoveInstructionBreaks + * + * DESCRIPTION: Clear the MetaMemory bit that tells the CPU loop to stop + * when we get to the desired locations. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::RemoveInstructionBreaks (void) +{ + TailPatchIndex::iterator iter = gInstalledTailpatches.begin (); + + while (iter != gInstalledTailpatches.end ()) + { + MetaMemory::UnmarkInstructionBreak (iter->fContext.fNextPC); + ++iter; + } +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::SetupForTailpatch + * + * DESCRIPTION: Set up the pending TRAP $F call to be tailpatched. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::SetupForTailpatch (TailpatchProc tp, const SystemCallContext& context) +{ + // See if this function is already tailpatched. If so, merely increment + // the use-count field. + + TailPatchIndex::iterator iter = gInstalledTailpatches.begin (); + + while (iter != gInstalledTailpatches.end ()) + { + if (iter->fContext.fNextPC == context.fNextPC) + { + ++(iter->fCount); + return; + } + + ++iter; + } + + // This function is not already tailpatched, so add a new entry + // for the the PC/opcode we want to save. + + EmAssert (gSession); + gSession->RemoveInstructionBreaks (); + + TailpatchType newTailpatch; + + newTailpatch.fContext = context; + newTailpatch.fCount = 1; + newTailpatch.fTailpatch = tp; + + gInstalledTailpatches.push_back (newTailpatch); + + gSession->InstallInstructionBreaks (); +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::RecoverFromTailpatch + * + * DESCRIPTION: . + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +TailpatchProc EmPatchMgr::RecoverFromTailpatch (emuptr startPC) +{ + // Get the current PC so that we can find the record for this tailpatch. + + emuptr patchPC = startPC; + + // Find the PC. + + TailPatchIndex::iterator iter = gInstalledTailpatches.begin (); + + while (iter != gInstalledTailpatches.end ()) + { + if (iter->fContext.fNextPC == patchPC) + { + TailpatchProc result = iter->fTailpatch; + + // Decrement the use-count. If it reaches zero, remove the + // patch from our list. + + if (--(iter->fCount) == 0) + { + EmAssert (gSession); + gSession->RemoveInstructionBreaks (); + + gInstalledTailpatches.erase (iter); + + gSession->InstallInstructionBreaks (); + } + + return result; + } + + ++iter; + } + + return NULL; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::CallHeadpatch + * + * DESCRIPTION: If the given system function is head patched, then call + * the headpatch. Return "handled" (which means whether + * or not to call the ROM function after this one). + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType EmPatchMgr::CallHeadpatch (HeadpatchProc hp, bool /* noProfiling */) +{ + CallROMType handled = kExecuteROM; + + if (hp) + { + // If (noProfiling == true) then stop all profiling activities. + // Stop cycle counting and stop the recording of function entries + // and exits. We want our trap patches to be as transparent as possible. + + StDisableAllProfiling stopper (/*noProfiling*/); + + handled = hp (); + } + + return handled; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::CallTailpatch + * + * DESCRIPTION: If the given function is tail patched, then call the + * tailpatch. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchMgr::CallTailpatch (TailpatchProc tp, bool /* noProfiling */) +{ + if (tp) + { + // Stop all profiling activities. Stop cycle counting and stop the + // recording of function entries and exits. We want our trap patches + // to be as transparent as possible. + + StDisableAllProfiling stopper (/*noProfiling*/); + + tp (); + } +} + + + + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::PuppetString + * + * DESCRIPTION: Puppet stringing function for inserting events into + * the system. We want to insert events when: + * + * - Gremlins is running + * - The user types characters + * - The user clicks with the mouse + * - We need to trigger a switch another application + * + * This function is called from headpatches to + * SysEvGroupWait and SysSemaphoreWait. When the Palm OS + * needs an event, it calls EvtGetEvent. EvtGetEvent + * looks in all the usual places for events to return. If + * it doesn't find any, it puts the system to sleep by + * calling SysEvGroupWait (or SysSemaphoreWait on 1.0 + * systems). SysEvGroupWait will wake up and return when + * an event is posted via something like EvtEnqueuePenPoint, + * EvtEnqueueKey, or KeyHandleInterrupt. + * + * To puppet-string Palm OS, we therefore patch those + * functions and post events, preventing them from actually + * going to sleep. + * + * PARAMETERS: callROM - return here whether or not the original ROM + * function still needs to be called. Normally, the + * answer is "yes". + * + * clearTimeout - set to true if the "timeout" parameter + * of the function we've patched needs to be prevented + * from being "infinite". + * + * RETURNED: nothing + * + ***********************************************************************/ + +static void PrvForceNilEvent (void) +{ + // No event was posted. What we'd like right now is to force + // EvtGetEvent to return a nil event. We can do that by returning + // a non-zero result code from SysEvGroupWait. EvtGetEvent doesn't + // look too closely at the result, but let's try to be as close to + // reality as possible. SysEvGroupWait currently returns "4" + // (CJ_WRTMOUT) to indicate a timeout condition. It should + // probably get turned into sysErrTimeout somewhere along the way, + // but that translation doesn't seem to occur. + + m68k_dreg (gRegs, 0) = 4; +} + +void EmPatchMgr::PuppetString (CallROMType& callROM, Bool& clearTimeout) +{ + callROM = kExecuteROM; + clearTimeout = false; + + // Set the return value (Err) to zero in case we return + // "true" (saying that we handled the trap). + + m68k_dreg (gRegs, 0) = 0; + + // If the low-memory global "idle" is true, then we're being + // called from EvtGetEvent or EvtGetPen, in which case we + // need to check if we need to post some events. + + if (EmLowMem::GetEvtMgrIdle ()) + { + // If there's an RPC request waiting for a nilEvent, + // let it know that it happened. + + if (EmPatchState::GetLastEvtTrap () == sysTrapEvtGetEvent) + { + RPC::SignalWaiters (hostSignalIdle); + } + + // If we're in the middle of calling a Palm OS function ourself, + // and we are somehow at the point where the system is about to + // doze, then just return now. Don't let it doze! Interrupts are + // off, and HwrDoze will never return! + + if (gSession->IsNested ()) + { + ::PrvForceNilEvent (); + callROM = kSkipROM; + return; + } + + EmAssert (gSession); + + // Check if Minimization is going on. + + if (EmEventPlayback::ReplayingEvents ()) + { + if (EmPatchState::GetLastEvtTrap () == sysTrapEvtGetEvent) + { + if (!EmEventPlayback::ReplayGetEvent ()) + { + ::PrvForceNilEvent (); + callROM = kSkipROM; + return; + } + } + else if (EmPatchState::GetLastEvtTrap () == sysTrapEvtGetPen) + { + EmEventPlayback::ReplayGetPen (); + } + + // Never let the timeout be infinite. If the above event-posting + // attempts failed (which could happen, for instance, if we attempted + // to post a pen event with the same coordinates as the previous + // pen event), we'd end up waiting forever. + + clearTimeout = true; + } + + // Check if Hords is going on. + + else if (Hordes::IsOn ()) + { + if (EmPatchState::GetLastEvtTrap () == sysTrapEvtGetEvent) + { + if (!Hordes::PostFakeEvent ()) + { + if (LogEnqueuedEvents ()) + { + LogAppendMsg ("Hordes::PostFakeEvent did not post an event."); + } + + ::PrvForceNilEvent (); + callROM = kSkipROM; + return; + } + } + else if (EmPatchState::GetLastEvtTrap () == sysTrapEvtGetPen) + { + Hordes::PostFakePenEvent (); + } + else + { + if (LogEnqueuedEvents ()) + { + LogAppendMsg ("Last event was 0x%04X, so not posting event.", EmPatchState::GetLastEvtTrap ()); + } + } + + // Never let the timeout be infinite. If the above event-posting + // attempts failed (which could happen, for instance, if we attempted + // to post a pen event with the same coordinates as the previous + // pen event), we'd end up waiting forever. + + clearTimeout = true; + } + + // Gremlins aren't on; let's see if the user has typed some + // keys that we need to pass on to the Palm device. + + else if (gSession->HasKeyEvent ()) + { + EmKeyEvent event = gSession->GetKeyEvent (); + + UInt16 modifiers = 0; + + if (event.fShiftDown) + modifiers |= shiftKeyMask; + + if (event.fCapsLockDown) + modifiers |= capsLockMask; + + if (event.fNumLockDown) + modifiers |= numLockMask; + + // We don't really want to set this one. commandKeyMask + // means something special in Palm OS +// if (event.fCommandDown) +// modifiers |= commandKeyMask; + + if (event.fOptionDown) + modifiers |= optionKeyMask; + + if (event.fControlDown) + modifiers |= controlKeyMask; + + if (event.fAltDown) + modifiers |= 0; // no bit defined for this + + if (event.fWindowsDown) + modifiers |= 0; // no bit defined for this + + ::StubAppEnqueueKey (event.fKey, 0, modifiers); + } + + // No key events, let's see if there are pen events. + + else if (gSession->HasPenEvent ()) + { + EmPoint pen (-1, -1); + EmPenEvent event = gSession->GetPenEvent (); + if (event.fPenIsDown) + { + pen = event.fPenPoint; + } + + PointType palmPen = pen; + StubAppEnqueuePt (&palmPen); + } + + // E. None of the above. Let's see if there's an app + // we're itching to switch to. + + else if (EmPatchState::GetNextAppDbID () != 0) + { + /*Err err =*/ SwitchToApp (EmPatchState::GetNextAppCardNo (), EmPatchState::GetNextAppDbID ()); + + EmPatchState::SetNextAppCardNo (0); + EmPatchState::SetNextAppDbID (0); + + clearTimeout = true; + } + } + else + { + if (Hordes::IsOn () && LogEnqueuedEvents ()) + { + LogAppendMsg ("Event Manager not idle, so not posting an event."); + } + } +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::IntlMgrAvailable + * + * DESCRIPTION: Indicates whether the international manager is available. + * + * PARAMETERS: + * + * RETURNED: True if it is (OS > 4.0), false otherwise. + * + ***********************************************************************/ + +Bool EmPatchMgr::IntlMgrAvailable (void) +{ + UInt32 romVersionData; + FtrGet (sysFileCSystem, sysFtrNumROMVersion, &romVersionData); + UInt32 romVersionMajor = sysGetROMVerMajor (romVersionData); + + return (romVersionMajor >= 4); +} + + + +/*********************************************************************** + * + * FUNCTION: EmPatchMgr::SwitchToApp + * + * DESCRIPTION: Switches to the given application or launchable document. + * + * PARAMETERS: cardNo - the card number of the app to switch to. + * + * dbID - the database id of the app to switch to. + * + * RETURNED: Err number of any errors that occur + * + ***********************************************************************/ + +Err EmPatchMgr::SwitchToApp (UInt16 cardNo, LocalID dbID) +{ + UInt16 dbAttrs; + UInt32 type, creator; + + Err err = ::DmDatabaseInfo ( + cardNo, + dbID, + NULL, /*name*/ + &dbAttrs, + NULL, /*version*/ + NULL, /*create date*/ + NULL, /*modDate*/ + NULL, /*backup date*/ + NULL, /*modNum*/ + NULL, /*appInfoID*/ + NULL, /*sortInfoID*/ + &type, + &creator); + + if (err) + return err; + + //--------------------------------------------------------------------- + // If this is an executable, call SysUIAppSwitch + //--------------------------------------------------------------------- + if (::IsExecutable (type, creator, dbAttrs)) + { + err = ::SysUIAppSwitch (cardNo, dbID, + sysAppLaunchCmdNormalLaunch, NULL); + + if (err) + return err; + } + + //--------------------------------------------------------------------- + // else, this must be a launchable data database. Find it's owner app + // and launch it with a pointer to the data database name. + //--------------------------------------------------------------------- + else + { + DmSearchStateType searchState; + UInt16 appCardNo; + LocalID appDbID; + + err = ::DmGetNextDatabaseByTypeCreator (true, &searchState, + sysFileTApplication, creator, + true, &appCardNo, &appDbID); + if (err) + return err; + + // Create the param block + + emuptr cmdPBP = (emuptr) ::MemPtrNew (sizeof (SysAppLaunchCmdOpenDBType)); + if (cmdPBP == EmMemNULL) + return memErrNotEnoughSpace; + + // Fill it in + + ::MemPtrSetOwner ((MemPtr) cmdPBP, 0); + EmMemPut16 (cmdPBP + offsetof (SysAppLaunchCmdOpenDBType, cardNo), cardNo); + EmMemPut32 (cmdPBP + offsetof (SysAppLaunchCmdOpenDBType, dbID), dbID); + + // Switch now + + err = ::SysUIAppSwitch (appCardNo, appDbID, sysAppLaunchCmdOpenDB, (MemPtr) cmdPBP); + if (err) + return err; + } + + return errNone; +} diff --git a/SrcShared/Patches/EmPatchMgr.h b/SrcShared/Patches/EmPatchMgr.h new file mode 100644 index 0000000..d2d0155 --- /dev/null +++ b/SrcShared/Patches/EmPatchMgr.h @@ -0,0 +1,103 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchMgr_h +#define EmPatchMgr_h + +#include "EcmObject.h" +#include "EmPatchIf.h" +#include "PreferenceMgr.h" // PrefKeyType + +#include <vector> + +class SessionFile; +struct SystemCallContext; + +struct IEmPatchModule; + + +class EmPatchMgr : public EcmObject, + ecm_implements IEmPatchContainer, + ecm_implements IEmPatchDllTempHacks +{ + public: + + ECM_CLASS_IF_LIST_BEGIN(EmPatchMgr, EcmObject) + ECM_CLASS_IF(kEmPatchContainerIfn, IEmPatchContainer) + ECM_CLASS_IF(kEmPatchDllTempHacksIfn, IEmPatchDllTempHacks) + ECM_CLASS_IF_LIST_END(EmPatchMgr, EcmObject) + + + +// ============================================================================== +// * BEGIN IEmPatchContainer +// ============================================================================== + +// ============================================================================== +// * END IEmPatchContainer +// ============================================================================== + +// ============================================================================== +// * BEGIN IEmPatchDllTempHacks +// ============================================================================== + + virtual Err GetGlobalMemBanks(void** membanksPP); + virtual Err GetGlobalRegs(void** regsPP); + +// ============================================================================== +// * END IEmPatchDllTempHacks +// ============================================================================== + + static void Initialize (void); + static void Reset (void); + static void Save (SessionFile&); + static void Load (SessionFile&); + static void Dispose (void); + + static void PostLoad (void); + + static CallROMType HandleSystemCall (const SystemCallContext&); + + static void HandleInstructionBreak (void); + static void InstallInstructionBreaks(void); + static void RemoveInstructionBreaks (void); + + static void GetPatches (const SystemCallContext&, + HeadpatchProc& hp, + TailpatchProc& tp); + + static CallROMType HandlePatches (const SystemCallContext&, + HeadpatchProc hp, + TailpatchProc tp); + + static IEmPatchModule* GetLibPatchTable (uint16 refNum); + + static CallROMType CallHeadpatch (HeadpatchProc, bool noProfiling = true); + static void CallTailpatch (TailpatchProc, bool noProfiling = true); + + static Err SwitchToApp (UInt16 cardNo, LocalID dbID); + + static void PuppetString (CallROMType& callROM, + Bool& clearTimeout); + + static Bool IntlMgrAvailable (void); + + private: + static void SetupForTailpatch (TailpatchProc tp, + const SystemCallContext&); + static TailpatchProc RecoverFromTailpatch (emuptr oldpc); +}; + +#endif /* EmPatchMgr_h */ + diff --git a/SrcShared/Patches/EmPatchModule.cpp b/SrcShared/Patches/EmPatchModule.cpp new file mode 100644 index 0000000..a4ad8a4 --- /dev/null +++ b/SrcShared/Patches/EmPatchModule.cpp @@ -0,0 +1,318 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchModule.h" + +#include "EmPatchModuleMap.h" +#include "EmStructs.h" +#include "EmPalmFunction.h" // SysTrapIndex, IsLibraryTrap + + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::EmPatchModule + * + * DESCRIPTION: Base EmPatchModule constructor + * + * PARAMETERS: mapIP Interface to the EmPatchModule map this module will be added to. + * nameCSP Unique name given to this EmPatchModule. + * loadTables boolean should ProtoPatchTables be loaded immediately? + * protoTable1P Optional Protopatch table 1 - AddProtoPatchTable can be used subsequently + * protoTable2P Optional Protopatch table 2 - AddProtoPatchTable can be used subsequently + * + * RETURNED: nothing + * + ***********************************************************************/ + +EmPatchModule::EmPatchModule(const char *nameCSP, ProtoPatchTableEntry *protoTable1P, ProtoPatchTableEntry *protoTable2P) +{ + fContainerIP = NULL; + + fProtoTableCount = 0; + fLoadedTableCount = 0; + + memset(fProtoTables, 0, kMaxProtoTables * sizeof(ProtoPatchTableEntry *)); + + fName = nameCSP; + + if (protoTable1P != NULL) + fProtoTables[fProtoTableCount++] = protoTable1P; + + if (protoTable2P != NULL) + fProtoTables[fProtoTableCount++] = protoTable2P; +} + + + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::PrvLoadProtoPatchTable + * + * DESCRIPTION: Loads the given ProtoPatch Table + * + * PARAMETERS: tableNbr - index of the internally referenced ProtoPatch tables to load + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchModule::PrvLoadProtoPatchTable (uint16 tableNbr) +{ + // Create a fast dispatch table for the managed module. A "fast + // dispatch table" is a table with a headpatch and tailpatch entry + // for each possible function in the module. If the function is + // not head or tailpatched, the corresponding entry is NULL. When + // a patch function is needed, the trap dispatch number is used as + // an index into the table in order to get the right patch function. + // + // For simplicity, "fast patch tables" are created from "proto patch + // tables". A proto patch table is a compact table containing the + // information needed to create a fast patch table. Each entry in + // the proto patch table is a trap-number/headpatch/tailpatch tupple. + // Each tuple is examined in turn. If there is a head or tail patch + // function for the indicated module function, that patch function + // is entered in the fast dispatch table, using the trap number as + // the index. + + ProtoPatchTableEntry *protoPatchTable = fProtoTables[tableNbr]; + + for (long ii = 0; protoPatchTable[ii].fTrapWord; ++ii) + { + // If there is a headpatch function... + + if (protoPatchTable[ii].fHeadpatch) + { + // Get the trap number. + + uint16 index = ::SysTrapIndex (protoPatchTable[ii].fTrapWord); + + // If the trap number is 0xA800-based, make it zero based. + + if (::IsLibraryTrap (index)) + index -= SysTrapIndex (sysLibTrapBase); + + // Resize the fast patch table, if necessary. + + if (index >= fHeadpatches.size ()) + { + fHeadpatches.resize (index + 1); + } + + // Add the headpatch function. + + fHeadpatches[index] = protoPatchTable[ii].fHeadpatch; + } + + // If there is a tailpatch function... + + if (protoPatchTable[ii].fTailpatch) + { + // Get the trap number. + + uint16 index = SysTrapIndex (protoPatchTable[ii].fTrapWord); + + // If the trap number is 0xA800-based, make it zero based. + + if (IsLibraryTrap (index)) + index -= SysTrapIndex (sysLibTrapBase); + + // Resize the fast patch table, if necessary. + + if (index >= fTailpatches.size ()) + { + fTailpatches.resize (index + 1); + } + + // Add the tailpatch function. + + fTailpatches[index] = protoPatchTable[ii].fTailpatch; + } + } +} + +// ============================================================================== +// * interface implementations +// ============================================================================== +// ============================================================================== +// * IEmPatchModule +// +// * Interface exposed by all PatchModules +// ============================================================================== + + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::Initialize + * + * DESCRIPTION: Initializes the EmPatchModule component + * + * PARAMETERS: none + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModule::Initialize(IEmPatchContainer &containerI) +{ + fContainerIP = &containerI; + + Clear(); + Load(); + + return kPatchErrNone; +} + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::Reset + * + * DESCRIPTION: Resets the EmPatchModule component + * + * PARAMETERS: none + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModule::Reset() +{ + return kPatchErrNone; +} + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::Dispose + * + * DESCRIPTION: Disposes the EmPatchModule component + * + * PARAMETERS: none + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModule::Dispose() +{ + Clear(); + return kPatchErrNone; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::Clear + * + * DESCRIPTION: Clears the EmPatchModule component + * + * PARAMETERS: none + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModule::Clear() +{ + fHeadpatches.clear (); + fTailpatches.clear (); + + fLoadedTableCount = 0; + + return kPatchErrNone; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::Load + * + * DESCRIPTION: Loads the EmPatchModule component + * + * PARAMETERS: none + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModule::Load() +{ + while (fLoadedTableCount < fProtoTableCount) + { + PrvLoadProtoPatchTable(fLoadedTableCount++); + } + + return kPatchErrNone; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchModule::GetName + * + * DESCRIPTION: Gets a reference to the unique string name of the EmPatchModule component + * + * PARAMETERS: none + * + * RETURNED: reference to the unique string name + * + ***********************************************************************/ + +const string &EmPatchModule::GetName() +{ + return fName; +} + + +// Return the patch function for the given module function The given +// module function *must* be given as a zero-based index. If there is +// no patch function for the modeule function, procP == NULL. +// +Err EmPatchModule::GetHeadpatch (uint16 index, HeadpatchProc& procP) +{ + Err err = kPatchErrInvalidIndex; + procP = NULL; + + if (index < fHeadpatches.size ()) + { + procP = fHeadpatches[index]; + err = kPatchErrNone; + } + + return err; +} + + +// Return the patch function for the given module function The given +// module function *must* be given as a zero-based index. If there is +// no patch function for the modeule function, procP == NULL. +// +Err EmPatchModule::GetTailpatch (uint16 index, TailpatchProc& procP) +{ + Err err = kPatchErrInvalidIndex; + procP = NULL; + + if (index < fTailpatches.size ()) + { + procP = fTailpatches[index]; + err = kPatchErrNone; + } + + return err; +} + + +// ============================================================================== +// * END IEmPatchModule +// ============================================================================== diff --git a/SrcShared/Patches/EmPatchModule.h b/SrcShared/Patches/EmPatchModule.h new file mode 100644 index 0000000..c867489 --- /dev/null +++ b/SrcShared/Patches/EmPatchModule.h @@ -0,0 +1,118 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchModule_h +#define EmPatchModule_h + +#include "EcmObject.h" +#include "EmPatchModuleTypes.h" +#include "ChunkFile.h" +#include "Miscellaneous.h" +#include "SystemMgr.h" + +#include <string> +#include <map> + + + +// =========================================================================== +// EmPatchModule +// =========================================================================== + + +const uint16 kMaxProtoTables = 5; + +class EmPatchModule : public EcmObject, + ecm_implements IEmPatchModule +{ + private: +// ============================================================================== +// * illegal constructors +// ============================================================================== + //don't let EmPatchModule be created using default constructor... must have a unique name. + // + EmPatchModule(){} + + public: + +// ============================================================================== +// * constructors +// ============================================================================== + + EmPatchModule(const char *nameCSP, ProtoPatchTableEntry *protoTable1P = NULL, ProtoPatchTableEntry *protoTable2P = NULL); + virtual ~EmPatchModule (void) {}; + +// ============================================================================== +// * interface implementations +// ============================================================================== +// ============================================================================== +// * BEGIN IEmPatchModule +// ============================================================================== + + virtual Err Initialize(IEmPatchContainer &containerIP); + + virtual Err Reset(); + + virtual Err Dispose(); + + virtual Err Clear (); + + virtual Err Load(); + + virtual const string &GetName(); + + virtual Err GetHeadpatch (uint16 index, HeadpatchProc& procP); + virtual Err GetTailpatch (uint16 index, TailpatchProc& procP); + +// ============================================================================== +// * END IEmPatchModule +// ============================================================================== + + + void AddProtoPatchTable (ProtoPatchTableEntry protoPatchTable[], bool loadTable = false) + { + fProtoTables[fProtoTableCount++] = protoPatchTable; + + if (loadTable) + Load(); + } + + + void PrvLoadProtoPatchTable (uint16 index); + + bool operator == (const char *nameCSP) const + { + return (fName == nameCSP); + } + + bool operator == (const string &nameStr) const + { + return (fName == nameStr); + } + + private: + string fName; + + vector<HeadpatchProc> fHeadpatches; + vector<TailpatchProc> fTailpatches; + + uint16 fProtoTableCount; + uint16 fLoadedTableCount; + + IEmPatchContainer* fContainerIP; + + ProtoPatchTableEntry* fProtoTables[kMaxProtoTables]; +}; + +#endif // EmPatchModule_h diff --git a/SrcShared/Patches/EmPatchModuleHtal.cpp b/SrcShared/Patches/EmPatchModuleHtal.cpp new file mode 100644 index 0000000..f22c760 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleHtal.cpp @@ -0,0 +1,89 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + Portions Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchModuleHtal.h" + +#include "EmSubroutine.h" +#include "Marshal.h" + + +class HtalLibHeadpatch +{ + public: + static CallROMType HtalLibSendReply (void); +}; + + +EmPatchModuleHtal::EmPatchModuleHtal (void) : + EmPatchModule ("~Htal") +{ +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleHtal::GetHeadpatch + * + * DESCRIPTION: Special overide of GetHeadpatch to return the same function for any + * index. + * + * PARAMETERS: index trap index to locate patch for + * procP patch procedure returned. + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + + +Err EmPatchModuleHtal::GetHeadpatch (uint16 /* index */, HeadpatchProc& procP) +{ + procP = HtalLibHeadpatch::HtalLibSendReply; + + return kPatchErrNone; +} + + +/*********************************************************************** + * + * FUNCTION: HtalLibHeadpatch::HtalLibSendReply + * + * DESCRIPTION: Ohhh...I'm going to Programmer Hell for this one... + * We call DlkDispatchRequest to install the user name in + * our UIInitialize patch. DlkDispatchRequest will + * eventually call HtalLibSendReply to return a result + * code. Well, we haven't fired up the Htal library, and + * wouldn't want it to send a response even if we had. + * Therefore, I'll subvert the whole process by setting + * the HTAL library refNum passed in to the Desktop Link + * Manager to an invalid value. I'll look for this + * value in the SysTrap handling code and no-op the call + * by calling this stub. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType HtalLibHeadpatch::HtalLibSendReply (void) +{ + CALLED_SETUP ("Err", "void"); + + PUT_RESULT_VAL (Err, errNone); + + return kSkipROM; +} diff --git a/SrcShared/Patches/EmPatchModuleHtal.h b/SrcShared/Patches/EmPatchModuleHtal.h new file mode 100644 index 0000000..7147fca --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleHtal.h @@ -0,0 +1,30 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchModuleHtal_h +#define EmPatchModuleHtal_h + +#include "EmPatchModule.h" + +class EmPatchModuleHtal : public EmPatchModule +{ + public: + EmPatchModuleHtal (void); + virtual ~EmPatchModuleHtal (void) {} + + virtual Err GetHeadpatch (uint16 index, HeadpatchProc& proc); +}; + + +#endif // EmPatchModuleHtal_h diff --git a/SrcShared/Patches/EmPatchModuleMap.cpp b/SrcShared/Patches/EmPatchModuleMap.cpp new file mode 100644 index 0000000..5124004 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleMap.cpp @@ -0,0 +1,146 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchModuleMap.h" + +#include "EmStructs.h" +#include "Miscellaneous.h" + + + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleMap::EmPatchModuleMap + * + * DESCRIPTION: EmPatchModuleMap constructor + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +EmPatchModuleMap::EmPatchModuleMap() +{ +} + + + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleMap::DoAll + * + * DESCRIPTION: Repeat the given operation for all modules in the PatchMap + * + * PARAMETERS: todo the operation to be performed + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModuleMap::DoAll(EPmOperation todo, IEmPatchContainer *conainerIP) +{ + Err ret = kPatchErrNone; + + SimplePatchModuleMap::iterator iter; + for (iter = fModMap.begin(); iter != fModMap.end(); ++iter) + { + switch (todo) + { + case EPMOpInitializeAll: + iter->second->Initialize(*conainerIP); + break; + case EPMOpResetAll: + iter->second->Reset(); + break; + case EPMOpDisposeAll: + iter->second->Dispose(); + break; + case EPMOpClearAll: + iter->second->Clear(); + break; + case EPMOpLoadAll: + iter->second->Load(); + break; + default: + break; + } + } + + return ret; +} + + +// ============================================================================== +// * interface implementations +// ============================================================================== +// ============================================================================== +// * BEGIN IEmAllPatchModules +// ============================================================================== + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleMap::GetModuleByName + * + * DESCRIPTION: Locates a PatchModule in the collection, based on the given + * unique PatchModule name. + * + * PARAMETERS: nameStr name of the PatchModule to be located + * moduleIP IEmPatchModule interface for the given PatchModule + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModuleMap::GetModuleByName (const string &nameStr, IEmPatchModule *& moduleIP) +{ + moduleIP = NULL; + SimplePatchModuleMap::iterator iter = fModMap.find(nameStr); + + if (iter != fModMap.end()) + moduleIP = iter->second; + + return kPatchErrNone; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleMap::AddModule + * + * DESCRIPTION: Add a PatchModule to the EmPatchModuleMap collection + * + * PARAMETERS: moduleIP address of the IEmPatchModule interface for + * the PatchModule to be added. + * + * RETURNED: patchErrNone + * + ***********************************************************************/ + +Err EmPatchModuleMap::AddModule (IEmPatchModule *moduleIP) +{ + if (moduleIP != NULL) + { + fModMap.insert(SimplePatchModuleMap::value_type(moduleIP->GetName(), moduleIP)); + } + + return kPatchErrNone; +} + +// ============================================================================== +// * END IEmPatchModuleMap +// ============================================================================== diff --git a/SrcShared/Patches/EmPatchModuleMap.h b/SrcShared/Patches/EmPatchModuleMap.h new file mode 100644 index 0000000..0e242a9 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleMap.h @@ -0,0 +1,100 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchModuleMap_h +#define EmPatchModuleMap_h + +#include "EmPatchIf.h" // IEmPatchModuleMap +#include "EmPatchModule.h" // IEmPatchModule + + +typedef map<string, IEmPatchModule*> SimplePatchModuleMap; + + +// EmPatchModuleMap defines a mapped list of Patch Modules created + +class EmPatchModuleMap : public EcmObject, + ecm_implements IEmPatchModuleMap +{ + public: +// ============================================================================== +// * constructors +// ============================================================================== + EmPatchModuleMap(); + virtual ~EmPatchModuleMap() {} + + +// ============================================================================== +// * Helper functions +// ============================================================================== + enum EPmOperation + { + EPMOpInitializeAll, + EPMOpResetAll, + EPMOpDisposeAll, + EPMOpClearAll, + EPMOpLoadAll + }; + + Err DoAll(EPmOperation todo, IEmPatchContainer *IP = NULL); + + +// ============================================================================== +// * interface implementations +// ============================================================================== +// ============================================================================== +// * BEGIN IEmPatchModuleMap +// ============================================================================== + Err InitializeAll(IEmPatchContainer &containerI) + { + return DoAll(EPMOpInitializeAll, &containerI); + } + + Err ResetAll() + { + return DoAll(EPMOpResetAll); + } + + Err DisposeAll() + { + return DoAll(EPMOpDisposeAll); + } + + Err ClearAll() + { + return DoAll(EPMOpClearAll); + } + + Err LoadAll() + { + return DoAll(EPMOpLoadAll); + } + + Err AddModule (IEmPatchModule *moduleIP); + + Err GetModuleByName (const string &nameStr, IEmPatchModule *& moduleIP); + +// ============================================================================== +// * BEGIN IEmPatchModuleMap +// ============================================================================== + + private: + SimplePatchModuleMap fModMap; +}; + + +Err AddStaticPatchModules(); + + +#endif // EmPatchModuleMap_h diff --git a/SrcShared/Patches/EmPatchModuleMemMgr.cpp b/SrcShared/Patches/EmPatchModuleMemMgr.cpp new file mode 100644 index 0000000..92a3df8 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleMemMgr.cpp @@ -0,0 +1,1902 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchModuleSys.h" + +#include "EmLowMem.h" // EmLowMem_GetGlobal +#include "EmMemory.h" // CEnableFullAccess +#include "EmPalmOS.h" // ForgetStacksIn +#include "EmPalmFunction.h" // FindFunctionName +#include "EmPalmHeap.h" // EmPalmHeap::MemMgrInit, etc. +#include "EmPatchState.h" // EnterMemMgr, ExitMemMgr,etc. +#include "EmSession.h" // ScheduleDeferredError +#include "EmSubroutine.h" +#include "Hordes.h" // gWarningHappened (!!! There's gotta be a better place for this!) +#include "Logging.h" // LogAppendMsg +#include "Marshal.h" // CALLED_SETUP +#include "MetaMemory.h" // MetaMemory mark functions +#include "PreferenceMgr.h" // ShouldContinue +#include "ROMStubs.h" // MemHandleLock, MemHandleUnlock + + +// ====================================================================== +// Proto patch table for the system functions. This array will be used +// to create a sparse array at runtime. +// ====================================================================== + +ProtoPatchTableEntry gProtoMemMgrPatchTable[] = +{ + #undef INSTALL_PATCH + #define INSTALL_PATCH(fn) {sysTrap##fn, MemMgrHeadpatch::fn, MemMgrTailpatch::fn}, + + FOR_EACH_MEMMGR_FUNCTION(INSTALL_PATCH) + + {0, NULL, NULL} +}; + + +#ifdef FILL_BLOCKS +const int kChunkNewValue = 0x31; +const int kChunkResizeValue = 0x33; +const int kChunkFreeValue = 0x35; +const int kHandleNewValue = 0x71; +const int kHandleResizeValue = 0x73; +const int kHandleFreeValue = 0x75; +const int kPtrNewValue = 0x91; +const int kPtrResizeValue = 0x93; +const int kPtrFreeValue = 0x95; +#endif + +static void PrvRememberHeapAndPtr (EmPalmHeap* h, emuptr p); +static EmPalmHeap* PrvGetRememberedHeap (emuptr p); + +static void PrvRememberChunk (emuptr); +static void PrvRememberHandle (emuptr); +static void PrvForgetChunk (emuptr); +static void PrvForgetHandle (emuptr); +static void PrvForgetAll (UInt16 heapID, UInt16 ownerID); +static int PrvCountLeaks (UInt16 ownerID); +static void PrvReportMemoryLeaks (UInt16 ownerID); +static void PrvReportLeakedChunk (const EmTrackedChunk& tracked, + const EmPalmChunk& chunk); +static Bool PrvLeakException (const EmPalmChunk& chunk); + + +// Define a bunch of wrapper head- and tailpatches. +// These are defined via macros for those functions that don't have a +// complex implementation. + +#define DEFINE_HEAD_PATCH(fn) CallROMType MemMgrHeadpatch::fn (void) { EmPatchState::EnterMemMgr (#fn); return kExecuteROM; } +#define DEFINE_TAIL_PATCH(fn) void MemMgrTailpatch::fn (void) { EmPatchState::ExitMemMgr (#fn); } + +FOR_EACH_STUB_HEADPATCH_FUNCTION(DEFINE_HEAD_PATCH) +FOR_EACH_STUB_BOTHPATCH_FUNCTION(DEFINE_HEAD_PATCH) + +FOR_EACH_STUB_TAILPATCH_FUNCTION(DEFINE_TAIL_PATCH) +FOR_EACH_STUB_BOTHPATCH_FUNCTION(DEFINE_TAIL_PATCH) + + +#pragma mark - + +/*********************************************************************** + * + * FUNCTION: MemMgrHeadpatch::MemChunkFree + * + * DESCRIPTION: If the user wants disposed blocks to be filled with a + * special value, handle that here. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType MemMgrHeadpatch::MemChunkFree (void) +{ + // Err MemChunkFree(MemPtr chunkDataP) + + EmPatchState::EnterMemMgr ("MemChunkFree"); + + CALLED_SETUP ("Err", "MemPtr p"); + + CALLED_GET_PARAM_VAL (MemPtr, p); + +#ifdef FILL_BLOCKS + + gHeapID = ::MemPtrHeapID (p); + + if (p && gPrefs->FillDisposedBlocks ()) + { + UInt32 size = ::MemPtrSize (p); + + CEnableFullAccess munge; + uae_memset (p, kChunkFreeValue, size); + } + +#endif + + ::PrvForgetChunk ((emuptr) (MemPtr) p); + + // Remember what heap the chunk was in for later when + // we need to resync with that heap. + + EmPalmHeap* heap = const_cast<EmPalmHeap*>(EmPalmHeap::GetHeapByPtr (p)); + ::PrvRememberHeapAndPtr (heap, (emuptr) (MemPtr) p); + + // In case this chunk contained a stack, forget all references + // to that stack (or those stacks). + + if (heap) + { + const EmPalmChunk* chunk = heap->GetChunkBodyContaining ((emuptr) (MemPtr) p); + if (chunk) + { + EmPalmOS::ForgetStacksIn (chunk->BodyStart (), chunk->BodySize ()); + } + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrHeadpatch::MemHandleFree + * + * DESCRIPTION: If the user wants disposed blocks to be filled with a + * special value, handle that here. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType MemMgrHeadpatch::MemHandleFree (void) +{ + // Err MemHandleFree(MemHandle h) + + EmPatchState::EnterMemMgr ("MemHandleFree"); + + CALLED_SETUP ("Err", "MemHandle h"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + +#ifdef FILL_BLOCKS + + gHeapID = ::MemHandleHeapID (h); + + if (h && gPrefs->FillDisposedBlocks ()) + { + UInt32 size = ::MemHandleSize (h); + if (p) + { + { + CEnableFullAccess munge; + uae_memset (p, kHandleFreeValue, size); + } + } + } + +#endif + + ::PrvForgetHandle ((emuptr) (MemHandle) h); + + // Remember what heap the chunk was in for later when + // we need to resync with that heap. + + EmPalmHeap* heap = const_cast<EmPalmHeap*>(EmPalmHeap::GetHeapByHdl (h)); + ::PrvRememberHeapAndPtr (heap, (emuptr) (MemHandle) h); + + // In case this chunk contained a stack, forget all references + // to that stack (or those stacks). + + if (heap) + { + const EmPalmChunk* chunk = heap->GetChunkReferencedBy (h); + if (chunk) + { + EmPalmOS::ForgetStacksIn (chunk->BodyStart (), chunk->BodySize ()); + } + } + + if (h) + { + // In case this chunk contained system code, invalid our cache + // of valid system code chunks. + + emuptr p = (emuptr) EmPalmHeap::DerefHandle (h); + MetaMemory::ChunkUnlocked (p); + + // In case this chunk held a bitmap, drop it from our list of + // registered bitmaps. + + MetaMemory::UnregisterBitmapHandle (h); + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrHeadpatch::MemHandleUnlock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType MemMgrHeadpatch::MemHandleUnlock (void) +{ + // Err MemHandleUnlock(MemHandle h) + + EmPatchState::EnterMemMgr ("MemHandleUnlock"); + + CALLED_SETUP ("Err", "MemHandle h"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + + // If this handle was for a bitmap resource, forget the pointer + // we registered earlier. + + if (MetaMemory::IsBitmapHandle (h)) + { + EmPalmHeap* heap = const_cast<EmPalmHeap*>(EmPalmHeap::GetHeapByHdl (h)); + + if (heap) + { + emuptr p = (emuptr) EmPalmHeap::DerefHandle (h) - heap->ChunkHeaderSize (); + + EmPalmChunk chunk (*heap, p); + + if (chunk.LockCount () == 1) + { + MetaMemory::UnregisterBitmapPointer ((MemPtr) p); + } + } + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrHeadpatch::MemPtrUnlock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType MemMgrHeadpatch::MemPtrUnlock (void) +{ + // Err MemPtrUnlock(MemPtr p) + + EmPatchState::EnterMemMgr ("MemPtrUnlock"); + + CALLED_SETUP ("Err", "MemPtr p"); + + CALLED_GET_PARAM_VAL (MemPtr, p); + + // If this handle was for a bitmap resource, forget the pointer + // we registered earlier. + + if (MetaMemory::IsBitmapPointer (p)) + { + MetaMemory::UnregisterBitmapPointer (p); + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrHeadpatch::MemSemaphoreRelease + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType MemMgrHeadpatch::MemSemaphoreRelease (void) +{ + // Err MemSemaphoreRelease (Boolean writeAccess) + + EmPatchState::EnterMemMgr ("MemSemaphoreRelease"); + + CALLED_SETUP ("Err", "Boolean writeAccess"); + + CALLED_GET_PARAM_VAL (Boolean, writeAccess); + + if (writeAccess + && --EmPatchState::fgData.fMemSemaphoreCount == 0 + && EmPatchState::HasWellBehavedMemSemaphoreUsage ()) + { + // Amount of time to allow before warning that the memory manager + // semaphore has been held too long. Note that this used to be + // 60 seconds. However, at current emulation speeds and the rate + // at which the tickcount is incremented, it seems that the + // Memory Manager itself can hold onto the semaphore longer than + // this threshold (in really, really full heaps when calling + // MemChunkNew, for example). So let's double it. + + const unsigned long kMaxElapsedSeconds = 120 /* seconds */ * 100 /* ticks per second */; + + CEnableFullAccess munge; + + unsigned long curCount = EmLowMem_GetGlobal (hwrCurTicks); + unsigned long elapsedTicks = curCount - EmPatchState::fgData.fMemSemaphoreReserveTime; + + if (elapsedTicks > kMaxElapsedSeconds) + { + EmAssert (gSession); + gSession->ScheduleDeferredError (new EmDeferredErrMemMgrSemaphore); + } + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrHeadpatch::MemSemaphoreReserve + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType MemMgrHeadpatch::MemSemaphoreReserve (void) +{ + // Err MemSemaphoreReserve (Boolean writeAccess) + + EmPatchState::EnterMemMgr ("MemSemaphoreReserve"); + + CALLED_SETUP ("Err", "Boolean writeAccess"); + + CALLED_GET_PARAM_VAL (Boolean, writeAccess); + + if (writeAccess + && EmPatchState::fgData.fMemSemaphoreCount++ == 0 + && EmPatchState::HasWellBehavedMemSemaphoreUsage ()) + { + CEnableFullAccess munge; + EmPatchState::fgData.fMemSemaphoreReserveTime = EmLowMem_GetGlobal (hwrCurTicks); + } + + return kExecuteROM; +} + + +#pragma mark - + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemChunkFree + * + * DESCRIPTION: If the user wants disposed blocks to be filled with a + * special value, handle that here. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemChunkFree (void) +{ + // Err MemChunkFree(MemPtr chunkDataP) + + CALLED_SETUP ("Err", "MemPtr p"); + + CALLED_GET_PARAM_VAL (MemPtr, p); + + EmPalmHeap* heap = ::PrvGetRememberedHeap ((emuptr) (MemPtr) p); + + EmPalmChunkList delta; + EmPalmHeap::MemChunkFree (heap, &delta); + MetaMemory::Resync (delta); + + { + CEnableFullAccess munge; + + emuptr w = EmLowMem_GetGlobal (uiGlobals.firstWindow); + if (w == (emuptr) (MemPtr) p) + { + EmPatchState::SetUIReset (false); + } + } + + EmPatchState::ExitMemMgr ("MemChunkFree"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemChunkNew + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemChunkNew (void) +{ + // MemPtr MemChunkNew(UInt16 heapID, UInt32 size, UInt16 attr) + + CALLED_SETUP ("MemPtr", "UInt16 heapID, UInt32 size, UInt16 attr"); + + CALLED_GET_PARAM_VAL (UInt16, heapID); +// CALLED_GET_PARAM_VAL (UInt32, size); + CALLED_GET_PARAM_VAL (UInt16, attr); + GET_RESULT_PTR (); + +#ifdef FILL_BLOCKS + + if (gPrefs->FillNewBlocks ()) + { + if (c) + { + + if (attr & memNewChunkFlagNonMovable) + { + CEnableFullAccess munge; + uae_memset (c, kChunkNewValue, size); + } + else + { + emuptr p = (emuptr) ::MemHandleLock ((MemHandle) c); + if (p) + { + { + CEnableFullAccess munge; + uae_memset (p, kChunkNewValue, size); + } + + ::MemHandleUnlock ((MemHandle) c); + } + } + } + } + +#endif + + EmPalmChunkList delta; + EmPalmHeap::MemChunkNew (heapID, (MemPtr) result, attr, &delta); + MetaMemory::Resync (delta); + +#define TRACK_BOOT_ALLOCATION 0 +#if TRACK_BOOT_ALLOCATION + if (attr & memNewChunkFlagNonMovable) + { + c = EmPalmHeap::DerefHandle (c); + } + + const EmPalmHeap* heap = EmPalmHeap::GetHeapByPtr ((MemPtr) result); + if (heap) + { + const EmPalmChunk* chunk = heap->GetChunkContaining (result); + if (chunk) + { + LogAppendMsg ("Chunk allocated, loc = 0x%08X, size = 0x%08X", + (int) chunk->Start (), (int) chunk->Size ()); + } + } +#endif + + if (attr & memNewChunkFlagNonMovable) + { + ::PrvRememberChunk (result); + } + + else if (attr & memNewChunkFlagPreLock) + { + MemHandle h = EmPalmHeap::RecoverHandle ((MemPtr) result); + ::PrvRememberHandle ((emuptr) h); + } + else + { + ::PrvRememberHandle (result); + } + + EmPatchState::ExitMemMgr ("MemChunkNew"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHandleFree + * + * DESCRIPTION: If the user wants disposed blocks to be filled with a + * special value, handle that here. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHandleFree (void) +{ + // Err MemHandleFree(MemHandle h) + + CALLED_SETUP ("Err", "MemHandle h"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + + EmPalmHeap* heap = ::PrvGetRememberedHeap ((emuptr) (MemHandle) h); + + EmPalmChunkList delta; + EmPalmHeap::MemHandleFree (heap, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemHandleFree"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHandleNew + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHandleNew (void) +{ + // MemHandle MemHandleNew(UInt32 size) + + CALLED_SETUP ("MemHandle", "UInt32 size"); + + GET_RESULT_PTR (); + + +#ifdef FILL_BLOCKS + + if (result) + { + if (size && gPrefs->FillNewBlocks ()) + { + emuptr p = (emuptr) ::MemHandleLock ((MemHandle) result); + if (p) + { + { + CEnableFullAccess munge; + uae_memset (p, kHandleNewValue, size); + } + + ::MemHandleUnlock ((MemHandle) result); + } + } + } + +#endif + + EmPalmChunkList delta; + EmPalmHeap::MemHandleNew ((MemHandle) result, &delta); + MetaMemory::Resync (delta); + +#if TRACK_BOOT_ALLOCATION + emuptr c; + + if (1) + { + c = EmPalmHeap::DerefHandle (result); + } + + const EmPalmHeap* heap = EmPalmHeap::GetHeapByPtr ((MemPtr) c); + if (heap) + { + const EmPalmChunk* chunk = heap->GetChunkContaining (c); + if (chunk) + { + LogAppendMsg ("Handle allocated, loc = 0x%08X, size = 0x%08X", + (int) chunk->Start (), (int) chunk->Size ()); + } + } +#endif + + ::PrvRememberHandle (result); + + EmPatchState::ExitMemMgr ("MemHandleNew"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHandleLock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHandleLock (void) +{ + // MemPtr MemHandleLock(MemHandle h) + + CALLED_SETUP ("MemPtr", "MemHandle h"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + + EmPalmChunkList delta; + EmPalmHeap::MemHandleLock ((MemHandle) h, &delta); + MetaMemory::Resync (delta); + + // If this handle was for a bitmap resource, remember the pointer + // for fast checking later. + + if (MetaMemory::IsBitmapHandle (h)) + { + GET_RESULT_PTR (); + MetaMemory::RegisterBitmapPointer ((MemPtr) result); + } + + EmPatchState::ExitMemMgr ("MemHandleLock"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHandleResetLock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHandleResetLock (void) +{ + // Err MemHandleResetLock(MemHandle h) + + CALLED_SETUP ("Err", "MemHandle h"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + + EmPalmChunkList delta; + EmPalmHeap::MemHandleResetLock ((MemHandle) h, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemHandleResetLock"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHandleResize + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHandleResize (void) +{ + // Err MemHandleResize(MemHandle h, UInt32 newSize) + + CALLED_SETUP ("Err", "MemHandle h, UInt32 newSize"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + +#ifdef FILL_BLOCKS + + if (h) + { + if (newSize > gResizeOrigSize && gPrefs->FillResizedBlocks ()) + { + emuptr p = (emuptr) ::MemHandleLock ((MemHandle) h); + if (p) + { + { + CEnableFullAccess munge; + uae_memset (p + gResizeOrigSize, kHandleResizeValue, newSize - gResizeOrigSize); + } + + ::MemHandleUnlock ((MemHandle) h); + } + } + } + +#endif + + EmPalmChunkList delta; + EmPalmHeap::MemHandleResize ((MemHandle) h, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemHandleResize"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHandleUnlock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHandleUnlock (void) +{ + // Err MemHandleUnlock(MemHandle h) + + CALLED_SETUP ("Err", "MemHandle h"); + + CALLED_GET_PARAM_VAL (MemHandle, h); + + EmPalmChunkList delta; + EmPalmHeap::MemHandleUnlock ((MemHandle) h, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemHandleUnlock"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHeapCompact + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHeapCompact (void) +{ + // Err MemHeapCompact(UInt16 heapID) + + CALLED_SETUP ("Err", "UInt16 heapID"); + + CALLED_GET_PARAM_VAL (UInt16, heapID); + + EmPalmChunkList delta; + EmPalmHeap::MemHeapCompact (heapID, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemHeapCompact"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHeapFreeByOwnerID + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +// !!! This should probably walk the heap itself so that it can just mark +// the chunks that are about to be freed. + +void MemMgrTailpatch::MemHeapFreeByOwnerID (void) +{ + // Err MemHeapFreeByOwnerID(UInt16 heapID, UInt16 ownerID) + + CALLED_SETUP ("Err", "UInt16 heapID, UInt16 ownerID"); + + CALLED_GET_PARAM_VAL (UInt16, heapID); + CALLED_GET_PARAM_VAL (UInt16, ownerID); + + EmPalmChunkList delta; + EmPalmHeap::MemHeapFreeByOwnerID (heapID, ownerID, &delta); + MetaMemory::Resync (delta); + + ::PrvForgetAll (heapID, ownerID); + + EmPatchState::ExitMemMgr ("MemHeapFreeByOwnerID"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemInitHeapTable + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemInitHeapTable (void) +{ + // Err MemInitHeapTable(UInt16 cardNo) + + CALLED_SETUP ("Err", "UInt16 cardNo"); + + CALLED_GET_PARAM_VAL (UInt16, cardNo); + + EmPalmHeap::MemInitHeapTable (cardNo); + + EmPatchState::ExitMemMgr ("MemInitHeapTable"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHeapInit + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHeapInit (void) +{ + // Err MemHeapInit(UInt16 heapID, Int16 numHandles, Boolean initContents) + + CALLED_SETUP ("Err", "UInt16 heapID, Int16 numHandles, Boolean initContents"); + + CALLED_GET_PARAM_VAL (UInt16, heapID); + CALLED_GET_PARAM_VAL (Int16, numHandles); + CALLED_GET_PARAM_VAL (Boolean, initContents); + + EmPalmHeap::MemHeapInit (heapID, numHandles, initContents); + + EmPatchState::ExitMemMgr ("MemHeapInit"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemHeapScramble + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemHeapScramble (void) +{ + // Err MemHeapScramble(UInt16 heapID) + + CALLED_SETUP ("Err", "UInt16 heapID"); + + CALLED_GET_PARAM_VAL (UInt16, heapID); + + EmPalmChunkList delta; + EmPalmHeap::MemHeapScramble (heapID, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemHeapScramble"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemKernelInit + * + * DESCRIPTION: MemKernelInit is called just after AMXDriversInit, which + * is where the exception vectors are set up. After those + * vectors are installed, there really shouldn't be any + * more memory accesses to that range of memory. Thus, + * memory access there is flagged as invalid. + * + * While we're here, let's mark some other memory + * locations, too. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemKernelInit (void) +{ + MetaMemory::MarkLowMemory ( MetaMemory::GetLowMemoryBegin (), + MetaMemory::GetLowMemoryEnd ()); + MetaMemory::MarkSystemGlobals ( MetaMemory::GetSysGlobalsBegin (), + MetaMemory::GetSysGlobalsEnd ()); + MetaMemory::MarkHeapHeader ( MetaMemory::GetHeapHdrBegin (0), + MetaMemory::GetHeapHdrEnd (0)); + + // On the Visor, these are fair game. + MetaMemory::MarkSystemGlobals (offsetof (M68KExcTableType, unassigned[12]), + offsetof (M68KExcTableType, unassigned[16])); + + EmPatchState::ExitMemMgr ("MemKernelInit"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemLocalIDToLockedPtr + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemLocalIDToLockedPtr (void) +{ + // MemPtr MemLocalIDToLockedPtr(LocalID local, UInt16 cardNo) + + CALLED_SETUP ("MemPtr", "LocalID local, UInt16 cardNo"); + + GET_RESULT_PTR (); + + EmPalmChunkList delta; + EmPalmHeap::MemLocalIDToLockedPtr ((MemPtr) result, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemLocalIDToLockedPtr"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemPtrNew + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemPtrNew (void) +{ + // MemPtr MemPtrNew(UInt32 size) + + CALLED_SETUP ("MemPtr", "UInt32 size"); + + GET_RESULT_PTR (); + +#ifdef FILL_BLOCKS + + if (result) + { + if (gPrefs->FillNewBlocks ()) + { + CEnableFullAccess munge; + uae_memset (result, kPtrNewValue, size); + } + } + +#endif + + EmPalmChunkList delta; + EmPalmHeap::MemPtrNew ((MemPtr) result, &delta); + MetaMemory::Resync (delta); + + ::PrvRememberChunk (result); + + EmPatchState::ExitMemMgr ("MemPtrNew"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemPtrResetLock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemPtrResetLock (void) +{ + // Err MemPtrResetLock(MemPtr p) + + CALLED_SETUP ("Err", "MemPtr p"); + + CALLED_GET_PARAM_VAL (MemPtr, p); + + EmPalmChunkList delta; + EmPalmHeap::MemPtrResetLock (p, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemPtrResetLock"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemPtrResize + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemPtrSetOwner (void) +{ + // Err MemPtrSetOwner(MemPtr chunkDataP, UInt8 owner) + + CALLED_SETUP ("Err", "MemPtr p, UInt16 owner"); + + CALLED_GET_PARAM_VAL (MemPtr, p); +// CALLED_GET_PARAM_VAL (UInt16, owner); + + EmPalmChunkList delta; + EmPalmHeap::MemPtrSetOwner (p, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemPtrSetOwner"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemPtrResize + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemPtrResize (void) +{ + // Err MemPtrResize(MemPtr p, UInt32 newSize) + + CALLED_SETUP ("Err", "MemPtr p, UInt32 newSize"); + + CALLED_GET_PARAM_VAL (MemPtr, p); + +#ifdef FILL_BLOCKS + + if (p) + { + if (newSize > gResizeOrigSize && gPrefs->FillResizedBlocks ()) + { + CEnableFullAccess munge; + uae_memset (p + gResizeOrigSize, kPtrResizeValue, newSize - gResizeOrigSize); + } + } + +#endif + + EmPalmChunkList delta; + EmPalmHeap::MemPtrResize (p, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemPtrResize"); +} + + +/*********************************************************************** + * + * FUNCTION: MemMgrTailpatch::MemPtrUnlock + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void MemMgrTailpatch::MemPtrUnlock (void) +{ + // Err MemPtrUnlock(MemPtr p) + + CALLED_SETUP ("Err", "MemPtr p"); + + CALLED_GET_PARAM_VAL (MemPtr, p); + + EmPalmChunkList delta; + EmPalmHeap::MemPtrUnlock (p, &delta); + MetaMemory::Resync (delta); + + EmPatchState::ExitMemMgr ("MemPtrUnlock"); +} + + +#pragma mark - + +/*********************************************************************** + * + * FUNCTION: PrvRememberHeapAndPtr + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void PrvRememberHeapAndPtr (EmPalmHeap* h, emuptr p) +{ + EmAssert (EmPatchState::fgData.fRememberedHeaps.find (p) == EmPatchState::fgData.fRememberedHeaps.end ()); + + EmPatchState::fgData.fRememberedHeaps[p] = h; +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetRememberedHeap + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +EmPalmHeap* PrvGetRememberedHeap (emuptr p) +{ + EmPalmHeap* result = NULL; + + map<emuptr, EmPalmHeap*>::iterator iter = EmPatchState::fgData.fRememberedHeaps.find (p); + if (iter != EmPatchState::fgData.fRememberedHeaps.end ()) + { + result = iter->second; + EmPatchState::fgData.fRememberedHeaps.erase (iter); + } + + EmAssert (result); + + return result; +} + + +#pragma mark - + +/*********************************************************************** + * + * FUNCTION: PrvRememberChunk + * + * DESCRIPTION: Remember the context in which the given pointer was + * allocated. Called after MemPtrNew or MemChunkNew + * completes. + * + * PARAMETERS: p - pointer returned from MemPtrNew or MemChunkNew. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvRememberChunk (emuptr p) +{ + // + // Track only allocations in the dynamic heap. + // + + const EmPalmHeap* heap = EmPalmHeap::GetHeapByPtr (p); + + if (!heap || heap->HeapID () != 0) + return; + +#ifdef _DEBUG + + // + // Make sure that this pointer is not a handle in disguise. + // + + MemHandle h = EmPalmHeap::RecoverHandle ((MemPtr) p); + + if (h) + { + EmAssert (false); + } + + // + // Ensure this pointer is not already on our list. + // + + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + // + // If we have recorded a handle, make sure that our handle + // does not reference this newly allocated chunk. That would + // indicate that we have a stale handle in our list. + // + + if (iter->isHandle) + { + emuptr hDereffed = (emuptr) EmPalmHeap::DerefHandle ((MemHandle) iter->ptr); + if (hDereffed == p) + { + EmAssert (false); + } + } + + // + // If we have recorded a pointer, make sure that it doesn't + // also point to the newly allocated chunk. That would indicate + // that we have a stale pointer in our list. + // + + else + { + if (iter->ptr == p) + { + EmAssert (false); + } + } + + ++iter; + } +#endif + + // + // Push an empty record onto our list. We'll update it after + // it's on the list in order to reduce any performance impact + // due to copying the stack crawl. Push the chunk at the front + // of the list; the theory here is that recently added chunks + // will be the ones most likely to be removed later, so adding + // them to the front will speed up the removal process when + // performing a forward traversal. + // + + EmTrackedChunk chunk; + EmPatchState::fgData.fTrackedChunks.push_front (chunk); + + // + // Get the pointer to the newly-added record. + // + + EmTrackedChunkList::reference newChunk = EmPatchState::fgData.fTrackedChunks.front (); + + // + // Fill in the newly added record. + // + + newChunk.ptr = p; + newChunk.isHandle = false; + + EmPalmOS::GenerateStackCrawl (newChunk.stackCrawl); +} + + +/*********************************************************************** + * + * FUNCTION: PrvRememberHandle + * + * DESCRIPTION: Remember the context in which the given handle was + * allocated. Called after MemHandleNew or MemChunkNew + * completes. + * + * PARAMETERS: h - handle returned from MemHandleNew or MemChunkNew. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvRememberHandle (emuptr h) +{ + // + // Track only allocations in the dynamic heap. + // + + const EmPalmHeap* heap = EmPalmHeap::GetHeapByHdl ((MemHandle) h); + + if (!heap || heap->HeapID () != 0) + return; + +#ifdef _DEBUG + // + // Ensure this handle is not already on our list. + // + + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + // + // If we have recorded a handle, make sure it does not + // match the newly allocated handle. That would indicate + // that we have a stale handle in our list. + // + + if (iter->isHandle) + { + if (iter->ptr == h) + { + EmAssert (false); + } + } + + // + // If we have recorded a pointer, make sure it is not + // pointed to by the newly allocate handle. That would + // indicate that we have a stale pointer in our list. + // + + else + { + emuptr hDereffed = (emuptr) EmPalmHeap::DerefHandle ((MemHandle) h); + + if (iter->ptr == hDereffed) + { + EmAssert (false); + } + } + + ++iter; + } +#endif + + // + // Push an empty record onto our list. We'll update it after + // it's on the list in order to reduce any performance impact + // due to copying the stack crawl. Push the handle at the front + // of the list; the theory here is that recently added chunks + // will be the ones most likely to be removed later, so adding + // them to the front will speed up the removal process when + // performing a forward traversal. + // + + EmTrackedChunk chunk; + EmPatchState::fgData.fTrackedChunks.push_front (chunk); + + // + // Get the pointer to the newly-added record. + // + + EmTrackedChunkList::reference newChunk = EmPatchState::fgData.fTrackedChunks.front (); + + // + // Fill in the newly added record. + // + + newChunk.ptr = h; + newChunk.isHandle = true; + + EmPalmOS::GenerateStackCrawl (newChunk.stackCrawl); +} + + +/*********************************************************************** + * + * FUNCTION: PrvForgetChunk + * + * DESCRIPTION: Forget about the given chunk. Also checks for pointers + * to relocatable blocks and calls PrvForgetHandle instead + * if appropriate. Called in response to MemChunkFree. + * + * PARAMETERS: p - handle passed to MemChunkFree. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvForgetChunk (emuptr p) +{ + // + // Deal with the goofwads who allocate by handle but + // dispose by pointer. + // + + MemHandle h = EmPalmHeap::RecoverHandle ((MemPtr) p); + + if (h) + { + ::PrvForgetHandle ((emuptr) h); + return; + } + + // + // Look for the given chunk in our records. + // + + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + if (!iter->isHandle && iter->ptr == p) + { + // + // If we've found it, erase it from our list and return. + // + + EmPatchState::fgData.fTrackedChunks.erase (iter); + return; + } + + ++iter; + } +} + + +/*********************************************************************** + * + * FUNCTION: PrvForgetHandle + * + * DESCRIPTION: Forget about the given handle. Called in response to + * MemHandleFree. + * + * PARAMETERS: h - handle passed to MemHandleFree. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvForgetHandle (emuptr h) +{ + // + // Look for the given handle in our records. + // + + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + if (iter->isHandle && iter->ptr == h) + { + // + // If we've found it, erase it from our list and return. + // + + EmPatchState::fgData.fTrackedChunks.erase (iter); + return; + } + + ++iter; + } +} + + +/*********************************************************************** + * + * FUNCTION: PrvForgetAll + * + * DESCRIPTION: Forget about all allocated chunks in the given heap + * with the given owner ID. Called in response to + * MemHeapFreeByOwnerID. + * + * PARAMETERS: heapID - heap ID passed to MemHeapFreeByOwnerID. + * + * ownerID - owner ID passed to MemHeapFreeByOwnerID. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvForgetAll (UInt16 heapID, UInt16 ownerID) +{ + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + const EmPalmHeap* heap = NULL; + const EmPalmChunk* chunk = NULL; + + if (iter->isHandle) + { + heap = EmPalmHeap::GetHeapByHdl ((MemHandle) iter->ptr); + + if (heap && heap->HeapID () == heapID) + { + chunk = heap->GetChunkReferencedBy ((MemHandle) iter->ptr); + } + } + else + { + heap = EmPalmHeap::GetHeapByPtr (iter->ptr); + + if (heap && heap->HeapID () == heapID) + { + chunk = heap->GetChunkBodyContaining (iter->ptr); + } + } + + if (chunk && chunk->Owner () == ownerID) + { + iter = EmPatchState::fgData.fTrackedChunks.erase (iter); + } + else + { + if (chunk) + EmAssert (!chunk->Free ()); + + ++iter; + } + } +} + + +/*********************************************************************** + * + * FUNCTION: PrvCountLeaks + * + * DESCRIPTION: Find and report memory leaks. Iterates over the + * allocated chunks, looking for ones with the given + * owner ID. + * + * PARAMETERS: ownerID - owner ID of the application quitting. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +int PrvCountLeaks (UInt16 ownerID) +{ + int leaks = 0; + + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + const EmPalmHeap* heap = NULL; + const EmPalmChunk* chunk = NULL; + + if (iter->isHandle) + { + heap = EmPalmHeap::GetHeapByHdl ((MemHandle) iter->ptr); + + if (heap) + { + chunk = heap->GetChunkReferencedBy ((MemHandle) iter->ptr); + } + } + else + { + heap = EmPalmHeap::GetHeapByPtr (iter->ptr); + + if (heap) + { + chunk = heap->GetChunkBodyContaining (iter->ptr); + } + } + + if (chunk && chunk->Owner () == ownerID) + { + // + // If this "leak" is not caused by the OS, count it. + // + + if (!::PrvLeakException (*chunk)) + { + ++leaks; + } + } + + ++iter; + } + + return leaks; +} + + +/*********************************************************************** + * + * FUNCTION: PrvReportMemoryLeaks + * + * DESCRIPTION: Find and report memory leaks. Iterates over the + * allocated chunks, looking for ones with the given + * owner ID. + * + * PARAMETERS: ownerID - owner ID of the application quitting. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvReportMemoryLeaks (UInt16 ownerID) +{ + EmTrackedChunkList::iterator iter = EmPatchState::fgData.fTrackedChunks.begin (); + while (iter != EmPatchState::fgData.fTrackedChunks.end ()) + { + const EmPalmHeap* heap = NULL; + const EmPalmChunk* chunk = NULL; + + if (iter->isHandle) + { + heap = EmPalmHeap::GetHeapByHdl ((MemHandle) iter->ptr); + + if (heap) + { + chunk = heap->GetChunkReferencedBy ((MemHandle) iter->ptr); + } + } + else + { + heap = EmPalmHeap::GetHeapByPtr (iter->ptr); + + if (heap) + { + chunk = heap->GetChunkBodyContaining (iter->ptr); + } + } + + if (chunk && chunk->Owner () == ownerID) + { + // + // If this "leak" is not caused by the OS, report it. + // + + if (!::PrvLeakException (*chunk)) + { + if (iter != EmPatchState::fgData.fTrackedChunks.begin ()) + { + LogAppendMsg ("--------------------------------------------------------"); + } + + ::PrvReportLeakedChunk (*iter, *chunk); + } + } + + ++iter; + } +} + + +/*********************************************************************** + * + * FUNCTION: PrvReportLeakedChunk + * + * DESCRIPTION: Report information on the leaked chunk: + * + * * Chunk address and size + * * Stack crawl of the context allocating the chunk + * * Contents of the chunk (truncated to 256 bytes). + * + * PARAMETERS: tracked - context information about the chunk. + * + * chunk - information on the leaked chunk. + * + * RETURNED: nothing. + * + ***********************************************************************/ + +void PrvReportLeakedChunk (const EmTrackedChunk& tracked, const EmPalmChunk& chunk) +{ + // + // Generate a full stack crawl. + // + + StringList stackCrawlFunctions; + + EmStackFrameList::const_iterator iter = tracked.stackCrawl.begin (); + while (iter != tracked.stackCrawl.end ()) + { + // Get the function name. + + char funcName[256] = {0}; + ::FindFunctionName (iter->fAddressInFunction, funcName, NULL, NULL, 255); + + // If we can't find the name, dummy one up. + + if (strlen (funcName) == 0) + { + sprintf (funcName, "<Unknown @ 0x%08lX>", iter->fAddressInFunction); + } + + stackCrawlFunctions.push_back (string (funcName)); + + ++iter; + } + + // + // Get some data to dump + // + + uint8 buffer[256]; + uint32 len = chunk.BodySize (); + + if (len > countof (buffer)) + { + len = countof (buffer); + } + + EmMem_memcpy ((void*) buffer, chunk.BodyStart (), len); + + // + // Print the message. + // + // * Chunk address and size + // * Stack crawl of the context allocating the chunk + // * Contents of the chunk (truncated to 256 bytes). + // + + LogAppendMsg ("%s chunk leaked at 0x%08X, size = %ld", + tracked.isHandle ? "Relocatable" : "Non-relocatable", + chunk.BodyStart (), chunk.BodySize ()); + + LogAppendMsg ("Chunk allocated by:"); + + StringList::iterator iter2 = stackCrawlFunctions.begin (); + while (iter2 != stackCrawlFunctions.end ()) + { + LogAppendMsg ("\t%s", iter2->c_str ()); + + ++iter2; + } + + if (chunk.BodySize () <= countof (buffer)) + LogAppendData (buffer, len, "Chunk contents:"); + else + LogAppendData (buffer, len, "Chunk contents (first %d bytes only):", countof (buffer)); +} + + +/*********************************************************************** + * + * FUNCTION: PrvLeakException + * + * DESCRIPTION: Return whether or not the given memory chunk should be + * quietly allowed as a leak. + * + * PARAMETERS: chunk - information on the chunk to be tested. + * + * RETURNED: TRUE if the chunk -- even though leaked -- should not + * be reported as a leak. FALSE otherwise. + * + ***********************************************************************/ + +Bool PrvLeakException (const EmPalmChunk& chunk) +{ + // Up to Palm OS 3.2, UIReset (called from the application's + // startup code) allocated the event queue and undo buffers + // using the application's chunk ID. In Palm OS 3.2, this + // allocation was moved to UIInitialize, causing the blocks + // to be marked with the system's chunk ID. + // + // At the same time, the call to InitWindowVariables (which + // allocated the RootWindow) was moved from UIReset to + // UIInitialize. + + if (EmPatchState::OSMajorMinorVersion () >= 32) + { + // Nothing + } + else if (EmPatchState::OSMajorMinorVersion () >= 31) + { + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV31.displayWindow)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV31.eventQ)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV31.undoGlobals.buffer)) + return true; + } + else if (EmPatchState::OSMajorMinorVersion () >= 30) + { + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV3.displayWindow)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV3.eventQ)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV3.undoGlobals.buffer)) + return true; + } + else if (EmPatchState::OSMajorMinorVersion () >= 20) + { + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV2.displayWindow)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV2.eventQ)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV2.undoGlobals.buffer)) + return true; + } + else // OSMajorMinorVersion < 20 + { + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV1.displayWindow)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV1.eventQ)) + return true; + + if (chunk.BodyStart () == EmLowMem_GetGlobal (uiGlobalsV1.undoGlobals.buffer)) + return true; + } + + return false; +} + + +/*********************************************************************** + * + * FUNCTION: CheckForMemoryLeaks + * + * DESCRIPTION: Entry point for checking for and reporting memory leaks. + * Called from SysAppExit patch. + * + * PARAMETERS: memOwnerID - memory owner ID of the function quitting. + * + * RETURNED: nothing + * + ***********************************************************************/ + +void CheckForMemoryLeaks (UInt32 memOwnerID) +{ + if (!EmPatchState::fgData.fMemMgrLeaks) + return; + + CEnableFullAccess munge; + + int leaks = ::PrvCountLeaks (memOwnerID); + + if (!leaks) + return; + + // + // Found some leaks, so report them. + // + + LogAppendMsg ("WARNING: ========================================================"); + LogAppendMsg ("WARNING: Memory Leaks"); + LogAppendMsg ("WARNING: ========================================================"); + LogAppendMsg ("WARNING: Begin Memory Leak Dump"); + LogAppendMsg ("WARNING: ========================================================"); + + ::PrvReportMemoryLeaks (memOwnerID); + + LogAppendMsg ("WARNING: ========================================================"); + LogAppendMsg ("WARNING: End Memory Leak Dump"); + LogAppendMsg ("WARNING: ========================================================"); + + LogDump (); + + // Now tell the user about them. + + Errors::ReportErrMemMgrLeaks (leaks); +} diff --git a/SrcShared/Patches/EmPatchModuleNetLib.cpp b/SrcShared/Patches/EmPatchModuleNetLib.cpp new file mode 100644 index 0000000..60c0d4b --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleNetLib.cpp @@ -0,0 +1,4100 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchModuleNetLib.h" + +#include "EmMemory.h" // CEnableFullAccess +#include "EmSubroutine.h" +#include "Logging.h" // LogAppendMsg +#include "Marshal.h" // PARAM_VAL, etc. +#include "Platform_NetLib.h" // Platform_NetLib + +#if PLATFORM_UNIX || PLATFORM_MAC +#include <netinet/in.h> // ntohs, ntohs +#endif + + +// ====================================================================== +// Patches for NetLib functions +// ====================================================================== + +class NetLibHeadpatch +{ + public: + static CallROMType NetLibOpen (void); + static CallROMType NetLibClose (void); + static CallROMType NetLibSleep (void); + static CallROMType NetLibWake (void); + static CallROMType NetLibAddrINToA (void); + static CallROMType NetLibAddrAToIN (void); + static CallROMType NetLibSocketOpen (void); + static CallROMType NetLibSocketClose (void); + static CallROMType NetLibSocketOptionSet (void); + static CallROMType NetLibSocketOptionGet (void); + static CallROMType NetLibSocketBind (void); + static CallROMType NetLibSocketConnect (void); + static CallROMType NetLibSocketListen (void); + static CallROMType NetLibSocketAccept (void); + static CallROMType NetLibSocketShutdown (void); + static CallROMType NetLibSendPB (void); + static CallROMType NetLibSend (void); + static CallROMType NetLibReceivePB (void); + static CallROMType NetLibReceive (void); + static CallROMType NetLibDmReceive (void); + static CallROMType NetLibSelect (void); + static CallROMType NetLibMaster (void); + static CallROMType NetLibGetHostByName (void); + static CallROMType NetLibSettingGet (void); + static CallROMType NetLibSettingSet (void); + static CallROMType NetLibIFAttach (void); + static CallROMType NetLibIFDetach (void); + static CallROMType NetLibIFGet (void); + static CallROMType NetLibIFSettingGet (void); + static CallROMType NetLibIFSettingSet (void); + static CallROMType NetLibIFUp (void); + static CallROMType NetLibIFDown (void); + static CallROMType NetLibGetHostByAddr (void); + static CallROMType NetLibGetServByName (void); + static CallROMType NetLibSocketAddr (void); + static CallROMType NetLibFinishCloseWait (void); + static CallROMType NetLibGetMailExchangeByName (void); + static CallROMType NetLibOpenCount (void); + static CallROMType NetLibTracePrintF (void); + static CallROMType NetLibTracePutS (void); + static CallROMType NetLibOpenIfCloseWait (void); + static CallROMType NetLibHandlePowerOff (void); + static CallROMType NetLibConnectionRefresh (void); + static CallROMType NetLibOpenConfig (void); + static CallROMType NetLibConfigMakeActive (void); + static CallROMType NetLibConfigList (void); + static CallROMType NetLibConfigIndexFromName (void); + static CallROMType NetLibConfigDelete (void); + static CallROMType NetLibConfigSaveAs (void); + static CallROMType NetLibConfigRename (void); + static CallROMType NetLibConfigAliasSet (void); + static CallROMType NetLibConfigAliasGet (void); +}; + + +class NetLibTailpatch +{ + public: + static void NetLibOpen (void); + static void NetLibClose (void); + static void NetLibSleep (void); + static void NetLibWake (void); + static void NetLibAddrINToA (void); + static void NetLibAddrAToIN (void); + static void NetLibSocketOpen (void); + static void NetLibSocketClose (void); + static void NetLibSocketOptionSet (void); + static void NetLibSocketOptionGet (void); + static void NetLibSocketBind (void); + static void NetLibSocketConnect (void); + static void NetLibSocketListen (void); + static void NetLibSocketAccept (void); + static void NetLibSocketShutdown (void); + static void NetLibSendPB (void); + static void NetLibSend (void); + static void NetLibReceivePB (void); + static void NetLibReceive (void); + static void NetLibDmReceive (void); + static void NetLibSelect (void); + static void NetLibMaster (void); + static void NetLibGetHostByName (void); + static void NetLibSettingGet (void); + static void NetLibSettingSet (void); + static void NetLibIFAttach (void); + static void NetLibIFDetach (void); + static void NetLibIFGet (void); + static void NetLibIFSettingGet (void); + static void NetLibIFSettingSet (void); + static void NetLibIFUp (void); + static void NetLibIFDown (void); + static void NetLibGetHostByAddr (void); + static void NetLibGetServByName (void); + static void NetLibSocketAddr (void); + static void NetLibFinishCloseWait (void); + static void NetLibGetMailExchangeByName (void); + static void NetLibOpenCount (void); + static void NetLibTracePrintF (void); + static void NetLibTracePutS (void); + static void NetLibOpenIfCloseWait (void); + static void NetLibHandlePowerOff (void); + static void NetLibConnectionRefresh (void); + static void NetLibOpenConfig (void); + static void NetLibConfigMakeActive (void); + static void NetLibConfigList (void); + static void NetLibConfigIndexFromName (void); + static void NetLibConfigDelete (void); + static void NetLibConfigSaveAs (void); + static void NetLibConfigRename (void); + static void NetLibConfigAliasSet (void); + static void NetLibConfigAliasGet (void); +}; + + +// ====================================================================== +// Proto patch table for NetLib functions. This array will be used +// to create a sparse array at runtime. +// ====================================================================== + +static ProtoPatchTableEntry gProtoNetLibPatchTable[] = +{ + {sysLibTrapOpen, NetLibHeadpatch::NetLibOpen, NetLibTailpatch::NetLibOpen}, + {sysLibTrapClose, NetLibHeadpatch::NetLibClose, NetLibTailpatch::NetLibClose}, + {sysLibTrapSleep, NetLibHeadpatch::NetLibSleep, NetLibTailpatch::NetLibSleep}, + {sysLibTrapWake, NetLibHeadpatch::NetLibWake, NetLibTailpatch::NetLibWake}, + {netLibTrapAddrINToA, NetLibHeadpatch::NetLibAddrINToA, NetLibTailpatch::NetLibAddrINToA}, + {netLibTrapAddrAToIN, NetLibHeadpatch::NetLibAddrAToIN, NetLibTailpatch::NetLibAddrAToIN}, + {netLibTrapSocketOpen, NetLibHeadpatch::NetLibSocketOpen, NetLibTailpatch::NetLibSocketOpen}, + {netLibTrapSocketClose, NetLibHeadpatch::NetLibSocketClose, NetLibTailpatch::NetLibSocketClose}, + {netLibTrapSocketOptionSet, NetLibHeadpatch::NetLibSocketOptionSet, NetLibTailpatch::NetLibSocketOptionSet}, + {netLibTrapSocketOptionGet, NetLibHeadpatch::NetLibSocketOptionGet, NetLibTailpatch::NetLibSocketOptionGet}, + {netLibTrapSocketBind, NetLibHeadpatch::NetLibSocketBind, NetLibTailpatch::NetLibSocketBind}, + {netLibTrapSocketConnect, NetLibHeadpatch::NetLibSocketConnect, NetLibTailpatch::NetLibSocketConnect}, + {netLibTrapSocketListen, NetLibHeadpatch::NetLibSocketListen, NetLibTailpatch::NetLibSocketListen}, + {netLibTrapSocketAccept, NetLibHeadpatch::NetLibSocketAccept, NetLibTailpatch::NetLibSocketAccept}, + {netLibTrapSocketShutdown, NetLibHeadpatch::NetLibSocketShutdown, NetLibTailpatch::NetLibSocketShutdown}, + {netLibTrapSendPB, NetLibHeadpatch::NetLibSendPB, NetLibTailpatch::NetLibSendPB}, + {netLibTrapSend, NetLibHeadpatch::NetLibSend, NetLibTailpatch::NetLibSend}, + {netLibTrapReceivePB, NetLibHeadpatch::NetLibReceivePB, NetLibTailpatch::NetLibReceivePB}, + {netLibTrapReceive, NetLibHeadpatch::NetLibReceive, NetLibTailpatch::NetLibReceive}, + {netLibTrapDmReceive, NetLibHeadpatch::NetLibDmReceive, NetLibTailpatch::NetLibDmReceive}, + {netLibTrapSelect, NetLibHeadpatch::NetLibSelect, NetLibTailpatch::NetLibSelect}, +// {netLibTrapPrefsGet, NULL, NULL}, +// {netLibTrapPrefsSet, NULL, NULL}, +// {netLibTrapDrvrWake, NULL, NULL}, +// {netLibTrapInterfacePtr, NULL, NULL}, + {netLibTrapMaster, NetLibHeadpatch::NetLibMaster, NetLibTailpatch::NetLibMaster}, + {netLibTrapGetHostByName, NetLibHeadpatch::NetLibGetHostByName, NetLibTailpatch::NetLibGetHostByName}, + {netLibTrapSettingGet, NetLibHeadpatch::NetLibSettingGet, NetLibTailpatch::NetLibSettingGet}, + {netLibTrapSettingSet, NetLibHeadpatch::NetLibSettingSet, NetLibTailpatch::NetLibSettingSet}, + {netLibTrapIFAttach, NetLibHeadpatch::NetLibIFAttach, NetLibTailpatch::NetLibIFAttach}, + {netLibTrapIFDetach, NetLibHeadpatch::NetLibIFDetach, NetLibTailpatch::NetLibIFDetach}, + {netLibTrapIFGet, NetLibHeadpatch::NetLibIFGet, NetLibTailpatch::NetLibIFGet}, + {netLibTrapIFSettingGet, NetLibHeadpatch::NetLibIFSettingGet, NetLibTailpatch::NetLibIFSettingGet}, + {netLibTrapIFSettingSet, NetLibHeadpatch::NetLibIFSettingSet, NetLibTailpatch::NetLibIFSettingSet}, + {netLibTrapIFUp, NetLibHeadpatch::NetLibIFUp, NetLibTailpatch::NetLibIFUp}, + {netLibTrapIFDown, NetLibHeadpatch::NetLibIFDown, NetLibTailpatch::NetLibIFDown}, +// {netLibTrapIFMediaUp, NULL, NULL}, +// {netLibTrapScriptExecute, NULL, NULL}, + {netLibTrapGetHostByAddr, NetLibHeadpatch::NetLibGetHostByAddr, NetLibTailpatch::NetLibGetHostByAddr}, + {netLibTrapGetServByName, NetLibHeadpatch::NetLibGetServByName, NetLibTailpatch::NetLibGetServByName}, + {netLibTrapSocketAddr, NetLibHeadpatch::NetLibSocketAddr, NetLibTailpatch::NetLibSocketAddr}, + {netLibTrapFinishCloseWait, NetLibHeadpatch::NetLibFinishCloseWait, NetLibTailpatch::NetLibFinishCloseWait}, + {netLibTrapGetMailExchangeByName,NetLibHeadpatch::NetLibGetMailExchangeByName, NetLibTailpatch::NetLibGetMailExchangeByName}, +// {netLibTrapPrefsAppend, NULL, NULL}, +// {netLibTrapIFMediaDown, NULL, NULL}, + {netLibTrapOpenCount, NetLibHeadpatch::NetLibOpenCount, NetLibTailpatch::NetLibOpenCount}, + {netLibTrapTracePrintF, NetLibHeadpatch::NetLibTracePrintF, NetLibTailpatch::NetLibTracePrintF}, + {netLibTrapTracePutS, NetLibHeadpatch::NetLibTracePutS, NetLibTailpatch::NetLibTracePutS}, + {netLibTrapOpenIfCloseWait, NetLibHeadpatch::NetLibOpenIfCloseWait, NetLibTailpatch::NetLibOpenIfCloseWait}, + {netLibTrapHandlePowerOff, NetLibHeadpatch::NetLibHandlePowerOff, NetLibTailpatch::NetLibHandlePowerOff}, + {netLibTrapConnectionRefresh, NetLibHeadpatch::NetLibConnectionRefresh, NetLibTailpatch::NetLibConnectionRefresh}, +// {netLibTrapBitMove, NULL, NULL}, +// {netLibTrapBitPutFixed, NULL, NULL}, +// {netLibTrapBitGetFixed, NULL, NULL}, +// {netLibTrapBitPutUIntV, NULL, NULL}, +// {netLibTrapBitGetUIntV, NULL, NULL}, +// {netLibTrapBitPutIntV, NULL, NULL}, +// {netLibTrapBitGetIntV, NULL, NULL}, + {netLibOpenConfig, NetLibHeadpatch::NetLibOpenConfig, NetLibTailpatch::NetLibOpenConfig}, + {netLibConfigMakeActive, NetLibHeadpatch::NetLibConfigMakeActive, NetLibTailpatch::NetLibConfigMakeActive}, + {netLibConfigList, NetLibHeadpatch::NetLibConfigList, NetLibTailpatch::NetLibConfigList}, + {netLibConfigIndexFromName, NetLibHeadpatch::NetLibConfigIndexFromName, NetLibTailpatch::NetLibConfigIndexFromName}, + {netLibConfigDelete, NetLibHeadpatch::NetLibConfigDelete, NetLibTailpatch::NetLibConfigDelete}, + {netLibConfigSaveAs, NetLibHeadpatch::NetLibConfigSaveAs, NetLibTailpatch::NetLibConfigSaveAs}, + {netLibConfigRename, NetLibHeadpatch::NetLibConfigRename, NetLibTailpatch::NetLibConfigRename}, + {netLibConfigAliasSet, NetLibHeadpatch::NetLibConfigAliasSet, NetLibTailpatch::NetLibConfigAliasSet}, + {netLibConfigAliasGet, NetLibHeadpatch::NetLibConfigAliasGet, NetLibTailpatch::NetLibConfigAliasGet}, + + {0, NULL, NULL} +}; + + + + +// ====================================================================== +// Private functions +// ====================================================================== + +static const char* PrvGetOptLevelString (NetSocketOptLevelEnum); +static const char* PrvGetOptString (NetSocketOptLevelEnum, NetSocketOptEnum); +static const char* PrvGetDottedIPString (const NetSocketAddrType& ipAddr); +static const char* PrvGetPortString (const NetSocketAddrType& ipAddr); +static const char* PrvGetErrorString (Err err); + + +#define PRINTF if (!LogNetLib ()) ; else LogAppendMsg + + +#pragma mark - + +// =========================================================================== +// ¥ EmPatchModuleNetLib +// =========================================================================== + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleNetLib::EmPatchModuleNetLib + * + * DESCRIPTION: Constructor + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +EmPatchModuleNetLib::EmPatchModuleNetLib() : + EmPatchModule ("Net.lib", gProtoNetLibPatchTable) +{ +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibOpen + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibOpen (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibOpen"); + + // Err NetLibOpen (UInt16 libRefNum, UInt16 *netIFErrsP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 *netIFErrsP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_REF (UInt16, netIFErrsP, Marshal::kOutput); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::Open (libRefNum, netIFErrsP); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (netIFErrsP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibOpen (void) +{ + // Err NetLibOpen (UInt16 libRefNum, UInt16 *netIFErrsP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 *netIFErrsP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_REF (UInt16, netIFErrsP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*netIFErrsP = %s (0x%04X)", PrvGetErrorString (*netIFErrsP), (long) *netIFErrsP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibClose + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibClose (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibClose"); + + // Err NetLibClose (UInt16 libRefNum, UInt16 immediate) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 immediate"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (UInt16, immediate); + + // Examine the parameters + PRINTF ("\timmediate = 0x%08X", (long) immediate); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::Close (libRefNum, immediate); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibClose (void) +{ + // Err NetLibClose (UInt16 libRefNum, UInt16 immediate) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 immediate"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (UInt16, immediate); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSleep + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSleep (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSleep"); + + // Err NetLibSleep (UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::Sleep (libRefNum); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + + +void NetLibTailpatch::NetLibSleep (void) +{ + // Err NetLibSleep (UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibWake + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibWake (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibWake"); + + // Err NetLibWake (UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::Wake (libRefNum); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibWake (void) +{ + // Err NetLibWake (UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibAddrINToA + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibAddrINToA (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibAddrINToA"); + + // Char * NetLibAddrINToA(UInt16 libRefNum, NetIPAddr inet, Char *spaceP) + + CALLED_SETUP ("Char*", "UInt16 libRefNum, NetIPAddr inet, Char *spaceP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibAddrINToA (void) +{ + // Char * NetLibAddrINToA(UInt16 libRefNum, NetIPAddr inet, Char *spaceP) + + CALLED_SETUP ("Char*", "UInt16 libRefNum, NetIPAddr inet, Char *spaceP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_PTR (); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibAddrAToIN + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibAddrAToIN (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibAddrAToIN"); + + // NetIPAddr NetLibAddrAToIN(UInt16 libRefNum, Char *a) + + CALLED_SETUP ("NetIPAddr", "UInt16 libRefNum, Char *a"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibAddrAToIN (void) +{ + // NetIPAddr NetLibAddrAToIN(UInt16 libRefNum, Char *a) + + CALLED_SETUP ("NetIPAddr", "UInt16 libRefNum, Char *a"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (NetIPAddr); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketOpen + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketOpen (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketOpen"); + + // NetSocketRef NetLibSocketOpen(UInt16 libRefNum, NetSocketAddrEnum domain, + // NetSocketTypeEnum type, Int16 protocol, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("NetSocketRef", "UInt16 libRefNum, NetSocketAddrEnum domain, " + "NetSocketTypeEnum type, Int16 protocol, Int32 timeout, " + "Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketAddrEnum, domain); + CALLED_GET_PARAM_VAL (NetSocketTypeEnum, type); + CALLED_GET_PARAM_VAL (Int16, protocol); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tdomain = 0x%08X", (long) domain); + PRINTF ("\ttype = 0x%08X", (long) type); + PRINTF ("\tprotocol = 0x%08X", (long) protocol); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + NetSocketRef result = Platform_NetLib::SocketOpen (libRefNum, + (NetSocketAddrEnum) (UInt8) domain, (NetSocketTypeEnum) (UInt8) type, + protocol, timeout, errP); + PUT_RESULT_VAL (NetSocketRef, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketOpen (void) +{ + CALLED_SETUP ("NetSocketRef", "UInt16 libRefNum, NetSocketAddrEnum domain, " + "NetSocketTypeEnum type, Int16 protocol, Int32 timeout, " + "Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketAddrEnum, domain); +// CALLED_GET_PARAM_VAL (NetSocketTypeEnum, type); +// CALLED_GET_PARAM_VAL (Int16, protocol); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (NetSocketRef); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketClose + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketClose (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketClose"); + + // Int16 NetLibSocketClose(UInt16 libRefNum, NetSocketRef socket, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketClose (libRefNum, + socket, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketClose (void) +{ + // Int16 NetLibSocketClose(UInt16 libRefNum, NetSocketRef socket, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketOptionSet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketOptionSet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketOptionSet"); + + // Int16 NetLibSocketOptionSet(UInt16 libRefNum, NetSocketRef socket, + // UInt16 /*NetSocketOptLevelEnum*/ level, UInt16 /*NetSocketOptEnum*/ option, + // void *optValueP, UInt16 optValueLen, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "UInt16 level, UInt16 option, " + "void *optValueP, UInt16 optValueLen," + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, level); + CALLED_GET_PARAM_VAL (UInt16, option); + CALLED_GET_PARAM_VAL (UInt16, optValueLen); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + CALLED_GET_PARAM_PTR (void, optValueP, optValueLen, Marshal::kInput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tlevel = %s (0x%08X)", PrvGetOptLevelString ((NetSocketOptLevelEnum) (UInt16) level), (long) (UInt16) level); + PRINTF ("\toption = %s (0x%08X)", PrvGetOptString ((NetSocketOptLevelEnum) (UInt16) level, (NetSocketOptEnum) (UInt16) option), (long) (UInt16) option); + PRINTF ("\toptValueP = 0x%08X", (long) (void*) optValueP); + PRINTF ("\toptValueLen = 0x%08X", (long) optValueLen); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketOptionSet (libRefNum, + socket, (NetSocketOptLevelEnum) (UInt16) level, + (NetSocketOptEnum) (UInt16) option, optValueP, + optValueLen, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (optValueP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketOptionSet (void) +{ + // Int16 NetLibSocketOptionSet(UInt16 libRefNum, NetSocketRef socket, + // UInt16 /*NetSocketOptLevelEnum*/ level, UInt16 /*NetSocketOptEnum*/ option, + // void *optValueP, UInt16 optValueLen, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "UInt16 level, UInt16 option, " + "void *optValueP, UInt16 optValueLen," + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_VAL (UInt16, level); +// CALLED_GET_PARAM_VAL (UInt16, option); + CALLED_GET_PARAM_VAL (UInt16, optValueLen); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + CALLED_GET_PARAM_PTR (void, optValueP, optValueLen, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketOptionGet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketOptionGet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketOptionGet"); + + // Int16 NetLibSocketOptionGet(UInt16 libRefNum, NetSocketRef socket, + // UInt16 /*NetSocketOptLevelEnum*/ level, UInt16 /*NetSocketOptEnum*/ option, + // void *optValueP, UInt16 *optValueLenP, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "UInt16 level, UInt16 option," + "void *optValueP, UInt16 *optValueLenP," + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, level); + CALLED_GET_PARAM_VAL (UInt16, option); + CALLED_GET_PARAM_REF (UInt16, optValueLenP, Marshal::kInOut); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + CALLED_GET_PARAM_PTR (void, optValueP, *optValueLenP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tlevel = 0x%08X", (long) level); + PRINTF ("\toption = 0x%08X", (long) option); + PRINTF ("\toptValueP = 0x%08X", (long) (void*) optValueP); + PRINTF ("\toptValueLenP = 0x%08X", (long) *optValueLenP); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketOptionGet (libRefNum, + socket, (NetSocketOptLevelEnum) (UInt16) level, + (NetSocketOptEnum) (UInt16) option, optValueP, + optValueLenP, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (optValueP); + CALLED_PUT_PARAM_REF (optValueLenP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketOptionGet (void) +{ + // Int16 NetLibSocketOptionGet(UInt16 libRefNum, NetSocketRef socket, + // UInt16 /*NetSocketOptLevelEnum*/ level, UInt16 /*NetSocketOptEnum*/ option, + // void *optValueP, UInt16 *optValueLenP, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "UInt16 level, UInt16 option," + "void *optValueP, UInt16 *optValueLenP," + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_VAL (UInt16, level); +// CALLED_GET_PARAM_VAL (UInt16, option); + CALLED_GET_PARAM_REF (UInt16, optValueLenP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + CALLED_GET_PARAM_PTR (void, optValueP, *optValueLenP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); + PRINTF ("\t*optValueLenP = 0x%08X", (long) *optValueLenP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketBind + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketBind (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketBind"); + + // Int16 NetLibSocketBind(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, " + "Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetSocketAddrType, sockAddrP, Marshal::kInput); + CALLED_GET_PARAM_VAL (Int16, addrLen); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tsockAddr.family = 0x%04X", (uint16) (*sockAddrP).family); + PRINTF ("\tsockAddr.port = %s", PrvGetPortString (*sockAddrP)); + PRINTF ("\tsockAddr.address = %s", PrvGetDottedIPString (*sockAddrP)); + PRINTF ("\taddrLen = 0x%08X", (long) addrLen); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketBind (libRefNum, socket, + sockAddrP, addrLen, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + if (result == 0) + { + CALLED_PUT_PARAM_REF (sockAddrP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketBind (void) +{ + // Int16 NetLibSocketBind(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, " + "Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_REF (NetSocketAddrType, sockAddrP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int16, addrLen); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketConnect + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketConnect (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketConnect"); + + // Int16 NetLibSocketConnect(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, " + "Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetSocketAddrType, sockAddrP, Marshal::kInput); + CALLED_GET_PARAM_VAL (Int16, addrLen); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tsockAddr.family = 0x%04X", (uint16) (*sockAddrP).family); + PRINTF ("\tsockAddr.port = %s", PrvGetPortString (*sockAddrP)); + PRINTF ("\tsockAddr.address = %s", PrvGetDottedIPString (*sockAddrP)); + PRINTF ("\taddrLen = 0x%08X", (long) addrLen); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketConnect (libRefNum, + socket, sockAddrP, addrLen, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + if (result == 0) + { + CALLED_PUT_PARAM_REF (sockAddrP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketConnect (void) +{ + // Int16 NetLibSocketConnect(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *sockAddrP, Int16 addrLen, Int32 timeout, " + "Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_REF (NetSocketAddrType, sockAddrP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int16, addrLen); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketListen + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketListen (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketListen"); + + // Int16 NetLibSocketListen(UInt16 libRefNum, NetSocketRef socket, + // UInt16 queueLen, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "UInt16 queueLen, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, queueLen); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tqueueLen = 0x%08X", (long) queueLen); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketListen (libRefNum, + socket, queueLen, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketListen (void) +{ + // Int16 NetLibSocketListen(UInt16 libRefNum, NetSocketRef socket, + // UInt16 queueLen, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "UInt16 queueLen, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_VAL (UInt16, queueLen); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketAccept + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketAccept (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketAccept"); + + // Int16 NetLibSocketAccept(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *sockAddrP, Int16 *addrLenP, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *sockAddrP, Int16 *addrLenP, Int32 timeout," + "Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetSocketAddrType, sockAddrP, Marshal::kOutput); + CALLED_GET_PARAM_REF (Int16, addrLenP, Marshal::kInOut); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\taddrLen = 0x%08X", (long) *addrLenP); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketAccept (libRefNum, + socket, sockAddrP, addrLenP, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + if (result >= 0) + { + CALLED_PUT_PARAM_REF (sockAddrP); + CALLED_PUT_PARAM_REF (addrLenP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketAccept (void) +{ + // Int16 NetLibSocketAccept(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *sockAddrP, Int16 *addrLenP, Int32 timeout, + // Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *sockAddrP, Int16 *addrLenP, Int32 timeout," + "Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetSocketAddrType, sockAddrP, Marshal::kInput); + CALLED_GET_PARAM_REF (Int16, addrLenP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); + PRINTF ("\tsockAddr.family = 0x%04X", (uint16) (*sockAddrP).family); + PRINTF ("\tsockAddr.port = %s", PrvGetPortString (*sockAddrP)); + PRINTF ("\tsockAddr.address = %s", PrvGetDottedIPString (*sockAddrP)); + PRINTF ("\taddrLen = 0x%08X", (long) *addrLenP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketShutdown + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketShutdown (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketShutdown"); + + // Int16 NetLibSocketShutdown(UInt16 libRefNum, NetSocketRef socket, + // Int16 /*NetSocketDirEnum*/ direction, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket, " + "Int16 direction, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (Int16, direction); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tdirection = 0x%08X", (long) direction); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketShutdown (libRefNum, + socket, direction, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketShutdown (void) +{ + // Int16 NetLibSocketShutdown(UInt16 libRefNum, NetSocketRef socket, + // Int16 /*NetSocketDirEnum*/ direction, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket, " + "Int16 direction, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_VAL (Int16, direction); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSendPB + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSendPB (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSendPB"); + + // Int16 NetLibSendPB(UInt16 libRefNum, NetSocketRef socket, + // NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetIOParamType, pbP, Marshal::kInput); + CALLED_GET_PARAM_VAL (UInt16, flags); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tflags = 0x%08X", (long) flags); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SendPB (libRefNum, + socket, pbP, flags, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (pbP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSendPB (void) +{ + // Int16 NetLibSendPB(UInt16 libRefNum, NetSocketRef socket, + // NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_REF (NetIOParamType, pbP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (UInt16, flags); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSend + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSend (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSend"); + + // Int16 NetLibSend(UInt16 libRefNum, NetSocketRef socket, + // void *bufP, UInt16 bufLen, UInt16 flags, + // void *toAddrP, UInt16 toLen, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "void *bufP, UInt16 bufLen, UInt16 flags," + "void *toAddrP, UInt16 toLen, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, bufLen); + CALLED_GET_PARAM_VAL (UInt16, flags); + CALLED_GET_PARAM_REF (NetSocketAddrType, toAddrP, Marshal::kInput); + CALLED_GET_PARAM_VAL (UInt16, toLen); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + CALLED_GET_PARAM_PTR (void, bufP, bufLen, Marshal::kInput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); +// PRINTF ("\tbufP = 0x%08X", (long) bufP); + PRINTF ("\tbufLen = 0x%08X", (long) bufLen); + PRINTF ("\tflags = 0x%08X", (long) flags); +// PRINTF ("\ttoAddrP = 0x%08X", (long) toAddrP); + PRINTF ("\ttoLen = 0x%08X", (long) toLen); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::Send (libRefNum, socket, + bufP, bufLen, flags, toAddrP, toLen, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (bufP); + CALLED_PUT_PARAM_REF (toAddrP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSend (void) +{ + // Int16 NetLibSend(UInt16 libRefNum, NetSocketRef socket, + // void *bufP, UInt16 bufLen, UInt16 flags, + // void *toAddrP, UInt16 toLen, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "void *bufP, UInt16 bufLen, UInt16 flags," + "void *toAddrP, UInt16 toLen, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, bufLen); +// CALLED_GET_PARAM_VAL (UInt16, flags); +// CALLED_GET_PARAM_REF (NetSocketAddrType, toAddrP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (UInt16, toLen); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + CALLED_GET_PARAM_PTR (void, bufP, bufLen, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibReceivePB + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibReceivePB (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibReceivePB"); + + // Int16 NetLibReceivePB(UInt16 libRefNum, NetSocketRef socket, + // NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetIOParamType, pbP, Marshal::kInOut); + CALLED_GET_PARAM_VAL (UInt16, flags); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); +// PRINTF ("\tpbP = 0x%08X", (long) pbP); + PRINTF ("\tflags = 0x%08X", (long) flags); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::ReceivePB (libRefNum, + socket, pbP, flags, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (pbP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibReceivePB (void) +{ + // Int16 NetLibReceivePB(UInt16 libRefNum, NetSocketRef socket, + // NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetIOParamType *pbP, UInt16 flags, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); +// CALLED_GET_PARAM_REF (NetIOParamType, pbP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (UInt16, flags); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibReceive + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibReceive (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibReceive"); + + // Int16 NetLibReceive(UInt16 libRefNum, NetSocketRef socket, + // void *bufP, UInt16 bufLen, UInt16 flags, + // void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "void *bufP, UInt16 bufLen, UInt16 flags, " + "void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, bufLen); + CALLED_GET_PARAM_VAL (UInt16, flags); + CALLED_GET_PARAM_REF (NetSocketAddrType, fromAddrP, Marshal::kOutput); + CALLED_GET_PARAM_REF (UInt16, fromLenP, Marshal::kInOut); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + CALLED_GET_PARAM_PTR (void, bufP, bufLen, Marshal::kInOut); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); +// PRINTF ("\tbufP = 0x%08X", (long) bufP); + PRINTF ("\tbufLen = 0x%08X", (long) bufLen); + PRINTF ("\tflags = 0x%08X", (long) flags); +// PRINTF ("\tfromAddrP = 0x%08X", (long) fromAddrP); + PRINTF ("\tfromLen = 0x%08X", (long) *fromLenP); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::Receive (libRefNum, + socket, bufP, bufLen, flags, fromAddrP, fromLenP, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (bufP); + CALLED_PUT_PARAM_REF (fromAddrP); + CALLED_PUT_PARAM_REF (fromLenP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibReceive (void) +{ + // Int16 NetLibReceive(UInt16 libRefNum, NetSocketRef socket, + // void *bufP, UInt16 bufLen, UInt16 flags, + // void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "void *bufP, UInt16 bufLen, UInt16 flags, " + "void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt16, bufLen); +// CALLED_GET_PARAM_VAL (UInt16, flags); +// CALLED_GET_PARAM_REF (NetSocketAddrType, fromAddrP, Marshal::kInput); +// CALLED_GET_PARAM_REF (UInt16, fromLenP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + CALLED_GET_PARAM_PTR (void, bufP, bufLen, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); + + if (LogNetLibData () && (((long) *errP) == 0) && (result > 0)) + { + LogAppendData (bufP, result, "Received Data"); + } +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibDmReceive + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibDmReceive (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibDmReceive"); + + // Int16 NetLibDmReceive(UInt16 libRefNum, NetSocketRef socket, + // void *recordP, UInt32 recordOffset, UInt16 rcvLen, UInt16 flags, + // void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "void *recordP, UInt32 recordOffset, UInt16 rcvLen, UInt16 flags, " + "void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt32, recordOffset); + CALLED_GET_PARAM_VAL (UInt16, rcvLen); + CALLED_GET_PARAM_VAL (UInt16, flags); + CALLED_GET_PARAM_REF (NetSocketAddrType, fromAddrP, Marshal::kOutput); + CALLED_GET_PARAM_REF (UInt16, fromLenP, Marshal::kInOut); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + CALLED_GET_PARAM_PTR (void, recordP, rcvLen + recordOffset, Marshal::kInOut); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + CEnableFullAccess munge; // Remove blocks on memory access. + + // Call the host function. + Int16 result = Platform_NetLib::DmReceive (libRefNum, + socket, recordP, recordOffset, rcvLen, flags, + fromAddrP, fromLenP, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (recordP); + CALLED_PUT_PARAM_REF (fromAddrP); + CALLED_PUT_PARAM_REF (fromLenP); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibDmReceive (void) +{ + // Int16 NetLibDmReceive(UInt16 libRefNum, NetSocketRef socket, + // void *recordP, UInt32 recordOffset, UInt16 rcvLen, UInt16 flags, + // void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "void *recordP, UInt32 recordOffset, UInt16 rcvLen, UInt16 flags, " + "void *fromAddrP, UInt16 *fromLenP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_VAL (UInt32, recordOffset); + CALLED_GET_PARAM_VAL (UInt16, rcvLen); +// CALLED_GET_PARAM_VAL (UInt16, flags); +// CALLED_GET_PARAM_REF (NetSocketAddrType, fromAddrP, Marshal::kInput); +// CALLED_GET_PARAM_REF (UInt16, fromLenP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + CALLED_GET_PARAM_PTR (void, recordP, recordOffset + rcvLen, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSelect + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSelect (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSelect"); + + // Int16 NetLibSelect(UInt16 libRefNum, UInt16 width, NetFDSetType *readFDs, + // NetFDSetType *writeFDs, NetFDSetType *exceptFDs, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, UInt16 width, NetFDSetType *readFDs, " + "NetFDSetType *writeFDs, NetFDSetType *exceptFDs," + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (UInt16, width); + CALLED_GET_PARAM_REF (NetFDSetType, readFDs, Marshal::kInOut); + CALLED_GET_PARAM_REF (NetFDSetType, writeFDs, Marshal::kInOut); + CALLED_GET_PARAM_REF (NetFDSetType, exceptFDs, Marshal::kInOut); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\twidth = 0x%08X", (long) width); + PRINTF ("\treadFDs = 0x%08X", (long) *readFDs); + PRINTF ("\twriteFDs = 0x%08X", (long) *writeFDs); + PRINTF ("\texceptFDs = 0x%08X", (long) *exceptFDs); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::Select (libRefNum, + width, readFDs, writeFDs, exceptFDs, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (readFDs); + CALLED_PUT_PARAM_REF (writeFDs); + CALLED_PUT_PARAM_REF (exceptFDs); + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSelect (void) +{ + // Int16 NetLibSelect(UInt16 libRefNum, UInt16 width, NetFDSetType *readFDs, + // NetFDSetType *writeFDs, NetFDSetType *exceptFDs, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, UInt16 width, NetFDSetType *readFDs, " + "NetFDSetType *writeFDs, NetFDSetType *exceptFDs," + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (UInt16, width); + CALLED_GET_PARAM_REF (NetFDSetType, readFDs, Marshal::kInput); + CALLED_GET_PARAM_REF (NetFDSetType, writeFDs, Marshal::kInput); + CALLED_GET_PARAM_REF (NetFDSetType, exceptFDs, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); + PRINTF ("\treadFDs = 0x%08X", (long) *readFDs); + PRINTF ("\twriteFDs = 0x%08X", (long) *writeFDs); + PRINTF ("\texceptFDs = 0x%08X", (long) *exceptFDs); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibMaster + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibMaster (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibMaster"); + + // Err NetLibMaster(UInt16 libRefNum, UInt16 cmd, NetMasterPBPtr pbP, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 cmd, NetMasterPBPtr pbP," + "Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibMaster (void) +{ + // Err NetLibMaster(UInt16 libRefNum, UInt16 cmd, NetMasterPBPtr pbP, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 cmd, NetMasterPBPtr pbP," + "Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibGetHostByName + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibGetHostByName (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibGetHostByName"); + + // NetHostInfoPtr NetLibGetHostByName(UInt16 libRefNum, Char *nameP, + // NetHostInfoBufPtr bufP, Int32 timeout, Err *errP) + + CALLED_SETUP ("NetHostInfoPtr", "UInt16 libRefNum, Char *nameP, " + "NetHostInfoBufPtr bufP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_STR (Char, nameP); + CALLED_GET_PARAM_REF (NetHostInfoBufType, bufP, Marshal::kOutput); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tnameP = %s", (Char*) nameP); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + NetHostInfoPtr p = Platform_NetLib::GetHostByName (libRefNum, + nameP, bufP, timeout, errP); + emuptr result = p ? (emuptr) bufP + offsetof (NetHostInfoBufType, hostInfo) : EmMemNULL; + PUT_RESULT_VAL (emuptr, result); + + // Return any pass-by-reference values. + // bufP is a complex type with internal pointers and such. We + // *can't* copy the contents back into emulated memory if they + // are uninitialized. Check for errors before attempting that. + if (result != EmMemNULL) + { + CALLED_PUT_PARAM_REF (nameP); + CALLED_PUT_PARAM_REF (bufP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibGetHostByName (void) +{ + // NetHostInfoPtr NetLibGetHostByName(UInt16 libRefNum, Char *nameP, + // NetHostInfoBufPtr bufP, Int32 timeout, Err *errP) + + CALLED_SETUP ("NetHostInfoPtr", "UInt16 libRefNum, Char *nameP, " + "NetHostInfoBufPtr bufP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_STR (Char, nameP); +// CALLED_GET_PARAM_REF (NetHostInfoBufType, bufP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_PTR (); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + + NetHostInfoBufType hostInfo; + Marshal::GetNetHostInfoBufType (result, hostInfo); +// PRINTF ("\t\tname = %s", hostInfo.name); +// PRINTF ("\t\taddress = 0x%08X", hostInfo.address[0]); + + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSettingGet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSettingGet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSettingGet"); + + // Err NetLibSettingGet(UInt16 libRefNum, + // UInt16 /*NetSettingEnum*/ setting, void *valueP, UInt16 *valueLenP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 setting, void *valueP, UInt16 *valueLenP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSettingGet (void) +{ + // Err NetLibSettingGet(UInt16 libRefNum, + // UInt16 /*NetSettingEnum*/ setting, void *valueP, UInt16 *valueLenP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 setting, void *valueP, UInt16 *valueLenP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSettingSet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSettingSet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSettingSet"); + + // Err NetLibSettingSet(UInt16 libRefNum, + // UInt16 /*NetSettingEnum*/ setting, void *valueP, UInt16 valueLen) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 setting, void *valueP, UInt16 valueLen"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSettingSet (void) +{ + // Err NetLibSettingSet(UInt16 libRefNum, + // UInt16 /*NetSettingEnum*/ setting, void *valueP, UInt16 valueLen) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 setting, void *valueP, UInt16 valueLen"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFAttach + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFAttach (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFAttach"); + + // Err NetLibIFAttach(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFAttach (void) +{ + // Err NetLibIFAttach(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFDetach + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFDetach (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFDetach"); + + // Err NetLibIFDetach(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance," + "Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFDetach (void) +{ + // Err NetLibIFDetach(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance," + "Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFGet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFGet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFGet"); + + // Err NetLibIFGet(UInt16 libRefNum, UInt16 index, UInt32 *ifCreatorP, + // UInt16 *ifInstanceP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 index, UInt32 *ifCreatorP, " + "UInt16 *ifInstanceP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFGet (void) +{ + // Err NetLibIFGet(UInt16 libRefNum, UInt16 index, UInt32 *ifCreatorP, + // UInt16 *ifInstanceP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 index, UInt32 *ifCreatorP, " + "UInt16 *ifInstanceP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFSettingGet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFSettingGet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFSettingGet"); + + // Err NetLibIFSettingGet(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // UInt16 /*NetIFSettingEnum*/ setting, void *valueP, UInt16 *valueLenP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance," + "UInt16 setting, void *valueP, UInt16 *valueLenP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFSettingGet (void) +{ + // Err NetLibIFSettingGet(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // UInt16 /*NetIFSettingEnum*/ setting, void *valueP, UInt16 *valueLenP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance," + "UInt16 setting, void *valueP, UInt16 *valueLenP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFSettingSet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFSettingSet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFSettingSet"); + + // Err NetLibIFSettingSet(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // UInt16 /*NetIFSettingEnum*/ setting, void *valueP, UInt16 valueLen) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance," + "UInt16 setting, void *valueP, UInt16 valueLen"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFSettingSet (void) +{ + // Err NetLibIFSettingSet(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // UInt16 /*NetIFSettingEnum*/ setting, void *valueP, UInt16 valueLen) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance," + "UInt16 setting, void *valueP, UInt16 valueLen"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFUp + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFUp (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFUp"); + + // Err NetLibIFUp(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFUp (void) +{ + // Err NetLibIFUp(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibIFDown + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibIFDown (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibIFDown"); + + // Err NetLibIFDown(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibIFDown (void) +{ + // Err NetLibIFDown(UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt32 ifCreator, UInt16 ifInstance, Int32 timeout"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibGetHostByAddr + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibGetHostByAddr (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibGetHostByAddr"); + + // NetHostInfoPtr NetLibGetHostByAddr(UInt16 libRefNum, UInt8 *addrP, UInt16 len, UInt16 type, + // NetHostInfoBufPtr bufP, Int32 timeout, Err *errP) + + CALLED_SETUP ("NetHostInfoPtr", "UInt16 libRefNum, UInt8 *addrP, UInt16 len, UInt16 type," + "NetHostInfoBufPtr bufP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (UInt16, len); + CALLED_GET_PARAM_PTR (UInt8, addrP, len, Marshal::kInput); + CALLED_GET_PARAM_VAL (UInt16, type); + CALLED_GET_PARAM_REF (NetHostInfoBufType, bufP, Marshal::kOutput); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + NetHostInfoPtr p = Platform_NetLib::GetHostByAddr (libRefNum, + (UInt8*) addrP, len, type, bufP, timeout, errP); + emuptr result = p ? (emuptr) bufP + offsetof (NetHostInfoBufType, hostInfo) : EmMemNULL; + PUT_RESULT_VAL (emuptr, result); + + // Return any pass-by-reference values. + // bufP is a complex type with internal pointers and such. We + // *can't* copy the contents back into emulated memory if they + // are uninitialized. Check for errors before attempting that. + if (result != EmMemNULL) + { + CALLED_PUT_PARAM_REF (addrP); + CALLED_PUT_PARAM_REF (bufP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibGetHostByAddr (void) +{ + // NetHostInfoPtr NetLibGetHostByAddr(UInt16 libRefNum, UInt8 *addrP, UInt16 len, UInt16 type, + // NetHostInfoBufPtr bufP, Int32 timeout, Err *errP) + + CALLED_SETUP ("NetHostInfoPtr", "UInt16 libRefNum, UInt8 *addrP, UInt16 len, UInt16 type," + "NetHostInfoBufPtr bufP, Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_REF (NetSocketAddrType, addrP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (UInt16, len); +// CALLED_GET_PARAM_VAL (UInt16, type); +// CALLED_GET_PARAM_REF (NetHostInfoBufType, bufP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_PTR (); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibGetServByName + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibGetServByName (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibGetServByName"); + + // NetServInfoPtr NetLibGetServByName(UInt16 libRefNum, const Char *servNameP, + // const Char *protoNameP, NetServInfoBufPtr bufP, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("NetServInfoPtr", "UInt16 libRefNum, const Char *servNameP, " + "const Char *protoNameP, NetServInfoBufPtr bufP, " + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_STR (Char, servNameP); + CALLED_GET_PARAM_STR (Char, protoNameP); + CALLED_GET_PARAM_REF (NetServInfoBufType, bufP, Marshal::kOutput); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tservNameP = %s", (Char*) servNameP); + PRINTF ("\tprotoNameP = %s", (Char*) protoNameP); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + NetServInfoPtr p = Platform_NetLib::GetServByName (libRefNum, + servNameP, protoNameP, bufP, timeout, errP); + emuptr result = p ? (emuptr) bufP + offsetof (NetServInfoBufType, servInfo) : EmMemNULL; + PUT_RESULT_VAL (emuptr, result); + + // Return any pass-by-reference values. + // bufP is a complex type with internal pointers and such. We + // *can't* copy the contents back into emulated memory if they + // are uninitialized. Check for errors before attempting that. + if (result != EmMemNULL) + { + CALLED_PUT_PARAM_REF (servNameP); + CALLED_PUT_PARAM_REF (protoNameP); + CALLED_PUT_PARAM_REF (bufP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibGetServByName (void) +{ + // NetServInfoPtr NetLibGetServByName(UInt16 libRefNum, const Char *servNameP, + // const Char *protoNameP, NetServInfoBufPtr bufP, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("NetServInfoPtr", "UInt16 libRefNum, const Char *servNameP, " + "const Char *protoNameP, NetServInfoBufPtr bufP, " + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_STR (Char, servNameP); + CALLED_GET_PARAM_STR (Char, protoNameP); +// CALLED_GET_PARAM_REF (NetServInfoBufType, bufP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_PTR (); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + + NetServInfoBufType servInfo; + Marshal::GetNetServInfoBufType (result, servInfo); +// PRINTF ("\t\tname = %s", servInfo.name); +// PRINTF ("\t\tport = 0x%04X", (UInt16) servInfo.servInfo.port); +// PRINTF ("\t\tprotoName = %s", servInfo.protoName); + + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibSocketAddr + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibSocketAddr (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibSocketAddr"); + + // Int16 NetLibSocketAddr(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *locAddrP, Int16 *locAddrLenP, + // NetSocketAddrType *remAddrP, Int16 *remAddrLenP, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *locAddrP, Int16 *locAddrLenP, " + "NetSocketAddrType *remAddrP, Int16 *remAddrLenP, " + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetSocketAddrType, locAddrP, Marshal::kOutput); + CALLED_GET_PARAM_REF (Int16, locAddrLenP, Marshal::kInOut); + CALLED_GET_PARAM_REF (NetSocketAddrType, remAddrP, Marshal::kOutput); + CALLED_GET_PARAM_REF (Int16, remAddrLenP, Marshal::kInOut); + CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tsocket = 0x%08X", (long) socket); + PRINTF ("\tlocAddrLen = 0x%08X", (long) *locAddrLenP); + PRINTF ("\tremAddrLen = 0x%08X", (long) *remAddrLenP); + PRINTF ("\ttimeout = 0x%08X", (long) timeout); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Int16 result = Platform_NetLib::SocketAddr (libRefNum, + socket, locAddrP, locAddrLenP, remAddrP, remAddrLenP, timeout, errP); + PUT_RESULT_VAL (Int16, result); + + // Return any pass-by-reference values. + if (result == 0) + { + CALLED_PUT_PARAM_REF (locAddrP); + CALLED_PUT_PARAM_REF (locAddrLenP); + CALLED_PUT_PARAM_REF (remAddrP); + CALLED_PUT_PARAM_REF (remAddrLenP); + } + CALLED_PUT_PARAM_REF (errP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibSocketAddr (void) +{ + // Int16 NetLibSocketAddr(UInt16 libRefNum, NetSocketRef socket, + // NetSocketAddrType *locAddrP, Int16 *locAddrLenP, + // NetSocketAddrType *remAddrP, Int16 *remAddrLenP, + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, NetSocketRef socket," + "NetSocketAddrType *locAddrP, Int16 *locAddrLenP, " + "NetSocketAddrType *remAddrP, Int16 *remAddrLenP, " + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (NetSocketRef, socket); + CALLED_GET_PARAM_REF (NetSocketAddrType, locAddrP, Marshal::kInput); + CALLED_GET_PARAM_REF (Int16, locAddrLenP, Marshal::kInput); + CALLED_GET_PARAM_REF (NetSocketAddrType, remAddrP, Marshal::kInput); + CALLED_GET_PARAM_REF (Int16, remAddrLenP, Marshal::kInput); +// CALLED_GET_PARAM_VAL (Int32, timeout); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); + PRINTF ("\tlocAddr.family = 0x%04X", (uint16) (*locAddrP).family); + PRINTF ("\tlocAddr.port = %s", PrvGetPortString (*locAddrP)); + PRINTF ("\tlocAddr.address = %s", PrvGetDottedIPString (*locAddrP)); + PRINTF ("\tlocAddrLen = 0x%08X", (long) *locAddrLenP); + PRINTF ("\tremAddr.family = 0x%04X", (uint16) (*remAddrP).family); + PRINTF ("\tremAddr.port = %s", PrvGetPortString (*remAddrP)); + PRINTF ("\tremAddr.address = %s", PrvGetDottedIPString (*remAddrP)); + PRINTF ("\tremAddrLen = 0x%08X", (long) *remAddrLenP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibFinishCloseWait + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibFinishCloseWait (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibFinishCloseWait"); + + // Err NetLibFinishCloseWait(UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::FinishCloseWait (libRefNum); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibFinishCloseWait (void) +{ + // Err NetLibFinishCloseWait(UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibGetMailExchangeByName + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibGetMailExchangeByName (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibGetMailExchangeByName"); + + // Int16 NetLibGetMailExchangeByName(UInt16 libRefNum, Char *mailNameP, + // UInt16 maxEntries, + // Char hostNames[][netDNSMaxDomainName+1], UInt16 priorities[], + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, Char *mailNameP, " + "UInt16 maxEntries, " + "Char** hostNames, UInt16* priorities, " + "Int32 timeout, Err *errP"); + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibGetMailExchangeByName (void) +{ + // Int16 NetLibGetMailExchangeByName(UInt16 libRefNum, Char *mailNameP, + // UInt16 maxEntries, + // Char hostNames[][netDNSMaxDomainName+1], UInt16 priorities[], + // Int32 timeout, Err *errP) + + CALLED_SETUP ("Int16", "UInt16 libRefNum, Char *mailNameP, " + "UInt16 maxEntries, " + "Char** hostNames, UInt16* priorities, " + "Int32 timeout, Err *errP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Int16); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*errP = %s (0x%04X)", PrvGetErrorString (*errP), (long) *errP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibOpenCount + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibOpenCount (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibOpenCount"); + + // Err NetLibOpenCount (UInt16 libRefNum, UInt16 *countP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 *countP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_REF (UInt16, countP, Marshal::kOutput); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::OpenCount (libRefNum, countP); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (countP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibOpenCount (void) +{ + // Err NetLibOpenCount (UInt16 libRefNum, UInt16 *countP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 *countP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_REF (UInt16, countP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\tcount = 0x%08X", (long) *countP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibTracePrintF + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibTracePrintF (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibTracePrintF"); + + // Err NetLibTracePrintF(UInt16 libRefNum, Char *formatStr, ...) + + CALLED_SETUP ("Err", "UInt16 libRefNum, Char *formatStr"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibTracePrintF (void) +{ + // Err NetLibTracePrintF(UInt16 libRefNum, Char *formatStr, ...) + + CALLED_SETUP ("Err", "UInt16 libRefNum, Char *formatStr"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibTracePutS + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibTracePutS (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibTracePutS"); + + // Err NetLibTracePutS(UInt16 libRefNum, Char *strP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, Char *strP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibTracePutS (void) +{ + // Err NetLibTracePutS(UInt16 libRefNum, Char *strP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, Char *strP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibOpenIfCloseWait + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibOpenIfCloseWait (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibOpenIfCloseWait"); + + // Err NetLibOpenIfCloseWait(UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::OpenIfCloseWait (libRefNum); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibOpenIfCloseWait (void) +{ + // Err NetLibOpenIfCloseWait(UInt16 libRefNum) + + CALLED_SETUP ("Err", "UInt16 libRefNum"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibHandlePowerOff + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibHandlePowerOff (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibHandlePowerOff"); + + // Err NetLibHandlePowerOff (UInt16 libRefNum, SysEventType *eventP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, SysEventType *eventP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_REF (EventType, eventP, Marshal::kInput); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::HandlePowerOff (libRefNum, eventP); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (eventP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibHandlePowerOff (void) +{ + // Err NetLibHandlePowerOff (UInt16 libRefNum, SysEventType *eventP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, SysEventType *eventP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_REF (EventType, eventP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConnectionRefresh + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConnectionRefresh (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConnectionRefresh"); + + // Err NetLibConnectionRefresh(UInt16 libRefNum, Boolean refresh, + // UInt8 *allInterfacesUpP, UInt16 *netIFErrP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, Boolean refresh, " + "UInt8 *allInterfacesUpP, UInt16 *netIFErrP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (Boolean, refresh); + CALLED_GET_PARAM_REF (Boolean, allInterfacesUpP, Marshal::kOutput); + CALLED_GET_PARAM_REF (UInt16, netIFErrP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\trefresh = 0x%08X", (long) refresh); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::ConnectionRefresh (libRefNum, + refresh, allInterfacesUpP, netIFErrP); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (allInterfacesUpP); + CALLED_PUT_PARAM_REF (netIFErrP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConnectionRefresh (void) +{ + // Err NetLibConnectionRefresh(UInt16 libRefNum, Boolean refresh, + // UInt8 *allInterfacesUpP, UInt16 *netIFErrP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, Boolean refresh, " + "UInt8 *allInterfacesUpP, UInt16 *netIFErrP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (Boolean, refresh); + CALLED_GET_PARAM_REF (Boolean, allInterfacesUpP, Marshal::kInput); + CALLED_GET_PARAM_REF (UInt16, netIFErrP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*netIFErrP = %s (0x%04X)", PrvGetErrorString (*netIFErrP), (long) *netIFErrP); + PRINTF ("\t*allInterfacesUpP = 0x%08X", (long) *allInterfacesUpP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibOpenConfig + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibOpenConfig (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibOpenConfig"); + + // Err NetLibOpenConfig( UInt16 libRefNum, UInt16 configIndex, UInt32 openFlags, + // UInt16 *netIFErrP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 configIndex, UInt32 openFlags," + "UInt16 *netIFErrP"); + + // Get the stack-based parameters. + CALLED_GET_PARAM_VAL (UInt16, libRefNum); + CALLED_GET_PARAM_VAL (UInt16, configIndex); + CALLED_GET_PARAM_VAL (UInt32, openFlags); + CALLED_GET_PARAM_REF (UInt16, netIFErrP, Marshal::kOutput); + + // Examine the parameters + PRINTF ("\tconfigIndex = 0x%08X", (long) configIndex); + PRINTF ("\topenFlags = 0x%08X", (long) openFlags); + + if (Platform_NetLib::Redirecting ()) + { + PRINTF ("\t-->Executing host version"); + + // Call the host function. + Err result = Platform_NetLib::OpenConfig (libRefNum, + configIndex, openFlags, netIFErrP); + PUT_RESULT_VAL (Err, result); + + // Return any pass-by-reference values. + CALLED_PUT_PARAM_REF (netIFErrP); + + return kSkipROM; + } + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibOpenConfig (void) +{ + // Err NetLibOpenConfig( UInt16 libRefNum, UInt16 configIndex, UInt32 openFlags, + // UInt16 *netIFErrP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 configIndex, UInt32 openFlags," + "UInt16 *netIFErrP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); +// CALLED_GET_PARAM_VAL (UInt16, configIndex); +// CALLED_GET_PARAM_VAL (UInt16, openFlags); + CALLED_GET_PARAM_REF (UInt16, netIFErrP, Marshal::kInput); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); + PRINTF ("\t*netIFErrP = %s (0x%04X)", PrvGetErrorString (*netIFErrP), (long) *netIFErrP); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigMakeActive + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigMakeActive (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigMakeActive"); + + // Err NetLibConfigMakeActive( UInt16 libRefNum, UInt16 configIndex) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 configIndex"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigMakeActive (void) +{ + // Err NetLibConfigMakeActive( UInt16 libRefNum, UInt16 configIndex) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 configIndex"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigList + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigList (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigList"); + + // Err NetLibConfigList( UInt16 libRefNum, NetConfigNameType nameArray[], + // UInt16 *arrayEntriesP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, NetConfigNameType* nameArray," + "UInt16 *arrayEntriesP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigList (void) +{ + // Err NetLibConfigList( UInt16 libRefNum, NetConfigNameType nameArray[], + // UInt16 *arrayEntriesP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, NetConfigNameType* nameArray," + "UInt16 *arrayEntriesP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigIndexFromName + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigIndexFromName (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigIndexFromName"); + + // Err NetLibConfigIndexFromName( UInt16 libRefNum, NetConfigNamePtr nameP, + // UInt16 *indexP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, NetConfigNamePtr nameP, UInt16 *indexP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigIndexFromName (void) +{ + // Err NetLibConfigIndexFromName( UInt16 libRefNum, NetConfigNamePtr nameP, + // UInt16 *indexP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, NetConfigNamePtr nameP, UInt16 *indexP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigDelete + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigDelete (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigDelete"); + + // Err NetLibConfigDelete( UInt16 libRefNum, UInt16 index) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 index"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigDelete (void) +{ + // Err NetLibConfigDelete( UInt16 libRefNum, UInt16 index) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 index"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigSaveAs + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigSaveAs (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigSaveAs"); + + // Err NetLibConfigSaveAs( UInt16 libRefNum, NetConfigNamePtr nameP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, NetConfigNamePtr nameP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigSaveAs (void) +{ + // Err NetLibConfigSaveAs( UInt16 libRefNum, NetConfigNamePtr nameP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, NetConfigNamePtr nameP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigRename + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigRename (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigRename"); + + // Err NetLibConfigRename( UInt16 libRefNum, UInt16 index, + // NetConfigNamePtr newNameP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 index, NetConfigNamePtr newNameP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigRename (void) +{ + // Err NetLibConfigRename( UInt16 libRefNum, UInt16 index, + // NetConfigNamePtr newNameP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 index, NetConfigNamePtr newNameP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigAliasSet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigAliasSet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigAliasSet"); + + // Err NetLibConfigAliasSet( UInt16 libRefNum, UInt16 configIndex, + // UInt16 aliasToIndex) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 configIndex, UInt16 aliasToIndex"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigAliasSet (void) +{ + // Err NetLibConfigAliasSet( UInt16 libRefNum, UInt16 configIndex, + // UInt16 aliasToIndex) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 configIndex, UInt16 aliasToIndex"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: NetLibHeadpatch::NetLibConfigAliasGet + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType NetLibHeadpatch::NetLibConfigAliasGet (void) +{ + PRINTF ("----------------------------------------"); + PRINTF ("NetLibConfigAliasGet"); + + // Err NetLibConfigAliasGet( UInt16 libRefNum, UInt16 aliasIndex, + // UInt16 *indexP, Boolean *isAnotherAliasP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 aliasIndex, UInt16 *indexP, Boolean *isAnotherAliasP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Examine the parameters + + PRINTF ("\t-->Executing ROM version"); + return kExecuteROM; +} + +void NetLibTailpatch::NetLibConfigAliasGet (void) +{ + // Err NetLibConfigAliasGet( UInt16 libRefNum, UInt16 aliasIndex, + // UInt16 *indexP, Boolean *isAnotherAliasP) + + CALLED_SETUP ("Err", "UInt16 libRefNum, UInt16 aliasIndex, UInt16 *indexP, Boolean *isAnotherAliasP"); + + // Get the stack-based parameters. +// CALLED_GET_PARAM_VAL (UInt16, libRefNum); + + // Get the result. + GET_RESULT_VAL (Err); + + // Examine the results. + PRINTF ("\tResult = 0x%08X", result); +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetOptLevelString + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +#define DOCASE(name) case name: return #name; + +const char* PrvGetOptLevelString (NetSocketOptLevelEnum level) +{ + switch (level) + { + DOCASE (netSocketOptLevelIP) + DOCASE (netSocketOptLevelTCP) + DOCASE (netSocketOptLevelSocket) + } + + return "Unknown NetSocketOptLevelEnum"; +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetOptString + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +const char* PrvGetOptString (NetSocketOptLevelEnum level, NetSocketOptEnum opt) +{ + switch (level) + { + case netSocketOptLevelIP: + switch (opt) + { + DOCASE (netSocketOptIPOptions) + +// case netSocketOptTCPNoDelay: == 1 (netSocketOptIPOptions) + case netSocketOptTCPMaxSeg: + +// case netSocketOptSockDebug: == 1 (netSocketOptIPOptions) +// case netSocketOptSockAcceptConn: == 2 (netSocketOptTCPMaxSeg) + case netSocketOptSockReuseAddr: + case netSocketOptSockKeepAlive: + case netSocketOptSockDontRoute: + case netSocketOptSockBroadcast: + case netSocketOptSockUseLoopback: + case netSocketOptSockLinger: + case netSocketOptSockOOBInLine: + case netSocketOptSockSndBufSize: + case netSocketOptSockRcvBufSize: + case netSocketOptSockSndLowWater: + case netSocketOptSockRcvLowWater: + case netSocketOptSockSndTimeout: + case netSocketOptSockRcvTimeout: + case netSocketOptSockErrorStatus: + case netSocketOptSockSocketType: + case netSocketOptSockNonBlocking: + case netSocketOptSockRequireErrClear: + case netSocketOptSockMultiPktAddr: + break; + } + break; + + case netSocketOptLevelTCP: + switch (opt) + { +// case netSocketOptIPOptions: == 1 (netSocketOptTCPNoDelay) +// break; + + DOCASE (netSocketOptTCPNoDelay) + DOCASE (netSocketOptTCPMaxSeg) + +// case netSocketOptSockDebug: == 1 (netSocketOptTCPNoDelay) +// case netSocketOptSockAcceptConn: == 2 (netSocketOptTCPMaxSeg) + case netSocketOptSockReuseAddr: + case netSocketOptSockKeepAlive: + case netSocketOptSockDontRoute: + case netSocketOptSockBroadcast: + case netSocketOptSockUseLoopback: + case netSocketOptSockLinger: + case netSocketOptSockOOBInLine: + case netSocketOptSockSndBufSize: + case netSocketOptSockRcvBufSize: + case netSocketOptSockSndLowWater: + case netSocketOptSockRcvLowWater: + case netSocketOptSockSndTimeout: + case netSocketOptSockRcvTimeout: + case netSocketOptSockErrorStatus: + case netSocketOptSockSocketType: + case netSocketOptSockNonBlocking: + case netSocketOptSockRequireErrClear: + case netSocketOptSockMultiPktAddr: + break; + } + break; + + case netSocketOptLevelSocket: + switch (opt) + { +// case netSocketOptIPOptions: +// case netSocketTCPNoDelay: +// case netSocketTCPMaxSeg: +// break; + + DOCASE (netSocketOptSockDebug) + DOCASE (netSocketOptSockAcceptConn) + DOCASE (netSocketOptSockReuseAddr) + DOCASE (netSocketOptSockKeepAlive) + DOCASE (netSocketOptSockDontRoute) + DOCASE (netSocketOptSockBroadcast) + DOCASE (netSocketOptSockUseLoopback) + DOCASE (netSocketOptSockLinger) + DOCASE (netSocketOptSockOOBInLine) + + DOCASE (netSocketOptSockSndBufSize) + DOCASE (netSocketOptSockRcvBufSize) + DOCASE (netSocketOptSockSndLowWater) + DOCASE (netSocketOptSockRcvLowWater) + DOCASE (netSocketOptSockSndTimeout) + DOCASE (netSocketOptSockRcvTimeout) + DOCASE (netSocketOptSockErrorStatus) + DOCASE (netSocketOptSockSocketType) + + DOCASE (netSocketOptSockNonBlocking) + DOCASE (netSocketOptSockRequireErrClear) + DOCASE (netSocketOptSockMultiPktAddr) + } + break; + } + + return "Unknown NetSocketOptEnum"; +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetDottedIPString + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +const char* PrvGetDottedIPString (const NetSocketAddrType& addr) +{ + NetSocketAddrINType ipAddr = (const NetSocketAddrINType&) addr; + long tempIP = ntohl (ipAddr.addr); + + static char dottedIPStr[20]; + + sprintf (dottedIPStr, "%ld.%ld.%ld.%ld", + ((tempIP >> 24) & 0xFF), + ((tempIP >> 16) & 0xFF), + ((tempIP >> 8) & 0xFF), + ((tempIP) & 0xFF)); + + return dottedIPStr; +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetPortString + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +const char* PrvGetPortString (const NetSocketAddrType& addr) +{ + NetSocketAddrINType ipAddr = (const NetSocketAddrINType&) addr; + UInt16 port = ntohs (ipAddr.port); + + static char portStr[10]; + + sprintf (portStr, "0x%04X", port); + + return portStr; +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetErrorString + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +const char* PrvGetErrorString (Err err) +{ + switch (err) + { + DOCASE (errNone) + DOCASE (netErrAlreadyOpen) + DOCASE (netErrNotOpen) + DOCASE (netErrStillOpen) + DOCASE (netErrParamErr) + DOCASE (netErrNoMoreSockets) + DOCASE (netErrOutOfResources) + DOCASE (netErrOutOfMemory) + DOCASE (netErrSocketNotOpen) + DOCASE (netErrSocketBusy) + DOCASE (netErrMessageTooBig) + DOCASE (netErrSocketNotConnected) + DOCASE (netErrNoInterfaces) + DOCASE (netErrBufTooSmall) + DOCASE (netErrUnimplemented) + DOCASE (netErrPortInUse) + DOCASE (netErrQuietTimeNotElapsed) + DOCASE (netErrInternal) + DOCASE (netErrTimeout) + DOCASE (netErrSocketAlreadyConnected) + DOCASE (netErrSocketClosedByRemote) + DOCASE (netErrOutOfCmdBlocks) + DOCASE (netErrWrongSocketType) + DOCASE (netErrSocketNotListening) + DOCASE (netErrUnknownSetting) + DOCASE (netErrInvalidSettingSize) + DOCASE (netErrPrefNotFound) + DOCASE (netErrInvalidInterface) + DOCASE (netErrInterfaceNotFound) + DOCASE (netErrTooManyInterfaces) + DOCASE (netErrBufWrongSize) + DOCASE (netErrUserCancel) + DOCASE (netErrBadScript) + DOCASE (netErrNoSocket) + DOCASE (netErrSocketRcvBufFull) + DOCASE (netErrNoPendingConnect) + DOCASE (netErrUnexpectedCmd) + DOCASE (netErrNoTCB) + DOCASE (netErrNilRemoteWindowSize) + DOCASE (netErrNoTimerProc) + DOCASE (netErrSocketInputShutdown) + DOCASE (netErrCmdBlockNotCheckedOut) + DOCASE (netErrCmdNotDone) + DOCASE (netErrUnknownProtocol) + DOCASE (netErrUnknownService) + DOCASE (netErrUnreachableDest) + DOCASE (netErrReadOnlySetting) + DOCASE (netErrWouldBlock) + DOCASE (netErrAlreadyInProgress) + DOCASE (netErrPPPTimeout) + DOCASE (netErrPPPBroughtDown) + DOCASE (netErrAuthFailure) + DOCASE (netErrPPPAddressRefused) + DOCASE (netErrDNSNameTooLong) + DOCASE (netErrDNSBadName) + DOCASE (netErrDNSBadArgs) + DOCASE (netErrDNSLabelTooLong) + DOCASE (netErrDNSAllocationFailure) + DOCASE (netErrDNSTimeout) + DOCASE (netErrDNSUnreachable) + DOCASE (netErrDNSFormat) + DOCASE (netErrDNSServerFailure) + DOCASE (netErrDNSNonexistantName) + DOCASE (netErrDNSNIY) + DOCASE (netErrDNSRefused) + DOCASE (netErrDNSImpossible) + DOCASE (netErrDNSNoRRS) + DOCASE (netErrDNSAborted) + DOCASE (netErrDNSBadProtocol) + DOCASE (netErrDNSTruncated) + DOCASE (netErrDNSNoRecursion) + DOCASE (netErrDNSIrrelevant) + DOCASE (netErrDNSNotInLocalCache) + DOCASE (netErrDNSNoPort) + DOCASE (netErrIPCantFragment) + DOCASE (netErrIPNoRoute) + DOCASE (netErrIPNoSrc) + DOCASE (netErrIPNoDst) + DOCASE (netErrIPktOverflow) + DOCASE (netErrTooManyTCPConnections) + DOCASE (netErrNoDNSServers) + DOCASE (netErrInterfaceDown) + DOCASE (netErrNoChannel) + DOCASE (netErrDieState) + DOCASE (netErrReturnedInMail) + DOCASE (netErrReturnedNoTransfer) + DOCASE (netErrReturnedIllegal) + DOCASE (netErrReturnedCongest) + DOCASE (netErrReturnedError) + DOCASE (netErrReturnedBusy) + DOCASE (netErrGMANState) + DOCASE (netErrQuitOnTxFail) + DOCASE (netErrFlexListFull) + DOCASE (netErrSenderMAN) + DOCASE (netErrIllegalType) + DOCASE (netErrIllegalState) + DOCASE (netErrIllegalFlags) + DOCASE (netErrIllegalSendlist) + DOCASE (netErrIllegalMPAKLength) + DOCASE (netErrIllegalAddressee) + DOCASE (netErrIllegalPacketClass) + DOCASE (netErrBufferLength) + DOCASE (netErrNiCdLowBattery) + DOCASE (netErrRFinterfaceFatal) + DOCASE (netErrIllegalLogout) + DOCASE (netErrAAARadioLoad) + DOCASE (netErrAntennaDown) + DOCASE (netErrNiCdCharging) + DOCASE (netErrAntennaWentDown) + DOCASE (netErrNotActivated) + DOCASE (netErrRadioTemp) + DOCASE (netErrConfigNotFound) + DOCASE (netErrConfigCantDelete) + DOCASE (netErrConfigTooMany) + DOCASE (netErrConfigBadName) + DOCASE (netErrConfigNotAlias) + DOCASE (netErrConfigCantPointToAlias) + DOCASE (netErrConfigEmpty) + DOCASE (netErrAlreadyOpenWithOtherConfig) + DOCASE (netErrConfigAliasErr) + DOCASE (netErrNoMultiPktAddr) + DOCASE (netErrOutOfPackets) + DOCASE (netErrMultiPktAddrReset) + DOCASE (netErrStaleMultiPktAddr) + } + + return "Unknown Error Code"; +} diff --git a/SrcShared/Patches/EmPatchModuleNetLib.h b/SrcShared/Patches/EmPatchModuleNetLib.h new file mode 100644 index 0000000..72e09d0 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleNetLib.h @@ -0,0 +1,27 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchModuleNetLib_h +#define EmPatchModuleNetLib_h + +#include "EmPatchModule.h" + +class EmPatchModuleNetLib : public EmPatchModule +{ + public: + EmPatchModuleNetLib (void); + virtual ~EmPatchModuleNetLib (void) {} +}; + +#endif // EmPatchModuleNetLib_h diff --git a/SrcShared/Patches/EmPatchModuleSys.cpp b/SrcShared/Patches/EmPatchModuleSys.cpp new file mode 100644 index 0000000..667f786 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleSys.cpp @@ -0,0 +1,3217 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchModuleSys.h" + +#include "CGremlinsStubs.h" // StubAppEnqueueKey +#include "DebugMgr.h" // Debug::ConnectedToTCPDebugger +#include "EmFileImport.h" // InstallExgMgrLib +#include "EmEventOutput.h" // EmEventOutput::PoppingUpForm +#include "EmEventPlayback.h" // EmEventPlayback::ReplayingEvents +#include "EmLowMem.h" // EmLowMem::GetEvtMgrIdle, EmLowMem::TrapExists, EmLowMem_SetGlobal, EmLowMem_GetGlobal +#include "EmMemory.h" // CEnableFullAccess, EmMem_memcpy, EmMem_strcpy, EmMem_strcmp +#include "EmPalmFunction.h" // InEggOfInfiniteWisdom +#include "EmPalmOS.h" // EmPalmOS::RememberStackRange +#include "EmPalmStructs.h" // EmAliasErr +#include "EmPatchMgr.h" // PuppetString +#include "EmPatchModule.h" // IntlMgrAvailable +#include "EmPatchState.h" +#include "EmRPC.h" // RPC::SignalWaiters +#include "EmSession.h" // GetDevice +#include "EmSubroutine.h" +#include "ErrorHandling.h" // Errors::SysFatalAlert +#include "Hordes.h" // Hordes::IsOn, Hordes::PostFakeEvent, Hordes::CanSwitchToApp +#include "HostControlPrv.h" // HandleHostControlCall +#include "Logging.h" // LogEvtAddEventToQueue, etc. +#include "Marshal.h" // CALLED_GET_PARAM_STR +#include "MetaMemory.h" // MetaMemory mark functions +#include "Miscellaneous.h" // SetHotSyncUserName, DateToDays, SystemCallContext +#include "Platform.h" // Platform::SndDoCmd, GetString +#include "PreferenceMgr.h" // Preference (kPrefKeyUserName) +#include "Profiling.h" // StDisableAllProfiling +#include "ROMStubs.h" // FtrSet, FtrUnregister, EvtWakeup, ... +#include "SessionFile.h" // SessionFile +#include "SLP.h" // SLP +#include "Startup.h" // Startup::GetAutoLoads +#include "Strings.r.h" // kStr_ values +#include "SystemPacket.h" // SystemPacket::SendMessage + +#include <vector> // vector + +#if PLATFORM_MAC +#include <errno.h> // ENOENT, errno +#include <sys/types.h> // u_short, ssize_t, etc. +#include <sys/socket.h> // sockaddr +#include <sys/errno.h> // Needed for error translation. +#include <sys/time.h> // fd_set +#include <netdb.h> // hostent +#include <unistd.h> // close +#include <sys/filio.h> // FIONBIO +#include <sys/ioctl.h> // ioctl +#include <netinet/in.h> // sockaddr_in +#include <netinet/tcp.h> // TCP_NODELAY +#include <arpa/inet.h> // inet_ntoa +#endif + +#if PLATFORM_UNIX +#include <errno.h> // ENOENT, errno +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> // timeval +#include <sys/ioctl.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <netdb.h> +#include <unistd.h> // close +#include <arpa/inet.h> // inet_ntoa +#endif + +#include "PalmPack.h" +#define NON_PORTABLE +#include "HwrROMToken.h" // hwrROMTokenIrda +#undef NON_PORTABLE +#include "PalmPackPop.h" + + +// ====================================================================== +// Global Interfaces +// ====================================================================== + + +// ====================================================================== +// Proto patch table for the system functions. This array will be used +// to create a sparse array at runtime. +// ====================================================================== + +ProtoPatchTableEntry gProtoSysPatchTable[] = +{ + {sysTrapBmpCreate, NULL, SysTailpatch::BmpCreate}, + {sysTrapBmpDelete, NULL, SysTailpatch::BmpDelete}, + {sysTrapClipboardGetItem, SysHeadpatch::ClipboardGetItem, NULL}, + {sysTrapDbgMessage, SysHeadpatch::DbgMessage, NULL}, + {sysTrapClipboardAddItem, NULL, SysTailpatch::ClipboardAddItem}, + {sysTrapClipboardAppendItem, NULL, SysTailpatch::ClipboardAppendItem}, + {sysTrapDmCloseDatabase, SysHeadpatch::DmCloseDatabase, NULL}, + {sysTrapDmInit, SysHeadpatch::DmInit, NULL}, + {sysTrapDmGet1Resource, NULL, SysTailpatch::DmGet1Resource}, + {sysTrapDmGetResource, NULL, SysTailpatch::DmGetResource}, + {sysTrapErrDisplayFileLineMsg, SysHeadpatch::ErrDisplayFileLineMsg, NULL}, + {sysTrapEvtAddEventToQueue, SysHeadpatch::EvtAddEventToQueue, NULL}, + {sysTrapEvtAddUniqueEventToQueue,SysHeadpatch::EvtAddUniqueEventToQueue,NULL}, + {sysTrapEvtEnqueueKey, SysHeadpatch::EvtEnqueueKey, NULL}, + {sysTrapEvtEnqueuePenPoint, SysHeadpatch::EvtEnqueuePenPoint, NULL}, + {sysTrapEvtGetEvent, SysHeadpatch::RecordTrapNumber, SysTailpatch::EvtGetEvent}, + {sysTrapEvtGetPen, SysHeadpatch::RecordTrapNumber, SysTailpatch::EvtGetPen}, + {sysTrapEvtGetSysEvent, NULL, SysTailpatch::EvtGetSysEvent}, + {sysTrapEvtSysEventAvail, NULL, SysTailpatch::EvtSysEventAvail}, + {sysTrapExgReceive, NULL, SysTailpatch::ExgReceive}, + {sysTrapExgSend, NULL, SysTailpatch::ExgSend}, + {sysTrapExgDoDialog, SysHeadpatch::ExgDoDialog, NULL}, + {sysTrapFrmCustomAlert, SysHeadpatch::FrmCustomAlert, NULL}, + {sysTrapFrmDrawForm, SysHeadpatch::FrmDrawForm, NULL}, + {sysTrapFrmPopupForm, SysHeadpatch::FrmPopupForm, NULL}, + {sysTrapFtrInit, NULL, SysTailpatch::FtrInit}, + {sysTrapFtrSet, NULL, SysTailpatch::FtrSet}, + {sysTrapHostControl, SysHeadpatch::HostControl, NULL}, + {sysTrapHwrBatteryLevel, SysHeadpatch::HwrBatteryLevel, NULL}, + {sysTrapHwrBattery, SysHeadpatch::HwrBattery, NULL}, + {sysTrapHwrDockStatus, SysHeadpatch::HwrDockStatus, NULL}, + {sysTrapHwrGetROMToken, SysHeadpatch::HwrGetROMToken, NULL}, + {sysTrapHwrMemReadable, NULL, SysTailpatch::HwrMemReadable}, + {sysTrapHwrSleep, SysHeadpatch::HwrSleep, SysTailpatch::HwrSleep}, + {sysTrapPenOpen, SysHeadpatch::PenOpen, NULL}, + {sysTrapPrefSetAppPreferences, SysHeadpatch::PrefSetAppPreferences, NULL}, + {sysTrapSndDoCmd, SysHeadpatch::SndDoCmd, NULL}, + {sysTrapSysAppExit, SysHeadpatch::SysAppExit, NULL}, + {sysTrapSysAppLaunch, SysHeadpatch::SysAppLaunch, NULL}, + {sysTrapSysAppStartup, NULL, SysTailpatch::SysAppStartup}, + {sysTrapSysBinarySearch, SysHeadpatch::SysBinarySearch, SysTailpatch::SysBinarySearch}, + {sysTrapSysEvGroupWait, SysHeadpatch::SysEvGroupWait, NULL}, + {sysTrapSysFatalAlert, SysHeadpatch::SysFatalAlert, NULL}, + {sysTrapSysLaunchConsole, SysHeadpatch::SysLaunchConsole, NULL}, + {sysTrapSysSemaphoreWait, SysHeadpatch::SysSemaphoreWait, NULL}, + {sysTrapSysTaskCreate, NULL, SysTailpatch::SysTaskCreate}, + {sysTrapSysUIAppSwitch, SysHeadpatch::SysUIAppSwitch, NULL}, + {sysTrapTblHandleEvent, SysHeadpatch::TblHandleEvent, SysTailpatch::TblHandleEvent}, + {sysTrapTimInit, NULL, SysTailpatch::TimInit}, + {sysTrapUIInitialize, NULL, SysTailpatch::UIInitialize}, + {sysTrapUIReset, NULL, SysTailpatch::UIReset}, + + {sysTrapCtlNewControl, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapFldNewField, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapFrmInitForm, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapFrmNewBitmap, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapFrmNewGadget, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapFrmNewGsi, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapFrmNewLabel, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapLstNewList, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapWinAddWindow, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + {sysTrapWinRemoveWindow, SysHeadpatch::UnmarkUIObjects, SysTailpatch::MarkUIObjects}, + + {0, NULL, NULL} +}; + + +extern ProtoPatchTableEntry gProtoMemMgrPatchTable[]; + + + + + +// =========================================================================== +// ¥ +// =========================================================================== + +// ====================================================================== +// Globals and constants +// ====================================================================== + + +static long gSaveDrawStateStackLevel; + +static Bool gDontPatchClipboardAddItem; +static Bool gDontPatchClipboardGetItem; + + +// ====================================================================== +// Private functions +// ====================================================================== + +static long PrvGetDrawStateStackLevel (void); +static void PrvCopyPalmClipboardToHost (void); +static void PrvCopyHostClipboardToPalm (void); + +void PrvAutoload (void); // Also called in PostLoad +void PrvSetCurrentDate (void); // Also called in PostLoad + + +#pragma mark - + + + +// =========================================================================== +// ¥ EmPatchModuleSys +// =========================================================================== + +/*********************************************************************** + * + * FUNCTION: EmPatchModuleSys::EmPatchModuleSys + * + * DESCRIPTION: Constructor + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +EmPatchModuleSys::EmPatchModuleSys() : + EmPatchModule ("~system", gProtoSysPatchTable, gProtoMemMgrPatchTable) +{ +} + + +// =========================================================================== +// ¥ SysHeadpatch +// =========================================================================== + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::RecordTrapNumber + * + * DESCRIPTION: Record the trap we're executing for our patch to + * SysEvGroupWait later. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::RecordTrapNumber (void) +{ + EmAssert (gCPU); + uint8* realMem = EmMemGetRealAddress (gCPU->GetPC ()); + + EmAssert (EmMemDoGet16 (realMem - 2) == (m68kTrapInstr + sysDispatchTrapNum)); + + EmPatchState::SetLastEvtTrap (EmMemDoGet16 (realMem)); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::ClipboardGetItem + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::ClipboardGetItem (void) +{ + if (!Hordes::IsOn () && !gDontPatchClipboardGetItem) + { + ::PrvCopyHostClipboardToPalm (); + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::UnmarkUIObjects + * + * DESCRIPTION: . + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::UnmarkUIObjects (void) +{ + MetaMemory::UnmarkUIObjects (); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::DbgMessage + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::DbgMessage (void) +{ + // void DbgMessage(const Char* aStr); + + CALLED_SETUP ("void", "const Char* aStr"); + + CALLED_GET_PARAM_STR (Char, aStr); + + if (aStr != EmMemNULL) + { + // Get the string that's passed in. + + string msgCopy (aStr); + CSocket* debuggerSocket = Debug::GetDebuggerSocket (); + Bool contactedDebugger = false; + + // If we're connected to a debugger, try to send it the string. + + if (debuggerSocket) + { + SLP slp (debuggerSocket); + ErrCode err = SystemPacket::SendMessage (slp, msgCopy.c_str ()); + if (!err) + { + contactedDebugger = true; + } + } + + // If that failed or if we're not connected to a debugger, + // tell the user in one of our own dialogs. + + if (!contactedDebugger) + { + // Squelch these debugger messages. Some functions in the ROM + // (see Content.c and Progress.c) use DbgMessage for logging + // instead of debugging. I'm hoping this will get fixed after + // Palm OS 4.0, so I'm only checking in versions before that. + // + // ("Transaction finished" actually appears only in 3.2 and + // 3.3 ROMs, so that one's already taken care of.) + // + // Also note that I have the last character as "\x0A". In + // the ROM sources, this is "\n". However, the value that + // that turns into is compiler-dependent, so I'm using the + // value that the Palm compiler is currently known to use. + + if ((msgCopy != "...Transaction cancelled\x0A" && + msgCopy != "Transaction finished\x0A" && + msgCopy != "c") || + EmPatchState::OSMajorMinorVersion () > 40) + { + Errors::ReportErrDbgMessage (msgCopy.c_str ()); + } + } + } + + return kSkipROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::DmCloseDatabase + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::DmCloseDatabase (void) +{ + // Err DmCloseDatabase(DmOpenRef dbR) + + CALLED_SETUP ("Err", "DmOpenRef dbR"); + + CALLED_GET_PARAM_VAL (DmOpenRef, dbR); + + // Allow for a NULL reference. Applications shouldn't be doing + // this, but the test harness does in order to make sure the + // OS recovers OK. We need to check for it specially, because + // even though DmCloseDatabase checks for and handles the NULL + // reference, we're inserting a call to DmOpenDatabaseInfo here, + // which does NOT handle the NULL reference (it will call + // ErrDisplay, but subsequent code is not defensive and will crash). + + if (dbR == NULL) + return kExecuteROM; + + UInt16 openCount; + Boolean resDB; + + Err err = ::DmOpenDatabaseInfo ( + dbR, // DmOpenRef dbR, + NULL, // LocalID* dbIDP, + &openCount, // UInt16 * openCountP, + NULL, // UInt16 * modeP, + NULL, // UInt16 * cardNoP, + &resDB); // Boolean * resDBP) + + if (!err && resDB && openCount == 1) + { + MemHandle resource; + UInt16 ii; + UInt16 numResources = ::DmNumResources (dbR); + + for (ii = 0; ii < numResources; ++ii) + { + resource = ::DmGetResourceIndex (dbR, ii); + MetaMemory::UnregisterBitmapHandle (resource); + } + + // Search for any overlay databases and unregister any + // bitmaps they may have, too. + // + // Overlays were added in Palm OS 3.5; don't check the + // "openType" field in older OSes. + + if (EmPatchState::OSMajorMinorVersion () >= 35) + { + emuptr dbAccessP = (emuptr) (DmOpenRef) dbR; + EmAliasDmAccessType<PAS> dbAccess (dbAccessP); + + // If this is a "base" database, look for a corresponding + // overlay database. Do this by iterating over the list + // of open databases and finding the one in the list + // preceding the base database we're closing. + + if (dbAccess.openType == openTypeBase) + { + // Get the first open database. + + DmOpenRef olRef = ::DmNextOpenDatabase (NULL); + + // Iterate over the open databases until we get to the end + // or until we meet up with then one we're closing. The + // overlay database will appear in the linked list *before* + // the one we're closing, so if we get to that one without + // finding the overlay, we never will find it. + + while (olRef && olRef != dbR) + { + // For each open database, see if it's an overlay type. + // If it is, see if the "next" field points to the database + // we're closing. + + emuptr olAccessP = (emuptr) olRef; + EmAliasDmAccessType<PAS> olAccess (olAccessP); + + UInt8 openType = olAccess.openType; + emuptr next = olAccess.next; + + if (openType == openTypeOverlay && next == dbAccessP) + { + // OK, now that we're here, let's iterate over + // the database and release any resources it + // has, too. + + numResources = ::DmNumResources (olRef); + for (ii = 0; ii < numResources; ++ii) + { + resource = ::DmGetResourceIndex (olRef, ii); + MetaMemory::UnregisterBitmapHandle (resource); + } + + break; // Break out of the "while (olRef && olRef != dbR)..." loop. + } + + // This either wasn't an overlay database, or it didn't + // belong to the base database we were closing. Move + // on to the next database. + + olRef = ::DmNextOpenDatabase (olRef); + } + + // Make sure we found the overlay. + + EmAssert (olRef && olRef != dbR); + } + } + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::DmInit + * + * DESCRIPTION: After MemInit is called, we need to sync up with the + * initial state of the heap(s). However, MemInit is not + * called via the trap table, so we can't easily tailpatch + * it. DmInit is the first such function called after + * MemInit, so we headpatch *it* instead of tailpatching + * MemInit. + * + * (Actually, MemHeapCompact is called as one of the last + * things MemInit does which makes it an interesting + * candidate for patching in order to sync up with the + * heap state. However, if we were to do a full sync on + * that call, a full sync would occur on *every* call to + * MemHeapCompact, which we don't really want to do.) + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::DmInit (void) +{ +// MetaMemory::SyncAllHeaps (); + + EmPatchState::SetHeapInitialized (true); + + // If they haven't been released by now, then release the boot keys. + + gSession->ReleaseBootKeys (); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::ErrDisplayFileLineMsg + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +typedef Bool (*VersionChecker)(void); +typedef Bool (*FunctionChecker)(emuptr addr); + +struct EmInvalidErrorMessageData +{ + VersionChecker fVersionChecker; + FunctionChecker fFunctionChecker; + const char* fMessage; +}; + +EmInvalidErrorMessageData kInvalidErrorMessages [] = +{ + { + &EmPatchState::HasECValidateFieldBug, + &::InECValidateField, + "Invalid insertion point position" + }, + { + &EmPatchState::HasPrvDrawSliderControlBug, + &::InPrvDrawSliderControl, + "Background must be at least half as wide as slider." + }, + { + NULL, // Don't care about the system version. + &::InPrvFindMemoryLeaks, + NULL // Don't care about the actual text. + } +}; + + +CallROMType SysHeadpatch::ErrDisplayFileLineMsg (void) +{ + // void ErrDisplayFileLineMsg(CharPtr filename, UInt16 lineno, CharPtr msg) + + CALLED_SETUP ("void", "CharPtr filename, UInt16 lineno, CharPtr msg"); + + CALLED_GET_PARAM_STR (Char, msg); + + { + CEnableFullAccess munge; // Remove blocks on memory access. + + // Force this guy to true. If it's false, ErrDisplayFileLineMsg will + // just try to enter the debugger. + + UInt16 sysMiscFlags = EmLowMem_GetGlobal (sysMiscFlags); + EmLowMem_SetGlobal (sysMiscFlags, sysMiscFlags | sysMiscFlagUIInitialized); + + // Clear this low-memory flag so that we force the dialog to display. + // If this flag is true, ErrDisplayFileLineMsg will just try to enter + // the debugger. + + EmLowMem_SetGlobal (dbgWasEntered, false); + } + + // Some ROMs incorrectly display error messages via ErrDisplayFileLineMsg. + // Check to see if we are running on a ROM version with one of those + // erroneous messages, check to see that we are in the function that + // displays the message, and check to see if the text of the message + // handed to us is one of the incorrect ones. If all conditions are + // true, squelch the message. + + for (size_t ii = 0; ii < countof (kInvalidErrorMessages); ++ii) + { + EmAssert (gCPU); + + EmInvalidErrorMessageData* d = &kInvalidErrorMessages[ii]; + + if ( + (!d->fVersionChecker || d->fVersionChecker ()) && + (!d->fFunctionChecker || d->fFunctionChecker (gCPU->GetPC ()))) + { + if (!d->fMessage || (strcmp (msg, d->fMessage) == 0)) + { + return kSkipROM; + } + } + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::EvtAddEventToQueue + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::EvtAddEventToQueue (void) +{ + // void EvtAddEventToQueue (const EventPtr event) + + CALLED_SETUP ("void", "const EventPtr event"); + + CALLED_GET_PARAM_REF (EventType, event, Marshal::kInput); + + LogEvtAddEventToQueue (*event); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::EvtAddUniqueEventToQueue + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::EvtAddUniqueEventToQueue (void) +{ + // void EvtAddUniqueEventToQueue(const EventPtr eventP, const UInt32 id, const Boolean inPlace) + + CALLED_SETUP ("void", "const EventPtr eventP, const UInt32 id, const Boolean inPlace"); + + CALLED_GET_PARAM_REF (EventType, eventP, Marshal::kInput); + CALLED_GET_PARAM_VAL (UInt32, id); + CALLED_GET_PARAM_VAL (Boolean, inPlace); + + LogEvtAddUniqueEventToQueue (*eventP, id, inPlace); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::EvtEnqueueKey + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::EvtEnqueueKey (void) +{ + // Err EvtEnqueueKey(UInt16 ascii, UInt16 keycode, UInt16 modifiers) + + CALLED_SETUP ("Err", "UInt16 ascii, UInt16 keycode, UInt16 modifiers"); + + CALLED_GET_PARAM_VAL (UInt16, ascii); + CALLED_GET_PARAM_VAL (UInt16, keycode); + CALLED_GET_PARAM_VAL (UInt16, modifiers); + + LogEvtEnqueueKey (ascii, keycode, modifiers); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::EvtEnqueuePenPoint + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::EvtEnqueuePenPoint (void) +{ + // Err EvtEnqueuePenPoint(PointType* ptP) + + CALLED_SETUP ("Err", "PointType* ptP"); + + CALLED_GET_PARAM_REF (PointType, ptP, Marshal::kInput); + + LogEvtEnqueuePenPoint (*ptP); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::ExgDoDialog + * + * DESCRIPTION: Always accept the beam if we're beaming it in via our + * special ExgMgr "driver". + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::ExgDoDialog (void) +{ + // Boolean ExgDoDialog(ExgSocketPtr socketP, ExgDialogInfoType *infoP, Err *errP) + + CALLED_SETUP ("Boolean", "ExgSocketPtr socketP, ExgDialogInfoType *infoP, Err *errP"); + + CALLED_GET_PARAM_VAL (ExgSocketPtr, socketP); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInOut); + + if (!EmPatchState::GetAutoAcceptBeamDialogs()) + return kExecuteROM; + + if (!socketP) + return kExecuteROM; + + CALLED_PUT_PARAM_REF (errP); + PUT_RESULT_VAL (Boolean, true); + + return kSkipROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::FrmCustomAlert + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +#define replaceBeamAppAlert 2008 +#define beamReplaceErrorAppIsRunning 2012 + +#define replaceBeamAppAlertYesButton 0 + +CallROMType SysHeadpatch::FrmCustomAlert (void) +{ + // UInt16 FrmCustomAlert (UInt16 alertId, const Char* s1, const Char* s2, const Char* s3) + + CALLED_SETUP ("UInt16", "UInt16 alertId, const Char* s1, const Char* s2, const Char* s3"); + + CALLED_GET_PARAM_VAL (UInt16, alertId); + + if (!EmPatchState::GetAutoAcceptBeamDialogs()) + return kExecuteROM; + + // "App already exists, replace it?" + + if (alertId == replaceBeamAppAlert) + { + PUT_RESULT_VAL (UInt16, replaceBeamAppAlertYesButton); + return kSkipROM; + } + + // "App is running. Switch first." + + if (alertId == beamReplaceErrorAppIsRunning) + { + PUT_RESULT_VAL (UInt16, 0); // Can be anything. + return kSkipROM; + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::FrmDrawForm + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::FrmDrawForm (void) +{ + // void FrmDrawForm (const FormPtr frm) + + CALLED_SETUP ("void", "const FormPtr frm"); + + CALLED_GET_PARAM_VAL (FormPtr, frm); + + ::ValidateFormObjects (frm); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::FrmPopupForm + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::FrmPopupForm (void) +{ + // void FrmPopupForm (UInt16 formId) + +// CALLED_SETUP ("void", "UInt16 formId"); + +// CALLED_GET_PARAM_VAL (UInt16, formId); + + EmEventOutput::PoppingUpForm (); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::HostControl + * + * DESCRIPTION: This one's kind of odd. Originally, there was + * SysGremlins, which was declared as follows: + * + * UInt32 SysGremlins(GremlinFunctionType selector, + * GremlinParamsType *params) + * + * Also originally, the only defined selector was + * GremlinIsOn. + * + * Now, SysGremlins is extended to be SysHostControl, + * which allows the Palm environment to access host + * functions if it's actually running under the simulator + * or emulator. + * + * Because of this extension, functions implemented via + * this trap are not limited to pushing a selector and + * parameter block on the stack. Now, they will all push + * on a selector, but what comes after is dependent on the + * selector. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::HostControl (void) +{ + return HandleHostControlCall (); +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::HwrBatteryLevel + * + * DESCRIPTION: Return that the battery is always full. HwrBatteryLevel + * is the bottleneck function called to determine the + * battery level. By patching it this way, we don't have + * to emulate the hardware registers that report the + * battery level. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::HwrBatteryLevel (void) +{ + // On non-328 devices, we emulate the hardware that returns this + // information, so we don't need to patch this function. + + // We don't currently emulate the Prism battery hardware, so we + // allow the patch. Not sure if this is called by the Prism ROM, + // but we patch it to be safe (better than dividing by zero). + + EmAssert (gSession); + + if (!gSession->GetDevice().Supports68328 () && + gSession->GetDevice().HardwareID () != 0x0a /*halModelIDVisorPrism*/) + { + return kExecuteROM; + } + + // UInt16 HwrBatteryLevel(void) + + CALLED_SETUP ("UInt16", "void"); + + PUT_RESULT_VAL (UInt16, 255); // Hardcode a maximum level + + return kSkipROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::HwrBattery + * + * DESCRIPTION: If queried for the battery level, return that the battery + * is always full. This is equivalent to the HwrBatteryLevel + * patch, necessary because some newer devices call HwrBattery + * for this information. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + * History: + * 2000-05-10 Added by Bob Petersen + * + ***********************************************************************/ + +CallROMType SysHeadpatch::HwrBattery (void) +{ + // On non-328 devices, we emulate the hardware that returns this + // information, so we don't need to patch this function. + + // We don't currently emulate the Prism battery hardware, so we + // allow the patch. + + EmAssert (gSession); + + if (!gSession->GetDevice().Supports68328 () && + gSession->GetDevice().HardwareID () != 0x0a /*halModelIDVisorPrism*/) + { + return kExecuteROM; + } + + // Err HwrBattery(UInt16 /* HwrBatterCmdEnum*/ cmd, void * cmdP) + + CALLED_SETUP ("Err", "UInt16 cmd, void * cmdP"); + + CALLED_GET_PARAM_VAL (UInt16, cmd); + + if (cmd == 2 /* hwrBatteryCmdMainRead */) + { + CALLED_GET_PARAM_REF (HwrBatCmdReadType, cmdP, Marshal::kInOut); + + if (gSession->GetDevice().HardwareID () == 0x0a /*halModelIDVisorPrism*/) + { + // MAINTAINER'S NOTE: The following code and comment are pretty + // much what I got from Handspring. The comment says 4.2 volts, + // and the code contains redundant assignments that first assign + // 4.2 volts and then 4.0 volts. I'm just keeping this in case + // they really want it this way for some reason. + + // DOLATER: Battery voltage should differ by battery type. + // 4.2 is returned to handle lithium ion batteries. 'mVolts' + // is the value used by the Prism display, not 'abs'. + (*cmdP).mVolts = 4200; // 4.2 volts + (*cmdP).mVolts = 4000; // 4.0 volts + } + else + { + (*cmdP).mVolts = 2500; // 2.5 volts + } + + (*cmdP).abs = 255; // Hardcode a maximum level + + cmdP.Put (); + + PUT_RESULT_VAL (Err, errNone); + return kSkipROM; + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::HwrDockStatus + * + * DESCRIPTION: Always return hwrDockStatusUsingExternalPower. We + * could fake this out by twiddling the right bits in the + * Dragonball and DragonballEZ emulation units, but those + * bits are different for almost every device. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::HwrDockStatus (void) +{ + // On non-328 devices, we emulate the hardware that returns this + // information, so we don't need to patch this function. + + EmAssert (gSession); + + if (!gSession->GetDevice().Supports68328 ()) + { + return kExecuteROM; + } + + // hwrDockStatusState HwrDockStatus(void) + // + // (added in Palm OS 3.1) + // (changed later to return UInt16) + + CALLED_SETUP ("UInt16", "void"); + + // Old enumerated values from Hardware.h: + // + // DockStatusNotDocked = 0, + // DockStatusInModem, + // DockStatusInCharger, + // DockStatusUnknown = 0xFF + + // New defines from HwrDock.h +#define hwrDockStatusUndocked 0x0000 // nothing is attached +#define hwrDockStatusModemAttached 0x0001 // some type of modem is attached +#define hwrDockStatusDockAttached 0x0002 // some type of dock is attached +#define hwrDockStatusUsingExternalPower 0x0004 // using some type of external power source +#define hwrDockStatusCharging 0x0008 // internal power cells are recharging + + PUT_RESULT_VAL (UInt16, hwrDockStatusUsingExternalPower); + + return kSkipROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::HwrGetROMToken + * + * DESCRIPTION: Patch this guy so that we never return the 'irda' token. + * We should take this out when some sort of IR support is + * added. + * + * NOTE: This patch is useless for diverting the ROM. It + * calls HwrGetROMToken directly, which means that it will + * bypass this patch. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::HwrGetROMToken (void) +{ + // Err HwrGetROMToken (UInt16 cardNo, UInt32 token, UInt8** dataP, UInt16* sizeP) + + CALLED_SETUP ("Err", "UInt16 cardNo, UInt32 token, UInt8** dataP, UInt16* sizeP"); + + CALLED_GET_PARAM_VAL (UInt16, cardNo); + CALLED_GET_PARAM_VAL (UInt32, token); + CALLED_GET_PARAM_REF (UInt8Ptr, dataP, Marshal::kInOut); + CALLED_GET_PARAM_REF (UInt16, sizeP, Marshal::kInOut); + + if (cardNo == 0 && token == hwrROMTokenIrda) + { + if (dataP) + { + *dataP = 0; + dataP.Put (); + } + + if (sizeP) + { + *sizeP = 0; + sizeP.Put (); + } + + PUT_RESULT_VAL (Err, ~0); // token not found. + + return kSkipROM; + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::HwrSleep + * + * DESCRIPTION: Record whether or not we are sleeping and update the + * boolean that determines if low-memory access is OK. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::HwrSleep (void) +{ + // void HwrSleep(Boolean untilReset, Boolean emergency) + + // HwrSleep changes the exception vectors for for the interrupts, + // so temporarily unlock those. We'll re-establish them in the + // HwrSleep tailpatch. + + MetaMemory::MarkTotalAccess (offsetof (M68KExcTableType, busErr), + offsetof (M68KExcTableType, busErr) + sizeof (emuptr)); + + MetaMemory::MarkTotalAccess (offsetof (M68KExcTableType, addressErr), + offsetof (M68KExcTableType, addressErr) + sizeof (emuptr)); + + MetaMemory::MarkTotalAccess (offsetof (M68KExcTableType, illegalInstr), + offsetof (M68KExcTableType, illegalInstr) + sizeof (emuptr)); + + MetaMemory::MarkTotalAccess (offsetof (M68KExcTableType, autoVec1), + offsetof (M68KExcTableType, trapN[0])); + + // On Palm OS 1.0, there was code in HwrSleep that would execute only if + // memory location 0xC2 was set. It looks like debugging code (that is, + // Ron could change it from the debugger to try different things out), + // but we still have to allow access to it. + + if (EmPatchState::OSMajorVersion () == 1) + { + MetaMemory::MarkTotalAccess (0x00C2, 0x00C3); + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::KeyCurrentState + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +// From Roger: +// +// I was thinking a bit more about Gremlins and games yesterday. Games which +// use the buttons as input have been a special case for Gremlins because +// Gremlins only faked events and pen points. Normally games have to fake +// their own button mask, and they get better results if have some buttons +// held down more often than others. +// +// Now I'm thinking different. With Poser, the KeyCurrentState call should +// be stolen when Gremlins is running. All of the keys possible should have +// their button bits on half the time. This will allow users to test games. +// By not tuning how often buttons should be held down, the testing process +// will take longer to excerise all app functionality, but it's better than +// now. App developers can override the default Gremlin values with their +// own for better results. +// +// To successfully test this, A game like SubHunt should play on it's own for +// a least a while. HardBall is an example of a game which would really +// benefit from recognizing Gremlins is running and tune itself to make the +// testing more effective. It should grant infinite balls until after the +// last level is finished. +// +// I actually think this is important enough to be for Acorn because it +// enables users to test a large class of apps which otherwise can't. I +// think it's easy to implement. Basically just have KeyCurrentState return +// the int from the random number generator. Each bit should be on about +// half the time. +// +// Follow-up commentary: it turns out that this patch is not having the +// effect we hoped. SubHunt was so overwhelmed with events from Gremlins +// that it rarely had the chance to call KeyCurrentState. We're thinking +// of Gremlins backing off on posting events if the SysGetEvent sleep time +// is small (i.e., not "forever"), but we'll have to think about the impact +// on other apps first. + +#if 0 +CallROMType SysHeadpatch::KeyCurrentState (void) +{ + // UInt32 KeyCurrentState(void) + + CALLED_SETUP ("UInt32", "void"); + + // Remove this for now. Its current implementation uses the Std C Lib + // random number generator, which is not in sync with the Gremlins RNG. + + if (Hordes::IsOn ()) + { + // Let's try setting each bit 1/4 of the time. + + uint32 bits = rand () & rand (); + + PUT_RESULT_VAL (Uint32, bits); + + return kSkipROM; + } + + return kExecuteROM; +} +#endif + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::PenOpen + * + * DESCRIPTION: This is where the pen calibration information is read. + * Preflight this call to add the calibration information + * to the preferences database if it doesn't exist. That + * way, we don't have to continually calibrate the screen + * when we boot up. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::PenOpen (void) +{ + // Err PenOpen(void) + + ::InstallCalibrationInfo (); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::PrefSetAppPreferences + * + * DESCRIPTION: Change the default proxy server address. If it looks + * like INet is establishing the old proxy server address, + * substitute the current one instead. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::PrefSetAppPreferences (void) +{ + // void PrefSetAppPreferences (UInt32 creator, UInt16 id, Int16 version, + // const void *prefs, UInt16 prefsSize, Boolean saved) + + CALLED_SETUP ("void", "UInt32 creator, UInt16 id, Int16 version, " + "const void *prefs, UInt16 prefsSize, Boolean saved"); + + CALLED_GET_PARAM_VAL (UInt32, creator); + CALLED_GET_PARAM_VAL (emuptr, prefs); + CALLED_GET_PARAM_VAL (UInt16, prefsSize); + CALLED_GET_PARAM_VAL (Boolean, saved); + +#define inetCreator 'inet' + + if ((creator == inetCreator) && saved && (prefsSize >= 3 + 64)) + { + emuptr proxyP = prefs + 3; + + if ((EmMem_strcmp (proxyP, "207.240.80.136") == 0) || + (EmMem_strcmp (proxyP, "209.247.202.106") == 0)) + { + static string currentIPAddress; + + // See if we've looked up the address, yet. + + if (currentIPAddress.empty ()) + { + // If not, get the host information. + + struct hostent* host = gethostbyname ("content-dev.palm.net"); + if (!(host && host->h_addrtype == AF_INET)) + { + host = gethostbyname ("content-dev2.palm.net"); + } + + if (host && host->h_addrtype == AF_INET) + { + // If the address family looks like one we can handle, + // get and use the first one. + + struct in_addr* addr_in = (struct in_addr*) host->h_addr_list[0]; + if (addr_in) + { + char* as_string = inet_ntoa (*addr_in); + currentIPAddress = as_string; + } + } + } + + // If we have the address cached NOW, use it to replace + // the hardcoded addresses. + + if (!currentIPAddress.empty ()) + { + EmMem_strcpy (proxyP, currentIPAddress.c_str ()); + } + } + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SndDoCmd + * + * DESCRIPTION: Intercept calls to the Sound Manager and generate the + * equivalent host commands. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SndDoCmd (void) +{ + Preference<bool> pref (kPrefKeyEnableSounds); + + if (!*pref) + return kExecuteROM; + + // Err SndDoCmd(void * chanP, SndCommandPtr cmdP, Boolean noWait) + + CALLED_SETUP ("Err", "void * chanP, SndCommandPtr cmdP, Boolean noWait"); + + CALLED_GET_PARAM_REF (SndCommandType, cmdP, Marshal::kInput); + + PUT_RESULT_VAL (Err, errNone); // Set default return value + + return Platform::SndDoCmd (*cmdP); +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysAppExit + * + * DESCRIPTION: If the application calling SysAppExit was launched as a + * full application, then "forget" any information we have + * about it. When the next application is launched, we'll + * collect information on it in SysAppStartup. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysAppExit (void) +{ + // Err SysAppExit(SysAppInfoPtr appInfoP, MemPtr prevGlobalsP, MemPtr globalsP) + + CALLED_SETUP ("Err", "SysAppInfoPtr appInfoP, MemPtr prevGlobalsP, MemPtr globalsP"); + + CALLED_GET_PARAM_REF (SysAppInfoType, appInfoP, Marshal::kInput); + + if (appInfoP == NULL) + return kExecuteROM; + + Int16 cmd = (*appInfoP).cmd; + UInt16 memOwnerID = (*appInfoP).memOwnerID; + UInt16 launchFlags = (*appInfoP).launchFlags; + + if (false /*LogLaunchCodes ()*/) + { + emuptr dbP = (emuptr) ((*appInfoP).dbP); + emuptr openP = EmMemGet32 (dbP + offsetof (DmAccessType, openP)); + LocalID dbID = EmMemGet32 (openP + offsetof (DmOpenInfoType, hdrID)); + UInt16 cardNo = EmMemGet16 (openP + offsetof (DmOpenInfoType, cardNo)); + + char name[dmDBNameLength] = {0}; + UInt32 type = 0; + UInt32 creator = 0; + + /* Err err =*/ ::DmDatabaseInfo ( + cardNo, dbID, name, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &type, &creator); + + LogAppendMsg ("SysAppExit called:"); + LogAppendMsg (" cardNo: %ld", (long) cardNo); + LogAppendMsg (" dbID: 0x%08lX", (long) dbID); + LogAppendMsg (" name: %s", name); + LogAppendMsg (" type: %04lX", type); + LogAppendMsg (" creator: %04lX", creator); + } + + if (cmd == sysAppLaunchCmdNormalLaunch) + { + EmuAppInfo appInfo; + EmPatchState::CollectCurrentAppInfo ((emuptr) appInfoP, appInfo); + + if (appInfo.fCardNo == EmPatchState::GetQuitAppCardNo () && appInfo.fDBID == EmPatchState::GetQuitAppDbID ()) + { + EmPatchState::SetTimeToQuit (); + } + } + + // Go through and dispose of any memory chunks allocated by this application. + // <chg 5-8-98 RM> Changed test to: launchFlags & sysAppLaunchFlagNewGlobals + // from rootP==NULL so that it works correcty for sublaunched apps + // that get their own globals. + + if (memOwnerID && (launchFlags & sysAppLaunchFlagNewGlobals)) + { + ::CheckForMemoryLeaks (memOwnerID); + } + + EmPatchState::RemoveCurAppInfo (); // !!! should probably make sure appInfoP matches + // the top guy on the stack. + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysAppLaunch + * + * DESCRIPTION: Log information app launches and action codes. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysAppLaunch (void) +{ + // Err SysAppLaunch(UInt16 cardNo, LocalID dbID, UInt16 launchFlags, + // UInt16 cmd, MemPtr cmdPBP, UInt32* resultP) + + CALLED_SETUP ("Err", "UInt16 cardNo, LocalID dbID, UInt16 launchFlags," + "UInt16 cmd, MemPtr cmdPBP, UInt32* resultP"); + + CALLED_GET_PARAM_VAL (UInt16, cardNo); + CALLED_GET_PARAM_VAL (LocalID, dbID); + CALLED_GET_PARAM_VAL (UInt16, launchFlags); + CALLED_GET_PARAM_VAL (UInt16, cmd); + + if (false /*LogLaunchCodes ()*/) + { + const char* launchStr = ::LaunchCmdToString (cmd); + + char name[dmDBNameLength] = {0}; + UInt32 type = 0; + UInt32 creator = 0; + + /* Err err =*/ ::DmDatabaseInfo ( + cardNo, dbID, name, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &type, &creator); + + LogAppendMsg ("SysAppLaunch called:"); + LogAppendMsg (" cardNo: %ld", (long) cardNo); + LogAppendMsg (" dbID: 0x%08lX", (long) dbID); + LogAppendMsg (" name: %s", name); + LogAppendMsg (" type: %04lX", type); + LogAppendMsg (" creator: %04lX", creator); + LogAppendMsg (" launchFlags: 0x%08lX", (long) launchFlags); + LogAppendMsg (" cmd: %ld (%s)", (long) cmd, launchStr); + +#if 0 + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + // No parameter block + break; + + case sysAppLaunchCmdFind: + { + FindParamsType parms; + + LogAppendMsg (" FindParamsType:"); + LogAppendMsg (" dbAccesMode: %ld", (long) parms.dbAccesMode); + LogAppendMsg (" recordNum: %ld", (long) parms.recordNum); + LogAppendMsg (" more: %ld", (long) parms.more); + LogAppendMsg (" strAsTyped: %ld", (long) parms.strAsTyped); + LogAppendMsg (" strToFind: %ld", (long) parms.strToFind); + LogAppendMsg (" numMatches: %ld", (long) parms.numMatches); + LogAppendMsg (" lineNumber: %ld", (long) parms.lineNumber); + LogAppendMsg (" continuation: %ld", (long) parms.continuation); + LogAppendMsg (" searchedCaller: %ld", (long) parms.searchedCaller); + LogAppendMsg (" callerAppDbID: %ld", (long) parms.callerAppDbID); + LogAppendMsg (" callerAppCardNo: %ld", (long) parms.callerAppCardNo); + LogAppendMsg (" appDbID: %ld", (long) parms.appCardNo); + LogAppendMsg (" newSearch: %ld", (long) parms.newSearch); + LogAppendMsg (" searchState: %ld", (long) parms.searchState); + LogAppendMsg (" match: %ld", (long) parms.match); + + break; + } + + case sysAppLaunchCmdGoTo: + // GoToParamsType + break; + + case sysAppLaunchCmdSyncNotify: + // No parameter block + break; + + case sysAppLaunchCmdTimeChange: + // No parameter block + break; + + case sysAppLaunchCmdSystemReset: + { + // SysAppLaunchCmdSystemResetType + SysAppLaunchCmdSystemResetType parms; + LogAppendMsg (" SysAppLaunchCmdSystemResetType:"); + LogAppendMsg (" hardReset: %s", parms.hardReset ? "TRUE" : "FALSE"); + LogAppendMsg (" createDefaultDB: %s", parms.createDefaultDB ? "TRUE" : "FALSE"); + break; + } + + case sysAppLaunchCmdAlarmTriggered: + // SysAlarmTriggeredParamType + break; + + case sysAppLaunchCmdDisplayAlarm: + // SysDisplayAlarmParamType + break; + + case sysAppLaunchCmdCountryChange: + // Not sent? + break; + + case sysAppLaunchCmdSyncRequestLocal: +// case sysAppLaunchCmdSyncRequest: + // No parameter block (I think...) + break; + + case sysAppLaunchCmdSaveData: + // SysAppLaunchCmdSaveDataType + break; + + case sysAppLaunchCmdInitDatabase: + // SysAppLaunchCmdInitDatabaseType + break; + + case sysAppLaunchCmdSyncCallApplicationV10: + // SysAppLaunchCmdSyncCallApplicationTypeV10 + break; + + case sysAppLaunchCmdPanelCalledFromApp: + // Panel specific? + // SvcCalledFromAppPBType + // NULL + break; + + case sysAppLaunchCmdReturnFromPanel: + // No parameter block + break; + + case sysAppLaunchCmdLookup: + // App-specific (see AppLaunchCmd.h) + break; + + case sysAppLaunchCmdSystemLock: + // No parameter block + break; + + case sysAppLaunchCmdSyncRequestRemote: + // No parameter block (I think...) + break; + + case sysAppLaunchCmdHandleSyncCallApp: + // SysAppLaunchCmdHandleSyncCallAppType + break; + + case sysAppLaunchCmdAddRecord: + // App-specific (see AppLaunchCmd.h) + break; + + case sysSvcLaunchCmdSetServiceID: + // ServiceIDType + break; + + case sysSvcLaunchCmdGetServiceID: + // ServiceIDType + break; + + case sysSvcLaunchCmdGetServiceList: + // serviceListType + break; + + case sysSvcLaunchCmdGetServiceInfo: + // serviceInfoType + break; + + case sysAppLaunchCmdFailedAppNotify: + // SysAppLaunchCmdFailedAppNotifyType + break; + + case sysAppLaunchCmdEventHook: + // EventType + break; + + case sysAppLaunchCmdExgReceiveData: + // ExgSocketType + break; + + case sysAppLaunchCmdExgAskUser: + // ExgAskParamType + break; + + case sysDialLaunchCmdDial: + // DialLaunchCmdDialType + break; + + case sysDialLaunchCmdHangUp: + // DialLaunchCmdDialType + break; + + case sysSvcLaunchCmdGetQuickEditLabel: + // SvcQuickEditLabelInfoType + break; + + case sysAppLaunchCmdURLParams: + // Part of the URL + break; + + case sysAppLaunchCmdNotify: + // SysNotifyParamType + break; + + case sysAppLaunchCmdOpenDB: + // SysAppLaunchCmdOpenDBType + break; + + case sysAppLaunchCmdAntennaUp: + // No parameter block + break; + + case sysAppLaunchCmdGoToURL: + // URL + break; + } +#endif + } + + // Prevent Symbol applications from running. + + if (cmd == sysAppLaunchCmdSystemReset) + { + UInt32 type; + UInt32 creator; + /*Err err =*/ ::DmDatabaseInfo ( + cardNo, dbID, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &type, &creator); + + if (type == sysFileTApplication && + (creator == 'SSRA' || creator == 'SYRA')) + { + PUT_RESULT_VAL (Err, errNone); + return kSkipROM; + } + } + + // Work around a bug in Launcher where it tries to send + // sysAppLaunchCmdSyncNotify to any received files that + // aren't PQAs. This code is pretty much the same as + // the fixed version of Launcher. + + static Bool recursing; + + if (!recursing && cmd == sysAppLaunchCmdSyncNotify && EmPatchState::HasSyncNotifyBug ()) + { + UInt32 type; + UInt32 creator; + Err err = ::DmDatabaseInfo ( + cardNo, dbID, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &type, &creator); + + if (!err) + { + // If it's not an application, then get the application that owns it. + + UInt16 appCardNo = cardNo; + LocalID appDbID = dbID; + + if (type != sysFileTApplication) + { + DmSearchStateType searchState; + + err = ::DmGetNextDatabaseByTypeCreator (true /*new search*/, + &searchState, sysFileTApplication, creator, + true /*latest version*/, &appCardNo, &appDbID); + } + + // If there's an error, pretend that everything went OK. + + if (err) + { + PUT_RESULT_VAL (Err, errNone); + return kSkipROM; + } + + // Otherwise, substitute the new cardNo and dbID for the + // ones on the stack. + + sub.SetParamVal ("cardNo", appCardNo); + sub.SetParamVal ("dbID", appDbID); + } + + // Could not get information on the specified database. + // Pass it off to the ROM as normal. + } + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysBinarySearch + * + * DESCRIPTION: There's a bug in pre-3.0 versions of SysBinarySearch + * that cause it to call the user callback function with a + * pointer just past the array to search. Make a note of + * when we enter SysBinarySearch so that we can make + * allowances for that in MetaMemory's memory checking. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysBinarySearch (void) +{ + EmPatchState::EnterSysBinarySearch (); + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysEvGroupWait + * + * DESCRIPTION: We patch SysEvGroupWait as the mechanism for feeding + * the Palm OS new events. See comments in + * EmPatchState::PuppetString. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysEvGroupWait (void) +{ + // Only do this under 2.0 and later. Under Palm OS 1.0, EvtGetSysEvent + // called SysSemaphoreWait instead. See our headpatch of that function + // for a chunk of pretty similar code. + + if (EmPatchState::OSMajorVersion () == 1) + { + return kExecuteROM; + } + + // Err SysEvGroupWait(UInt32 evID, UInt32 mask, UInt32 value, Int32 matchType, + // Int32 timeout) + + CALLED_SETUP ("Err", "UInt32 evID, UInt32 mask, UInt32 value, Int32 matchType," + "Int32 timeout"); + + CALLED_GET_PARAM_VAL (Int32, timeout); + + CallROMType result; + Bool clearTimeout; + + EmPatchMgr::PuppetString (result, clearTimeout); + + // If timeout is infinite, the kernel wants 0. + // If timeout is none, the kernel wants -1. + + if (clearTimeout && timeout == 0) + { + sub.SetParamVal ("timeout", (Int32) -1); + } + + return result; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysFatalAlert + * + * DESCRIPTION: Intercept this and show the user a dialog. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysFatalAlert (void) +{ + Preference<bool> pref (kPrefKeyInterceptSysFatalAlert); + if (!*pref) + { + // Palm OS will display a dialog with just a Reset button + // in it. So *always* turn off the Gremlin, as the user + // won't be able to select "Continue". + + Hordes::Stop (); + return kExecuteROM; + } + + // UInt16 SysFatalAlert (const Char* msg) + + CALLED_SETUP ("UInt16", "const Char* msg"); + + CALLED_GET_PARAM_STR (Char, msg); + + string msgString; + + if (msg) + { + msgString = string (msg); + } + else + { + msgString = Platform::GetString (kStr_UnknownFatalError); + } + + Errors::ReportErrSysFatalAlert (msgString.c_str ()); + + // On Debug or Reset, an exception will be thrown past this point, + // meaning that we don't have to return fatalEnterDebugger or fatalReset. + // On the psuedo Next Gremlin, Hordes::ErrorEncountered will have been + // called. Otherwise, Continue and Next Gremlin end up coming here, and + // we should return fatalDoNothing. + + PUT_RESULT_VAL (UInt16, fatalDoNothing); + + return kSkipROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysLaunchConsole + * + * DESCRIPTION: Stub this function out so that it doesn't do anything. + * We completely handle the console in DebugMgr, so there's + * no need to get the ROM all heated up. Also, there are + * problems with actually letting the ROM try to launch its + * console task, at least on the Mac. It will try to open + * a serial port socket and do stuff with it. That attempt + * will fail, as much of the serial port processing on the + * Mac is handled at idle time, and idle time processing is + * inhibited when handling debugger packets + * (SysLaunchConsole is usually called by a debugger via + * the RPC packet). Since serial port processing doesn't + * occur, SysLaunchConsole hangs. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysLaunchConsole (void) +{ + // Err SysLaunchConsole(void) + + CALLED_SETUP ("Err", "void"); + + PUT_RESULT_VAL (Err, errNone); + + return kSkipROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysSemaphoreWait + * + * DESCRIPTION: We patch SysSemaphoreWait as the mechanism for feeding + * the Palm OS new events. See comments in + * EmPatchState::PuppetString. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::SysSemaphoreWait (void) +{ + // Only do this under 1.0. Under Palm OS 2.0 and later, EvtGetSysEvent + // calls SysEvGroupWait instead. See our headpatch of that function + // for a chunk of pretty similar code. + + if (EmPatchState::OSMajorVersion () != 1) + { + return kExecuteROM; + } + + // Err SysSemaphoreWait(UInt32 smID, UInt32 priority, Int32 timeout) + + CALLED_SETUP ("Err", "UInt32 smID, UInt32 priority, Int32 timeout"); + + CALLED_GET_PARAM_VAL (Int32, timeout); + + CallROMType result; + Bool clearTimeout; + + EmPatchMgr::PuppetString (result, clearTimeout); + + // If timeout is infinite, the kernel wants 0. + // If timeout is none, the kernel wants -1. + + if (clearTimeout && timeout == 0) + { + sub.SetParamVal ("timeout", (Int32) -1); + } + + return result; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::SysUIAppSwitch + * + * DESCRIPTION: SysUIAppSwitch is called from the following locations + * for the given reasons. When running Gremlins, we want + * to prevent SysUIAppSwitch from doing its job, which is + * to record information about the application to switch + * to and to then post an appStopEvent to the current + * application. + * + * There are a couple of places where SysUIAppSwitch is + * called to quit and re-run the current application. + * Therefore, we want to stub out SysUIAppSwitch only when + * the application being switched to is not the currently + * running application. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +// Places where this is called: +// +// - LauncherMain.c (AppsViewSwitchApp) to launch new app. +// - PrefApp (PilotMain) to launch a panel. +// - SyncApp (prvLaunchExternalModule) to launch a "service owner" +// - AppLaunchCmd.h (AppLaunchWithCommand) ??? +// - ModemPanel.h (ModemPanelLaunch) ??? +// - callApp.h (LaunchApp) ??? +// - ExgMgr.c (ExgNotifyReceive) to send a sysAppLaunchCmdGoTo message. +// - GraffitiGlue.c (PrvLaunchGraffitiDemo) to launch Graffiti demo. +// - Keyboard.c (PrvLaunchGraffitiDemo) to launch Graffiti demo. +// - Launcher.c (LauncherFormHandleEvent) handles taps on launcher icons. +// - SystemMgr.c (SysHandleEvent) to send sysAppLaunchCmdSystemLock +// in response to seeing a lockChr keyboard message. +// - SystemMgr.c (SysHandleEvent) to switch apps in response to hard#Chr +// keyboard messages. +// - Find.c (Find) to send sysAppLaunchCmdGoTo message. +// +// - ButtonsPanel.c (ButtonsFormHandleEvent) switch to another panel. +// - FormatsPanel.c (FormatsFormHandleEvent) switch to another panel. +// - GeneralPanel.c (GeneralFormHandleEvent) switch to another panel. +// - ModemPanel.c (ModemFormHandleEvent) switch to another panel. +// - NetworkPanel.c (NetworkFormHandleEvent) switch to another panel. +// - OwnerPanel.c (OwnerViewHandleEvent) switch to another panel. +// - ShortCutsPanel.c (ShortCutFormHandleEvent) switch to another panel. + +CallROMType SysHeadpatch::SysUIAppSwitch (void) +{ + // Err SysUIAppSwitch(UInt16 cardNo, LocalID dbID, UInt16 cmd, MemPtr cmdPBP) + + CALLED_SETUP ("Err", "UInt16 cardNo, LocalID dbID, UInt16 cmd, MemPtr cmdPBP"); + + CALLED_GET_PARAM_VAL (UInt16, cardNo); + CALLED_GET_PARAM_VAL (LocalID, dbID); + CALLED_GET_PARAM_VAL (MemPtr, cmdPBP); + + if (false /*LogLaunchCodes ()*/) + { + char name[dmDBNameLength] = {0}; + UInt32 type = 0; + UInt32 creator = 0; + + /* Err err =*/ ::DmDatabaseInfo ( + cardNo, dbID, name, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &type, &creator); + + LogAppendMsg ("SysUIAppSwitch called:"); + LogAppendMsg (" cardNo: %ld", (long) cardNo); + LogAppendMsg (" dbID: 0x%08lX", (long) dbID); + LogAppendMsg (" name: %s", name); + LogAppendMsg (" type: %04lX", type); + LogAppendMsg (" creator: %04lX", creator); + } + + // We are headpatching SysUIAppSwitch; if we skip the ROM version, we + // need to replicate at least this part of its functionality: + // + // If the last launch attempt failed, release the command parameter block, if + // any. When a launch succeeds, the UIAppShell will clear this global + // and free the chunk itself when the app quits. + { + CEnableFullAccess munge; // Remove blocks on memory access. + emuptr nextUIAppCmdPBP = EmLowMem_GetGlobal (nextUIAppCmdPBP); + if (nextUIAppCmdPBP) + { + MemPtrFree((MemPtr) nextUIAppCmdPBP); + EmLowMem_SetGlobal (nextUIAppCmdPBP, 0); + } + } + + // Get the current application card and db. If we are attempting to switch + // to the same app, allow it. + + UInt16 currentCardNo; + LocalID currentDbID; + Err err = SysCurAppDatabase (¤tCardNo, ¤tDbID); + + // Got an error? Give up and let default handling occur. + + if (err != 0) + return kExecuteROM; + + // Switching to current app; let default handling occur. + + if ((cardNo == currentCardNo) && (dbID == currentDbID)) + return kExecuteROM; + + // OK, we're switching to a different application. If Gremlins is running + // and we're trying to switch to an application that's not on its list, + // then stub out SysUIAppSwitch to do nothing. + + if ((Hordes::IsOn () || EmEventPlayback::ReplayingEvents ()) && + !Hordes::CanSwitchToApp (cardNo, dbID)) + { + // Store the incoming parameter block in nextUIAppCmdPBP, just + // like the real version would. This way, it will get cleaned + // up by the code above, or by the return code in UIAppShell, or + // by the real SysUIAppSwitch, or whatever. By not freeing it + // now, we preserve compatibility with any application that + // expects the block to stay around for a while. + + // CEnableFullAccess munge; // Remove blocks on memory access. + // EmLowMem_SetGlobal (nextUIAppCmdPBP, (MemPtr) cmdPBP); + + // Actually, let's not take that approach. It looks to me that + // it could lead to problems in UIAppShell. When SysAppLaunch + // returns, UIAppShell will try to free the block that previously + // was in nextUIAppCmdPBP, which it had saved in a local variable. + // So let's examing the following: UIAppShell launches an application, + // saving the parameter block. The next application tries calling + // SysUIAppSwitch with a parameter block. We save that parameter + // block in nextUIAppCmdPBP and then keep the application running. + // Then the application decides to quit for whatever reason. + // UIAppShell will free any parameter it originally used to free + // the application. It then notices that the application just up + // and quit, and so tries launching some default application (usually + // the previous application). However, in doing so, one of two + // things can happen. (1) nextUIAppCmdPBP is set to NULL by UIAppShell + // without first deleting any contents. (2) The next application + // is launched with its parameter block set to whatever is left over + // in nextUIAppCmdPBP, which is now the parameter block to the application + // we earlier prevented from running. + // + // Neither of those is correct, so let's see if we can just dump + // the block now, and hope that no applications complain. + + MemPtr p = (MemPtr) cmdPBP; + if (p) + { + MemPtrFree (p); + } + + PUT_RESULT_VAL (Err, errNone); + return kSkipROM; + } + + // Do the normal app switch. + + return kExecuteROM; +} + + +/*********************************************************************** + * + * FUNCTION: SysHeadpatch::TblHandleEvent + * + * DESCRIPTION: See comments in SysTailpatch::TblHandleEvent. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +CallROMType SysHeadpatch::TblHandleEvent (void) +{ + if (EmPatchState::HasSelectItemBug ()) + { + gSaveDrawStateStackLevel = ::PrvGetDrawStateStackLevel (); + } + + return kExecuteROM; +} + + +#pragma mark - + +// =========================================================================== +// ¥ SysTailpatch +// =========================================================================== + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::MarkUIObjects + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::MarkUIObjects (void) +{ + MetaMemory::MarkUIObjects (); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::BmpCreate + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::BmpCreate (void) +{ + // BitmapType *BmpCreate (Coord width, Coord height, UInt8 depth, + // ColorTableType *colortableP, UInt16 *error) + + CALLED_SETUP ("BitmapType*", "Coord width, Coord height, UInt8 depth" + "ColorTableType *colortableP, UInt16 *error"); + + GET_RESULT_PTR (); + + MetaMemory::RegisterBitmapPointer ((MemPtr) result); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::BmpDelete + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::BmpDelete (void) +{ + // Err BmpDelete (BitmapType *bitmapP) + + CALLED_SETUP ("Err", "BitmapType *bitmapP"); + + CALLED_GET_PARAM_VAL (MemPtr, bitmapP); + + MetaMemory::UnregisterBitmapPointer (bitmapP); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::ClipboardAddItem + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::ClipboardAddItem (void) +{ + if (!Hordes::IsOn () && !gDontPatchClipboardAddItem) + { + ::PrvCopyPalmClipboardToHost (); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::ClipboardAppendItem + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::ClipboardAppendItem (void) +{ + if (!Hordes::IsOn () && !gDontPatchClipboardAddItem) + { + ::PrvCopyPalmClipboardToHost (); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::DmGet1Resource + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::DmGet1Resource (void) +{ + // MemHandle DmGet1Resource (DmResType type, DmResID id) + + CALLED_SETUP ("MemHandle", "DmResType type, DmResID id"); + + CALLED_GET_PARAM_VAL (DmResType, type); +// CALLED_GET_PARAM_VAL (DmResID, id); + +#define iconType 'tAIB' +#define bitmapRsc 'Tbmp' + + if (type == iconType || type == bitmapRsc) + { + GET_RESULT_PTR (); + MetaMemory::RegisterBitmapHandle ((MemHandle) result); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::DmGetResource + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::DmGetResource (void) +{ + // MemHandle DmGetResource (DmResType type, DmResID id) + + CALLED_SETUP ("MemHandle", "DmResType type, DmResID id"); + + CALLED_GET_PARAM_VAL (DmResType, type); +// CALLED_GET_PARAM_VAL (DmResID, id); + + if (type == iconType || type == bitmapRsc) + { + GET_RESULT_PTR (); + MetaMemory::RegisterBitmapHandle ((MemHandle) result); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::EvtGetEvent + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::EvtGetEvent (void) +{ + // void EvtGetEvent(const EventPtr eventP, Int32 timeout); + + CALLED_SETUP ("void", "const EventPtr eventP, Int32 timeout"); + + CALLED_GET_PARAM_REF (EventType, eventP, Marshal::kInput); + CALLED_GET_PARAM_VAL (Int32, timeout); + + LogEvtGetEvent (*eventP, timeout); + + EmPatchState::SetEvtGetEventCalled (true); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::EvtGetPen + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::EvtGetPen (void) +{ + // void EvtGetPen(Int16 *pScreenX, Int16 *pScreenY, Boolean *pPenDown) + + CALLED_SETUP ("void", "Int16 *pScreenX, Int16 *pScreenY, Boolean *pPenDown"); + + CALLED_GET_PARAM_REF (Int16, pScreenX, Marshal::kInput); + CALLED_GET_PARAM_REF (Int16, pScreenY, Marshal::kInput); + CALLED_GET_PARAM_REF (Boolean, pPenDown, Marshal::kInput); + + LogEvtGetPen (*pScreenX, *pScreenY, *pPenDown); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::EvtGetSysEvent + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::EvtGetSysEvent (void) +{ + // void EvtGetSysEvent(EventPtr eventP, Int32 timeout) + + CALLED_SETUP ("void", "EventPtr eventP, Int32 timeout"); + + CALLED_GET_PARAM_REF (EventType, eventP, Marshal::kInput); + CALLED_GET_PARAM_VAL (Int32, timeout); + + LogEvtGetSysEvent (*eventP, timeout); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::EvtSysEventAvail + * + * DESCRIPTION: If there are no pending events in the real system, + * check to see if we have any pen events to insert. + * Set the function's return value to TRUE if so. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::EvtSysEventAvail (void) +{ + // Boolean EvtSysEventAvail(Boolean ignorePenUps) + + CALLED_SETUP ("Boolean", "Boolean ignorePenUps"); + + CALLED_GET_PARAM_VAL (Boolean, ignorePenUps); + GET_RESULT_VAL (Boolean); + + if (result == 0) + { + EmAssert (gSession); + if (gSession->HasPenEvent ()) + { + EmPenEvent event = gSession->PeekPenEvent (); + + if (event.fPenIsDown || !ignorePenUps) + { + PUT_RESULT_VAL (Boolean, true); + } + } + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::ExgReceive + * + * DESCRIPTION: Log Exchange Manager data. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::ExgReceive (void) +{ + // UInt32 ExgReceive (ExgSocketPtr exgSocketP, void* bufP, const UInt32 bufLen, Err* errP) + + CALLED_SETUP ("UInt32", "ExgSocketPtr exgSocketP, void* bufP, const UInt32 bufLen, Err* errP"); + + CALLED_GET_PARAM_VAL (UInt32, bufLen); + CALLED_GET_PARAM_PTR (void, bufP, bufLen, Marshal::kInput); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + GET_RESULT_VAL (UInt32); + + if (LogExgMgr ()) + { + LogAppendMsg ("ExgMgr: received %ld bytes, err = 0x%04X.", result, *errP); + } + else if (LogExgMgrData ()) + { + LogAppendData ((void*) bufP, bufLen, "ExgMgr: received %ld bytes, err = 0x%04X.", result, *errP); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::ExgSend + * + * DESCRIPTION: Log Exchange Manager data. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::ExgSend (void) +{ + // UInt32 ExgSend (ExgSocketPtr exgSocketP, void* bufP, const UInt32 bufLen, Err* errP) = 0; + + CALLED_SETUP ("UInt32", "ExgSocketPtr exgSocketP, void* bufP, const UInt32 bufLen, Err* errP"); + + CALLED_GET_PARAM_VAL (UInt32, bufLen); + CALLED_GET_PARAM_PTR (void, bufP, bufLen, Marshal::kInput); + CALLED_GET_PARAM_REF (Err, errP, Marshal::kInput); + GET_RESULT_VAL (UInt32); + + if (LogExgMgr ()) + { + LogAppendMsg ("ExgMgr: sent %ld bytes, err = 0x%04X.", result, *errP); + } + else if (LogExgMgrData ()) + { + LogAppendData ((void*) bufP, bufLen, "ExgMgr: sent %ld bytes, err = 0x%04X.", result, *errP); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::FtrInit + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::FtrInit (void) +{ + // void FtrInit(void) + + // Get information about the current OS so that we know + // what features are implemented (for those cases when we + // can't make other tests, like above where we test for + // the existance of a trap before calling it). + + // Read the version into a local variable; the ROM Stub facility + // automatically maps local variables into Palm space so that ROM + // functions can get to them. If we were to pass &gOSVersion, + // the DummyBank functions would complain about an invalid address. + + UInt32 value; + Err err = ::FtrGet (sysFtrCreator, sysFtrNumROMVersion, &value); + + if (err == errNone) + { + EmPatchState::SetOSVersion(value); + } + else + { + EmPatchState::SetOSVersion(kOSUndeterminedVersion); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::FtrSet + * + * DESCRIPTION: Look for calls indicating that we're running a + * non-Roman system + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::FtrSet (void) +{ + // Err FtrSet (UInt32 creator, UInt16 featureNum, UInt32 newValue) + + CALLED_SETUP ("Err", "UInt32 creator, UInt16 featureNum, UInt32 newValue"); + + CALLED_GET_PARAM_VAL (UInt32, creator); + CALLED_GET_PARAM_VAL (UInt16, featureNum); + CALLED_GET_PARAM_VAL (UInt32, newValue); + GET_RESULT_VAL (Err); + + // Look for calls indicating that we're running a non-Roman system. + + if (result == errNone) + { + if (creator == sysFtrCreator && featureNum == sysFtrNumEncoding) + { + EmPatchState::SetEncoding (newValue); + } + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::HwrMemReadable + * + * DESCRIPTION: Patch this function so that it returns non-zero if the + * address is in the range of memory that we've mapped in + * to emulated space. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::HwrMemReadable (void) +{ + // UInt32 HwrMemReadable(MemPtr address) + + CALLED_SETUP ("UInt32", "MemPtr address"); + + CALLED_GET_PARAM_VAL (emuptr, address); + GET_RESULT_VAL (UInt32); + + if (result == 0) + { + void* addrStart; + uint32 addrLen; + + Memory::GetMappingInfo (address, &addrStart, &addrLen); + + PUT_RESULT_VAL (UInt32, addrLen); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::HwrSleep + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::HwrSleep (void) +{ + // void HwrSleep(Boolean untilReset, Boolean emergency) + + MetaMemory::MarkLowMemory (offsetof (M68KExcTableType, busErr), + offsetof (M68KExcTableType, busErr) + sizeof (emuptr)); + + MetaMemory::MarkLowMemory (offsetof (M68KExcTableType, addressErr), + offsetof (M68KExcTableType, addressErr) + sizeof (emuptr)); + + MetaMemory::MarkLowMemory (offsetof (M68KExcTableType, illegalInstr), + offsetof (M68KExcTableType, illegalInstr) + sizeof (emuptr)); + + MetaMemory::MarkLowMemory (offsetof (M68KExcTableType, autoVec1), + offsetof (M68KExcTableType, trapN[0])); + + // On Palm OS 1.0, there was code in HwrSleep that would execute only if + // memory location 0xC2 was set. It looks like debugging code (that is, + // Ron could change it from the debugger to try different things out), + // but we still have to allow access to it. + + if (EmPatchState::OSMajorVersion () == 1) + { + MetaMemory::MarkLowMemory (0x00C2, 0x00C3); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::SysAppStartup + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::SysAppStartup (void) +{ + // Err SysAppStartup(SysAppInfoPtr* appInfoPP, MemPtr* prevGlobalsP, MemPtr* globalsPtrP) + + CALLED_SETUP ("Err", "SysAppInfoPtr* appInfoPP, MemPtr* prevGlobalsP, MemPtr* globalsPtrP"); + + CALLED_GET_PARAM_REF (SysAppInfoPtr, appInfoPP, Marshal::kInput); + GET_RESULT_VAL (Err); + + if (result != errNone) + return; + + if (appInfoPP == EmMemNULL) + return; + + emuptr appInfoP = EmMemGet32 (appInfoPP); + if (!appInfoP) + return; + + if (false /*LogLaunchCodes ()*/) + { + emuptr dbP = EmMemGet32 (appInfoP + offsetof (SysAppInfoType, dbP)); + emuptr openP = EmMemGet32 (dbP + offsetof (DmAccessType, openP)); + LocalID dbID = EmMemGet32 (openP + offsetof (DmOpenInfoType, hdrID)); + UInt16 cardNo = EmMemGet16 (openP + offsetof (DmOpenInfoType, cardNo)); + + char name[dmDBNameLength] = {0}; + UInt32 type = 0; + UInt32 creator = 0; + + /* Err err =*/ ::DmDatabaseInfo ( + cardNo, dbID, name, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &type, &creator); + + LogAppendMsg ("SysAppStartup called:"); + LogAppendMsg (" cardNo: %ld", (long) cardNo); + LogAppendMsg (" dbID: 0x%08lX", (long) dbID); + LogAppendMsg (" name: %s", name); + LogAppendMsg (" type: %04lX", type); + LogAppendMsg (" creator: %04lX", creator); + } + + Int16 cmd = EmMemGet16 (appInfoP + offsetof (SysAppInfoType, cmd)); + + EmuAppInfo newAppInfo; + EmPatchState::CollectCurrentAppInfo (appInfoP, newAppInfo); + + newAppInfo.fCmd = cmd; + EmPatchState::AddAppInfo(newAppInfo); + + if (cmd == sysAppLaunchCmdNormalLaunch) + { + // Clear the flags that tell us which warnings we've already issued. + // We reset these flags any time a new application is launched. + // + // !!! Put these flags into EmuAppInfo? That way, we can keep + // separate sets for sub-launched applications. + +// Errors::ClearWarningFlags (); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::SysBinarySearch + * + * DESCRIPTION: There's a bug in pre-3.0 versions of SysBinarySearch + * that cause it to call the user callback function with a + * pointer just past the array to search. Make a note of + * when we enter SysBinarySearch so that we can make + * allowances for that in MetaMemory's memory checking. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::SysBinarySearch (void) +{ + EmPatchState::ExitSysBinarySearch (); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::SysTaskCreate + * + * DESCRIPTION: Track calls to SysTaskCreate to get information on any + * stacks created. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::SysTaskCreate (void) +{ + // Err SysTaskCreate(UInt32 * taskIDP, UInt32 * creator, ProcPtr codeP, + // MemPtr stackP, UInt32 stackSize, UInt32 attr, UInt32 priority, + // UInt32 tSlice) + + CALLED_SETUP ("Err", "UInt32 * taskIDP, UInt32 * creator, ProcPtr codeP," + "MemPtr stackP, UInt32 stackSize, UInt32 attr, UInt32 priority," + "UInt32 tSlice"); + + CALLED_GET_PARAM_VAL (emuptr, stackP); + CALLED_GET_PARAM_VAL (UInt32, stackSize); + GET_RESULT_VAL (Err); + + if (result == errNone) + { + StackRange range (stackP, stackP + stackSize); + EmPalmOS::RememberStackRange (range); + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::TblHandleEvent + * + * DESCRIPTION: There's a bug in a private Table Manager function called + * SelectItem (that's the name of the function, not the + * bug). Under certain circumstances, the function will + * exit early without popping the draw state that it pushed + * onto the stack at the start of the function. This + * tailpatch remedies that problem. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::TblHandleEvent (void) +{ + if (EmPatchState::HasSelectItemBug ()) + { + long curDrawStateStackLevel = ::PrvGetDrawStateStackLevel (); + long levelDelta = curDrawStateStackLevel - gSaveDrawStateStackLevel; + + if (levelDelta == 1) + { + WinPopDrawState (); + } + } +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::TimInit + * + * DESCRIPTION: TimInit is where a special boolean is set to trigger a + * bunch of RTC bug workarounds in the ROM (that is, there + * are RTC bugs in the Dragonball that the ROM needs to + * workaround). We're not emulating those bugs, so turn + * off that boolean. Otherwise, we'd have to add support + * for the 1-second, 1-minute, and 1-day RTC interrupts in + * order to get those workarounds to work. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::TimInit (void) +{ + // Err TimInit(void) + + // Turn off the RTC bug workaround flag. + + CEnableFullAccess munge; + + emuptr timGlobalsP = EmLowMem_GetGlobal (timGlobalsP); + EmAliasTimGlobalsType<PAS> timGlobals (timGlobalsP); + + if (timGlobals.rtcBugWorkaround == 0x01) + { + timGlobals.rtcBugWorkaround = 0; + } + + // Set the current date. + + ::PrvSetCurrentDate (); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::UIInitialize + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::UIInitialize (void) +{ + // Void UIInitialize (void) + + EmPatchState::SetUIInitialized (true); + + // Reconfirm the strict intl checks setting, whether on or off. + + Preference<Bool> intlPref (kPrefKeyReportStrictIntlChecks); + + if (EmPatchMgr::IntlMgrAvailable ()) + { + ::IntlSetStrictChecks (*intlPref); + } + + // Reconfirm the overlay checks setting, whether on or off. + + Preference<Bool> overlayPref (kPrefKeyReportOverlayErrors); + (void) ::FtrSet (omFtrCreator, omFtrShowErrorsFlag, *overlayPref); + + // Prevent the device from going to sleep. + + ::SysSetAutoOffTime (0); + + // Can't call PrefSetPreference on 1.0 devices.... + + if (EmLowMem::TrapExists (sysTrapPrefSetPreference)) + { + ::PrefSetPreference (prefAutoOffDuration, 0); + } + + // Install a 'pose' feature so that people can tell if they're running + // under the emulator or not. We *had* added a HostControl function + // for this, but people can call that only under Poser or under 3.0 + // and later ROMs. Which means that there's no way to tell under 2.0 + // and earlier ROMs when running on an actual device. + // + // Note that we do this here instead of in a tailpatch to FtrInit because + // of a goofy inter-dependency. FtrInit is called early in the boot process + // before a valid stack has been allocated and switched to. During this time, + // the ROM is using a range of memory that happens to reside in a free + // memory chunk. Routines in MetaMemory know about this and allow the use + // of this unallocate range of memory. However, in order to work, they need + // to know the current stack pointer value. If we were to call FtrSet from + // the FtrInit tailpatch, the stack pointer will point to the stack set up + // by the ATrap object, not the faux stack in use at the time of FtrInit. + // Thus, the MetaMemory routines get confused and end up getting in a state + // where accesses to the temporary OS stack are flagged as invalid. Hence, + // we defer adding these Features until much later in the boot process (here). + + ::FtrSet ('pose', 0, 0); + + // If we're listening on a socket, install the 'gdbS' feature. The + // existance of this feature causes programs written with the prc tools + // to enter the debugger when they're launched. + + if (Debug::ConnectedToTCPDebugger ()) + { + ::FtrSet ('gdbS', 0, 0x12BEEF34); + } + + // Install the HotSync user-name. + + Preference<string> userName (kPrefKeyUserName); + ::SetHotSyncUserName (userName->c_str ()); + + // Auto-load any files in the Autoload[Foo] directories. + + ::PrvAutoload (); + + // Install our ExgMgr driver + + // Don't do this for now. We don't currently use it, and people get + // confused seeing it show up in application lists, etc. + +// EmFileImport::InstallExgMgrLib (); +} + + +/*********************************************************************** + * + * FUNCTION: SysTailpatch::UIReset + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void SysTailpatch::UIReset (void) +{ + // Void UIReset (void) + + EmPatchState::SetUIReset (true); +} + + +#pragma mark - + + +/*********************************************************************** + * + * FUNCTION: PrvAutoload + * + * DESCRIPTION: Install the files in the various Autoload directories. + * If there are any designated to be run, pick on to run. + * If the emulator should exit when the picked application + * quits, schedule it to do so. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +void PrvAutoload (void) +{ + // Load all the files in one blow. + + EmFileRefList fileList; + Startup::GetAutoLoads (fileList); + + vector<LocalID> idList; + EmFileImport::LoadPalmFileList (fileList, kMethodHomebrew, idList); + + // Get the application to switch to (if any); + + string appToRun = Startup::GetAutoRunApp (); + + if (!appToRun.empty()) + { + char name[dmDBNameLength]; + strcpy (name, appToRun.c_str()); + + UInt16 cardNo = 0; + LocalID dbID = ::DmFindDatabase (cardNo, name); + + if (dbID != 0) + { + EmPatchState::SetSwitchApp (cardNo, dbID); + + // If we're supposed to quit after running this application, + // start that process in motion. + + if (Startup::QuitOnExit ()) + { + EmPatchState::SetQuitApp (cardNo, dbID); + } + } + } +} + + +/*********************************************************************** + * + * FUNCTION: PrvSetCurrentDate + * + * DESCRIPTION: . + * + * PARAMETERS: None. + * + * RETURNED: Nothing. + * + ***********************************************************************/ + +void PrvSetCurrentDate (void) +{ + CEnableFullAccess munge; + + // Get the current date. + + long year, month, day; + ::GetHostDate (&year, &month, &day); + + // Convert it to days -- and then hourse -- since 1/1/1904 + + UInt32 rtcHours = ::DateToDays (year, month, day) * 24; + + // Update the "hours adjustment" value to contain the current date. + + emuptr timGlobalsP = EmLowMem_GetGlobal (timGlobalsP); + EmAliasTimGlobalsType<PAS> timGlobals (timGlobalsP); + + timGlobals.rtcHours = rtcHours; +} + + +/*********************************************************************** + * + * FUNCTION: PrvGetDrawStateStackLevel + * + * DESCRIPTION: . + * + * PARAMETERS: None. + * + * RETURNED: Nothing. + * + ***********************************************************************/ + +long PrvGetDrawStateStackLevel (void) +{ + CEnableFullAccess munge; + UInt16 level = EmLowMem_GetGlobal (uiGlobals.gStateV3.drawStateIndex); + return level; +} + + +/*********************************************************************** + * + * FUNCTION: PrvCopyPalmClipboardToHost + * + * DESCRIPTION: . + * + * PARAMETERS: None. + * + * RETURNED: Nothing. + * + ***********************************************************************/ + +void PrvCopyPalmClipboardToHost (void) +{ + gDontPatchClipboardGetItem = true; + + UInt16 length; + MemHandle dataHdl = ::ClipboardGetItem (clipboardText, &length); + + gDontPatchClipboardGetItem = false; + + if (length > 0) + { + MemPtr dataPtr = ::MemHandleLock (dataHdl); + if (dataPtr) + { + void* dataCopy = Platform::AllocateMemory (length); + if (dataCopy) + { + EmMem_memcpy (dataCopy, (emuptr) dataPtr, length); + + ByteList palmChars; + ByteList hostChars; + char* charData = (char*) dataCopy; + + copy (charData, charData + length, back_inserter (palmChars)); + + Platform::CopyToClipboard (palmChars, hostChars); + Platform::DisposeMemory (dataCopy); + } + + ::MemHandleUnlock (dataHdl); + } + } + else + { + ByteList palmChars; + ByteList hostChars; + + Platform::CopyToClipboard (palmChars, hostChars); + } +} + + +/*********************************************************************** + * + * FUNCTION: PrvCopyHostClipboardToPalm + * + * DESCRIPTION: . + * + * PARAMETERS: None. + * + * RETURNED: Nothing. + * + ***********************************************************************/ + +void PrvCopyHostClipboardToPalm (void) +{ + ByteList palmChars; + ByteList hostChars; + + Platform::CopyFromClipboard (palmChars, hostChars); + + gDontPatchClipboardAddItem = true; + + if (palmChars.size () > 0) + { + // Limit us to cbdMaxTextLength characters so as to not + // overburden the dynamic heap. This is the same limit used by + // the Field Manager does when calling ClipboardAddItem (except + // that the Field Manager puts up a dialog saying that it won't + // copy the text to the clipboard instead of truncating). + + if (palmChars.size () > cbdMaxTextLength) + { + palmChars.resize (cbdMaxTextLength); + } + + // Set the Palm OS clipboard to the text data. + + ::ClipboardAddItem (clipboardText, &palmChars[0], palmChars.size ()); + } + else + { + ::ClipboardAddItem (clipboardText, NULL, 0); + } + + gDontPatchClipboardAddItem = false; +} diff --git a/SrcShared/Patches/EmPatchModuleSys.h b/SrcShared/Patches/EmPatchModuleSys.h new file mode 100644 index 0000000..dc59a03 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleSys.h @@ -0,0 +1,271 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchModuleSys_h +#define EmPatchModuleSys_h + +#include "EmPatchModule.h" + +class EmPatchModuleSys : public EmPatchModule +{ + public: + EmPatchModuleSys(); + virtual ~EmPatchModuleSys() {} +}; + + +// ====================================================================== +// PatchModule for system functions. +// ====================================================================== + +class SysHeadpatch +{ + public: + static CallROMType UnmarkUIObjects (void); // CtlNewControl, FldNewField, FrmInitForm, FrmNewBitmap, FrmNewGadget, FrmNewGsi, FrmNewLabel, LstNewList, WinAddWindow, WinRemoveWindow + static CallROMType RecordTrapNumber (void); // EvtGetEvent & EvtGetPen + + static CallROMType ClipboardGetItem (void); + static CallROMType DbgMessage (void); + static CallROMType DmCloseDatabase (void); + static CallROMType DmInit (void); + static CallROMType ErrDisplayFileLineMsg (void); + static CallROMType EvtAddEventToQueue (void); + static CallROMType EvtAddUniqueEventToQueue(void); + static CallROMType EvtEnqueueKey (void); + static CallROMType EvtEnqueuePenPoint (void); + static CallROMType ExgDoDialog (void); + static CallROMType FrmCustomAlert (void); + static CallROMType FrmDrawForm (void); + static CallROMType FrmPopupForm (void); + static CallROMType HostControl (void); + static CallROMType HwrBatteryLevel (void); + static CallROMType HwrBattery (void); + static CallROMType HwrDockStatus (void); + static CallROMType HwrGetROMToken (void); + static CallROMType HwrSleep (void); + static CallROMType PenOpen (void); + static CallROMType PrefSetAppPreferences (void); + static CallROMType SndDoCmd (void); + static CallROMType SysAppExit (void); + static CallROMType SysAppLaunch (void); + static CallROMType SysBinarySearch (void); + static CallROMType SysEvGroupWait (void); + static CallROMType SysFatalAlert (void); + static CallROMType SysLaunchConsole (void); + static CallROMType SysSemaphoreWait (void); + static CallROMType SysUIAppSwitch (void); + static CallROMType TblHandleEvent (void); +}; + +class SysTailpatch +{ + public: + static void MarkUIObjects (void); // CtlNewControl, FldNewField, FrmInitForm, FrmNewBitmap, FrmNewGadget, FrmNewGsi, FrmNewLabel, LstNewList, WinAddWindow, WinRemoveWindow + + static void BmpCreate (void); + static void BmpDelete (void); + static void ClipboardAddItem (void); + static void ClipboardAppendItem (void); + static void DmGet1Resource (void); + static void DmGetResource (void); + static void EvtGetEvent (void); + static void EvtGetPen (void); + static void EvtGetSysEvent (void); + static void EvtSysEventAvail (void); + static void ExgReceive (void); + static void ExgSend (void); + static void FtrInit (void); + static void FtrSet (void); + static void HwrMemReadable (void); + static void HwrSleep (void); + static void SysAppStartup (void); + static void SysBinarySearch (void); + static void SysTaskCreate (void); + static void TblHandleEvent (void); + static void TimInit (void); + static void UIInitialize (void); + static void UIReset (void); +}; + + + + + +/* =========================================================================== + The following macros are used to help us generate patches to all the + Memory Manager functions. We patch the entire Memory Manager in order + to track when we are "in" the Memory Manager. We want to know this so + that we can extend special privileges to the Memory Manager when it + accesses memory; the Memory Manager can touch more of RAM than any other + executing code. + + Since our patches mostly just increment and decrement a counter, most of + them are generated automatically with macros. I call these "simple" + head- and tailpatches. However, we patch a few other the other Memory + Manager functions for other reasons. We can't let the macros generate + simple patches for these functions and instead have to write them + ourselves, making sure to perform the same incrementing and decrementing + the simple functions would do. I call these patches "complex" head- and + tailpatches. + + Therefore, there are four "categories" of patchings: functions for which + we want simple head- and tailpatches, functions for which we have a + complex headpatch but need a simple tailpatch, functions for which we + have a complex tailpatch but need a simple headpatch, and functions for + which we already have complex head- and tailpatches and don't need + simple patches. + + (Actually, there is a fifth category: Memory Manager functions that we + don't want to treat as Memory Manager functions. The functions in this + category are MemSet, MemMove, and MemCmp. We don't want to extend to + these functions the same privileges that other Memory Manager functions + get.) + + (And there's kind of a sixth category as well: non-Memory Manager + functions that we want to treat as Memory Manager functions. For + instance, DmWriteCheck grovels over Memory Manager data structures, so + we have to give it Memory Manager function privileges. + PrvFindMemoryLeaks is also a function like this, but since it's not in + the trap table, we can't patch it, and have to handle it differently. + See MetaMemory.cpp for this.) + + The macros below divide the set of Memory Manager functions into the + four categories. Any function on any of the four lists will + automatically have generated for it declarations for head- and + tailpatches. Additionally, depending on which list it's on, it will + optionally have simple head- and tailpatch functions generated for it. +=========================================================================== */ + +// List of functions for which we want to automatically generate simple +// head- and tailpatches. +// +// DmWriteCheck is on this list because it grovels over memory, making sure +// everything is OK before it writes to the storage heap. ScrInit is on +// this list because it calls MemMove to move the contents of the temporary +// LCD buffer to the real one after it's been allocated; the source of this +// move is a faux buffer out in the middle of an unallocated block. + +#define FOR_EACH_STUB_BOTHPATCH_FUNCTION(DO_TO_FUNCTION) \ + DO_TO_FUNCTION(MemInit) \ + DO_TO_FUNCTION(MemNumCards) \ + DO_TO_FUNCTION(MemCardFormat) \ + DO_TO_FUNCTION(MemCardInfo) \ + DO_TO_FUNCTION(MemStoreInfo) \ + DO_TO_FUNCTION(MemStoreSetInfo) \ + DO_TO_FUNCTION(MemNumHeaps) \ + DO_TO_FUNCTION(MemNumRAMHeaps) \ + DO_TO_FUNCTION(MemHeapID) \ + DO_TO_FUNCTION(MemHeapDynamic) \ + DO_TO_FUNCTION(MemHeapFreeBytes) \ + DO_TO_FUNCTION(MemHeapSize) \ + DO_TO_FUNCTION(MemHeapFlags) \ + DO_TO_FUNCTION(MemPtrRecoverHandle) \ + DO_TO_FUNCTION(MemPtrFlags) \ + DO_TO_FUNCTION(MemPtrSize) \ + DO_TO_FUNCTION(MemPtrOwner) \ + DO_TO_FUNCTION(MemPtrHeapID) \ + DO_TO_FUNCTION(MemPtrDataStorage) \ + DO_TO_FUNCTION(MemPtrCardNo) \ + DO_TO_FUNCTION(MemPtrToLocalID) \ + DO_TO_FUNCTION(MemHandleFlags) \ + DO_TO_FUNCTION(MemHandleSize) \ + DO_TO_FUNCTION(MemHandleOwner) \ + DO_TO_FUNCTION(MemHandleLockCount) \ + DO_TO_FUNCTION(MemHandleHeapID) \ + DO_TO_FUNCTION(MemHandleDataStorage) \ + DO_TO_FUNCTION(MemHandleCardNo) \ + DO_TO_FUNCTION(MemHandleToLocalID) \ + DO_TO_FUNCTION(MemHandleSetOwner) \ + DO_TO_FUNCTION(MemLocalIDToGlobal) \ + DO_TO_FUNCTION(MemLocalIDKind) \ + DO_TO_FUNCTION(MemLocalIDToPtr) \ + DO_TO_FUNCTION(MemDebugMode) \ + DO_TO_FUNCTION(MemSetDebugMode) \ + DO_TO_FUNCTION(MemHeapCheck) \ + DO_TO_FUNCTION(MemHeapPtr) \ + DO_TO_FUNCTION(MemStoreSearch) \ + DO_TO_FUNCTION(MemStoreInit) \ + DO_TO_FUNCTION(MemNVParams) \ + DO_TO_FUNCTION(DmWriteCheck) \ + DO_TO_FUNCTION(WinScreenInit) + +// List of functions for which we want to automatically +// generate simple headpatches only. + +#define FOR_EACH_STUB_HEADPATCH_FUNCTION(DO_TO_FUNCTION) \ + DO_TO_FUNCTION(MemKernelInit) \ + DO_TO_FUNCTION(MemInitHeapTable) \ + DO_TO_FUNCTION(MemHeapInit) \ + DO_TO_FUNCTION(MemHeapCompact) \ + DO_TO_FUNCTION(MemHeapFreeByOwnerID) \ + DO_TO_FUNCTION(MemChunkNew) \ + DO_TO_FUNCTION(MemPtrNew) \ + DO_TO_FUNCTION(MemPtrSetOwner) \ + DO_TO_FUNCTION(MemPtrResize) \ + DO_TO_FUNCTION(MemPtrResetLock) \ + DO_TO_FUNCTION(MemHandleNew) \ + DO_TO_FUNCTION(MemHandleResize) \ + DO_TO_FUNCTION(MemHandleLock) \ + DO_TO_FUNCTION(MemHandleResetLock) \ + DO_TO_FUNCTION(MemLocalIDToLockedPtr) \ + DO_TO_FUNCTION(MemHeapScramble) + +// List of functions for which we want to automatically +// generate simple tailpatches only. + +#define FOR_EACH_STUB_TAILPATCH_FUNCTION(DO_TO_FUNCTION) \ + DO_TO_FUNCTION(MemSemaphoreReserve) \ + DO_TO_FUNCTION(MemSemaphoreRelease) + +// List of functions for which we have compex head- and tailpatches. + +#define FOR_EACH_STUB_NOPATCH_FUNCTION(DO_TO_FUNCTION) \ + DO_TO_FUNCTION(MemChunkFree) \ + DO_TO_FUNCTION(MemHandleFree) \ + DO_TO_FUNCTION(MemHandleUnlock) \ + DO_TO_FUNCTION(MemPtrUnlock) \ + +// This macro contains _all_ memory manager functions. + +#define FOR_EACH_MEMMGR_FUNCTION(DO_TO_FUNCTION) \ + FOR_EACH_STUB_BOTHPATCH_FUNCTION(DO_TO_FUNCTION) \ + FOR_EACH_STUB_HEADPATCH_FUNCTION(DO_TO_FUNCTION) \ + FOR_EACH_STUB_TAILPATCH_FUNCTION(DO_TO_FUNCTION) \ + FOR_EACH_STUB_NOPATCH_FUNCTION(DO_TO_FUNCTION) + + +class MemMgrHeadpatch +{ + public: + // Declare headpatches for all the memory manager functions. + + #define DECLARE_HEAD_PATCH(fn) static CallROMType fn (void); + FOR_EACH_MEMMGR_FUNCTION(DECLARE_HEAD_PATCH) +}; + + +class MemMgrTailpatch +{ + public: + // Declare tailpatches for all the memory manager functions. + + #define DECLARE_TAIL_PATCH(fn) static void fn (void); + FOR_EACH_MEMMGR_FUNCTION(DECLARE_TAIL_PATCH) +}; + + +void CheckForMemoryLeaks (UInt32 memOwnerID); + + +#endif // EmPatchModuleSys_h diff --git a/SrcShared/Patches/EmPatchModuleTypes.h b/SrcShared/Patches/EmPatchModuleTypes.h new file mode 100644 index 0000000..6ffb475 --- /dev/null +++ b/SrcShared/Patches/EmPatchModuleTypes.h @@ -0,0 +1,94 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 2001 PocketPyro, Inc. + Portions Copyright (c) Palm, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchModuleTypes_h +#define EmPatchModuleTypes_h + +#include "EmPatchIf.h" // HeadpatchProc, TailpatchProc, IEmPatchModule +#include "EmStructs.h" // SystemCallContext + + +// ====================================================================== +// At compile time, the list of functions we want to head- and tailpatch +// are stored in an array of ProtoPatchTableEntries. At runtime, these +// compact arrays are expanded by PatchModule into a sparse array +// so that the function dispatch number can be used to look up the +// patch function. +// ====================================================================== + +struct ProtoPatchTableEntry +{ + uint16 fTrapWord; + HeadpatchProc fHeadpatch; + TailpatchProc fTailpatch; +}; + + +// =========================================================================== +// InstalledLibPatchEntry +// =========================================================================== +// Structure used to hold tail-patch information. + +class InstalledLibPatchEntry +{ + public: + InstalledLibPatchEntry (void) : + fIsDirty (true), + fTableP (NULL) + { + } + + bool IsDirty (void) const + { + return fIsDirty; + } + + void SetDirty (bool dirty = true) + { + fIsDirty = dirty; + } + + IEmPatchModule* GetPatchTableP (void) const + { + return fTableP; + } + + void SetPatchTableP (IEmPatchModule* tableP) + { + fTableP = tableP; + } + + private: + bool fIsDirty; + IEmPatchModule* fTableP; +}; + +typedef vector<InstalledLibPatchEntry> PatchedLibIndex; + + +// =========================================================================== +// ¥ TailpatchType +// =========================================================================== +// Structure used to hold tail-patch information. + +struct TailpatchType +{ + SystemCallContext fContext; + int32 fCount; + TailpatchProc fTailpatch; +}; + +typedef vector<TailpatchType> TailPatchIndex; + +#endif // EmPatchModuleTypes_h diff --git a/SrcShared/Patches/EmPatchState.cpp b/SrcShared/Patches/EmPatchState.cpp new file mode 100644 index 0000000..d5acc50 --- /dev/null +++ b/SrcShared/Patches/EmPatchState.cpp @@ -0,0 +1,1034 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + + Portions Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#include "EmCommon.h" +#include "EmPatchState.h" + +#include "EmApplication.h" // ScheduleQuit +#include "EmMemory.h" // EmMem_strcpy +#include "Miscellaneous.h" // SysTrapIndex, SystemCallContext +#include "PreferenceMgr.h" // Preference, kPrefKeyReportMemMgrLeaks +#include "ROMStubs.h" + + +EmStream& operator >> (EmStream& inStream, EmStackFrame& outInfo); +EmStream& operator << (EmStream& inStream, const EmStackFrame& inInfo); +EmStream& operator >> (EmStream& inStream, EmTrackedChunk& outInfo); +EmStream& operator << (EmStream& inStream, const EmTrackedChunk& inInfo); + + +// STATIC class data: + +EmPatchStateData EmPatchState::fgData; + + +Err EmPatchState::Initialize (void) +{ + // Add a notification for MemMgrLeaks + + gPrefs->AddNotification (&EmPatchState::MemMgrLeaksPrefsChanged, kPrefKeyReportMemMgrLeaks); + + return errNone; +} + + +Err EmPatchState::Dispose (void) +{ + fgData.fUIInitialized = false; + fgData.fUIReset = false; + fgData.fHeapInitialized = false; + fgData.fEvtGetEventCalled = false; + fgData.fEncoding = charEncodingUnknown; + + return errNone; +} + + +Err EmPatchState::Reset (void) +{ + fgData.fMemMgrCount = 0; + fgData.fMemSemaphoreCount = 0; + fgData.fMemSemaphoreReserveTime = 0; + fgData.fResizeOrigSize = 0; + fgData.fHeapID = 0; + + fgData.fRememberedHeaps.clear (); + fgData.fTrackedChunks.clear (); + + fgData.fLastEvtTrap = 0; + fgData.fOSVersion = kOSUndeterminedVersion; + + fgData.fEvtGetEventCalled = false; + fgData.fEncoding = charEncodingUnknown; + fgData.fSysBinarySearchCount = 0; + + fgData.fUIInitialized = false; + fgData.fUIReset = false; + fgData.fHeapInitialized = false; + + + SetQuitApp (0, 0); + SetSwitchApp (0, 0); + + // Clear out everything we know about the current applications. + + fgData.fCurAppInfo.clear (); + + // Cache the preference about checking for memory manager leaks. + + Preference<Bool> pref (kPrefKeyReportMemMgrLeaks); + fgData.fMemMgrLeaks = pref.Loaded () && *pref; + + return errNone; +} + + + +Err EmPatchState::Save (EmStreamChunk &s, long streamFmtVer, PersistencePhase pass) +{ + UNUSED_PARAM (streamFmtVer); + + if (pass == PSPersistAll || pass == PSPersistStep1) + { + s << fgData.fUIInitialized; + s << fgData.fHeapInitialized; + s << fgData.fSysBinarySearchCount; + + s << fgData.fMemMgrCount; + s << fgData.fMemSemaphoreCount; + s << fgData.fMemSemaphoreReserveTime; + s << fgData.fResizeOrigSize; + s << fgData.fHeapID; + + s << fgData.fNextAppCardNo; + s << fgData.fNextAppDbID; + s << (long) 0; // was gQuitStage; + + SaveCurAppInfo (s); + } + + if (pass == PSPersistAll || pass == PSPersistStep2) + { + s << fgData.fLastEvtTrap; + s << fgData.fOSVersion; + + // Added in version 2. + + s << false; // was: gJapanese + + // Added in version 3. + + s << fgData.fEncoding; + + // Added in version 4. + + s << fgData.fUIReset; + + // Added in version 5 + + s << fgData.fTrackedChunks; + } + + return errNone; +} + + +Err EmPatchState::Load (EmStreamChunk &s, long streamFmtVer, PersistencePhase pass) +{ + if (pass == PSPersistAll || pass == PSPersistStep1) + { + long unused; + + s >> fgData.fUIInitialized; + s >> fgData.fHeapInitialized; + + SetEvtGetEventCalled (false); + + + s >> fgData.fSysBinarySearchCount; + + s >> fgData.fMemMgrCount; + s >> fgData.fMemSemaphoreCount; + s >> fgData.fMemSemaphoreReserveTime; + s >> fgData.fResizeOrigSize; + s >> fgData.fHeapID; + + s >> fgData.fNextAppCardNo; + s >> fgData.fNextAppDbID; + s >> unused; // was gQuitStage; + + EmPatchState::LoadCurAppInfo (s); + } + + if (pass == PSPersistAll || pass == PSPersistStep2) + { + if (streamFmtVer >= 1) + { + s >> fgData.fLastEvtTrap; + s >> fgData.fOSVersion; + } + + if (streamFmtVer >= 2) + { + bool dummy; + s >> dummy; // was: gJapanese + } + + if (streamFmtVer >= 3) + { + s >> fgData.fEncoding; + } + else + { + fgData.fEncoding = charEncodingUnknown; + } + + if (streamFmtVer >= 4) + { + s >> fgData.fUIReset; + } + + if (streamFmtVer >= 5) + { + s >> fgData.fTrackedChunks; + } + } + + // Cache the preference about checking for memory manager leaks. + + Preference<Bool> pref (kPrefKeyReportMemMgrLeaks); + fgData.fMemMgrLeaks = pref.Loaded () && *pref; + + return errNone; +} + + + + +Err EmPatchState::SaveCurAppInfo (EmStreamChunk &s) +{ + s << (long) fgData.fCurAppInfo.size (); + + EmuAppInfoList::iterator iter; + for (iter = fgData.fCurAppInfo.begin (); iter != fgData.fCurAppInfo.end (); ++iter) + { + s << iter->fCmd; + s << (long) iter->fDB; + s << iter->fCardNo; + s << iter->fDBID; + s << iter->fMemOwnerID; + s << iter->fStackP; + s << iter->fStackEndP; + s << iter->fStackSize; + s << iter->fName; + s << iter->fVersion; + } + + return errNone; +} + +Err EmPatchState::LoadCurAppInfo (EmStreamChunk &s) +{ + fgData.fCurAppInfo.clear (); + + long numApps; + + s >> numApps; + + long ii; + + for (ii = 0; ii < numApps; ++ii) + { + EmuAppInfo info; + + s >> info.fCmd; + + long temp; + + s >> temp; + info.fDB = (DmOpenRef) temp; + + + s >> info.fCardNo; + s >> info.fDBID; + s >> info.fMemOwnerID; + s >> info.fStackP; + s >> info.fStackEndP; + s >> info.fStackSize; + s >> info.fName; + s >> info.fVersion; + + fgData.fCurAppInfo.push_back (info); + } + + return errNone; +} + +Err EmPatchState::AddAppInfo (EmuAppInfo &newAppInfo) +{ + fgData.fCurAppInfo.push_back (newAppInfo); + return errNone; +} + +Err EmPatchState::RemoveCurAppInfo (void) +{ + fgData.fCurAppInfo.pop_back (); + return errNone; +} + + + +Err EmPatchState::SetLastEvtTrap (uint16 lastEvtTrap) +{ + fgData.fLastEvtTrap = lastEvtTrap; + + return errNone; +} + +uint16 EmPatchState::GetLastEvtTrap (void) +{ + return fgData.fLastEvtTrap; +} + +Err EmPatchState::SetEvtGetEventCalled (bool wasCalled) +{ + fgData.fEvtGetEventCalled = wasCalled; + + return errNone; +} + +Err EmPatchState::SetQuitApp (UInt16 cardNo, LocalID dbID) +{ + fgData.fTimeToQuit = false; + fgData.fQuitAppCardNo = cardNo; + fgData.fQuitAppDbID = dbID; + + return errNone; +} + +void EmPatchState::SetTimeToQuit (void) +{ + gApplication->ScheduleQuit (); +} + + + + +// --------------------------------------------------------------------------- +// ¥ EmPatchState::MemMgrLeaksPrefsChanged +// --------------------------------------------------------------------------- +// Respond to a preference change. + +void EmPatchState::MemMgrLeaksPrefsChanged (PrefKeyType, void*) +{ + Preference<Bool> pref (kPrefKeyReportMemMgrLeaks, false); + fgData.fMemMgrLeaks = *pref; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::OSVersion +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +UInt32 EmPatchState::OSVersion (void) +{ + EmAssert (fgData.fOSVersion != kOSUndeterminedVersion); + + return fgData.fOSVersion; +} + +void EmPatchState::SetOSVersion (UInt32 version) +{ + fgData.fOSVersion = version; +} + +/*********************************************************************** +* +* FUNCTION: EmPatchState::OSMajorMinorVersion +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +UInt32 EmPatchState::OSMajorMinorVersion (void) +{ + return OSMajorVersion () * 10 + OSMinorVersion (); +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::OSMajorVersion +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +UInt32 EmPatchState::OSMajorVersion (void) +{ + EmAssert (fgData.fOSVersion != kOSUndeterminedVersion); + + return sysGetROMVerMajor (fgData.fOSVersion); +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::OSMinorVersion +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +UInt32 EmPatchState::OSMinorVersion (void) +{ + EmAssert (fgData.fOSVersion != kOSUndeterminedVersion); + + return sysGetROMVerMinor (fgData.fOSVersion); +} + + +/*********************************************************************** + * + * FUNCTION: SetSwitchApp + * + * DESCRIPTION: Sets an application or launchable document to switch to + * the next time the system can manage it. + * + * PARAMETERS: cardNo - the card number of the app to switch to. + * + * dbID - the database id of the app to switch to. + * + * RETURNED: nothing + * + ***********************************************************************/ + +void EmPatchState::SetSwitchApp (UInt16 cardNo, LocalID dbID) +{ + fgData.fNextAppCardNo = cardNo; + fgData.fNextAppDbID = dbID; +} + + +Bool EmPatchState::DatabaseInfoHasStackInfo (void) +{ + return OSMajorVersion () <= 2; +} // Changed in 3.0 + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::HasWellBehavedMemSemaphoreUsage +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +Bool EmPatchState::HasWellBehavedMemSemaphoreUsage (void) +{ + // Palm OS 3.0 and later should not be holding the memory manager + // semaphore for longer than 1 minute. I imagine that older ROMs + // don't hold the semaphore for longer than this, but Roger still + // suggested testing for 3.0. + + return fgData.fOSVersion != kOSUndeterminedVersion && OSMajorMinorVersion () >= 30; +} + + +// Bugs fixed in 3.0. +Bool EmPatchState::HasFindShowResultsBug (void) +{ + return OSMajorVersion () <= 2; +} + +Bool EmPatchState::HasSysBinarySearchBug (void) +{ + return OSMajorVersion () <= 2; +} + +// Bugs fixed in 3.1 +Bool EmPatchState::HasGrfProcessStrokeBug (void) +{ + return OSMajorMinorVersion () <= 30; +} + +Bool EmPatchState::HasMenuHandleEventBug (void) +{ + return OSMajorMinorVersion () <= 30; +} + +// Bugs fixed in 3.2 +Bool EmPatchState::HasBackspaceCharBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +Bool EmPatchState::HasDeletedStackBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +Bool EmPatchState::HasFindSaveFindStrBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +Bool EmPatchState::HasFldDeleteBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +Bool EmPatchState::HasFntDefineFontBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +Bool EmPatchState::HasNetPrvTaskMainBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +Bool EmPatchState::HasNetPrvSettingSetBug (void) +{ + return OSMajorMinorVersion () <= 31; +} + +// Bugs fixed in 3.3 +Bool EmPatchState::HasECValidateFieldBug (void) +{ + return OSMajorMinorVersion () <= 32; +} + +// Bugs fixed in 3.5 +Bool EmPatchState::HasConvertDepth1To2BWBug (void) +{ + return OSMajorMinorVersion () <= 33; +} + +// Bugs fixed in 4.0 +Bool EmPatchState::HasSelectItemBug (void) +{ + return OSMajorMinorVersion () == 35; +} + +Bool EmPatchState::HasSyncNotifyBug (void) +{ + return OSMajorVersion () <= 3; +} + +// Bugs fixed in ??? +Bool EmPatchState::HasPrvDrawSliderControlBug (void) +{ + return OSMajorMinorVersion () <= 40; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::GetAutoAcceptBeamDialogs +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +Bool EmPatchState::GetAutoAcceptBeamDialogs (void) +{ + return fgData.fAutoAcceptBeamDialogs; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::AutoAcceptBeamDialogs +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +Bool EmPatchState::AutoAcceptBeamDialogs (Bool newState) +{ + bool oldState = fgData.fAutoAcceptBeamDialogs; + fgData.fAutoAcceptBeamDialogs = newState != 0; + return oldState; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::GetROMCharEncoding (was TurningJapanese) +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: Palm OS character encoding used by ROM. +* +***********************************************************************/ + +UInt16 EmPatchState::GetROMCharEncoding (void) +{ + return fgData.fEncoding; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::EvtGetEventCalled +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +Bool EmPatchState::EvtGetEventCalled (void) +{ + return fgData.fEvtGetEventCalled; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::IsInSysBinarySearch +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +Bool EmPatchState::IsInSysBinarySearch (void) +{ + return fgData.fSysBinarySearchCount > 0; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::EnterSysBinarySearch +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +void EmPatchState::EnterSysBinarySearch (void) +{ + EmAssert (fgData.fSysBinarySearchCount < 10); + ++fgData.fSysBinarySearchCount; +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::ExitSysBinarySearch +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +void EmPatchState::ExitSysBinarySearch (void) +{ + --fgData.fSysBinarySearchCount; + EmAssert (fgData.fSysBinarySearchCount >= 0); +} + + + +uint16 EmPatchState::GetQuitAppCardNo (void) +{ + return fgData.fQuitAppCardNo; +} + + +LocalID EmPatchState::GetQuitAppDbID (void) +{ + return fgData.fQuitAppDbID; +} + +void EmPatchState::SetEncoding (uint32 encoding) +{ + fgData.fEncoding = encoding; +} + +Bool EmPatchState::IsPCInMemMgr (void) +{ + return fgData.fMemMgrCount > 0; +} + +/*********************************************************************** +* +* FUNCTION: EmPatchState::EnterMemMgr +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +void EmPatchState::EnterMemMgr (const char* fnName) +{ + UNUSED_PARAM (fnName) + + ++fgData.fMemMgrCount; + EmAssert (fgData.fMemMgrCount < 10); +} + + +/*********************************************************************** +* +* FUNCTION: EmPatchState::ExitMemMgr +* +* DESCRIPTION: +* +* PARAMETERS: none +* +* RETURNED: nothing +* +***********************************************************************/ + +void EmPatchState::ExitMemMgr (const char* fnName) +{ + UNUSED_PARAM (fnName) + + --fgData.fMemMgrCount; + EmAssert (fgData.fMemMgrCount >= 0); + + #if 0 // _DEBUG + if (fgData.fMemMgrCount == 0) + { + EmPalmHeap::ValidateAllHeaps (); + } + #endif +} + +Bool EmPatchState::UIInitialized (void) +{ + return fgData.fUIInitialized; +} + +void EmPatchState::SetUIInitialized (Bool value) +{ + fgData.fUIInitialized = value != 0; +} + +Bool EmPatchState::UIReset (void) +{ + return fgData.fUIReset; +} + +void EmPatchState::SetUIReset (Bool value) +{ + fgData.fUIReset = value != 0; +} + +Bool EmPatchState::HeapInitialized (void) +{ + return fgData.fHeapInitialized; +} + +void EmPatchState::SetHeapInitialized (Bool value) +{ + fgData.fHeapInitialized = value != 0; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchState::CollectCurrentAppInfo + * + * DESCRIPTION: + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +Err EmPatchState::CollectCurrentAppInfo (emuptr appInfoP, EmuAppInfo &newAppInfo) +{ + memset (&newAppInfo, 0, sizeof (newAppInfo)); + + // Scarf some information out of the app info block. + + newAppInfo.fDB = (DmOpenRef) EmMemGet32 (appInfoP + offsetof (SysAppInfoType, dbP)); + newAppInfo.fStackP = EmMemGet32 (appInfoP + offsetof (SysAppInfoType, stackP)); + newAppInfo.fMemOwnerID = EmMemGet16 (appInfoP + offsetof (SysAppInfoType, memOwnerID)); + + // Determine the current stack range. Under Palm OS 3.0 and later, this information + // is in the DatabaseInfo block. Under earlier OSes, we only get the low-end of the stack + // (that is, the address that was returned by MemPtrNew). To get the high-end of + // the stack, assume that stackP pointed to a chunk of memory allocated by MemPtrNew + // and call MemPtrSize. + + if (DatabaseInfoHasStackInfo ()) + { + if (newAppInfo.fStackP) + { + UInt32 stackSize = ::MemPtrSize ((MemPtr) newAppInfo.fStackP); + if (stackSize) + { + newAppInfo.fStackEndP = newAppInfo.fStackP + stackSize; + } + else + { + newAppInfo.fStackEndP = EmMemNULL; + } + } + } + else + { + newAppInfo.fStackEndP = EmMemGet32 (appInfoP + offsetof (SysAppInfoType, stackEndP)); + } + + newAppInfo.fStackSize = newAppInfo.fStackEndP - newAppInfo.fStackP; + + // Remember the current application name and version information. We use + // this information when telling users that something has gone haywire. Collect + // this information now instead of later (on demand) as we can't be sure that + // we can make the necessary DataMgr calls after an error occurs. + // + // If the database has a 'tAIN' resource, get the name from there. + // Otherwise, use the database name. + // + // (Write the name into a temporary local variable. The local variable is + // on the stack, which will get "mapped" into the emulated address space so + // that the emulated DmDatabaseInfo can get to it.) + + UInt16 cardNo; + LocalID dbID; + + Err err = ::DmOpenDatabaseInfo (newAppInfo.fDB, &dbID, NULL, NULL, &cardNo, NULL); + if (err) + return err; + + newAppInfo.fCardNo = cardNo; + newAppInfo.fDBID = dbID; + + char appName[dmDBNameLength] = {0}; + char appVersion[256] = {0}; // <gulp> I hope this is big enough... + +// DmOpenRef dbP = DmOpenDatabase (cardNo, dbID, dmModeReadOnly); + +// if (dbP) + { + MemHandle strH; + + // Get the app name from the 'tAIN' resource. + + strH = ::DmGet1Resource (ainRsc, ainID); + if (strH) + { + emuptr strP = (emuptr) ::MemHandleLock (strH); + EmMem_strcpy (appName, strP); + ::MemHandleUnlock (strH); + ::DmReleaseResource (strH); + } + + // Get the version from the 'tver' resource, using ID's 1 and 1000 + + strH = ::DmGet1Resource (verRsc, appVersionID); + if (strH == NULL) + strH = ::DmGet1Resource (verRsc, appVersionAlternateID); + if (strH) + { + emuptr strP = (emuptr) ::MemHandleLock (strH); + EmMem_strcpy (appVersion, strP); + ::MemHandleUnlock (strH); + ::DmReleaseResource (strH); + } + +// ::DmCloseDatabase (dbP); + } + + if (appName[0] == 0) // No 'tAIN' resource, so use database name + { + ::DmDatabaseInfo (cardNo, dbID, + appName, + NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL); + } + + // Copy the strings from the stack to their permanent homes. + + strcpy (newAppInfo.fName, appName); + strcpy (newAppInfo.fVersion, appVersion); + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchState::GetCurrentAppInfo + * + * DESCRIPTION: Return information on the last application launched + * with SysAppLaunch (and that hasn't exited yet). + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + + +EmuAppInfo EmPatchState::GetCurrentAppInfo (void) +{ + EmuAppInfo result; + memset (&result, 0, sizeof (result)); + + if (fgData.fCurAppInfo.size () > 0) + { + result = *(fgData.fCurAppInfo.rbegin ()); + } + + return result; +} + + +/*********************************************************************** + * + * FUNCTION: EmPatchState::GetRootAppInfo + * + * DESCRIPTION: Return information on the last application launched + * with SysAppLaunch and with the launch code of + * sysAppLaunchCmdNormalLaunch (and that hasn't exited yet). + * + * PARAMETERS: none + * + * RETURNED: nothing + * + ***********************************************************************/ + +EmuAppInfo EmPatchState::GetRootAppInfo (void) +{ + EmuAppInfo result; + memset (&result, 0, sizeof (result)); + + EmuAppInfoList::reverse_iterator iter = fgData.fCurAppInfo.rbegin (); + + while (iter != fgData.fCurAppInfo.rend ()) + { + if ((*iter).fCmd == sysAppLaunchCmdNormalLaunch) + { + result = *iter; + break; + } + + ++iter; + } + + return result; +} + + +// --------------------------------------------------------------------------- +// ¥ operator >> (EmStream&, EmStackFrame&) +// --------------------------------------------------------------------------- + +EmStream& operator >> (EmStream& inStream, EmStackFrame& outInfo) +{ + inStream >> outInfo.fAddressInFunction; + inStream >> outInfo.fA6; + + return inStream; +} + + +// --------------------------------------------------------------------------- +// ¥ operator << (EmStream&, const EmStackFrame&) +// --------------------------------------------------------------------------- + +EmStream& operator << (EmStream& inStream, const EmStackFrame& inInfo) +{ + inStream << inInfo.fAddressInFunction; + inStream << inInfo.fA6; + + return inStream; +} + + +// --------------------------------------------------------------------------- +// ¥ operator >> (EmStream&, EmTrackedChunk&) +// --------------------------------------------------------------------------- + +EmStream& operator >> (EmStream& inStream, EmTrackedChunk& outInfo) +{ + inStream >> outInfo.ptr; + inStream >> outInfo.isHandle; + inStream >> outInfo.stackCrawl; + + return inStream; +} + + +// --------------------------------------------------------------------------- +// ¥ operator << (EmStream&, const EmTrackedChunk&) +// --------------------------------------------------------------------------- + +EmStream& operator << (EmStream& inStream, const EmTrackedChunk& inInfo) +{ + inStream << inInfo.ptr; + inStream << inInfo.isHandle; + inStream << inInfo.stackCrawl; + + return inStream; +} diff --git a/SrcShared/Patches/EmPatchState.h b/SrcShared/Patches/EmPatchState.h new file mode 100644 index 0000000..1c8fa2d --- /dev/null +++ b/SrcShared/Patches/EmPatchState.h @@ -0,0 +1,264 @@ +/* -*- mode: C++; tab-width: 4 -*- */ +/* ===================================================================== *\ + Copyright (c) 1998-2001 Palm, Inc. or its subsidiaries. + Copyright (c) 2001 PocketPyro, Inc. + All rights reserved. + + This file is part of the Palm OS Emulator. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. +\* ===================================================================== */ + +#ifndef EmPatchState_h +#define EmPatchState_h + +#include "ChunkFile.h" +#include "EmPalmHeap.h" +#include "EmPatchModuleTypes.h" +#include "PreferenceMgr.h" // PrefKeyType + +#include <vector> +#include <map> + + +const UInt32 kOSUndeterminedVersion = ~0; + + +typedef map<emuptr, EmPalmHeap*> EmHeapMap; + + + +// Structure used to hold information about the currently +// running Palm OS application (as recorded when SysAppStartup +// is called). + +struct EmuAppInfo +{ + Int16 fCmd; // launch code + DmOpenRef fDB; + UInt16 fCardNo; + LocalID fDBID; + UInt16 fMemOwnerID; + emuptr fStackP; + emuptr fStackEndP; + long fStackSize; + char fName[dmDBNameLength]; + char fVersion[256]; // <gulp> I hope this is big enough... +}; + +typedef vector<EmuAppInfo> EmuAppInfoList; + + +// Structure used to keep track of the context in which +// memory chunks were allocated. + +struct EmTrackedChunk +{ + emuptr ptr; + bool isHandle; + EmStackFrameList stackCrawl; +}; + +typedef list<EmTrackedChunk> EmTrackedChunkList; + + +struct EmPatchStateData +{ + public: + EmPatchStateData () : + fUIInitialized (false), + fUIReset (false), + + fEvtGetEventCalled (false), + fAutoAcceptBeamDialogs (false), + fTimeToQuit (false), + + fLastEvtTrap (0), + fOSVersion (0), + fEncoding (0), + + fSysBinarySearchCount (0), + + fQuitAppCardNo (0), + fQuitAppDbID (0), + fNextAppCardNo (0), + fNextAppDbID (0), + + fHeapInitialized (false), + fMemMgrCount (0), + fMemSemaphoreCount (0), + fMemSemaphoreReserveTime (0), + fResizeOrigSize (0), + fHeapID (0) + { + } + + bool fUIInitialized; + bool fUIReset; + bool fEvtGetEventCalled; + bool fAutoAcceptBeamDialogs; + bool fTimeToQuit; + + uint16 fLastEvtTrap; + uint32 fOSVersion; + uint32 fEncoding; + + long fSysBinarySearchCount; + + uint16 fQuitAppCardNo; + LocalID fQuitAppDbID; + uint16 fNextAppCardNo; + LocalID fNextAppDbID; + + EmuAppInfoList fCurAppInfo; + + bool fHeapInitialized; + + long fMemMgrCount; + Bool fMemMgrLeaks; + long fMemSemaphoreCount; + unsigned long fMemSemaphoreReserveTime; + + uint32 fResizeOrigSize; + uint16 fHeapID; + + EmHeapMap fRememberedHeaps; + + EmTrackedChunkList fTrackedChunks; +}; + + + +class EmPatchState +{ + public: + static Err Initialize (void); + static Err Dispose (void); + static Err Reset (void); + + enum PersistencePhase + { + PSPersistAll, // save/load all + PSPersistStep1, // Backward compatability step 1 + PSPersistStep2 // Backward compatability step 2 + }; + + static Err Save (EmStreamChunk &s, long version = 1, PersistencePhase pass = PSPersistAll); + static Err Load (EmStreamChunk &s, long version = 1, PersistencePhase pass = PSPersistAll); + + static Err SaveCurAppInfo (EmStreamChunk &s); + static Err LoadCurAppInfo (EmStreamChunk &s); + + static uint16 GetLastEvtTrap (void); + static EmuAppInfo GetCurrentAppInfo (void); + static EmuAppInfo GetRootAppInfo (void); + + + static Err AddAppInfo (EmuAppInfo &newAppInfo); + static Err RemoveCurAppInfo (void); + + static Err SetLastEvtTrap (uint16 lastEvtTrap); + static Err SetEvtGetEventCalled (bool wasCalled); + + static Err SetQuitApp (UInt16 cardNo, LocalID dbID); + static void SetTimeToQuit (void); + + static void MemMgrLeaksPrefsChanged (PrefKeyType, void*); + + static Err CollectCurrentAppInfo (emuptr appInfoP, EmuAppInfo &newAppInfo); + + + static UInt32 OSVersion (void); + static void SetOSVersion (UInt32 version); + static UInt32 OSMajorMinorVersion (void); + static UInt32 OSMajorVersion (void); + static UInt32 OSMinorVersion (void); + static void SetSwitchApp (UInt16 cardNo, LocalID dbID); + static Bool DatabaseInfoHasStackInfo(void); + static Bool HasWellBehavedMemSemaphoreUsage (void); + + + // Bugs fixed in 3.0. + static Bool HasFindShowResultsBug (void); + static Bool HasSysBinarySearchBug (void); + + // Bugs fixed in 3.1 + static Bool HasGrfProcessStrokeBug (void); + static Bool HasMenuHandleEventBug (void); + + // Bugs fixed in 3.2 + static Bool HasBackspaceCharBug (void); + static Bool HasDeletedStackBug (void); + static Bool HasFindSaveFindStrBug (void); + static Bool HasFldDeleteBug (void); + static Bool HasFntDefineFontBug (void); + static Bool HasNetPrvTaskMainBug (void); + static Bool HasNetPrvSettingSetBug (void); + + // Bugs fixed in 3.3 + static Bool HasECValidateFieldBug (void); + + // Bugs fixed in 3.5 + static Bool HasConvertDepth1To2BWBug(void); + + // Bugs fixed in 4.0 + static Bool HasSelectItemBug (void); + static Bool HasSyncNotifyBug (void); + + // Bugs fixed in ??? + static Bool HasPrvDrawSliderControlBug (void); + + + static Bool GetAutoAcceptBeamDialogs (void); + static Bool AutoAcceptBeamDialogs (Bool newState); + static UInt16 GetROMCharEncoding (void); + static Bool EvtGetEventCalled (void); + static Bool IsInSysBinarySearch (void); + static void EnterSysBinarySearch (void); + static void ExitSysBinarySearch (void); + static uint16 GetQuitAppCardNo (void); + static LocalID GetQuitAppDbID (void); + static void SetEncoding (uint32 encoding); + + static Bool IsPCInMemMgr (void); + static void EnterMemMgr (const char* fnName); + static void ExitMemMgr (const char* fnName); + static Bool UIInitialized (void); + + static void SetUIInitialized (Bool value = true); + static void SetUIReset (Bool value = true); + static void SetHeapInitialized (Bool value = true); + + static Bool UIReset (void); + static Bool HeapInitialized (void); + + // inline functions + + static uint16 GetNextAppCardNo (void) + { + return fgData.fNextAppCardNo; + } + + static LocalID GetNextAppDbID (void) + { + return fgData.fNextAppDbID; + } + + static void SetNextAppCardNo (uint16 cardno) + { + fgData.fNextAppCardNo = cardno; + } + + static void SetNextAppDbID (LocalID id) + { + fgData.fNextAppDbID = id; + } + + public: + static EmPatchStateData fgData; +}; + +#endif // EmPatchState_h |