Update contrib.
1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
23 #define WIN32_LEAN_AND_MEAN
24 #pragma warning( disable : 4201 ) // nonstandard extension used : nameless struct/union
28 #pragma warning( default : 4201 ) // nonstandard extension used : nameless struct/union
33 GLDEF_C TInt E32Dll(TDllReason)
39 // -------------- CLIENT IMPLEMENTATION -----------------------------
41 EXPORT_C void RWin32Stream::StartServer()
43 // Static function which spawns the three servers
46 CWin32Stream::StartServer(Kstdin);
47 CWin32Stream::StartServer(Kstdout);
48 CWin32Stream::StartServer(Kstderr);
51 EXPORT_C TInt RWin32Stream::Open(TInt aStream)
54 if (CWin32Stream::StreamName(aStream,stream)!=KErrNone)
56 TVersion version(1,0,0);
57 return CreateSession(stream,version,1); // only one message allowed - no concurrency
60 TInt RWin32Stream::CheckEOF(TRequestStatus& aStatus)
64 TRequestStatus* aStatusPtr=&aStatus;
65 User::RequestComplete(aStatusPtr,KErrEof);
69 EXPORT_C void RWin32Stream::Read(TRequestStatus& aStatus, TDes8& aDes)
71 Read(aStatus, aDes, aDes.MaxLength());
74 EXPORT_C void RWin32Stream::Read(TRequestStatus& aStatus, TDes8& aDes, TInt aLength)
76 if (CheckEOF(aStatus))
78 SendReceive(EWin32Read,TIpcArgs(&aDes,aLength),aStatus);
81 EXPORT_C void RWin32Stream::Write(TRequestStatus& aStatus, const TDesC8& aDes)
83 Write(aStatus, aDes, aDes.Length());
86 EXPORT_C void RWin32Stream::Write(TRequestStatus& aStatus, const TDesC8& aDes, TInt aLength)
88 // Write aLength bytes
91 if (CheckEOF(aStatus))
93 SendReceive(EWin32Write,TIpcArgs(&aDes,aLength),aStatus);
96 EXPORT_C void RWin32Stream::Flush(TRequestStatus& aStatus)
101 if (CheckEOF(aStatus))
103 SendReceive(EWin32Flush,aStatus);
106 // -------------- SERVER IMPLEMENTATION -----------------------------
108 // This is only relevant to WINS, so we know that in truth it's all a single address space
109 // and we can just operate on the descriptors directly.
111 //#define ESTW32_LOGGING // log the stream output into a file
113 TInt CWin32Stream::StreamName(TInt aStream, TDes& aBuf)
118 aBuf=_L("stdin"); break;
120 aBuf=_L("stdout"); break;
122 aBuf=_L("stderr"); break;
131 TRequestStatus* iStatus;
137 void CWin32Stream::StartServer(TInt aStream)
139 // Static function which spawns a server thread
142 TRequestStatus status(KRequestPending);
143 struct rendezvous rv;
146 TInt err=StreamName(aStream,rv.iStreamName);
149 err=rv.iCaller.Duplicate(RThread(),EOwnerProcess);
153 err=server.Create(rv.iStreamName,ThreadFunction,2048,4096,65536,(TAny*)&rv,EOwnerProcess);
157 User::WaitForRequest(status);
163 TInt CWin32Stream::ThreadFunction(TAny* aPtr)
165 struct rendezvous* rvp=(struct rendezvous*)aPtr;
166 TInt err=KErrNoMemory;
167 CWin32Stream* stream = new CWin32Stream();
169 err=stream->Init(rvp->iStream, rvp->iStreamName);
170 rvp->iCaller.RequestComplete(rvp->iStatus,err); // let the caller continue
174 stream->HandleMessage();
183 TInt CWin32Stream::Init(TInt aStream, const TDesC& aStreamName)
185 iHandle = GetStdHandle((STD_INPUT_HANDLE)-(int)aStream);
186 if (iHandle==INVALID_HANDLE_VALUE)
189 #ifdef ESTW32_LOGGING
190 static char* logs[3]={ "x:\\stdin.log", "x:\\stdout.log", "x:\\stderr.log"};
191 iLogHandle=CreateFile(logs[aStream], GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
193 iLogHandle=INVALID_HANDLE_VALUE;
196 return iServer.CreateGlobal(aStreamName);
199 void CWin32Stream::HandleMessage()
201 iServer.Receive(iMessage);
203 TInt f=iMessage.Function();
206 case RMessage2::EConnect:
207 case RMessage2::EDisConnect:
208 // RServer2 connection management - nothing interesting to be done
212 err=ReadStream(iMessage);
215 err=WriteStream(iMessage);
222 err=KErrNotSupported;
225 iMessage.Complete(err);
228 TInt CWin32Stream::ReadStream(RMessage2& aMessage)
230 TDes8* bufDes = (TDes8*)(aMessage.Ptr0());
231 int length = aMessage.Int1();
232 unsigned long nbytes;
234 if (ReadFile(iHandle, (TAny*)(bufDes->Ptr()), length, &nbytes, 0) && nbytes>0)
236 bufDes->SetLength(nbytes);
239 return MapWin32Error(KErrEof);
242 TInt CWin32Stream::WriteStream(RMessage2& aMessage)
244 TDesC8* bufDes = (TDesC8*)(aMessage.Ptr0());
245 int length = aMessage.Int1();
247 unsigned long nbytes;
249 #ifdef ESTW32_LOGGING
250 WriteFile(iLogHandle, bufDes->Ptr(), length, &nbytes, 0);
251 FlushFileBuffers(iLogHandle);
254 while (length>offset)
256 if (!WriteFile(iHandle, bufDes->Ptr()+offset, length-offset, &nbytes, 0))
257 return MapWin32Error(KErrEof);
263 void CWin32Stream::FlushStream()
265 FlushFileBuffers(iHandle); // don't care if it works or not
268 #include <winerror.h>
270 TInt CWin32Stream::MapWin32Error(TInt aDefault)
272 switch (GetLastError())
274 case ERROR_INVALID_HANDLE:
275 return KErrBadHandle;
276 case ERROR_HANDLE_EOF: