os/kernelhwsrv/kernel/eka/euser/rpipe.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
/**
sl@0
    17
 @file rpipe.cpp
sl@0
    18
 @internalTechnology
sl@0
    19
*/
sl@0
    20
sl@0
    21
#include <e32def.h>
sl@0
    22
#include <e32def_private.h>
sl@0
    23
#include "rpipe.h"
sl@0
    24
sl@0
    25
EXPORT_C TInt RPipe::Init()
sl@0
    26
/**
sl@0
    27
Static method to load the pipe device driver.  
sl@0
    28
sl@0
    29
@param None
sl@0
    30
sl@0
    31
@return KErrNone	If the pipe is successfully loaded, otherwise one of the 
sl@0
    32
					system wide error code.
sl@0
    33
*/
sl@0
    34
	{
sl@0
    35
	_LIT(KDriverLddFileName,"PIPELIB");
sl@0
    36
	return User::LoadLogicalDevice(KDriverLddFileName);
sl@0
    37
	}
sl@0
    38
sl@0
    39
sl@0
    40
EXPORT_C  TInt RPipe::Create( TInt aSize, RPipe& aReader, RPipe& aWriter, TOwnerType aTypeR, TOwnerType aTypeW)
sl@0
    41
/**
sl@0
    42
Static method to create a new, unnamed pipe. 
sl@0
    43
By default, any thread in the process can use the handle to access the Pipe. However, 
sl@0
    44
specifying EOwnerThread as the second and fourth parameter to this function, means 
sl@0
    45
that only the creating thread can use this  handle to access the Pipe.
sl@0
    46
sl@0
    47
@param	aReader			Handle to the read end of the pipe. If the call is successful, 
sl@0
    48
						this handle will be opened for reading.
sl@0
    49
@param aWriter			Handle to the write end of the pipe. If the call is successful, 
sl@0
    50
						this handle will be opened for writing.
sl@0
    51
@param aTypeR, aTypeW	The type of the ownership of the handle to be created for the 
sl@0
    52
						read and write
sl@0
    53
@param aSize			Size of the pipe to be created, in bytes.
sl@0
    54
sl@0
    55
@return KErrNone				Pipe successfully created and the read and write handles opened,
sl@0
    56
		KErrOverflow			Maximum number of pipes has been reached.
sl@0
    57
		KErrNoMemory			Insufficient memory to create pipe
sl@0
    58
		KErrArgument			If the specified size is negative or zero
sl@0
    59
		KErrInUse				The current handle has already been opened.
sl@0
    60
								otherwise one of the other system wide error codes
sl@0
    61
*/
sl@0
    62
sl@0
    63
	{
sl@0
    64
 	TInt err = aReader.Create(aSize, aTypeR);
sl@0
    65
	if (err != KErrNone )
sl@0
    66
		return err;
sl@0
    67
	else
sl@0
    68
		{
sl@0
    69
		err = aWriter.Open(aReader, aTypeW);	
sl@0
    70
		if(err!= KErrNone)
sl@0
    71
			aReader.Close();
sl@0
    72
		}
sl@0
    73
	return err;
sl@0
    74
	}
sl@0
    75
sl@0
    76
TInt RPipe::Create(TInt aSize, TOwnerType aType)
sl@0
    77
/**
sl@0
    78
Creates a Kernel side pipe and opens a handle for reading.
sl@0
    79
By default any thread in the process can use the handle to access to Read the Pipe. 
sl@0
    80
However, specifying EOwnerThread as the second parameter to this function, means 
sl@0
    81
that only the creating thread can use this handle to access the pipe.
sl@0
    82
sl@0
    83
@param	aSize			Size of the  pipe to create, in bytes.
sl@0
    84
sl@0
    85
@param	aType			The type of the handle to be created for the reading 
sl@0
    86
						end of the pipe
sl@0
    87
sl@0
    88
@return KErrNone				Pipe successfully created and handle opened for reading, 
sl@0
    89
		 KErrInUse				The current handle has already been opened.
sl@0
    90
		 KErrOverflow	      	Maximum number of pipes has been reached.
sl@0
    91
		 KErrNoMemory			Insufficient memory to create pipe
sl@0
    92
	 	 KErrArgument			If the specified size is negative or zero
sl@0
    93
								otherwise one of the other system wide error code
sl@0
    94
*/
sl@0
    95
	{
sl@0
    96
sl@0
    97
	// Check if the current handle is already opened for reading/writing
sl@0
    98
	if ( iHandle && HandleType())
sl@0
    99
		return KErrInUse;
sl@0
   100
	
sl@0
   101
	if(aSize <= 0 )
sl@0
   102
		return KErrArgument;
sl@0
   103
	
sl@0
   104
	// Perform the capability check and create the channel
sl@0
   105
	TInt err = DoCreate(Name(), VersionRequired(), KNullUnit, NULL, NULL, aType, ETrue);
sl@0
   106
	if (err!= KErrNone)	
sl@0
   107
			return err;
sl@0
   108
	
sl@0
   109
	// Create an un-named pipe with the specified size 
sl@0
   110
	err = DoControl(ECreateUnNamedPipe, (TAny*)&aSize);
sl@0
   111
	if (err>0)
sl@0
   112
		{
sl@0
   113
		iSize = DoControl(ESize);
sl@0
   114
		iHandleType = EReadChannel;
sl@0
   115
		iPipeHandle = err;
sl@0
   116
		err = KErrNone;
sl@0
   117
		}
sl@0
   118
	else
sl@0
   119
		{
sl@0
   120
		Close();
sl@0
   121
		}
sl@0
   122
	return err;
sl@0
   123
	}
sl@0
   124
sl@0
   125
sl@0
   126
EXPORT_C TInt RPipe::Open(RMessagePtr2 aMessage, TInt aParam, TOwnerType aType)
sl@0
   127
/**
sl@0
   128
Opens a handle to pipe using a handle number sent by a client to a server.
sl@0
   129
This function is called by the server.
sl@0
   130
sl@0
   131
@param	aMessage		The message pointer. 
sl@0
   132
sl@0
   133
@param	aParam			An index specifying which of the four message arguments contains the handle number. 
sl@0
   134
sl@0
   135
@param	aType			An enumeration whose enumerators define the ownership of this logical channel handle. 
sl@0
   136
						If not explicitly specified, EOwnerProcess is taken as default.
sl@0
   137
@return	KErrNone		if successful; 
sl@0
   138
		KErrArgument	if the value of aParam is outside the range 0-3; 
sl@0
   139
		KErrBadHandle	if not a valid handle; 
sl@0
   140
						otherwise one of the other system-wide error codes. 
sl@0
   141
sl@0
   142
sl@0
   143
*/
sl@0
   144
	{
sl@0
   145
	TInt err = RBusLogicalChannel::Open(aMessage, aParam,  aType);
sl@0
   146
	if (err)
sl@0
   147
		{
sl@0
   148
		return err;
sl@0
   149
		}
sl@0
   150
	err = DoControl(RPipe::EGetPipeInfo,&iHandleType,&iSize);
sl@0
   151
	return err;	
sl@0
   152
sl@0
   153
	}
