📄 esrvstartup.cpp
字号:
//
// ESrvStartup.cpp
//
// exedll server startup code for EPOC servers
#include "esrvstartup.h"
#include "sserv.h"
#include "configservercmds.h"
class TServerStarter
{
TInt LoadAndStartInProcess(const TDesC& aFileName, const TDesC& aServerName);
TInt LoadAndStartInThread(const TDesC& aFileName, const TDesC& aServerName);
TThreadFunction iThreadFn;
public:
TServerStarter() {}
TServerStarter(TThreadFunction aFn) : iThreadFn(aFn) {}
TInt LoadAndStart(const TDesC& aFileName, const TDesC& aServerName);
};
TInt TServerStarter::LoadAndStartInProcess(const TDesC& aFileName, const TDesC& aServerName)
{
TRequestStatus status;
TServerStartSignal signal(status, aServerName);
// TPckg<TServerStartSignal> command_line(signal);
TPtr16 command_line(((TUint16 *)&signal), sizeof(signal) / 2, sizeof(signal) / 2);
RProcess server;
TInt err = server.Create( aFileName
, command_line
, TUidType(KNullUid, KNullUid, KNullUid)
, EOwnerThread
);
if (!err)
{
return err;
}
server.Resume();
server.Close();
// wait for launch to complete
User::WaitForRequest(status);
return status.Int();
}
TInt TServerStarter::LoadAndStartInThread(const TDesC& aFileName, const TDesC& aServerName)
{
// set up waiting apparatus
TRequestStatus status;
TServerStartSignal signal(status, aServerName);
// launch server thread (emulator)
RThread server;
TInt err = server.Create( aFileName
, iThreadFn
, KDefaultStackSize
, KMinHeapSize
, 100000
, &signal
, EOwnerProcess
);
if (err)
{
return err;
}
server.Resume();
server.Close();
// wait for launch to complete
User::WaitForRequest(status);
return status.Int();
}
TInt TServerStarter::LoadAndStart(const TDesC& aFileName, const TDesC& aServerName)
{
#ifdef __WINS__
return LoadAndStartInThread(aFileName, aServerName);
#else
return LoadAndStartInProcess(aFileName, aServerName);
#endif
}
// Create and start a new server.
CServer* NewServerL(const TDesC& aServerName)
{
// start scheduler and server
CActiveScheduler* pA = new (ELeave) CActiveScheduler;
CActiveScheduler::Install(pA);
CSmallServServer* pS = CSmallServServer::NewLC();
pS->StartL(aServerName);
CleanupStack::Pop();
return pS;
}
TInt ThreadStart(TServerStartSignal& aSignal)
{
__UHEAP_MARK;
// get thread that started us
RThread starter;
TInt err = starter.Open(aSignal.iId, EOwnerThread);
// debug output so we can see the server starting (for now!)
TBuf<100> message;
_LIT(KMessage, "ID: %x, Name: %S (res: %d)");
message.Format(KMessage, aSignal.iId, &aSignal.iServerName, err);
User::InfoPrint(message);
if (err == KErrNone)
{
// get cleanup stack
CTrapCleanup* cleanup = CTrapCleanup::New();
CServer* server = NULL;
// initialize all up to and excluding starting scheduler
if (cleanup)
{
TRAP(err, server = NewServerL(aSignal.iServerName));
}
else
{
err=KErrNoMemory;
}
// tell starting thread we've started
starter.RequestComplete(aSignal.iStatus, err);
starter.Close();
// start the active scheduler
if (err == KErrNone)
{
CActiveScheduler::Start();
}
// close things down
delete server;
delete CActiveScheduler::Current();
delete cleanup;
}
__UHEAP_MARKEND;
return err;
}
#ifdef __WINS__
// DLL entry point
GLDEF_C TInt E32Dll(TDllReason /*aReason*/)
{
return(KErrNone);
}
TInt ThreadFunction(TAny* aParam)
{
// get a handle to our code to prevent yank on client death
RLibrary lib;
_LIT(KTxtServerPanic,"WINS SERVER");
__ASSERT_ALWAYS(lib.Load(KServerFileName) == KErrNone, User::Panic(KTxtServerPanic,KErrGeneral));
// go with the thread
return ThreadStart(*REINTERPRET_CAST(TServerStartSignal*, aParam));
}
EXPORT_C TInt StartServer()
{
return (TInt) new TServerStarter(ThreadFunction);
}
#else
// this deceptively simple function uses a lot of stack space,
// that isn't needed throughout the lifetime of the server
// that's why it's separate from E32Main()
// don't be tempted to amalgamate it back again!
void SetSignal(TPckgBuf<TServerStartSignal>& aSignal)
{
TBuf<1000> cmdline;
RProcess().CommandLine(cmdline);
TPtr8 signal((TUint8*) cmdline.Ptr(), cmdline.Size(), cmdline.Size());
// signal.Copy(cmdline);
aSignal.Copy(signal);
}
GLDEF_C TInt E32Main()
{
TPckgBuf<TServerStartSignal>* signal = new TPckgBuf<TServerStartSignal>();
TInt result = KErrNoMemory;
if (signal)
{
SetSignal(*signal);
result = ThreadStart((*signal)());
}
delete signal;
return result;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -