aboutsummaryrefslogtreecommitdiff
path: root/SrcShared/EmExgMgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'SrcShared/EmExgMgr.cpp')
-rw-r--r--SrcShared/EmExgMgr.cpp681
1 files changed, 681 insertions, 0 deletions
diff --git a/SrcShared/EmExgMgr.cpp b/SrcShared/EmExgMgr.cpp
new file mode 100644
index 0000000..25f9374
--- /dev/null
+++ b/SrcShared/EmExgMgr.cpp
@@ -0,0 +1,681 @@
+/* -*- mode: C++; tab-width: 4 -*- */
+/* ===================================================================== *\
+ Copyright (c) 2000-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 "EmExgMgr.h"
+
+#include "EmBankMapped.h" // EmBankMapped
+#include "EmCPU.h" // Emulator::SetBreakReason (kBreak_TaskFinished)
+#include "EmFileImport.h" // SetResult, SetDone
+#include "EmMemory.h" // EmMem_strncpy, EmMem_memset
+#include "EmPalmStructs.h" // SysLibTblEntryType, ExgGoToType, ExgSocketType
+#include "EmSession.h" // gSession, SuspendByTimeout
+#include "EmStream.h" // EmStream
+#include "EmStreamFile.h" // EmStreamFile
+#include "ROMStubs.h" // SysLibTblEntry
+
+
+// ======================================================================
+// Globals
+// ======================================================================
+
+#define exgLibCtlGetTitle 1 // get title for Exg dialogs
+#define exgLibCtlSpecificOp 0x8000 // start of range for library specific control codes
+
+const UInt16 kHostExgLibInitSocket = exgLibCtlSpecificOp | 0;
+const UInt16 kHostExgLibFreeSocket = exgLibCtlSpecificOp | 1;
+const UInt16 kHostExgLibBeamCompleted = exgLibCtlSpecificOp | 2;
+
+#define exgMemError (exgErrorClass | 1)
+#define exgErrStackInit (exgErrorClass | 2) // stack could not initialize
+#define exgErrUserCancel (exgErrorClass | 3)
+#define exgErrNoReceiver (exgErrorClass | 4) // receiver device not found
+#define exgErrNoKnownTarget (exgErrorClass | 5) // can't find a target app
+#define exgErrTargetMissing (exgErrorClass | 6) // target app is known but missing
+#define exgErrNotAllowed (exgErrorClass | 7) // operation not allowed
+#define exgErrBadData (exgErrorClass | 8) // internal data was not valid
+#define exgErrAppError (exgErrorClass | 9) // generic application error
+#define exgErrUnknown (exgErrorClass | 10) // unknown general error
+#define exgErrDeviceFull (exgErrorClass | 11) // device is full
+#define exgErrDisconnected (exgErrorClass | 12) // link disconnected
+#define exgErrNotFound (exgErrorClass | 13) // requested object not found
+#define exgErrBadParam (exgErrorClass | 14) // bad parameter to call
+#define exgErrNotSupported (exgErrorClass | 15) // operation not supported by this library
+#define exgErrDeviceBusy (exgErrorClass | 16) // device is busy
+#define exgErrBadLibrary (exgErrorClass | 17) // bad or missing ExgLibrary
+
+
+/***********************************************************************
+ *
+ * CLASS: EmExgMgr
+ *
+ * DESCRIPTION: This class represents an Exchange Manager driver
+ * library. It works in conjunction with an actual stub library
+ * installed by Poser into the current session when the session
+ * is created. Using HostControl callback functions, the stub
+ * library calls into methods in EmExgMgr subclasses. We thus
+ * create subclasses in order to provide specific library
+ * functionality.
+ *
+ * EmExgMgr doesn't do anything itself except define an interface.
+ * All useful functionality is provided by subclasses.
+ *
+ * Besides forwarding all calls ExgLib calls back to Poser via
+ * HostControl functions, the stub library does the following:
+ *
+ * * Looks for irGotDataChr characters in the event stream and
+ * starts a beam process when it finds one.
+ *
+ * * Sends a kHostExgLibInitSocket control code to the host
+ * driver to fill out the ExgSocketType data structure.
+ *
+ * * Calls ExgNotifyReceive. Note that having the stub library
+ * make this call is very important. If the host driver
+ * were to call ExgNotifyReceive in its implementation of
+ * ExgLibHandleEvent, then control would not be returned back
+ * to us until ExgNotifyReceive had completed. And without
+ * control, we can't update progress dialogs or look for
+ * clicks on Cancel buttons.
+ *
+ * * Sends a kHostExgLibFreeSocket control code to clean up anything
+ * set up by the kHostExgLibInitSocket code.
+ *
+ * * Sends a kHostExgLibBeamCompleted control code to the host
+ * driver in order to let it know that it can now remove any
+ * progress dialogs and/or display error messages.
+ *
+ * PROBLEMS:
+ *
+ * This module needs to take into account a number of problems
+ * in order to work:
+ *
+ * * There is a bug in Launcher 3.0 - 3.5 where it tries to send
+ * sysAppLaunchCmdSyncNotify to anything received that's not a
+ * PQA. We have a patch on SysAppLaunch to deal with this.
+ *
+ * * We have to make sure no UI will appear. We have patches on
+ * FrmCustomAlert and ExgDoDialog to make sure this doesn't happen.
+ *
+ * * Palm VII's aren't even registered to recieve PQAs!
+ *
+ ***********************************************************************/
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgr::EmExgMgr
+// ---------------------------------------------------------------------------
+// Constructor for abstract base class. Does nothing.
+
+EmExgMgr::EmExgMgr (void)
+{
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgr::~EmExgMgr
+// ---------------------------------------------------------------------------
+// Destructor for abstract base class. Does nothing.
+
+EmExgMgr::~EmExgMgr (void)
+{
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgr::GetExgMgr
+// ---------------------------------------------------------------------------
+// Static method for finding and returning the host-implemented Exchange
+// Manager driver associated with the given library or socket. Our stub
+// library stores the pointer to the EmExgMgr subclass in its library
+// globals field, so we fetch it from there.
+
+EmExgMgr* EmExgMgr::GetExgMgr (UInt16 libRefNum)
+{
+ emuptr entryP = (emuptr) ::SysLibTblEntry (libRefNum);
+ if (!entryP)
+ return NULL;
+
+ EmAliasSysLibTblEntryType<PAS> entry (entryP);
+ emuptr globalsP = entry.globalsP;
+ return (EmExgMgr*) globalsP;
+}
+
+
+#pragma mark -
+
+/***********************************************************************
+ *
+ * CLASS: EmExgMgrStream
+ *
+ * DESCRIPTION: .
+ *
+ ***********************************************************************/
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::EmExgMgrStream
+// ---------------------------------------------------------------------------
+
+EmExgMgrStream::EmExgMgrStream (EmStream& stream) :
+ fStream (stream)
+{
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::~EmExgMgrStream
+// ---------------------------------------------------------------------------
+
+EmExgMgrStream::~EmExgMgrStream (void)
+{
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibOpen
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibOpen (UInt16 /*libRefNum*/)
+{
+ return errNone;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibClose
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibClose (UInt16 /*libRefNum*/)
+{
+ return errNone;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibSleep
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibSleep (UInt16 /*libRefNum*/)
+{
+ return errNone;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibWake
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibWake (UInt16 /*libRefNum*/)
+{
+ return errNone;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibHandleEvent
+// ---------------------------------------------------------------------------
+
+Boolean EmExgMgrStream::ExgLibHandleEvent (UInt16 /*libRefNum*/, emuptr /*eventP*/)
+{
+ return false;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibConnect
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibConnect (UInt16 libRefNum, emuptr exgSocketP)
+{
+ // Same as ExgLibPut? Applications seems to call ExgLibPut.
+ // Additionally, IrLib's version of ExgLibConnect merely forwards
+ // to ExgLibPut.
+
+ return EmExgMgrStream::ExgLibPut (libRefNum, exgSocketP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibAccept
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibAccept (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/)
+{
+ fStream.SetMarker (0, kStreamFromStart);
+ return errNone;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibDisconnect
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibDisconnect (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/, Err error)
+{
+ return error;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibPut
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibPut (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/)
+{
+ // Same as ExgLibConnect? Applications seems to call ExgLibPut.
+ // Additionally, IrLib's version of ExgLibConnect merely forwards
+ // to ExgLibPut.
+
+ return exgErrNotSupported;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibGet
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibGet (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/)
+{
+ // What does this function do? Nothing in the ROM seems to call
+ // it, and the IrLib version merely returns zero.
+
+ return exgErrNotSupported;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibSend
+// ---------------------------------------------------------------------------
+
+UInt32 EmExgMgrStream::ExgLibSend (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/,
+ void* bufP, const UInt32 bufLen, Err* errP)
+{
+ if (bufLen > 0)
+ {
+ // Transfer the bytes.
+
+ *errP = fStream.PutBytes (bufP, bufLen);
+ }
+ else
+ {
+ *errP = errNone;
+ }
+
+ return bufLen;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibReceive
+// ---------------------------------------------------------------------------
+
+UInt32 EmExgMgrStream::ExgLibReceive (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/,
+ void* bufP, const UInt32 bufLen, Err* errP)
+{
+ // Determine how many bytes to transfer.
+
+ long amountToCopy = bufLen;
+ long amountLeftInBuffer = fStream.GetLength () - fStream.GetMarker ();
+ if (amountToCopy > amountLeftInBuffer)
+ amountToCopy = amountLeftInBuffer;
+
+ if (amountToCopy > 0)
+ {
+ // Transfer the bytes.
+
+ *errP = fStream.GetBytes (bufP, amountToCopy);
+ }
+ else
+ {
+ *errP = errNone;
+ }
+
+ return amountToCopy;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibControl
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibControl (UInt16 libRefNum, UInt16 op,
+ emuptr valueP, emuptr valueLenP)
+{
+ Err err = errNone;
+
+ switch (op)
+ {
+ case exgLibCtlGetTitle:
+ if (valueP && valueLenP)
+ {
+ EmAliasUInt16<PAS> valueLen (valueLenP);
+ EmMem_strncpy (valueP, "Poser Beam", valueLen);
+ }
+ else
+ {
+ err = exgErrBadParam;
+ }
+ break;
+
+ case kHostExgLibInitSocket:
+ if (valueP && valueLenP)
+ {
+ EmAliasUInt16<PAS> valueLen (valueLenP);
+ EmAliasExgSocketType<PAS> socket (valueP);
+
+ EmAssert ((UInt16) valueLen == socket.GetSize ());
+
+ const UInt16 kLocalModeBit = 0x8000;
+// const UInt16 kPacketModeBit = 0x4000;
+// const UInt16 kNoGoToBit = 0x2000;
+ const UInt16 kNoStatusBit = 0x1000;
+
+ EmMem_memset (valueP, 0, valueLen);
+
+ socket.libraryRef = libRefNum; // identifies the Exg library in use
+// socket.socketRef = 0; // used by Exg library to identify this connection
+// socket.target = 0; // Creator ID of application this is sent to
+// socket.count = 0; // # of objects in this connection (usually 1)
+// socket.length = 0; // # total byte count for all objects being sent (optional)
+// socket.time = 0; // last modified time of object (optional)
+// socket.appData = 0; // application specific info
+// socket.goToCreator = 0; // creator ID of app to launch with goto after receive
+// socket.goToParams; // If launchCreator then this contains goto find info
+// socket.goToParams.dbCardNo = 0; // card number of the database
+// socket.goToParams.dbID = 0; // LocalID of the database
+// socket.goToParams.recordNum = 0; // index of record that contain a match
+// socket.goToParams.uniqueID = 0; // postion in record of the match.
+// socket.goToParams.matchCustom = 0; // application specific info
+ socket.flags = kLocalModeBit | kNoStatusBit; // system flags
+// socket.description = EmMemNULL; // text description of object (for user)
+// socket.type = EmMemNULL; // Mime type of object (optional)
+// socket.name = EmMemNULL; // name of object, generally a file name (optional)
+
+ EmStreamFile* s = dynamic_cast<EmStreamFile*> (&fStream);
+ if (s)
+ {
+ fFileName = s->GetFileRef().GetName ();
+ EmBankMapped::MapPhysicalMemory (fFileName.c_str (), fFileName.size () + 1);
+ socket.name = EmBankMapped::GetEmulatedAddress (fFileName.c_str ());
+ }
+ }
+ else
+ {
+ err = exgErrBadParam;
+ }
+ break;
+
+ case kHostExgLibFreeSocket:
+ {
+ // Unmap file name and drop our reference to it.
+
+#ifndef NDEBUG
+ EmAliasUInt16<PAS> valueLen (valueLenP);
+#endif
+ EmAliasExgSocketType<PAS> socket (valueP);
+
+ EmAssert ((UInt16) valueLen == socket.GetSize ());
+
+ socket.name = EmMemNULL;
+ EmBankMapped::UnmapPhysicalMemory (fFileName.c_str ());
+ break;
+ }
+
+ default:
+ err = exgErrNotSupported;
+ }
+
+ return err;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrStream::ExgLibRequest
+// ---------------------------------------------------------------------------
+
+Err EmExgMgrStream::ExgLibRequest (UInt16 /*libRefNum*/, emuptr /*exgSocketP*/)
+{
+ return exgErrNotSupported;
+}
+
+
+#pragma mark -
+
+/***********************************************************************
+ *
+ * CLASS: EmExgMgrImportWrapper
+ *
+ * DESCRIPTION: This class is used to wrap up other EmExgMgr
+ * implementations. It adds the facility for communicating
+ * information back to the EmFileImport class (for instance
+ * progress information and whether or not the beam
+ * process is completed). It also allows the beaming
+ * process to be aborted.
+ *
+ ***********************************************************************/
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::EmExgMgrImportWrapper
+// ---------------------------------------------------------------------------
+// Remember the wrapped object, as well as the EmFileImport object we
+// communicate with. Initialize our "aborting" flag to false.
+
+EmExgMgrImportWrapper::EmExgMgrImportWrapper (EmExgMgr& exgMgr, EmFileImport& importer) :
+ fExgMgr (exgMgr),
+ fImporter (importer),
+ fAborting (false)
+{
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::~EmExgMgrImportWrapper
+// ---------------------------------------------------------------------------
+
+EmExgMgrImportWrapper::~EmExgMgrImportWrapper (void)
+{
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::Cancel
+// ---------------------------------------------------------------------------
+// Set our "aborting" flag to true. This will cause our read and write
+// methods to return "user cancelled".
+
+void EmExgMgrImportWrapper::Cancel (void)
+{
+ fAborting = true;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibOpen
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibOpen (UInt16 libRefNum)
+{
+ return fExgMgr.ExgLibOpen (libRefNum);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibClose
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibClose (UInt16 libRefNum)
+{
+ return fExgMgr.ExgLibClose (libRefNum);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibSleep
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibSleep (UInt16 libRefNum)
+{
+ return fExgMgr.ExgLibSleep (libRefNum);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibWake
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibWake (UInt16 libRefNum)
+{
+ return fExgMgr.ExgLibWake (libRefNum);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibHandleEvent
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Boolean EmExgMgrImportWrapper::ExgLibHandleEvent (UInt16 libRefNum, emuptr eventP)
+{
+ return fExgMgr.ExgLibHandleEvent (libRefNum, eventP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibConnect
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibConnect (UInt16 libRefNum, emuptr exgSocketP)
+{
+ return fExgMgr.ExgLibConnect (libRefNum, exgSocketP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibAccept
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibAccept (UInt16 libRefNum, emuptr exgSocketP)
+{
+ return fExgMgr.ExgLibAccept (libRefNum, exgSocketP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibDisconnect
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibDisconnect (UInt16 libRefNum, emuptr exgSocketP, Err error)
+{
+ return fExgMgr.ExgLibDisconnect (libRefNum, exgSocketP, error);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibPut
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibPut (UInt16 libRefNum, emuptr exgSocketP)
+{
+ return fExgMgr.ExgLibPut (libRefNum, exgSocketP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibGet
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibGet (UInt16 libRefNum, emuptr exgSocketP)
+{
+ return fExgMgr.ExgLibGet (libRefNum, exgSocketP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibSend
+// ---------------------------------------------------------------------------
+// If aborting, return "user cancelled". Otherwise, call the wrapped method.
+
+UInt32 EmExgMgrImportWrapper::ExgLibSend (UInt16 libRefNum, emuptr exgSocketP, void* bufP, const UInt32 bufLen, Err* errP)
+{
+ if (fAborting)
+ {
+ *errP = exgErrUserCancel;
+ return 0;
+ }
+
+ return fExgMgr.ExgLibSend (libRefNum, exgSocketP, bufP, bufLen, errP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibReceive
+// ---------------------------------------------------------------------------
+// If aborting, return "user cancelled". Otherwise, call the wrapped method.
+// Also, set the emulator flag indicating that the emulation loop should
+// exit. Doing this allows the UI task to regain control, update dialogs
+// and check for Stop button clicks.
+
+UInt32 EmExgMgrImportWrapper::ExgLibReceive (UInt16 libRefNum, emuptr exgSocketP, void* bufP, const UInt32 bufLen, Err* errP)
+{
+ if (fAborting)
+ {
+ *errP = exgErrUserCancel;
+ return 0;
+ }
+
+ UInt32 result = fExgMgr.ExgLibReceive (libRefNum, exgSocketP, bufP, bufLen, errP);
+
+ EmAssert (gSession);
+ gSession->ScheduleSuspendTimeout ();
+
+ return result;
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibControl
+// ---------------------------------------------------------------------------
+// See if the operation is "beam completed". If so, let the EmFileImport
+// object know so that it can close the progress dialog and report any
+// errors. In all cases, also call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibControl (UInt16 libRefNum, UInt16 op, emuptr valueP, emuptr valueLenP)
+{
+ if (op == kHostExgLibBeamCompleted)
+ {
+ EmAliasErr<PAS> err (valueP);
+
+ fImporter.SetResult ((Err) err);
+ fImporter.SetDone ();
+ }
+
+ return fExgMgr.ExgLibControl (libRefNum, op, valueP, valueLenP);
+}
+
+
+// ---------------------------------------------------------------------------
+// ¥ EmExgMgrImportWrapper::ExgLibRequest
+// ---------------------------------------------------------------------------
+// Merely call the wrapped method.
+
+Err EmExgMgrImportWrapper::ExgLibRequest (UInt16 libRefNum, emuptr exgSocketP)
+{
+ return fExgMgr.ExgLibRequest (libRefNum, exgSocketP);
+}