sl@0
   154
	
sl@0
   155
sl@0
   156
EXPORT_C TInt RPipe::Open(TInt aArgumentIndex, TOwnerType aType)
sl@0
   157
/**
sl@0
   158
Opens the handle to pipe which is passed by a process to child process using 
sl@0
   159
RProcess.SetParameter function call. Pipe handle type remains same(i.e. if read handle is passed 
sl@0
   160
by process then read handle will be open).
sl@0
   161
sl@0
   162
@param	aArgumentIndex	An index that identifies the slot in the process environment 
sl@0
   163
						data that contains the handle number. This is a value relative 
sl@0
   164
						to zero, i.e. 0 is the first item/slot. This can range from 0 to 15.
sl@0
   165
sl@0
   166
@param	aType			The type of the handle to be created for the read/write end
sl@0
   167
sl@0
   168
@return	KErrNone		Pipe successfully created, 
sl@0
   169
						otherwise of the other system wide error code.
sl@0
   170
*/
sl@0
   171
	{
sl@0
   172
	
sl@0
   173
	TInt err = RBusLogicalChannel::Open(aArgumentIndex,aType);
sl@0
   174
	if (err)
sl@0
   175
		{
sl@0
   176
		return err;
sl@0
   177
		}
sl@0
   178
	err = DoControl(RPipe::EGetPipeInfo,&iHandleType,&iSize);
sl@0
   179
	return err;
sl@0
   180
	}
sl@0
   181
sl@0
   182
TInt RPipe::Open(const RPipe& aReader, TOwnerType aType)
sl@0
   183
/**
sl@0
   184
Opens a handle to write to a pipe. The pipe must have been created previously. 
sl@0
   185
By default any thread in the process can use the handle to access to write to 
sl@0
   186
the pipe. However, specifying EOwnerThread as the second parameter to this function, 
sl@0
   187
means that only the opening thread can use this handle to write to the pipe.
sl@0
   188
sl@0
   189
@param	aReader		Handle to the reading end of the pipe.
sl@0
   190
sl@0
   191
@param	aType		The type of the handle to be created for the write end
sl@0
   192
sl@0
   193
@return	KErrNone				Pipe successfully created, 
sl@0
   194
			KErrInUse			The current handle has already been opened
sl@0
   195
			KErrAccessDenied	The read handle is not open for reading
sl@0
   196
								otherwise of the other system wide error code.
sl@0
   197
*/
sl@0
   198
	{
sl@0
   199
	// Check if the current handle is already opened for reading/writing
sl@0
   200
	if ( iHandle && HandleType())
sl@0
   201
		return KErrInUse;
sl@0
   202
	
sl@0
   203
	// Check the read handle 
sl@0
   204
sl@0
   205
	if (aReader.HandleType() != EReadChannel) 
sl@0
   206
		return KErrAccessDenied;
sl@0
   207
	
sl@0
   208
	// Perform the capability check and create the channel
sl@0
   209
	TInt err = DoCreate(Name(),VersionRequired(), KNullUnit, NULL, NULL, aType, ETrue);
sl@0
   210
	if (err!= KErrNone)
sl@0
   211
		return err;
sl@0
   212
	
sl@0
   213
	// Obtained the handle number
sl@0
   214
	TInt id = aReader.PipeHandle();
sl@0
   215
	
sl@0
   216
sl@0
   217
	// Set the Write channel 
sl@0
   218
	err = DoControl(EOpenUnNamedPipe,(TAny*)&id);
sl@0
   219
	
sl@0
   220
	if( err == KErrNone)
sl@0
   221
		{
sl@0
   222
		iSize = DoControl(ESize);
sl@0
   223
		iHandleType  = EWriteChannel;
sl@0
   224
		iPipeHandle = id;	
sl@0
   225
		
sl@0
   226
		}
sl@0
   227
	else
sl@0
   228
		{
sl@0
   229
		Close();
sl@0
   230
		}
sl@0
   231
		
sl@0
   232
		
sl@0
   233
	return err;
sl@0
   234
	}
sl@0
   235
sl@0
   236
sl@0
   237
// Methods to Support Named Pipe
sl@0
   238
sl@0
   239
EXPORT_C TInt RPipe::Define(const TDesC& aName, TInt aSize)
sl@0
   240
/**
sl@0
   241
Static method to create a new, named pipe of a given size. Calling this method 
sl@0
   242
will create a new kernel object only. No user-side handles are created or opened.
sl@0
   243
sl@0
   244
@param	aName		Name to be assigned to the Kernel-side pipe object.
sl@0
   245
@param	aSize		Size of the pipe to create, in bytes.
sl@0
   246
sl@0
   247
@return KErrNone					Pipe successfully created.
sl@0
   248
		 KErrBadName				If the length of aName is greater than KMaxFileName
sl@0
   249
									or Null
sl@0
   250
		 KErrOverflow				Maximum number of pipes has been reached
sl@0
   251
		 KErrNoMemory				Insufficient memory to create pipe.
sl@0
   252
		 KErrArgument				if Size is negative
sl@0
   253
		 KErrAlreadyExist			If a pipe with the specified name already exist.
sl@0
   254
		 							otherwise one of the other system wide error code.
sl@0
   255
*/
sl@0
   256
	{
sl@0
   257
	// Code to check a valid Name field as per Symbian naming convention
sl@0
   258
	TInt err = User::ValidateName(aName);
sl@0
   259
	if(KErrNone!=err)
sl@0
   260
		return err;  
sl@0
   261
	
sl@0
   262
	if((aName.Length() > KMaxKernelName) || (aName.Length() == 0))
sl@0
   263
		return KErrBadName;
sl@0
   264
	
sl@0
   265
	if(aSize <= 0)
sl@0
   266
		return KErrArgument;
sl@0
   267
	
sl@0
   268
	// Perform the capability check and create the channel
sl@0
   269
	RPipe temp;
sl@0
   270
 	err = temp.DoCreate(Name(),VersionRequired(), KNullUnit, NULL, NULL);
sl@0
   271
	if (err!= KErrNone)
sl@0
   272
		return err;
sl@0
   273
	
sl@0
   274
		// Define
sl@0
   275
	TPipeInfoBuf aInfo;
sl@0
   276
	aInfo().isize = aSize;
sl@0
   277
	aInfo().iName.Copy(aName);
sl@0
   278
	
sl@0
   279
	// Define the Named pipe 
sl@0
   280
	err = temp.DoControl(EDefineNamedPipe, (TAny*)&aInfo);
sl@0
   281
	temp.Close();	
sl@0
   282
	return err;
sl@0
   283
sl@0
   284
	}
sl@0
   285
	
sl@0
   286
sl@0
   287
EXPORT_C TInt RPipe::Define( const  TDesC& aName, TInt aSize, const TSecurityPolicy& aPolicy)
sl@0
   288
/**
sl@0
   289
Static method to create a new, named pipe of a given size. Calling this method 
sl@0
   290
will create a new kernel object only. No user-side handles are created or opened.
sl@0
   291
sl@0
   292
@param	aName		Name to be assigned to the Kernel-side pipe object.
sl@0
   293
@param	aSize		Size of the pipe to create, in bytes.
sl@0
   294
sl@0
   295
@return KErrNone					Pipe successfully created.
sl@0
   296
		 KErrBadName				If the length of aName is greater than KMaxFileName
sl@0
   297
									or Null
sl@0
   298
		 KErrOverflow				Maximum number of pipes has been reached
sl@0
   299
		 KErrNoMemory				Insufficient memory to create pipe.
sl@0
   300
		 KErrArgument				if Size is negative
sl@0
   301
		 KErrPermissionDenied		Not sufficient capabiliites
sl@0
   302
		 KErrAlreadyExist			If a pipe with the specified name already exist.
sl@0
   303
		 							otherwise one of the other system wide error code.
sl@0
   304
*/
sl@0
   305
	{
sl@0
   306
	
sl@0
   307
	// Code to check a valid Name field as per Symbian naming convention
sl@0
   308
	TInt err = User::ValidateName(aName);
sl@0
   309
	if(KErrNone!=err)
sl@0
   310
		return err;  
sl@0
   311
	
sl@0
   312
	if((aName.Length() > KMaxKernelName) || (aName.Length() == 0))
sl@0
   313
		return KErrBadName;
sl@0
   314
	
sl@0
   315
	if(aSize <= 0)
sl@0
   316
		return KErrArgument;
sl@0
   317
	
sl@0
   318
	// Perform the capability check and create the channel
sl@0
   319
	RPipe temp;
sl@0
   320
 	err = temp.DoCreate(Name(),VersionRequired(), KNullUnit, NULL, NULL);
sl@0
   321
	if (err!= KErrNone)
sl@0
   322
		return err;
sl@0
   323
	
sl@0
   324
	// Define
sl@0
   325
	TPipeInfoBuf aInfo;
sl@0
   326
	aInfo().isize = aSize;
sl@0
   327
	aInfo().iName.Copy(aName);
sl@0
   328
	err = temp.DoControl(EDefineNamedPipe, (TAny*)&aInfo, (TAny*)&aPolicy);
sl@0
   329
	temp.Close();
sl@0
   330
		
sl@0
   331
	return err;
sl@0
   332
	
sl@0
   333
	
sl@0
   334
	}
sl@0
   335
	
sl@0
   336
		
sl@0
   337
sl@0
   338
EXPORT_C  TInt RPipe::Destroy( const TDesC& aName)
sl@0
   339
/**
sl@0
   340
Static method to destroy a previously created named pipe. Any data not read from 
sl@0
   341
the pipe will be discarded. This method will fail if there is any handles still 
sl@0
   342
open on the pipe or the calling thread as insufficient capabilities.
sl@0
   343
sl@0
   344
@param	aName		Name of the Kernel-side pipe object to destroy
sl@0
   345
		
sl@0
   346
@return  KErrNone					Pipe successfully destroyed
sl@0
   347
		 KErrInUse					The pipe still has one or more handle open to it
sl@0
   348
		 KErrPermissionDenied		Not sufficient capabiliites
sl@0
   349
		 KErrNotFound				If no kernel pipe exist with the specified name
sl@0
   350
		 							otherwise one of the other system wide error code.
sl@0
   351
*/
sl@0
   352
	{
sl@0
   353
	// Code to check a valid Name field as per Symbian naming convention
sl@0
   354
	TInt err = User::ValidateName(aName);
sl@0
   355
	if(KErrNone!=err)
sl@0
   356
		return err;  
sl@0
   357
	
sl@0
   358
	if((aName.Length() > KMaxKernelName) || (aName.Length() == 0))
sl@0
   359
		return KErrBadName;
sl@0
   360
	
sl@0
   361
	// Perform the capability check and create the channel
sl@0
   362
	RPipe temp;
sl@0
   363
 	err = temp.DoCreate(Name(),VersionRequired(), KNullUnit, NULL, NULL);
sl@0
   364
	if (err!= KErrNone)
sl@0
   365
		return err;
sl@0
   366
	
sl@0
   367
	TBuf8<KMaxKernelName> name;
sl@0
   368
	name.Copy(aName);
sl@0
   369
	
sl@0
   370
	// Destroy 
sl@0
   371
	err = temp.DoControl(EDestroyNamedPipe, (TAny*)&name, NULL);
sl@0
   372
	temp.Close();
sl@0
   373
		
sl@0
   374
	return err;
sl@0
   375
sl@0
   376
	}
sl@0
   377
sl@0
   378
sl@0
   379
EXPORT_C TInt RPipe::Open(const TDesC& aName, TMode aMode)
sl@0
   380
/**
sl@0
   381
Opens the pipe for the access mode specified. If the handle is opened to read or Write. 
sl@0
   382
The handle is opened regardless of whether or not there is a open handle at the other end.
sl@0
   383
sl@0
   384
If the handle is opened as " Write but Fail On No Readers" the call will fail unless there 
sl@0
   385
is atleast one handle open for reading at the other end.
sl@0
   386
sl@0
   387
@param		aName		Name of the kernel-side pipe object to destroy
sl@0
   388
@param		aMode		Access mode for the handle.
sl@0
   389
sl@0
   390
@return 	KErrNone				Handle successfully opened.
sl@0
   391
			KErrBadName				If the length of aName is greater than KMaxFileName or Null
sl@0
   392
			KErrInUse				The pipe still has one or more handle open to it.
sl@0
   393
			KErrPermissionDenied	Not sufficient capabiliites
sl@0
   394
			KErrNotFond				If there is no kernel instance with the specified name
sl@0
   395
			KErrNotReady			Open Fails when no Readers is available while opening
sl@0
   396
									With TMode = EOpenToWriteButFailOnNoReaders
sl@0
   397
									otherwise one of the other system wide error code.
sl@0
   398
									
sl@0
   399
*/
sl@0
   400
	{
sl@0
   401
sl@0
   402
	// Check if the current handle is already opened for reading/writing
sl@0
   403
	if ( iHandle && HandleType())
sl@0
   404
		return KErrInUse;	
sl@0
   405
	
sl@0
   406
	TInt err = User::ValidateName(aName);
sl@0
   407
	if(KErrNone!=err)
sl@0
   408
		return err; 
sl@0
   409
	
sl@0
   410
	if((aName.Length() > KMaxKernelName) || (aName.Length() == 0))
sl@0
   411
		return KErrBadName;
sl@0
   412
	
sl@0
   413
	// Perform the capability check and create the channel
sl@0
   414
	err = DoCreate(Name(),VersionRequired(), KNullUnit, NULL, NULL);
sl@0
   415
	if (err!= KErrNone)
sl@0
   416
		return err;
sl@0
   417
	
sl@0
   418
	TBuf8<KMaxKernelName> name;
sl@0
   419
	name.Copy(aName);
sl@0
   420
sl@0
   421
sl@0
   422
    if (aMode == EOpenToRead)
sl@0
   423
    	{
sl@0
   424
 		err = DoControl(EOpenToReadNamedPipe,(TAny*)&name);
sl@0
   425
		if(err == KErrNone)
sl@0
   426
			{
sl@0
   427
			iSize = DoControl(ESize);
sl@0
   428
			iHandleType = EReadChannel;		
sl@0
   429
			}
sl@0
   430
		else 
sl@0
   431
			Close();
sl@0
   432
 		}
sl@0
   433
 	else if(aMode == EOpenToWrite)
sl@0
   434
 		{
sl@0
   435
 		err = DoControl(EOpenToWriteNamedPipe, (TAny*)&name);
sl@0
   436
		if(err == KErrNone)
sl@0
   437
			{
sl@0
   438
			iSize = DoControl(ESize);
sl@0
   439
			iHandleType = EWriteChannel;			 			
sl@0
   440
			}
sl@0
   441
		else
sl@0
   442
			Close();
sl@0
   443
 	}
sl@0
   444
 	else if (aMode == EOpenToWriteNamedPipeButFailOnNoReaders)
sl@0
   445
 		{
sl@0
   446
 		err = DoControl(EOpenToWriteButFailOnNoReaderNamedPipe, (TAny*)&name);
sl@0
   447
		if(err == KErrNone)
sl@0
   448
			{
sl@0
   449
			iSize = DoControl(ESize);
sl@0
   450
			iHandleType = EWriteChannel;	
sl@0
   451
			}
sl@0
   452
		else
sl@0
   453
		Close();	
sl@0
   454
 		}
sl@0
   455
 	else
sl@0
   456
 		{	
sl@0
   457
 		Close();	
sl@0
   458
 		err = KErrArgument;
sl@0
   459
 		}
sl@0
   460
	return err;
sl@0
   461
	}
sl@0
   462
sl@0
   463
sl@0
   464
sl@0
   465
EXPORT_C void RPipe::Wait(const TDesC& aName, TRequestStatus& aStatus)
sl@0
   466
/**
sl@0
   467
Block the thread until the other end of the pipe is opened for reading. If the other end
sl@0
   468
is already opened for reading the call will not block and status will complete immediately
sl@0
   469
This function will be deprecated , use WaitForReader.
sl@0
   470
Please note that Wait API will open a valid Write End of the pipe if not opened already.
sl@0
   471
User need not open write end of the pipe again after Wait call.
sl@0
   472
sl@0
   473
sl@0
   474
@param	aName			Name of the kernel-side pipe object to wait for 
sl@0
   475
@param  aStatus			Status request that will complete when the other end is opened
sl@0
   476
						for reading.
sl@0
   477
sl@0
   478
@return  KErrNone				Request is successfully registered
sl@0
   479
		 KErrBadName			If the length of aName is greater then KMaxFileName or NULL
sl@0
   480
		 KErrInUse				A notifier of this type has already been registered.
sl@0
   481
		 KErrPermissionDenied	Not sufficient capabiliites
sl@0
   482
		 						otherwise one of the other system wide error code.
sl@0
   483
*/
sl@0
   484
	{
sl@0
   485
	// To wait for Reader end pass flag as EWaitForReader.
sl@0
   486
	TInt aFlag = EWaitForReader;
sl@0
   487
	Wait(aName, aStatus , aFlag );
sl@0
   488
	}
sl@0
   489
sl@0
   490
sl@0
   491
EXPORT_C  void RPipe::CancelWait()
sl@0
   492
/**
sl@0
   493
Cancel previous call to RPipe::Wait(), RPipe::WaitForReader (), RPipe::WaitForWriter ()
sl@0
   494
sl@0
   495
@param	None
sl@0
   496
@return None
sl@0
   497
*/
sl@0
   498
	{
sl@0
   499
	if(!iHandle)
sl@0
   500
		return;	
sl@0
   501
	DoCancel(ECancelWaitNotification);
sl@0
   502
	}
sl@0
   503
sl@0
   504
sl@0
   505
sl@0
   506
// Generic Methods
sl@0
   507
sl@0
   508
EXPORT_C void RPipe::Close()
sl@0
   509
/**
sl@0
   510
Close the handle. This method exhibits different behaviour depending upon whether the pipe
sl@0
   511
is named or unnamed.
sl@0
   512
Named pipes are allowed to persist without any open handles. Closing the last handle on a 
sl@0
   513
named pipe will not destroy the kernel-side object. For an unnamed pipe, closing the last 
sl@0
   514
handle will destroy the kernel-side pipe object. Any unread data in the pipe will be 
sl@0
   515
discarded.
sl@0
   516
An attempt to close an unnamed pipe will have no effect. Closing a handle will not affect 
sl@0
   517
the state of any other handles that may be open on the pipe.
sl@0
   518
sl@0
   519
@param		None
sl@0
   520
sl@0
   521
@return		None
sl@0
   522
*/
sl@0
   523
	{
sl@0
   524
	if(!iHandle)
sl@0
   525
		return;
sl@0
   526
	RHandleBase::Close();
sl@0
   527
	}
sl@0
   528
sl@0
   529
sl@0
   530
sl@0
   531
sl@0
   532
EXPORT_C TInt RPipe::MaxSize()
sl@0
   533
/**
sl@0
   534
Returns the total size, in bytes, of the Pipe
sl@0
   535
@param		None
sl@0
   536
sl@0
   537
@return 	>= 0				Size of the pipe in bytes
sl@0
   538
			KErrBadHandle		The handle is not open
sl@0
   539
								otherwise one of the other system wide error code.
sl@0
   540
*/
sl@0
   541
	{
sl@0
   542
	if (!iHandle )
sl@0
   543
		 return KErrBadHandle;
sl@0
   544
	
sl@0
   545
	if(iHandleType == EReadChannel || iHandleType == EWriteChannel)
sl@0
   546
		return iSize;
sl@0
   547
	else
sl@0
   548
 		return KErrAccessDenied;
sl@0
   549
	}
sl@0
   550
sl@0
   551
sl@0
   552
sl@0
   553
EXPORT_C TInt RPipe::Read(TDes8& aMsg, TInt aNumByte)
sl@0
   554
/**
sl@0
   555
This is non-blocking synchronous method to read aNumByte bytes from the pipe into the 
sl@0
   556
descriptor aMsg and returns the number of bytes read. If the pipe is empty the call will
sl@0
   557
immediately return a value of zero to indicate that no data was read
sl@0
   558
sl@0
   559
A successful RPipe::Read() operation will free up more space in the pipe.
sl@0
   560
sl@0
   561
@param	aMsg		Descriptor to receive data
sl@0
   562
@param	aNumByte	Number of bytes to be received.
sl@0
   563
sl@0
   564
@return 	>0					Amount of data read from the pipe, in bytes.
sl@0
   565
			KErrUnderFlow		The pipe was empty, no data was read
sl@0
   566
			KErrAccessDenied	An attempt has been made to read from a handle 
sl@0
   567
								has been opened for writing.
sl@0
   568
			KErrBadHandle		An attempt has been made to read from a handle
sl@0
   569
								that has not been opened.
sl@0
   570
			KErrNotReady	    Write end is closed and Pipe is empty.
sl@0
   571
			0					No Data is available
sl@0
   572
								otherwise one of the other system wide error code.
sl@0
   573
*/
sl@0
   574
	{
sl@0
   575
	// Check for the error condition
sl@0
   576
	if (!iHandle)
sl@0
   577
		return KErrBadHandle;
sl@0
   578
	
sl@0
   579
	// Check for KErrArgument
sl@0
   580
	if(aNumByte > aMsg.MaxLength())
sl@0
   581
		return KErrArgument;
sl@0
   582
sl@0
   583
	if(iHandleType != EReadChannel)
sl@0
   584
		return KErrAccessDenied;
sl@0
   585
sl@0
   586
	return DoControl(ERead, (TAny*)&aMsg, (TAny*)&aNumByte);
sl@0
   587
	}
sl@0
   588
sl@0
   589
sl@0
   590
sl@0
   591
sl@0
   592
EXPORT_C TInt RPipe::Write( const TDesC8& aData, TInt aNumByte)
sl@0
   593
/**
sl@0
   594
This is non-blocking synchronous method to write data from aData. If the pipe is 
sl@0
   595
full it will return immediately with KErrOverFlow
sl@0
   596
sl@0
   597
@param	 aData			Descriptor from which data has to be written to the pipe
sl@0
   598
sl@0
   599
@return	>0					Amount of data written to the pipe, in bytes
sl@0
   600
		KErrAccessDenied	An attempt has been made to write to a handle that
sl@0
   601
							has been opened for reading.
sl@0
   602
		KErrArgument		If the size is more then aData's length
sl@0
   603
		KErrBadName
sl@0
   604
		KErrOverFlow		The pipe is full. No data was inserted into the pipe.
sl@0
   605
		KErrBadHandle		An attempt has been made to read from a handle that
sl@0
   606
							has not been opened.
sl@0
   607
		KErrCompletion		If the specified size is greater then the available size.
sl@0
   608
		KErrNotReady	    Read end is closed.
sl@0
   609
							otherwise one of the other system wide error code.
sl@0
   610
	
sl@0
   611
*/
sl@0
   612
	{
sl@0
   613
	// Check for the error condition
sl@0
   614
	if (!iHandle)
sl@0
   615
		return KErrBadHandle;
sl@0
   616
	
sl@0
   617
	// Check for KErrArgument
sl@0
   618
	if(aNumByte > aData.Length())
sl@0
   619
		return KErrArgument;
sl@0
   620
	
sl@0
   621
	if(iHandleType == EReadChannel)
sl@0
   622
		return KErrAccessDenied;
sl@0
   623
sl@0
   624
	return DoControl(EWrite, (TAny*)&aData, (TAny*)&aNumByte);
sl@0
   625
sl@0
   626
	}
sl@0
   627
sl@0
   628
sl@0
   629
EXPORT_C TInt RPipe::ReadBlocking( TDes8& aMsg, TInt aNumByte)
sl@0
   630
/**
sl@0
   631
This is synchronous, blocking read operation. If the pipe is empty the client thread will 
sl@0
   632
be blocked until data become available. A successful RPipe::ReadBlocking() operation will
sl@0
   633
free up more space in the pipe. This method is accompanied by data notification method to
sl@0
   634
complete the blocking mechanism
sl@0
   635
sl@0
   636
@param		aMsg		Descriptor to receive data
sl@0
   637
@param		aNumByte	Number of bytes to be received
sl@0
   638
sl@0
   639
@return 	>0					Amount of data read from the pipe in bytes.
sl@0
   640
			KErrAccessDenied	Am attempt has been made to read from the handle that
sl@0
   641
								has been opened for writing.
sl@0
   642
			KErrBadHandle		Am attempt has been made to read from a handle that has
sl@0
   643
								not been opened.
sl@0
   644
			KErrArgument 		if the size is negative.
sl@0
   645
			KErrInUse			If the call is active from some another thread.
sl@0
   646
			KErrNotReady	    Write end is closed and Pipe is empty.
sl@0
   647
								otherwise one of the system wide error code.
sl@0
   648
*/
sl@0
   649
	{
sl@0
   650
sl@0
   651
	TRequestStatus stat = KRequestPending;
sl@0
   652
 	TInt err = KErrNone;
sl@0
   653
 	
sl@0
   654
	// Check for the error condition
sl@0
   655
	if (!iHandle)
sl@0
   656
		return KErrBadHandle;
sl@0
   657
	
sl@0
   658
	if(aNumByte <= 0)
sl@0
   659
		return KErrArgument;
sl@0
   660
sl@0
   661
	if(iHandleType != EReadChannel)
sl@0
   662
		return KErrAccessDenied;
sl@0
   663
sl@0
   664
	// Asynchronous request to notify the data available.
sl@0
   665
	do 
sl@0
   666
		{
sl@0
   667
	 	stat = KRequestPending;
sl@0
   668
		DoRequest(EReadBlocking, stat);
sl@0
   669
		User::WaitForRequest(stat);
sl@0
   670
		err = stat.Int();
sl@0
   671
		if (err == KErrInUse || err == KErrNotReady)
sl@0
   672
			{
sl@0
   673
			return err;
sl@0
   674
			}
sl@0
   675
			
sl@0
   676
		// Synchronous read operation
sl@0
   677
	 	err = DoControl(ERead, (TAny*)&aMsg, (TAny*)&aNumByte); 
sl@0
   678
	 	if (err == KErrNotReady)
sl@0
   679
	 		return err;
sl@0
   680
	 	
sl@0
   681
	 	} while (err == 0);
sl@0
   682
	
sl@0
   683
 	return err;	
sl@0
   684
	}
sl@0
   685
sl@0
   686
sl@0
   687
sl@0
   688
EXPORT_C  TInt RPipe::WriteBlocking(const TDesC8& aData, TInt aNumByte)
sl@0
   689
/**
sl@0
   690
This is a synchronous, blocking write operation. It will attempt to
sl@0
   691
write aNumByte's worth of data to the pipe, waiting till space is available.
sl@0
   692
If aNumByte is less than or equal to the pipe size, MaxSize(), the write
sl@0
   693
shall be atomic (w.r.t other threads sharing this channel), otherwise
sl@0
   694
the data will be split into multiple atomic writes of pipe size
sl@0
   695
(except, of course, if less than MaxSize bytes of data remain to be written).
sl@0
   696
sl@0
   697
@param		aData		Descriptor from which data has to be written to the pipe.
sl@0
   698
@param      aNumByte	Amount of data to be written to the pipe
sl@0
   699
sl@0
   700
@return 	>0					Amount of data written to the pipe, in bytes.
sl@0
   701
			KErrAccessDenied	An attempt has been made to write to a handle that
sl@0
   702
								has been opened for reading.
sl@0
   703
			KErrBadHandle		An attempt has been made to read from a handle that has
sl@0
   704
								not been open.
sl@0
   705
			KErrArgument 		if the size is negative.
sl@0
   706
			KErrNotReady	    Read end is closed.
sl@0
   707
								otherwise one of the other system wide error code.
sl@0
   708
*/				
sl@0
   709
	{
sl@0
   710
	TBool first = ETrue;
sl@0
   711
	TRequestStatus stat = KRequestPending;
sl@0
   712
 	TInt err = 0;
sl@0
   713
 	TInt index = 0;
sl@0
   714
 	TInt writeindex =0;
sl@0
   715
 	TPtrC8 tmp;
sl@0
   716
	TInt r = aNumByte;
sl@0
   717
sl@0
   718
	// Check for the error condition
sl@0
   719
	if (!iHandle)
sl@0
   720
		return KErrBadHandle;
sl@0
   721
	
sl@0
   722
	
sl@0
   723
	if(aNumByte <= 0)
sl@0
   724
		return KErrArgument;
sl@0
   725
	
sl@0
   726
	
sl@0
   727
	if(iHandleType == EReadChannel)
sl@0
   728
		return KErrAccessDenied;
sl@0
   729
	
sl@0
   730
	if (aNumByte <= iSize)
sl@0
   731
		writeindex = aNumByte;
sl@0
   732
	else 
sl@0
   733
		writeindex = iSize;
sl@0
   734
	
sl@0
   735
	do
sl@0
   736
		{			
sl@0
   737
		// Asynchronous request to notify the space available.
sl@0
   738
 		stat = KRequestPending;
sl@0
   739
 		DoRequest(EWriteBlocking, stat,(TAny*)&writeindex);
sl@0
   740
 		User::WaitForRequest(stat);
sl@0
   741
 		err = stat.Int();
sl@0
   742
 		if (err == KErrInUse || err == KErrNotReady) 
sl@0
   743
 			{
sl@0
   744
 			return err;
sl@0
   745
 			}
sl@0
   746
 									
sl@0
   747
		// Synchronous write operation
sl@0
   748
		tmp.Set(aData.Ptr()+index, writeindex);
sl@0
   749
 		err = DoControl(EWrite, (TAny*)&tmp, (TAny*)&writeindex); 
sl@0
   750
 		if(err == KErrNotReady)
sl@0
   751
 			{
sl@0
   752
 			return err;
sl@0
   753
 			}
sl@0
   754
		else
sl@0
   755
			{
sl@0
   756
			if ( err == aNumByte)  
sl@0
   757
				{
sl@0
   758
				first = EFalse;
sl@0
   759
				}		
sl@0
   760
			else
sl@0
   761
				{
sl@0
   762
				index  = index + err;
sl@0
   763
				aNumByte = r - index;
sl@0
   764
				if(aNumByte < iSize)
sl@0
   765
					writeindex = aNumByte;
sl@0
   766
				}
sl@0
   767
			}	
sl@0
   768
		}while(first);
sl@0
   769
		
sl@0
   770
	return r;	
sl@0
   771
	}
sl@0
   772
sl@0
   773
sl@0
   774
EXPORT_C void RPipe::NotifyDataAvailable(TRequestStatus& aStatus)
sl@0
   775
/**
sl@0
   776
This method registers the request status object to be completed when data become
sl@0
   777
available in the pipe. 
sl@0
   778
sl@0
   779
@param	aStatus			Status request that will complete when Data is available.
sl@0
   780
sl@0
   781
@return KErrNone				Successfully registered.
sl@0
   782
		KErrAccessDenied		Am attempt has been made to register a space available
sl@0
   783
								notification on a handle that has not been opened for
sl@0
   784
								reading.
sl@0
   785
		KErrCompletion			The request was NOT registered as the condition succeeded before wait.
sl@0
   786
		KErrBadHandle			The handle is not yet associated with a kernel pipe
sl@0
   787
								otherwise of the other system wide error code.
sl@0
   788
sl@0
   789
sl@0
   790
*/
sl@0
   791
	{
sl@0
   792
	TInt err = KErrNone;
sl@0
   793
	if(!iHandle)
sl@0
   794
		{	
sl@0
   795
		err = KErrBadHandle;
sl@0
   796
		}
sl@0
   797
	else if(iHandleType != EReadChannel)
sl@0
   798
		{
sl@0
   799
		err = KErrAccessDenied;
sl@0
   800
		}
sl@0
   801
	if(err!= KErrNone)
sl@0
   802
		{
sl@0
   803
		ReqComplete(aStatus, err);
sl@0
   804
		return;
sl@0
   805
		}
sl@0
   806
	aStatus = KRequestPending;
sl@0
   807
	DoRequest(EDataAvailable, aStatus);
sl@0
   808
	}
sl@0
   809
sl@0
   810
sl@0
   811
sl@0
   812
sl@0
   813
EXPORT_C void RPipe::NotifySpaceAvailable(TInt aSize, TRequestStatus& aStatus)
sl@0
   814
/**
sl@0
   815
This method registers the request status object to be completed when at least
sl@0
   816
aSize bytes are available for writing data into the pipe.
sl@0
   817
sl@0
   818
@param	aSize			Amount of space to wait for in the pipe.
sl@0
   819
@param	aStatus			Status request that will complete when aSize
sl@0
   820
						bytes become available.
sl@0
   821
sl@0
   822
@returns KErrNone				Successfully registered.
sl@0
   823
		 KErrAccessDenied		An attempt has been made to register a space
sl@0
   824
								available notification on a handle that has
sl@0
   825
								not been opened for writing.
sl@0
   826
		 KErrArgument			If the size is negative, zero, or greater than maximum pipe size
sl@0
   827
		 KErrBadHandle			The handle is not yet associated with a kernel pipe
sl@0
   828
		 						otherwise one of the other system wide error code
sl@0
   829
sl@0
   830
sl@0
   831
*/
sl@0
   832
	{
sl@0
   833
	
sl@0
   834
	TInt err = KErrNone;
sl@0
   835
	if(!iHandle)
sl@0
   836
		{	
sl@0
   837
		err = KErrBadHandle;
sl@0
   838
		}
sl@0
   839
	else if(iHandleType == EReadChannel)
sl@0
   840
		{
sl@0
   841
		err = KErrAccessDenied;
sl@0
   842
		}
sl@0
   843
	else if(aSize <= 0 || aSize > MaxSize())
sl@0
   844
		{
sl@0
   845
		err = KErrArgument;
sl@0
   846
		}
sl@0
   847
		
sl@0
   848
	if(err!= KErrNone)
sl@0
   849
		{
sl@0
   850
		ReqComplete(aStatus, err);
sl@0
   851
		return;
sl@0
   852
		}
sl@0
   853
	aStatus = KRequestPending;
sl@0
   854
	DoRequest(ESpaceAvailable, aStatus, (TAny*)&aSize);
sl@0
   855
	}
sl@0
   856
sl@0
   857
sl@0
   858
sl@0
   859
sl@0
   860
EXPORT_C TInt RPipe::CancelSpaceAvailable()
sl@0
   861
/**
sl@0
   862
Cancels an outstanding space available notifier request.
sl@0
   863
sl@0
   864
@param		None
sl@0
   865
sl@0
   866
@returns KErrNone			Successfully cancelled the SpaceAvailable request.
sl@0
   867
		 KErrBadHandle		An attempt has been made to Cancel Data Available with a 
sl@0
   868
							handle which has not been associated with any kernel pipe.
sl@0
   869
		 KErrAccessDenied	An attempt has been made to cancel a space available
sl@0
   870
							notification on a handle that has been opened for reading.
sl@0
   871
		 					other wise on of the other system wide error code.
sl@0
   872
*/
sl@0
   873
	{
sl@0
   874
	if(!iHandle)
sl@0
   875
		return KErrBadHandle;
sl@0
   876
	
sl@0
   877
	if(iHandleType != EWriteChannel)
sl@0
   878
		return KErrAccessDenied;
sl@0
   879
	
sl@0
   880
	DoCancel(ECancelSpaceAvailable);
sl@0
   881
	
sl@0
   882
	return KErrNone;
sl@0
   883
	}
sl@0
   884
sl@0
   885
sl@0
   886
sl@0
   887
EXPORT_C TInt RPipe::CancelDataAvailable()
sl@0
   888
/**
sl@0
   889
Cancels an outstanding data available notifier request.
sl@0
   890
sl@0
   891
@param		None
sl@0
   892
@return	KErrNone			Successfully cancelled the DataAvailable request.
sl@0
   893
		KErrBadHandle		An attempt has been made to Cancel Data Available with a 
sl@0
   894
							handle which has not been associated with any kernel pipe.
sl@0
   895
		KErrAccessDenied	Am attempt has been made to cancel a data available
sl@0
   896
							notification on a handle that has been opened for writing.
sl@0
   897
							otherwise one of the other system wide error code
sl@0
   898
*/
sl@0
   899
	{
sl@0
   900
	if(!iHandle)
sl@0
   901
		return KErrBadHandle;
sl@0
   902
	
sl@0
   903
	if(iHandleType != EReadChannel)
sl@0
   904
		return KErrAccessDenied;
sl@0
   905
	
sl@0
   906
	DoCancel(ECancelDataAvailable);
sl@0
   907
	
sl@0
   908
	return KErrNone;
sl@0
   909
	}
sl@0
   910
sl@0
   911
sl@0
   912
EXPORT_C void RPipe::Flush()
sl@0
   913
/**
sl@0
   914
This method will empty the pipe of all data
sl@0
   915
sl@0
   916
@param	None
sl@0
   917
@returns None
sl@0
   918
*/
sl@0
   919
	{
sl@0
   920
		DoControl(EFlushPipe);
sl@0
   921
	}
sl@0
   922
sl@0
   923
sl@0
   924
EXPORT_C TInt RPipe::HandleType()const 
sl@0
   925
/**
sl@0
   926
This method returns the Type of operation it can perform with the current handle.
sl@0
   927
@param None
sl@0
   928
@returns 
sl@0
   929
		EReadChannel	If the current handle is associated to the kernel-side 
sl@0
   930
						pipe object as to perform Read operations.
sl@0
   931
		EWriteChannel	If the  current handle is associated to the kernel-side
sl@0
   932
						pipe object as to perform Write operations.
sl@0
   933
		KErrBadHandle   If the handle is not associated with Kernel-side object.
sl@0
   934
						otherwise one of the other system wide error code
sl@0
   935
*/
sl@0
   936
	{
sl@0
   937
	if(!iHandle)
sl@0
   938
		return KErrBadHandle;
sl@0
   939
	else
sl@0
   940
		return iHandleType;
sl@0
   941
	}
sl@0
   942
sl@0
   943
sl@0
   944
EXPORT_C TInt RPipe::Size()
sl@0
   945
/**
sl@0
   946
Returns the available data in the pipe
sl@0
   947
@param	None
sl@0
   948
@return >= 0				Amount of data available in the pipe
sl@0
   949
		KErrBadHandle		The handle is not yet opened 
sl@0
   950
							otherwise one of the other system wide error code.
sl@0
   951
sl@0
   952
*/
sl@0
   953
	{
sl@0
   954
	if(!iHandle)
sl@0
   955
		return KErrBadHandle;
sl@0
   956
	
sl@0
   957
	return DoControl(EDataAvailableCount);	
sl@0
   958
	}
sl@0
   959
sl@0
   960
sl@0
   961
TInt RPipe::PipeHandle()const
sl@0
   962
/**
sl@0
   963
Returns the id of Pipe it has created.
sl@0
   964
*/
sl@0
   965
	{
sl@0
   966
	return iPipeHandle;
sl@0
   967
	}
sl@0
   968
sl@0
   969
sl@0
   970
void RPipe::ReqComplete(TRequestStatus& aStatus, TInt err)
sl@0
   971
	{
sl@0
   972
	TRequestStatus* req=(&aStatus);
sl@0
   973
	User::RequestComplete(req,err);	
sl@0
   974
	}
sl@0
   975
	
sl@0
   976
EXPORT_C void RPipe::WaitForReader(const TDesC& aName, TRequestStatus& aStatus)
sl@0
   977
/**
sl@0
   978
Block the thread until the other end of the pipe is opened for reading. If the other end
sl@0
   979
is already opened for reading the call will not block and status will complete immediately.
sl@0
   980
sl@0
   981
Please note that WaitForReader API will open a valid Write End of the pipe if not opened already.
sl@0
   982
User need not open write end of the pipe again after WaitForReader call.
sl@0
   983
sl@0
   984
@param	aName			Name of the kernel-side pipe object to wait for 
sl@0
   985
@param  aStatus			Status request that will complete when the other end is opened
sl@0
   986
						for reading.
sl@0
   987
sl@0
   988
@return  KErrNone				Request is successfully registered
sl@0
   989
		 KErrBadName			If the length of aName is greater then KMaxFileName or NULL
sl@0
   990
		 KErrInUse				A notifier of this type has already been registered.
sl@0
   991
		 KErrPermissionDenied	Not sufficient capabiliites
sl@0
   992
		 KErrAccessDenied		WaitForReader request is issued using Read handle.
sl@0
   993
		 						otherwise one of the other system wide error code.
sl@0
   994
*/
sl@0
   995
	{
sl@0
   996
	// To wait for Reader end pass flag as EWaitForReader.
sl@0
   997
	TInt aFlag = EWaitForReader;
sl@0
   998
	Wait(aName, aStatus , aFlag );
sl@0
   999
	}
sl@0
  1000
sl@0
  1001
EXPORT_C void RPipe::WaitForWriter(const TDesC& aName, TRequestStatus& aStatus)
sl@0
  1002
/**
sl@0
  1003
Block the thread until the other end of the pipe is opened for writing. If the other end
sl@0
  1004
is already opened for writing the call will not block and status will complete immediately
sl@0
  1005
sl@0
  1006
Please note that WaitForWriter API will open a valid Read End of the pipe if not opened already.
sl@0
  1007
User need not open read end of the pipe again after WaitForWriter call.
sl@0
  1008
sl@0
  1009
@param	aName			Name of the kernel-side pipe object to wait for 
sl@0
  1010
@param  aStatus			Status request that will complete when the other end is opened
sl@0
  1011
						for writing.
sl@0
  1012
sl@0
  1013
@return  KErrNone				Request is successfully registered
sl@0
  1014
		 KErrBadName			If the length of aName is greater then KMaxFileName or NULL
sl@0
  1015
		 KErrInUse				A notifier of this type has already been registered.
sl@0
  1016
		 KErrPermissionDenied	Not sufficient capabiliites
sl@0
  1017
		 KErrAccessDenied		WaitForWriter request is issued using Write handle.
sl@0
  1018
		 						otherwise one of the other system wide error code.
sl@0
  1019
*/
sl@0
  1020
	{
sl@0
  1021
	// To wait for Writer end pass flag as EWaitForWriter.
sl@0
  1022
	TInt aFlag = EWaitForWriter;
sl@0
  1023
	Wait(aName, aStatus , aFlag );
sl@0
  1024
	}
sl@0
  1025
sl@0
  1026
sl@0
  1027
void RPipe::Wait(const TDesC& aName, TRequestStatus& aStatus , TInt aChoice)
sl@0
  1028
/**
sl@0
  1029
Block the thread until the other end of the pipe is opened for reading (or writing). If the other end
sl@0
  1030
is already opened for reading (or writing) the call will not block and status will complete immediately.
sl@0
  1031
sl@0
  1032
sl@0
  1033
sl@0
  1034
@param	aName			Name of the kernel-side pipe object to wait for 
sl@0
  1035
@param  aStatus			Status request that will complete when the other end is opened
sl@0
  1036
						for reading (or Writing).
sl@0
  1037
@param  aChoice			EWaitForReader for WaitForReader.
sl@0
  1038
						EWaitForWriter for WaitForWriter.
sl@0
  1039
sl@0
  1040
@return  KErrNone				Request is successfully registered
sl@0
  1041
		 KErrBadName			If the length of aName is greater then KMaxFileName or NULL
sl@0
  1042
		 KErrInUse				A notifier of this type has already been registered.
sl@0
  1043
		 KErrPermissionDenied	Not sufficient capabiliites
sl@0
  1044
		 KErrAccessDenied		WaitForReader request is issued using Read handle or 
sl@0
  1045
		 						WaitForWriter request is issued using Write handle.	
sl@0
  1046
		 						otherwise one of the other system wide error code.
sl@0
  1047
*/
sl@0
  1048
	{
sl@0
  1049
	
sl@0
  1050
	// Code to check a valid Name field as per Symbian naming convention
sl@0
  1051
	TInt err = User::ValidateName(aName);
sl@0
  1052
	if(err != KErrNone)
sl@0
  1053
		{
sl@0
  1054
		ReqComplete(aStatus, err);
sl@0
  1055
		return;	
sl@0
  1056
		}
sl@0
  1057
	
sl@0
  1058
	if((aName.Length() > KMaxKernelName) || (aName.Length() == 0))
sl@0
  1059
		{
sl@0
  1060
		ReqComplete(aStatus, KErrBadName);
sl@0
  1061
		return;		
sl@0
  1062
		}
sl@0
  1063
	
sl@0
  1064
	TBuf8<KMaxKernelName> name8;
sl@0
  1065
	name8.Copy(aName);
sl@0
  1066
	
sl@0
  1067
	aStatus = KRequestPending;
sl@0
  1068
	// Check if the current instance of RPipe is already opened.
sl@0
  1069
	if (!iHandle)
sl@0
  1070
		{
sl@0
  1071
		// Perform the capability check and create the channel
sl@0
  1072
		err = DoCreate(Name(),VersionRequired(), KNullUnit, NULL, NULL);
sl@0
  1073
		if (err!= KErrNone)
sl@0
  1074
			{
sl@0
  1075
			ReqComplete(aStatus, err);
sl@0
  1076
			return;		
sl@0
  1077
			}
sl@0
  1078
		
sl@0
  1079
		if (aChoice == EWaitForReader) 
sl@0
  1080
			{
sl@0
  1081
			// Open the Write handle.
sl@0
  1082
			err = DoControl(EOpenToWriteNamedPipe, (TAny*)&name8);
sl@0
  1083
			if(err == KErrNone)
sl@0
  1084
				{
sl@0
  1085
				iSize = DoControl(ESize);
sl@0
  1086
				iHandleType = EWriteChannel;
sl@0
  1087
				}
sl@0
  1088
			}
sl@0
  1089
		else 
sl@0
  1090
			{
sl@0
  1091
			// Open the Read handle.
sl@0
  1092
			err = DoControl(EOpenToReadNamedPipe, (TAny*)&name8);	
sl@0
  1093
			if(err == KErrNone)
sl@0
  1094
				{
sl@0
  1095
				iSize = DoControl(ESize);
sl@0
  1096
				iHandleType = EReadChannel;
sl@0
  1097
				}
sl@0
  1098
			}
sl@0
  1099
		
sl@0
  1100
		if ( err!= KErrNone)
sl@0
  1101
			{
sl@0
  1102
			Close();
sl@0
  1103
			ReqComplete(aStatus, err);
sl@0
  1104
			return;
sl@0
  1105
			}
sl@0
  1106
		}		
sl@0
  1107
	// use the existing Logical channel to send the request.
sl@0
  1108
	DoRequest(EWaitNotification, aStatus, (TAny*)&name8,(TAny*)&aChoice);
sl@0
  1109
	}
sl@0
  1110
sl@0
  1111