localisation/apparchitecture/apparc/APACMDLN.CPP
branchSymbian3
changeset 57 b8d18c84f71c
parent 6 c108117318cb
equal deleted inserted replaced
56:aa99f2208aad 57:b8d18c84f71c
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     7 //
     8 // Initial Contributors:
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
     9 // Nokia Corporation - initial contribution.
    10 //
    10 //
    11 // Contributors:
    11 // Contributors:
    12 //
    12 //
    13 // Description:
    13 // Description:
       
    14 // apacmdln.cpp
    14 //
    15 //
       
    16 
       
    17 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    18 #if !defined(__APA_INTERNAL_H__)
       
    19 #include "apainternal.h"
       
    20 #endif
       
    21 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
    15 
    22 
    16 #include <apacmdln.h>
    23 #include <apacmdln.h>
    17 #include "APASTD.H" // Panics etc.
    24 #include "APASTD.H" // Panics etc.
    18 #include <s32mem.h>
    25 #include <s32mem.h>
    19 
    26 
    20 #include <e32svr.h>
    27 #include <e32svr.h>
       
    28 
       
    29 // comand line tokens
       
    30 const TUint KApaCommandLetterOpen='O';
       
    31 const TUint KApaCommandLetterCreate='C';
       
    32 const TUint KApaCommandLetterRun='R';
       
    33 const TUint KApaCommandLetterBackground='B';
       
    34 const TUint KApaCommandLetterViewActivate='V';
       
    35 const TUint KApaCommandLetterRunWithoutViews='W';
       
    36 const TUint KApaCommandLetterBackgroundAndWithoutViews='A';
    21 
    37 
    22 _LIT(KLitTokenServerDifferentiator, "-srvDfr=");
    38 _LIT(KLitTokenServerDifferentiator, "-srvDfr=");
    23 _LIT(KLitTokenDefaultScreenNumber, "-dsc=");
    39 _LIT(KLitTokenDefaultScreenNumber, "-dsc=");
    24 _LIT(KLitTokenParentWindowGroupID, "-prntwgid=");
    40 _LIT(KLitTokenParentWindowGroupID, "-prntwgid=");
    25 _LIT(KLitTokenDebugMemFail, "-debugMemFail:");
    41 _LIT(KLitTokenDebugMemFail, "-debugMemFail:");
    26 _LIT(KLitTokenAppStartupInstrumentationEventIdBase, "-appStartupInstrEvIdBase=");
    42 _LIT(KLitTokenAppStartupInstrumentationEventIdBase, "-appStartupInstrEvIdBase=");
    27 _LIT(KLitTokenOpaqueData, "-opaque=");
    43 _LIT(KLitTokenOpaqueData, "-opaque=");
    28 
    44 
       
    45 enum TProcessEnvironmentSots 
       
    46 	{
       
    47 	EEnvironmentSlotUnused = 0,
       
    48 	EEnvironmentSlotMain = 1,
       
    49 	EEnvironmentSlotFsSession = 2,
       
    50 	EEnvironmentSlotFile = 3,
       
    51 	EFirstEnvironmentSlotForPublicUse = 8,
       
    52 	ENumberOfEnvironmentSlotsForPublicUse = 4
       
    53 	};
       
    54 
       
    55 enum TIpcMessageSlots
       
    56 	{
       
    57 	EIpcSlotMain = 0,
       
    58 	EIpcSlotFsSession = 1,
       
    59 	EIpcSlotFile = 2
       
    60 	};
       
    61 
       
    62 
    29 // CApaCommandLine
    63 // CApaCommandLine
    30 
    64 
       
    65 /** Private c'tor - initialize using NewLC()
       
    66 @internalTechnology */
    31 CApaCommandLine::CApaCommandLine() : 
    67 CApaCommandLine::CApaCommandLine() : 
    32 	iDocumentName( NULL), iExecutableName(NULL), iOpaqueData(NULL),
    68 	iCommand(EApaCommandRun), iServerDifferentiator(0), iDefaultScreenNumber(KErrNotFound),
    33 	iTailEnd(NULL), iCommand(EApaCommandRun),
       
    34 	iServerDifferentiator(0), iDefaultScreenNumber(-1),
       
    35 	iParentWindowGroupID(0), iDebugMemFail(0), iAppStartupInstrumentationEventIdBase(0),
    69 	iParentWindowGroupID(0), iDebugMemFail(0), iAppStartupInstrumentationEventIdBase(0),
    36 	iFile(), iParentProcessId(KNullProcessId)
    70 	iFile(), iParentProcessId(KNullProcessId)
    37 	//
    71 	{
    38 	// private c'tor - initialize using NewLC()
    72 	}
    39 	//
    73 
    40 	{
    74 /** Destructor.
    41 	}
    75 Frees resources owned by the object prior to deletion. */
    42 
       
    43 EXPORT_C CApaCommandLine::~CApaCommandLine()
    76 EXPORT_C CApaCommandLine::~CApaCommandLine()
    44 /** Destructor.
    77 	{
    45 
    78 	iDocumentName.Close();
    46 Frees resources owned by the object prior to deletion. */
    79 	iExecutableName.Close();
    47 	{
    80 	iOpaqueData.Close();
    48 	delete iDocumentName;
    81 	iTailEnd.Close();
    49 	delete iExecutableName;
       
    50 	delete iOpaqueData;
       
    51 	delete iTailEnd;
       
    52 	iFile.Close();
    82 	iFile.Close();
    53 	}
    83 	}
    54 
    84 
       
    85 /** Creates an empty command line object.
       
    86 @return A pointer to the new command line object. */
    55 EXPORT_C CApaCommandLine* CApaCommandLine::NewL()
    87 EXPORT_C CApaCommandLine* CApaCommandLine::NewL()
    56 /** Creates an empty command line object.
    88 	{
    57 
    89 	CApaCommandLine* self = CApaCommandLine::NewLC();
       
    90 	CleanupStack::Pop();
       
    91 	return self;
       
    92 	}
       
    93 
       
    94 /** Creates an empty command line object, and puts a pointer to it onto the cleanup stack.
    58 @return A pointer to the new command line object. */
    95 @return A pointer to the new command line object. */
    59 	{
       
    60 	CApaCommandLine* This=CApaCommandLine::NewLC();
       
    61 	CleanupStack::Pop();
       
    62 	return This;
       
    63 	}
       
    64 
       
    65 EXPORT_C void CApaCommandLine::ConstructCmdLineFromMessageL(const RMessage2& aMessage)
       
    66 /** Acts as a second constructor and completes a commandline object from 
       
    67 	the aMessage object.
       
    68 
       
    69 @internalTechnology */
       
    70 	{
       
    71 	const TInt bufLen = aMessage.GetDesLengthL(EIpcSlotMain);
       
    72 	HBufC8* const buffer=HBufC8::NewLC(bufLen);
       
    73 	{TPtr8 buffer_asWritable(buffer->Des());
       
    74 	aMessage.ReadL(EIpcSlotMain, buffer_asWritable);}
       
    75 	RDesReadStream stream;
       
    76 	stream.Open(*buffer);
       
    77 	InternalizeL(stream);
       
    78 	CleanupStack::PopAndDestroy(buffer);
       
    79 
       
    80 	iFile.AdoptFromClient(aMessage, EIpcSlotFsSession, EIpcSlotFile); // ignore the returned error - assume it means that no file has been passed across
       
    81 	}
       
    82 
       
    83 void CApaCommandLine::GetCommandLineFromProcessEnvironmentL()
       
    84 	{
       
    85 	const TInt bufLen = User::ParameterLength(EEnvironmentSlotMain);
       
    86 	if (bufLen==KErrNotFound)
       
    87 		{
       
    88 		HBufC* const commandLineString=HBufC::NewLC(User::CommandLineLength());
       
    89 		{TPtr commandLineString_asWritable(commandLineString->Des());
       
    90 		User::CommandLine(commandLineString_asWritable);}
       
    91 		User::LeaveIfError(Parse(*commandLineString));
       
    92 		CleanupStack::PopAndDestroy(commandLineString);
       
    93 		}
       
    94 	else
       
    95 		{
       
    96 		User::LeaveIfError(bufLen); // in case bufLen is some error other than KErrNotFound
       
    97 		HBufC8* const buffer=HBufC8::NewLC(bufLen);
       
    98 		{TPtr8 buffer_asWritable(buffer->Des());
       
    99 		User::LeaveIfError(User::GetDesParameter(EEnvironmentSlotMain, buffer_asWritable));}
       
   100 		RDesReadStream stream;
       
   101 		stream.Open(*buffer);
       
   102 		InternalizeL(stream);
       
   103 		CleanupStack::PopAndDestroy(buffer);
       
   104 		}
       
   105 
       
   106 	iFile.AdoptFromCreator(EEnvironmentSlotFsSession, EEnvironmentSlotFile); // ignore the returned error - assume it means that no file has been passed across
       
   107 	}
       
   108 
       
   109 EXPORT_C CApaCommandLine* CApaCommandLine::NewLC()
    96 EXPORT_C CApaCommandLine* CApaCommandLine::NewLC()
   110 /** Creates an empty command line object, and puts a pointer to it onto the cleanup 
    97 	{
   111 stack.
    98 	CApaCommandLine* self = new(ELeave) CApaCommandLine;
   112 
    99 	CleanupStack::PushL(self);
   113 @return A pointer to the new command line object. */
   100 	return self;
   114 	{
       
   115 	CApaCommandLine* This=new(ELeave) CApaCommandLine;
       
   116 	CleanupStack::PushL(This);
       
   117 	return This;
       
   118 	}
   101 	}
   119 
   102 
   120 EXPORT_C void CApaCommandLine::SetDocumentNameL(const TDesC& aDocName)
   103 EXPORT_C void CApaCommandLine::SetDocumentNameL(const TDesC& aDocName)
   121 /** Sets the document name from the specified descriptor.
   104 /** Sets the document name from the specified descriptor.
   122 
   105 
   123 If the document name has embedded spaces, then it must be enclosed within 
   106 If the document name has embedded spaces, then it must be enclosed within 
   124 quotation marks.
   107 quotation marks.
   125 
   108 
   126 @param aDocName A descriptor containing the document name. */
   109 @param aDocName A descriptor containing the document name. */
   127 	{
   110 	{
   128 	HBufC* const documentName=aDocName.AllocL();
   111 	RBuf documentName;
   129 	delete iDocumentName; // only done after the AllocL succeeds
   112 	documentName.CreateL(aDocName);
   130 	iDocumentName=documentName;
   113 	
   131 	}
   114 	iDocumentName.Close();	// free any existing memory
   132 
   115 	iDocumentName.Assign(documentName);	
   133 EXPORT_C TPtrC CApaCommandLine::DocumentName() const
   116 	}
       
   117 
   134 /** Gets the document name from the launch information.
   118 /** Gets the document name from the launch information.
   135 
       
   136 @return A pointer descriptor representing the document name. The document 
   119 @return A pointer descriptor representing the document name. The document 
   137 name is returned without any enclosing quotation marks. If the launch information 
   120 name is returned without any enclosing quotation marks. If the launch information 
   138 contains no document name, then the pointer descriptor has zero length. */
   121 contains no document name, then the pointer descriptor has zero length. */
   139 	{
   122 EXPORT_C TPtrC CApaCommandLine::DocumentName() const
   140 	if (iDocumentName!=NULL)
   123 	{
   141 		{
   124 	return iDocumentName;
   142 		return *iDocumentName;
   125 	}
   143 		}
   126 
   144 	return KNullDesC();
   127 /** Sets the executable name from the specified descriptor.
   145 	}
   128 @param aExecutableName A descriptor containing the executable name. */
   146 
       
   147 EXPORT_C void CApaCommandLine::SetExecutableNameL(const TDesC& aExecutableName)
   129 EXPORT_C void CApaCommandLine::SetExecutableNameL(const TDesC& aExecutableName)
   148 /** Sets the executable name from the specified descriptor.
   130 	{
   149 
   131 	RBuf executableName;
   150 @param aExecutableName A descriptor containing the executable name. */
   132 	executableName.CreateL(aExecutableName);
   151 	{
   133 	
   152 	HBufC* const executableName=aExecutableName.AllocL();
   134 	iExecutableName.Close();	// free any existing memory
   153 	delete iExecutableName; // only done after the AllocL succeeds
   135 	iExecutableName.Assign(executableName);
   154 	iExecutableName=executableName;
   136 	}
   155 	}
   137 
   156 
   138 /** Gets the executable name from the launch information.
       
   139 @return A pointer descriptor representing the executable name. */
   157 EXPORT_C TPtrC CApaCommandLine::ExecutableName() const
   140 EXPORT_C TPtrC CApaCommandLine::ExecutableName() const
   158 /** Gets the executable name from the launch information.
   141 	{
   159 
   142 	return iExecutableName;
   160 @return A pointer descriptor representing the executable name. */
   143 	}
   161 	{
   144 
   162 	if (iExecutableName!=NULL)
       
   163 		{
       
   164 		return *iExecutableName;
       
   165 		}
       
   166 	return KNullDesC();
       
   167 	}
       
   168 
       
   169 EXPORT_C void CApaCommandLine::SetOpaqueDataL(const TDesC8& aOpaqueData)
       
   170 /** Sets the opaque-data from the specified 8-bit descriptor.
   145 /** Sets the opaque-data from the specified 8-bit descriptor.
   171 
   146 
   172 This is called internally and populated from the data in the application's registration resource file, 
   147 This is called internally and populated from the data in the application's registration resource file, 
   173 i.e. from the resource indicated by the opaque_data field of the APP_REGISTRATION_INFO resource (if the 
   148 i.e. from the resource indicated by the opaque_data field of the APP_REGISTRATION_INFO resource (if the 
   174 opaque_data field was non-zero).
   149 opaque_data field was non-zero).
   175 
   150 
   176 @param aOpaqueData An 8-bit descriptor containing the opaque-data. */
   151 @param aOpaqueData An 8-bit descriptor containing the opaque-data. 
   177 	{
   152 */
   178 	HBufC8* const opaqueData = aOpaqueData.AllocL();
   153 EXPORT_C void CApaCommandLine::SetOpaqueDataL(const TDesC8& aOpaqueData)
   179 	delete iOpaqueData;
   154 	{
   180 	iOpaqueData = opaqueData;
   155 	RBuf8 opaqueData;
   181 	}
   156 	opaqueData.CreateL(aOpaqueData);
   182 
   157 	
       
   158 	iOpaqueData.Close();	// free any existing memory
       
   159 	iOpaqueData.Assign(opaqueData);
       
   160 	}
       
   161 
       
   162 /** Gets the opaque-data from the launch information.
       
   163 
       
   164 See the description of SetOpaqueDataL. By default, this attribute is an empty descriptor.
       
   165 
       
   166 @see SetOpaqueDataL
       
   167 @return An 8-bit pointer descriptor representing the opaque-data. 
       
   168 */
   183 EXPORT_C TPtrC8 CApaCommandLine::OpaqueData() const
   169 EXPORT_C TPtrC8 CApaCommandLine::OpaqueData() const
   184 /** Gets the opaque-data from the launch information.
   170 	{
   185 
   171 	return iOpaqueData;
   186 See the description of SetOpaqueDataL. By default, this attribute is an empty descriptor.
   172 	}
   187 
   173 
   188 @see SetOpaqueDataL
       
   189 @return An 8-bit pointer descriptor representing the opaque-data. */
       
   190 	{
       
   191 	if (iOpaqueData != NULL)
       
   192 		{
       
   193 		return *iOpaqueData;
       
   194 		}
       
   195 	return KNullDesC8();
       
   196 	}
       
   197 
       
   198 EXPORT_C void CApaCommandLine::SetCommandL(TApaCommand aCommand)
       
   199 /** Sets the command code.
   174 /** Sets the command code.
   200 
   175 
   201 The command code is used to indicate how an application is to be launched.
   176 The command code is used to indicate how an application is to be launched.
   202 
   177 
   203 @see TApaCommand
   178 @see TApaCommand
   204 @param aCommand The command code. */
   179 @param aCommand The command code. */
   205 	{
   180 EXPORT_C void CApaCommandLine::SetCommandL(TApaCommand aCommand)
   206 	iCommand=aCommand;
   181 	{
   207 	}
   182 	iCommand = aCommand;
   208 
   183 	}
   209 EXPORT_C TApaCommand CApaCommandLine::Command() const
   184 
   210 /** Gets the command code from the launch information.
   185 /** Gets the command code from the launch information.
   211 
   186 
   212 See the description of SetCommandL.
   187 See the description of SetCommandL.
   213 
   188 
   214 @see SetCommandL
   189 @see SetCommandL
   215 @see TApaCommand
   190 @see TApaCommand
   216 @return The command code. */
   191 @return The command code. */
       
   192 EXPORT_C TApaCommand CApaCommandLine::Command() const
   217 	{
   193 	{
   218 	return iCommand;
   194 	return iCommand;
   219 	}
   195 	}
   220 
   196 
   221 EXPORT_C void CApaCommandLine::SetTailEndL(const TDesC8& aTailEnd)
       
   222 /** Sets the trailing data.
   197 /** Sets the trailing data.
   223 
   198 
   224 The UI Framework provides a specific set of pre-defined command line 
   199 The UI Framework provides a specific set of pre-defined command line 
   225 options. Additional user defined or pre-defined command line options, 
   200 options. Additional user defined or pre-defined command line options, 
   226 may be passed to an application by setting the TailEnd.
   201 may be passed to an application by setting the TailEnd.
   227 
   202 
   228 @param aTailEnd An 8 bit descriptor containing the trailing data. */
   203 @param aTailEnd An 8 bit descriptor containing the trailing data. 
   229 	{
   204 @publishedAll */
   230 	HBufC8* const newTailEnd=aTailEnd.AllocL();
   205 EXPORT_C void CApaCommandLine::SetTailEndL(const TDesC8& aTailEnd)
   231 	delete iTailEnd; // only done after the AllocL succeeds
   206 	{
   232 	iTailEnd=newTailEnd;
   207 	RBuf8 tailEnd;
   233 	}
   208 	tailEnd.CreateL(aTailEnd);
   234 
   209 	
   235 EXPORT_C TPtrC8 CApaCommandLine::TailEnd() const
   210 	iTailEnd.Close();	// free any existing memory
       
   211 	iTailEnd.Assign(tailEnd);
       
   212 	}
       
   213 
   236 /** Gets the trailing data from the launch information.
   214 /** Gets the trailing data from the launch information.
   237 
   215 
   238 See the description of SetTailEndL.
   216 See the description of SetTailEndL.
   239 
   217 
   240 @see SetTailEndL
   218 @see SetTailEndL
   241 @return A pointer descriptor representing the trailing data. If the launch 
   219 @return A pointer descriptor representing the trailing data. If the launch 
   242 information contains no trailing data, then the pointer descriptor has zero 
   220 information contains no trailing data, then the pointer descriptor has zero 
   243 length. */
   221 length. 
   244 	{
   222 @publishedAll */
   245 	if (iTailEnd!=NULL)
   223 EXPORT_C TPtrC8 CApaCommandLine::TailEnd() const
   246 		{
   224 	{
   247 		return *iTailEnd;
   225 	return iTailEnd;
   248 		}
   226 	}
   249 	return KNullDesC8();
   227 
   250 	}
       
   251 
       
   252 EXPORT_C void CApaCommandLine::SetFileByHandleL(const RFile& aFile)
       
   253 /** Sets the file to be passed into the application (by handle). 
   228 /** Sets the file to be passed into the application (by handle). 
   254 This will then be retrieved by that application-process calling GetFileByHandleL().
   229 This will then be retrieved by that application-process calling GetFileByHandleL().
   255 
   230 
   256 @publishedPartner
   231 @publishedPartner
   257 @released
   232 @released
   258 @param aFile The file object to be passed into the application. No transfer of this 
   233 @param aFile The file object to be passed into the application. No transfer of this 
   259 object's ownership takes place in this function. */
   234 object's ownership takes place in this function. */
   260 	{
   235 EXPORT_C void CApaCommandLine::SetFileByHandleL(const RFile& aFile)
   261 	__ASSERT_ALWAYS(aFile.SubSessionHandle()!=KNullHandle, Panic(EPanicInvalidHandle));
   236 	{
   262 	__ASSERT_ALWAYS(iFile.SubSessionHandle()==KNullHandle, Panic(EPanicHandleAlreadySet));
   237 	__ASSERT_ALWAYS(aFile.SubSessionHandle() != KNullHandle, Panic(EPanicInvalidHandle));
       
   238 	__ASSERT_ALWAYS(iFile.SubSessionHandle() == KNullHandle, Panic(EPanicHandleAlreadySet));
       
   239 	
   263 	User::LeaveIfError(iFile.Duplicate(aFile));
   240 	User::LeaveIfError(iFile.Duplicate(aFile));
   264 	}
   241 	}
   265 
   242 
   266 EXPORT_C void CApaCommandLine::GetFileByHandleL(RFile& aFile) const
       
   267 /** Opens (by handle) the file that was passed into SetFileByHandleL by the process launching the local application.
   243 /** Opens (by handle) the file that was passed into SetFileByHandleL by the process launching the local application.
   268 
   244 
   269 On entering this function, aFile must be non-open. It is recommended that aFile is 
   245 On entering this function, aFile must be non-open. It is recommended that aFile is 
   270 pushed onto the cleanup-stack (via CleanupClosePushL()) before this function is called.
   246 pushed onto the cleanup-stack (via CleanupClosePushL()) before this function is called.
   271 
   247 
   272 @publishedPartner
   248 @publishedPartner
   273 @released
   249 @released
   274 @param aFile The file object to be set up from the handle passed into the application. The 
   250 @param aFile The file object to be set up from the handle passed into the application. The 
   275 caller has the responsibility to Close() this object, even if this function leaves. */
   251 caller has the responsibility to Close() this object, even if this function leaves. */
       
   252 EXPORT_C void CApaCommandLine::GetFileByHandleL(RFile& aFile) const
   276 	{
   253 	{
   277 	__ASSERT_ALWAYS(aFile.SubSessionHandle()==KNullHandle, Panic(EPanicHandleAlreadySet));
   254 	__ASSERT_ALWAYS(aFile.SubSessionHandle()==KNullHandle, Panic(EPanicHandleAlreadySet));
   278 	if (iFile.SubSessionHandle()!=KNullHandle)
   255 
   279 		{
   256 	if (iFile.SubSessionHandle() != KNullHandle)
   280 		User::LeaveIfError(aFile.Duplicate(iFile));
   257 		User::LeaveIfError(aFile.Duplicate(iFile));
   281 		}
       
   282 	}
   258 	}
   283 
   259 
   284 /** Assigns a command line to a process (EKA2 only). 
   260 /** Assigns a command line to a process (EKA2 only). 
   285 
   261 
   286 This replaces the EKA1 method which involved retrieving the full command line (using 
   262 This replaces the EKA1 method which involved retrieving the full command line (using 
   302 @leave KErrNotSupported This indicates that the function was called on EKA1.
   278 @leave KErrNotSupported This indicates that the function was called on EKA1.
   303 @see RApaLsSession::StartApp()
   279 @see RApaLsSession::StartApp()
   304 */
   280 */
   305 EXPORT_C void CApaCommandLine::SetProcessEnvironmentL(RProcess& aProcess) const
   281 EXPORT_C void CApaCommandLine::SetProcessEnvironmentL(RProcess& aProcess) const
   306 	{
   282 	{
   307 	HBufC8* const streamableAttributes=StreamableAttributesLC();
   283 	HBufC8* const streamableAttributes = StreamableAttributesLC();
   308 	User::LeaveIfError(aProcess.SetParameter(EEnvironmentSlotMain, *streamableAttributes));
   284 	User::LeaveIfError(aProcess.SetParameter(EEnvironmentSlotMain, *streamableAttributes));
   309 	CleanupStack::PopAndDestroy(streamableAttributes);
   285 	CleanupStack::PopAndDestroy(streamableAttributes);
   310 
   286 
   311 	if (iFile.SubSessionHandle()!=KNullHandle)
   287 	if (iFile.SubSessionHandle() != KNullHandle)
   312 		{
       
   313 		User::LeaveIfError(iFile.TransferToProcess(aProcess, EEnvironmentSlotFsSession, EEnvironmentSlotFile));
   288 		User::LeaveIfError(iFile.TransferToProcess(aProcess, EEnvironmentSlotFsSession, EEnvironmentSlotFile));
   314 		}
   289 	}
   315 	}
   290 
   316 
       
   317 EXPORT_C void CApaCommandLine::GetIpcArgsLC(TIpcArgs& aIpcArgs) const
       
   318 /**
   291 /**
   319 @internalTechnology
   292 @internalTechnology
   320 */
   293 */
       
   294 EXPORT_C void CApaCommandLine::GetIpcArgsLC(TIpcArgs& aIpcArgs) const
   321 	{
   295 	{
   322 	aIpcArgs.Set(EIpcSlotMain, StreamableAttributesLC());
   296 	aIpcArgs.Set(EIpcSlotMain, StreamableAttributesLC());
   323 	if (iFile.SubSessionHandle()!=KNullHandle)
   297 	if (iFile.SubSessionHandle() != KNullHandle)
   324 		{
       
   325 		User::LeaveIfError(iFile.TransferToServer(aIpcArgs, EIpcSlotFsSession, EIpcSlotFile));
   298 		User::LeaveIfError(iFile.TransferToServer(aIpcArgs, EIpcSlotFsSession, EIpcSlotFile));
   326 		}
   299 	}
   327 	}
   300 
   328 
   301 /**
   329 EXPORT_C TInt CApaCommandLine::GetCommandLineFromProcessEnvironment(CApaCommandLine*& aCommandLine)
   302 @internalTechnology
       
   303 */
       
   304 HBufC8* CApaCommandLine::StreamableAttributesLC() const
       
   305 	{
       
   306 	CBufFlat* const buffer = CBufFlat::NewL(128);
       
   307 	CleanupStack::PushL(buffer);
       
   308 	
       
   309 	RBufWriteStream writeStream;
       
   310 	writeStream.Truncate(*buffer);
       
   311 	ExternalizeL(writeStream);
       
   312 	writeStream.CommitL();
       
   313 	HBufC8* const bufferAsDescriptor = buffer->Ptr(0).AllocL();
       
   314 	
       
   315 	CleanupStack::PopAndDestroy(buffer);
       
   316 	
       
   317 	CleanupStack::PushL(bufferAsDescriptor);
       
   318 	return bufferAsDescriptor;
       
   319 	}
       
   320 
       
   321 /** Acts as a second constructor and completes a commandline object from 
       
   322 the aMessage object.
       
   323 @internalTechnology */
       
   324 EXPORT_C void CApaCommandLine::ConstructCmdLineFromMessageL(const RMessage2& aMessage)
       
   325 	{
       
   326 	// Create a buffer of the right size and get the data from the RMessage2
       
   327 	RBuf8 buffer;
       
   328 	buffer.CleanupClosePushL();
       
   329 	buffer.CreateL(aMessage.GetDesLengthL(EIpcSlotMain));
       
   330 	aMessage.ReadL(EIpcSlotMain, buffer);
       
   331 	
       
   332 	// Create a stream and use it to read the data from the buffer
       
   333 	RDesReadStream stream;
       
   334 	CleanupClosePushL(stream);
       
   335 	stream.Open(buffer);
       
   336 	InternalizeL(stream);
       
   337 	CleanupStack::PopAndDestroy();	// stream
       
   338 	
       
   339 	CleanupStack::PopAndDestroy();	// buffer
       
   340 	iFile.AdoptFromClient(aMessage, EIpcSlotFsSession, EIpcSlotFile); // ignore the returned error - assume it means that no file has been passed across
       
   341 	}
       
   342 
   330 /** Constructs a command line object.
   343 /** Constructs a command line object.
   331 
   344 
   332 If command line information is provided in the environment-slots it creates command line object from
   345 If command line information is provided in the environment-slots it creates command line object from
   333 process environment-slots, else creates it from the information returned by User::CommandLine().
   346 process environment-slots, else creates it from the information returned by User::CommandLine().
   334 
   347 
   341 
   354 
   342 @see CEikAppUi::ProcessCommandParametersL(CApaCommandLine& aCommandLine).
   355 @see CEikAppUi::ProcessCommandParametersL(CApaCommandLine& aCommandLine).
   343 @param aCommandLine On return, a pointer to a newly constructed command line object.
   356 @param aCommandLine On return, a pointer to a newly constructed command line object.
   344 @return KErrNone, if successful; otherwise one of the other system-wide error codes.
   357 @return KErrNone, if successful; otherwise one of the other system-wide error codes.
   345 @internalTechnology */
   358 @internalTechnology */
       
   359 EXPORT_C TInt CApaCommandLine::GetCommandLineFromProcessEnvironment(CApaCommandLine*& aCommandLine)
   346 	{ // static
   360 	{ // static
   347 	aCommandLine = NULL;
   361 	aCommandLine = NULL;
   348 	CApaCommandLine* const commandLine = new CApaCommandLine;
   362 	CApaCommandLine* const commandLine = new CApaCommandLine;
   349 	if(!commandLine)
   363 	if(!commandLine)
   350 		return KErrNoMemory;
   364 		return KErrNoMemory;
   358 			delete commandLine;
   372 			delete commandLine;
   359 			return KErrNoMemory;
   373 			return KErrNoMemory;
   360 			}
   374 			}
   361 		}
   375 		}
   362 	
   376 	
   363 	TRAPD(error, commandLine->GetCommandLineFromProcessEnvironmentL());
   377 	TRAPD(error, commandLine->DoGetCommandLineFromProcessEnvironmentL());
   364 	aCommandLine = commandLine;
   378 	aCommandLine = commandLine;
   365 	delete trapCleanup;
   379 	delete trapCleanup;
   366 	return error;
   380 	return error;
   367 	}
   381 	}
   368 
   382 
   369 EXPORT_C void CApaCommandLine::SetParentProcessId(TProcessId aProcessId)
   383 void CApaCommandLine::DoGetCommandLineFromProcessEnvironmentL()
       
   384 	{
       
   385 	const TInt bufLen = User::ParameterLength(EEnvironmentSlotMain);
       
   386 	if (bufLen == KErrNotFound)
       
   387 		{
       
   388 		RBuf commandLineString;
       
   389 		commandLineString.CleanupClosePushL();
       
   390 		commandLineString.CreateL(User::CommandLineLength());
       
   391 		User::CommandLine(commandLineString);
       
   392 		User::LeaveIfError(DoGetParametersFromCommandLineString(commandLineString));
       
   393 		CleanupStack::PopAndDestroy();	// commandLineString
       
   394 		}
       
   395 	else
       
   396 		{
       
   397 		User::LeaveIfError(bufLen); // in case bufLen is some error other than KErrNotFound
       
   398 		RBuf8 buffer;
       
   399 		buffer.CleanupClosePushL();
       
   400 		buffer.CreateL(bufLen);
       
   401 		
       
   402 		User::LeaveIfError(User::GetDesParameter(EEnvironmentSlotMain, buffer));
       
   403 		RDesReadStream stream;
       
   404 		CleanupClosePushL(stream);
       
   405 		stream.Open(buffer);
       
   406 		InternalizeL(stream);
       
   407 		CleanupStack::PopAndDestroy();	// stream
       
   408 		
       
   409 		CleanupStack::PopAndDestroy();	// buffer
       
   410 		}
       
   411 
       
   412 	iFile.AdoptFromCreator(EEnvironmentSlotFsSession, EEnvironmentSlotFile); // ignore the returned error - assume it means that no file has been passed across
       
   413 	}
       
   414 
   370 /** Sets the Parent Process ID for the Child Process launched with this command line.
   415 /** Sets the Parent Process ID for the Child Process launched with this command line.
   371 
   416 
   372 This establishes a Parent-Child relationship which ensures that the child process is
   417 This establishes a Parent-Child relationship which ensures that the child process is
   373 terminated when the parent terminates.
   418 terminated when the parent terminates.
   374 
   419 
   375 @param aProcessId The Process ID. */
   420 @param aProcessId The Process ID. */
   376 	{
   421 EXPORT_C void CApaCommandLine::SetParentProcessId(TProcessId aProcessId)
   377 	iParentProcessId=aProcessId;
   422 	{
   378 	}
   423 	iParentProcessId = aProcessId;
   379 
   424 	}
   380 EXPORT_C TProcessId CApaCommandLine::ParentProcessId() const
   425 
   381 /** Gets the Parent Process ID of the Child Process launched with this command line.
   426 /** Gets the Parent Process ID of the Child Process launched with this command line.
   382 
   427 
   383 See the description of SetParentProcessId.
   428 See the description of SetParentProcessId.
   384 
   429 
   385 @see SetParentProcessId
   430 @see SetParentProcessId
   386 @return The Parent Process ID. */
   431 @return The Parent Process ID. */
       
   432 EXPORT_C TProcessId CApaCommandLine::ParentProcessId() const
   387 	{
   433 	{
   388 	return iParentProcessId;
   434 	return iParentProcessId;
   389 	}
   435 	}
   390 
       
   391 
   436 
   392 void CApaCommandLine::ExternalizeL(RWriteStream& aStream) const
   437 void CApaCommandLine::ExternalizeL(RWriteStream& aStream) const
   393 	{
   438 	{
   394 	// iFile is not supported via RReadStream/RWriteStream
   439 	// iFile is not supported via RReadStream/RWriteStream
   395 	aStream << DocumentName();
   440 	aStream << DocumentName();
   403 	aStream.WriteInt32L(iDebugMemFail);
   448 	aStream.WriteInt32L(iDebugMemFail);
   404 	aStream.WriteInt32L(iAppStartupInstrumentationEventIdBase);
   449 	aStream.WriteInt32L(iAppStartupInstrumentationEventIdBase);
   405 	aStream.WriteInt32L(iParentProcessId);
   450 	aStream.WriteInt32L(iParentProcessId);
   406 	}
   451 	}
   407 
   452 
   408 
       
   409 void CApaCommandLine::InternalizeL(RReadStream& aStream)
   453 void CApaCommandLine::InternalizeL(RReadStream& aStream)
   410 	{
   454 	{
   411 	// iFile is not supported via RReadStream/RWriteStream
   455 	// iFile is not supported via RReadStream/RWriteStream
   412 	const TInt KMaxBufLength = 4000;
   456 	const TInt KMaxBufLength = 4000;
   413 	iDocumentName = HBufC::NewL(aStream,KMaxBufLength);
   457 	iDocumentName.Close();	// free any existing memory
   414 	iExecutableName = HBufC::NewL(aStream,KMaxBufLength);
   458 	iDocumentName.CreateL(aStream, KMaxBufLength);
   415 	iOpaqueData = HBufC8::NewL(aStream, KMaxBufLength);
   459 	iExecutableName.Close();	// free any existing memory
   416 	iTailEnd = HBufC8::NewL(aStream,KMaxBufLength);
   460 	iExecutableName.CreateL(aStream, KMaxBufLength);
       
   461 	iOpaqueData.Close();	// free any existing memory
       
   462 	iOpaqueData.CreateL(aStream, KMaxBufLength);
       
   463 	iTailEnd.Close();	// free any existing memory
       
   464 	iTailEnd.CreateL(aStream, KMaxBufLength);
   417 	iCommand = static_cast<TApaCommand>(aStream.ReadInt32L());
   465 	iCommand = static_cast<TApaCommand>(aStream.ReadInt32L());
   418 	iServerDifferentiator = aStream.ReadInt32L();
   466 	iServerDifferentiator = aStream.ReadInt32L();
   419 	iDefaultScreenNumber = aStream.ReadInt32L();
   467 	iDefaultScreenNumber = aStream.ReadInt32L();
   420 	iParentWindowGroupID = aStream.ReadInt32L();
   468 	iParentWindowGroupID = aStream.ReadInt32L();
   421 	iDebugMemFail = aStream.ReadInt32L();
   469 	iDebugMemFail = aStream.ReadInt32L();
   422 	iAppStartupInstrumentationEventIdBase = aStream.ReadInt32L();
   470 	iAppStartupInstrumentationEventIdBase = aStream.ReadInt32L();
   423 	iParentProcessId=aStream.ReadInt32L();
   471 	iParentProcessId = aStream.ReadInt32L();
   424 	}
   472 	}
   425 
   473 
   426 HBufC8* CApaCommandLine::StreamableAttributesLC() const
       
   427 	{
       
   428 	CBufFlat* const buffer = CBufFlat::NewL(128);
       
   429 	CleanupStack::PushL(buffer);
       
   430 	RBufWriteStream writeStream;
       
   431 	writeStream.Truncate(*buffer);
       
   432 	ExternalizeL(writeStream);
       
   433 	writeStream.CommitL();
       
   434 	HBufC8* const bufferAsDescriptor = buffer->Ptr(0).AllocL();
       
   435 	CleanupStack::PopAndDestroy(buffer);
       
   436 	CleanupStack::PushL(bufferAsDescriptor);
       
   437 	return bufferAsDescriptor;
       
   438 	}
       
   439 
       
   440 EXPORT_C void CApaCommandLine::SetServerNotRequiredL()
       
   441 /** Sets that no server is required.
   474 /** Sets that no server is required.
   442 
   475 
   443 The value of server differentiator is set to zero, to indicate that no server
   476 The value of server differentiator is set to zero, to indicate that no server
   444 is required.
   477 is required.
   445 
   478 
   446 See the description of SetServerRequiredL.
   479 See the description of SetServerRequiredL.
   447 @see SetServerRequiredL
   480 @see SetServerRequiredL
   448 */
   481 */
       
   482 EXPORT_C void CApaCommandLine::SetServerNotRequiredL()
   449 	{
   483 	{
   450 	SetServerDifferentiatorL(0);
   484 	SetServerDifferentiatorL(0);
   451 	}
   485 	}
   452 
   486 
   453 EXPORT_C void CApaCommandLine::SetServerRequiredL(TUint aServerDifferentiator)
       
   454 /** Sets the required server.
   487 /** Sets the required server.
   455 
   488 
   456 The server differentiator is a number generated by the client that helps to uniquely 
   489 The server differentiator is a number generated by the client that helps to uniquely 
   457 identify the server. It is used by an application to indicate whether a server should
   490 identify the server. It is used by an application to indicate whether a server should
   458 be created and how it should be named.
   491 be created and how it should be named.
   459 
   492 
   460 @param aServerDifferentiator A differentiator for the required server.*/
   493 @param aServerDifferentiator A differentiator for the required server.
   461 
   494 @see REikAppServiceBase::LaunchAppL() 
       
   495 */
       
   496 EXPORT_C void CApaCommandLine::SetServerRequiredL(TUint aServerDifferentiator)
   462 	{
   497 	{
   463 	SetServerDifferentiatorL(aServerDifferentiator);
   498 	SetServerDifferentiatorL(aServerDifferentiator);
   464 	}
   499 	}
   465 
   500 
       
   501 /**
       
   502 @see REikAppServiceBase::LaunchAppL()
       
   503 @internalTechnology
       
   504 */
   466 void CApaCommandLine::SetServerDifferentiatorL(TUint aServerDifferentiator)
   505 void CApaCommandLine::SetServerDifferentiatorL(TUint aServerDifferentiator)
   467 	{
   506 	{
   468 	iServerDifferentiator=aServerDifferentiator;
   507 	iServerDifferentiator = aServerDifferentiator;
   469 	}
   508 	}
   470 	
   509 	
   471 EXPORT_C TUint CApaCommandLine::ServerRequired() const
       
   472 /** Gets the server differentiator.
   510 /** Gets the server differentiator.
   473 
   511 
   474 See the description of SetServerRequiredL.
   512 See the description of SetServerRequiredL.
   475 
   513 
   476 @see SetServerRequiredL
   514 @see SetServerRequiredL
   477 @return The non-zero differentiator for the server, else zero indicating a server 
   515 @return The non-zero differentiator for the server, else zero indicating a server 
   478 is not required.*/
   516 is not required.
       
   517 @see REikAppServiceBase::LaunchAppL() */
       
   518 EXPORT_C TUint CApaCommandLine::ServerRequired() const
   479 	{
   519 	{
   480 	return iServerDifferentiator;
   520 	return iServerDifferentiator;
   481 	}
   521 	}
   482 
   522 
   483 EXPORT_C void CApaCommandLine::SetDefaultScreenL(TInt aDefaultScreenNumber)
       
   484 /** Provides support for devices with more than one screen.  A number representing the default
   523 /** Provides support for devices with more than one screen.  A number representing the default
   485 or startup screen may be passed to an application.
   524 or startup screen may be passed to an application.
   486 Screen numbers and characteristics are defined in the window server initialisation 
   525 Screen numbers and characteristics are defined in the window server initialisation 
   487 file (wsini.ini).
   526 file (wsini.ini).
   488 
   527 
   489 @param aDefaultScreenNumber The number of the default (startup) screen. */
   528 @param aDefaultScreenNumber The number of the default (startup) screen.
       
   529 @publishedAll */
       
   530 EXPORT_C void CApaCommandLine::SetDefaultScreenL(TInt aDefaultScreenNumber)
   490 	{
   531 	{
   491 	__ASSERT_ALWAYS(aDefaultScreenNumber>=0, Panic(EPanicInvalidScreenNumber));
   532 	__ASSERT_ALWAYS(aDefaultScreenNumber>=0, Panic(EPanicInvalidScreenNumber));
   492 	iDefaultScreenNumber=aDefaultScreenNumber;
   533 	iDefaultScreenNumber = aDefaultScreenNumber;
   493 	}
   534 	}
   494 
   535 
       
   536 /** Extracts and returns the default (startup) screen that was specified in the command line.
       
   537 
       
   538 @return	A number representing the default (startup) screen.  0 (Zero) if nothing present.
       
   539 @publishedAll */
   495 EXPORT_C TInt CApaCommandLine::DefaultScreen() const
   540 EXPORT_C TInt CApaCommandLine::DefaultScreen() const
   496 /** Extracts and returns the default (startup) screen that was specified in the command line.
       
   497 
       
   498 @return	A number representing the default (startup) screen.  0 (Zero) if nothing present. */
       
   499 	{
   541 	{
   500 	return Max(0, iDefaultScreenNumber);
   542 	return Max(0, iDefaultScreenNumber);
   501 	}
   543 	}
   502 	
   544 	
       
   545 /**
       
   546 @publishedAll
       
   547 */
   503 EXPORT_C TBool CApaCommandLine::IsDefaultScreenSet() const
   548 EXPORT_C TBool CApaCommandLine::IsDefaultScreenSet() const
   504 /**
   549 	{
   505 @internalTechnology
   550 	return (iDefaultScreenNumber != KErrNotFound);
   506 */
       
   507 	{
       
   508 	return (iDefaultScreenNumber>=0);
       
   509  	}
   551  	}
   510 
   552 
   511 EXPORT_C void CApaCommandLine::SetParentWindowGroupID(TInt aParentWindowGroupID)
       
   512 /** Sets the ID of the parent window-group - the application should create its own 
   553 /** Sets the ID of the parent window-group - the application should create its own 
   513 window-group as a child off this parent.
   554 window-group as a child off this parent.
   514 
   555 
   515 @param aParentWindowGroupID The ID of the parent window-group - the application 
   556 @param aParentWindowGroupID The ID of the parent window-group - the application 
   516 should create its window-group as a child off this parent. */
   557 should create its window-group as a child off this parent. */
   517 	{
   558 EXPORT_C void CApaCommandLine::SetParentWindowGroupID(TInt aParentWindowGroupID)
   518 	iParentWindowGroupID=aParentWindowGroupID;
   559 	{
   519 	}
   560 	iParentWindowGroupID = aParentWindowGroupID;
   520 
   561 	}
   521 EXPORT_C TInt CApaCommandLine::ParentWindowGroupID() const
   562 
   522 /** Returns the ID of the parent window-group - the application should create its own 
   563 /** Returns the ID of the parent window-group - the application should create its own 
   523 window-group as a child of this parent.
   564 window-group as a child of this parent.
   524 
   565 
   525 @return The ID of the parent window-group - the application should create its 
   566 @return The ID of the parent window-group - the application should create its 
   526 window-group as a child off this . */
   567 window-group as a child off this . */
       
   568 EXPORT_C TInt CApaCommandLine::ParentWindowGroupID() const
   527 	{
   569 	{
   528 	return iParentWindowGroupID;
   570 	return iParentWindowGroupID;
   529 	}
   571 	}
   530 
   572 
       
   573 /** @internalAll */
   531 EXPORT_C void CApaCommandLine::SetDebugMemFailL(TInt aDebugMemFail)
   574 EXPORT_C void CApaCommandLine::SetDebugMemFailL(TInt aDebugMemFail)
       
   575 	{
       
   576 	iDebugMemFail = aDebugMemFail;
       
   577 	}
       
   578 
   532 /** @internalAll */
   579 /** @internalAll */
   533 	{
       
   534 	iDebugMemFail=aDebugMemFail;
       
   535 	}
       
   536 
       
   537 EXPORT_C TInt CApaCommandLine::DebugMemFail() const
   580 EXPORT_C TInt CApaCommandLine::DebugMemFail() const
       
   581 	{
       
   582 	return iDebugMemFail;
       
   583 	}
       
   584 
   538 /** @internalAll */
   585 /** @internalAll */
   539 	{
       
   540 	return iDebugMemFail;
       
   541 	}
       
   542 
       
   543 EXPORT_C void CApaCommandLine::SetAppStartupInstrumentationEventIdBaseL(TInt aAppStartupInstrumentationEventIdBase)
   586 EXPORT_C void CApaCommandLine::SetAppStartupInstrumentationEventIdBaseL(TInt aAppStartupInstrumentationEventIdBase)
       
   587 	{
       
   588 	iAppStartupInstrumentationEventIdBase = aAppStartupInstrumentationEventIdBase;
       
   589 	}
       
   590 
   544 /** @internalAll */
   591 /** @internalAll */
   545 	{
       
   546 	iAppStartupInstrumentationEventIdBase=aAppStartupInstrumentationEventIdBase;
       
   547 	}
       
   548 
       
   549 EXPORT_C TInt CApaCommandLine::AppStartupInstrumentationEventIdBase() const
   592 EXPORT_C TInt CApaCommandLine::AppStartupInstrumentationEventIdBase() const
   550 /** @internalAll */
       
   551 	{
   593 	{
   552 	return iAppStartupInstrumentationEventIdBase;
   594 	return iAppStartupInstrumentationEventIdBase;
   553 	}
   595 	}
   554 
   596 
   555 EXPORT_C TInt CApaCommandLine::EnvironmentSlotForPublicUse(TInt aIndex)
       
   556 /** Returns the index of a process environment-slot for public use (in other words, 
   597 /** Returns the index of a process environment-slot for public use (in other words, 
   557 one that is not used internally by CApaCommandLine). The number of slots available 
   598 one that is not used internally by CApaCommandLine). The number of slots available 
   558 for public use can be found in the (private) enum value CApaCommandLine::ENumberOfEnvironmentSlotsForPublicUse, 
   599 for public use is returned from NumberOfEnvironmentSlotsForPublicUse(), (this value 
   559 (this value may be increased over time). The returned value can then be passed into 
   600 may be increased over time). The returned value can then be passed into any of the 
   560 any of the Open(TInt,...) functions on RSessionBase, RMutex, RChunk, RCondVar, etc, 
   601 Open(TInt,...) functions on RSessionBase, RMutex, RChunk, RCondVar, etc, or into 
   561 or into User::GetTIntParameter(), User::GetDesParameter(), etc, depending on the type 
   602 User::GetTIntParameter(), User::GetDesParameter(), etc, depending on the type 
   562 of the object in that environment slot.
   603 of the object in that environment slot.
   563 
   604 
   564 @param aIndex The logical index of the public environment-slot. This must be greater 
   605 @param aIndex The logical index of the public environment-slot. This must be greater 
   565 than or equal to zero, and less than CApaCommandLine::ENumberOfEnvironmentSlotsForPublicUse.
   606 than or equal to zero, and less than the value returned from NumberOfEnvironmentSlotsForPublicUse().
   566 @return The physical index of an environment-slot in the local process. */
   607 @return The physical index of an environment-slot in the local process. 
       
   608 @publishedAll
       
   609 */
       
   610 EXPORT_C TInt CApaCommandLine::EnvironmentSlotForPublicUse(TInt aIndex)
   567 	{ // static
   611 	{ // static
   568 	__ASSERT_ALWAYS((aIndex>=0) && (aIndex<ENumberOfEnvironmentSlotsForPublicUse), Panic(EPanicEnvironmentSlotNotForPublicUse));
   612 	__ASSERT_ALWAYS((aIndex>=0) && (aIndex < ENumberOfEnvironmentSlotsForPublicUse), Panic(EPanicEnvironmentSlotNotForPublicUse));
   569 	return EFirstEnvironmentSlotForPublicUse+aIndex;
   613 	return EFirstEnvironmentSlotForPublicUse + aIndex;
   570 	}
   614 	}
   571 
   615 
   572 TInt CApaCommandLine::Parse(const TDesC& aCmdLine)
   616 /**
       
   617 The number of process environment-slot available for public use.
       
   618 @publishedAll
       
   619 */
       
   620 EXPORT_C TInt CApaCommandLine::NumberOfEnvironmentSlotsForPublicUse()
       
   621 	{
       
   622 	return ENumberOfEnvironmentSlotsForPublicUse;
       
   623 	}
       
   624 
       
   625 // For use in CApaCommandLine::DoGetParametersFromCommandLineString() only.
       
   626 struct SOption
       
   627 	{
       
   628 	const TDesC* iToken;
       
   629 	TInt* iResult;
       
   630 	TRadix iRadix;
       
   631 	HBufC8* iHBufC8Result;
       
   632 	};
       
   633 
       
   634 TInt CApaCommandLine::DoGetParametersFromCommandLineString(const TDesC& aCmdLine)
   573 // does the opposite of SetCmdLineL, i.e. sets iDocumentName, iExecutableName, iTailEnd, iCommand, iServerDifferentiator, iDefaultScreenNumber, iParentWindowGroupID , iDebugMemFail & iAppStartupInstrumentationEventIdBase from aCmdLine
   635 // does the opposite of SetCmdLineL, i.e. sets iDocumentName, iExecutableName, iTailEnd, iCommand, iServerDifferentiator, iDefaultScreenNumber, iParentWindowGroupID , iDebugMemFail & iAppStartupInstrumentationEventIdBase from aCmdLine
   574 // also sets iOpaqueData
   636 // also sets iOpaqueData
   575 	{
   637 	{
   576 	const TInt cmdLength=aCmdLine.Length();
   638 	const TInt cmdLength = aCmdLine.Length();
   577 
   639 	TInt endLibNameOffset = cmdLength-1;
   578 	// these variables are all "shadows" of member variables - we'll set the member variables corresponding to these at the end of this function, once all memory-allocation has succeeded, to make this function atomic
   640 	TInt endDocNameOffset = cmdLength-1;
   579 	TInt endLibNameOffset=cmdLength-1;
   641 
   580 	TInt endDocNameOffset=cmdLength-1;
   642 	// these variables are all "shadows" of member variables - we'll set the member variables corresponding to these at the end of this function, once all memory-allocation has succeeded, to make this function atomic	
   581 	HBufC* documentName=NULL;
   643 	HBufC* documentName = NULL;
   582 	HBufC* executableName=NULL;
   644 	HBufC* executableName = NULL;
   583 	HBufC8* tailEnd=NULL;
   645 	HBufC8* tailEnd = NULL;
   584 	HBufC8* opaqueData=NULL;
   646 	HBufC8* opaqueData = NULL;
   585 	TApaCommand command=EApaCommandRun;
   647 	
   586 	TInt serverDifferentiator=0;
   648 	TApaCommand command = EApaCommandRun;
   587 	TInt defaultScreenNumber=-1;
   649 	TInt serverDifferentiator = 0;
   588 	TInt parentWindowGroupID=0;
   650 	TInt defaultScreenNumber = KErrNotFound;
   589 	TInt debugMemFail=0;
   651 	TInt parentWindowGroupID = 0;
   590 	TInt appStartupInstrumentationEventIdBase=0;
   652 	TInt debugMemFail = 0;
   591 	TInt notUsed;
   653 	TInt appStartupInstrumentationEventIdBase = 0;
   592 
   654 	TInt notUsed = 0;
   593 	TBool openQuote=EFalse;
   655 
   594 	TBool foundEndLibName=EFalse;
   656 	// Look for the name of the executable
   595 	for (TInt i=0; i<cmdLength; ++i)
   657 	executableName = NameOfExecutable(aCmdLine, endDocNameOffset);
       
   658 	if (!executableName)
       
   659 	{
       
   660 	delete executableName;
       
   661 	return KErrNoMemory;	
       
   662 	}
       
   663 	
       
   664 	// Work out the type of command		
       
   665 	const TInt offset = endDocNameOffset-endLibNameOffset;
       
   666 	if (offset > 1)
   596 		{
   667 		{
   597 		TChar current=aCmdLine[i];
   668 		const TChar commandLetter = aCmdLine[endLibNameOffset+2];
   598 		if (current=='"')
       
   599 			{
       
   600 			openQuote=!openQuote;
       
   601 			continue;
       
   602 			};
       
   603 		if ((current==' ') && !openQuote)
       
   604 			{
       
   605 			// space found outside of quotes
       
   606 			if (foundEndLibName)
       
   607 				{
       
   608 				endDocNameOffset=i-1;
       
   609 				break; // parse no further
       
   610 				}
       
   611 			endLibNameOffset=i-1;
       
   612 			foundEndLibName=ETrue;
       
   613 			}
       
   614 		}
       
   615 	if (endLibNameOffset>-1)
       
   616 		{
       
   617 		executableName=StripQuotes(aCmdLine.Left(endLibNameOffset+1)).Alloc();
       
   618 		if (executableName==NULL)
       
   619 			{
       
   620 			delete documentName;
       
   621 			delete executableName;
       
   622 			delete tailEnd;
       
   623 			delete opaqueData;
       
   624 			return KErrNoMemory;
       
   625 			}
       
   626 		}
       
   627 	TInt offset=endDocNameOffset-endLibNameOffset;
       
   628 	if (offset>1)
       
   629 		{
       
   630 		TChar commandLetter=aCmdLine[endLibNameOffset+2];
       
   631 		switch (commandLetter)
   669 		switch (commandLetter)
   632 			{
   670 			{
   633 		case KApaCommandLetterOpen:
   671 		case KApaCommandLetterOpen:
   634 			command=EApaCommandOpen;
   672 			command = EApaCommandOpen;
   635 			break;
   673 			break;
   636 		case KApaCommandLetterCreate:
   674 		case KApaCommandLetterCreate:
   637 			command=EApaCommandCreate;
   675 			command = EApaCommandCreate;
   638 			break;
   676 			break;
   639 		case KApaCommandLetterViewActivate:
   677 		case KApaCommandLetterViewActivate:
   640 			command=EApaCommandViewActivate;
   678 			command = EApaCommandViewActivate;
   641 			break;
   679 			break;
   642 		case KApaCommandLetterRunWithoutViews:
   680 		case KApaCommandLetterRunWithoutViews:
   643 			command=EApaCommandRunWithoutViews;
   681 			command = EApaCommandRunWithoutViews;
   644 			break;
   682 			break;
   645 		case KApaCommandLetterBackgroundAndWithoutViews:
   683 		case KApaCommandLetterBackgroundAndWithoutViews:
   646 			command=EApaCommandBackgroundAndWithoutViews;
   684 			command = EApaCommandBackgroundAndWithoutViews;
   647 			break;
   685 			break;
   648 		case KApaCommandLetterRun:
   686 		case KApaCommandLetterRun:
   649 		default:
   687 		default:
   650 			break;
   688 			break;
   651 		case KApaCommandLetterBackground:
   689 		case KApaCommandLetterBackground:
   652 			command=EApaCommandBackground;
   690 			command = EApaCommandBackground;
   653 			break;
   691 			break;
   654 			}
   692 			}
   655 
   693 
   656 		if (offset>2)
   694 	// Get the name of the document file, if any.
       
   695 	if (offset > 2)
       
   696 		{
       
   697 		const TInt documentNameStartPosition = endLibNameOffset+3;
       
   698 		documentName = StripQuotes(aCmdLine.Mid(documentNameStartPosition, (endDocNameOffset+1)-documentNameStartPosition)).Alloc();
       
   699 		if (!documentName)
   657 			{
   700 			{
   658 			const TInt documentNameStartPosition=endLibNameOffset+3;
   701 			delete executableName;
   659 			documentName=StripQuotes(aCmdLine.Mid(documentNameStartPosition, (endDocNameOffset+1)-documentNameStartPosition)).Alloc();
   702 			delete documentName;
   660 			if (documentName==NULL)
   703 			return KErrNoMemory;			
   661 				{
       
   662 				delete documentName;
       
   663 				delete executableName;
       
   664 				delete tailEnd;
       
   665 				delete opaqueData;
       
   666 				return KErrNoMemory;
       
   667 				}
       
   668 			}
   704 			}
   669 		}
   705 		}
   670 	const TInt KNumberOfSupportedOptions=6;
   706 	}
       
   707 	
       
   708 	// Translate the command line tokens into their corresponing options
       
   709 	const TInt KNumberOfSupportedOptions = 6;
   671 	TFixedArray<SOption, KNumberOfSupportedOptions> optionArray;
   710 	TFixedArray<SOption, KNumberOfSupportedOptions> optionArray;
   672 	optionArray[0].iToken=&KLitTokenServerDifferentiator;
   711 	optionArray[0].iToken = &KLitTokenServerDifferentiator;
   673 	optionArray[0].iResult=&serverDifferentiator;
   712 	optionArray[0].iResult = &serverDifferentiator;
   674 	optionArray[0].iRadix=EDecimal;
   713 	optionArray[0].iRadix = EDecimal;
   675 	optionArray[1].iToken=&KLitTokenDefaultScreenNumber;
   714 	optionArray[1].iToken = &KLitTokenDefaultScreenNumber;
   676 	optionArray[1].iResult=&defaultScreenNumber;
   715 	optionArray[1].iResult = &defaultScreenNumber;
   677 	optionArray[1].iRadix=EDecimal;
   716 	optionArray[1].iRadix = EDecimal;
   678 	optionArray[2].iToken=&KLitTokenParentWindowGroupID;
   717 	optionArray[2].iToken = &KLitTokenParentWindowGroupID;
   679 	optionArray[2].iResult=&parentWindowGroupID;
   718 	optionArray[2].iResult = &parentWindowGroupID;
   680 	optionArray[2].iRadix=EDecimal;
   719 	optionArray[2].iRadix = EDecimal;
   681 	optionArray[3].iToken=&KLitTokenDebugMemFail;
   720 	optionArray[3].iToken = &KLitTokenDebugMemFail;
   682 	optionArray[3].iResult=&debugMemFail;
   721 	optionArray[3].iResult = &debugMemFail;
   683 	optionArray[3].iRadix=EHex;
   722 	optionArray[3].iRadix = EHex;
   684 	optionArray[4].iToken=&KLitTokenAppStartupInstrumentationEventIdBase;
   723 	optionArray[4].iToken = &KLitTokenAppStartupInstrumentationEventIdBase;
   685 	optionArray[4].iResult=&appStartupInstrumentationEventIdBase;
   724 	optionArray[4].iResult = &appStartupInstrumentationEventIdBase;
   686 	optionArray[4].iRadix=EDecimal;
   725 	optionArray[4].iRadix = EDecimal;
   687 	optionArray[5].iToken=&KLitTokenOpaqueData;
   726 	optionArray[5].iToken = &KLitTokenOpaqueData;
   688 	optionArray[5].iResult=&notUsed;
   727 	optionArray[5].iResult = &notUsed;
   689 	optionArray[5].iRadix=EDecimal; // should not used if the command-line is well-formed
   728 	optionArray[5].iRadix = EDecimal; // should not used if the command-line is well-formed
       
   729 	
   690 	TLex lex(aCmdLine.Mid(endDocNameOffset+1));
   730 	TLex lex(aCmdLine.Mid(endDocNameOffset+1));
   691 	lex.Mark();
   731 	lex.Mark();
   692 	for (TInt optionIndex=0; optionIndex<KNumberOfSupportedOptions; ++optionIndex)
   732 	for (TInt optionIndex = 0; optionIndex < KNumberOfSupportedOptions; ++optionIndex)
   693 		{
   733 		{
   694 		lex.SkipSpace();
   734 		lex.SkipSpace();
   695 		SOption& option=optionArray[optionIndex];
   735 		const SOption& option = optionArray[optionIndex];
   696 		const TPtrC remainder(lex.Remainder());
   736 		const TPtrC remainder(lex.Remainder());
   697 		__ASSERT_DEBUG(option.iToken, Panic(EDPanicInvalidToken));
   737 		__ASSERT_DEBUG(option.iToken, Panic(EDPanicInvalidToken));
   698 		const TInt tokenLength=option.iToken->Length();
   738 		const TInt tokenLength = option.iToken->Length();
   699 		if ((remainder.Length()>=tokenLength) && (remainder.Left(tokenLength).CompareF(*option.iToken)==0))
   739 		if ((remainder.Length() >= tokenLength) && (remainder.Left(tokenLength).CompareF(*option.iToken) == 0))
   700 			{
   740 			{
   701 			if (option.iToken==&KLitTokenOpaqueData)
   741 			if (option.iToken == &KLitTokenOpaqueData)
   702 				{
   742 				{
   703 				TInt endOfOpaqueDataIndex = 0;			
   743 				TInt endOfOpaqueDataIndex = 0;			
   704 				for (TInt i=tokenLength; i<remainder.Length(); ++i)
   744 				for (TInt i = tokenLength; i < remainder.Length(); ++i)
   705 					{
   745 					{
   706 					TChar current=remainder[i];
   746 					const TChar current = remainder[i];
   707 					if (current==' ')
   747 					if (current == ' ')
   708 						{
   748 						{
   709 						endOfOpaqueDataIndex = i;
   749 						endOfOpaqueDataIndex = i;
   710 						break; // parse no further
   750 						break; // parse no further
   711 						}
   751 						}
   712 					}
   752 					}
       
   753 					
   713 				if(endOfOpaqueDataIndex > tokenLength)
   754 				if(endOfOpaqueDataIndex > tokenLength)
   714 					{
   755 					{
   715 					const TInt opaqueDataLength = endOfOpaqueDataIndex - tokenLength;
   756 					const TInt opaqueDataLength = endOfOpaqueDataIndex - tokenLength;
   716 					delete opaqueData;
   757 					delete opaqueData;
   717 					opaqueData=TPtrC8(reinterpret_cast<const TUint8*>(remainder.Mid(tokenLength, opaqueDataLength).Ptr()),opaqueDataLength*sizeof(TText)).Alloc();
   758 					opaqueData = TPtrC8(reinterpret_cast<const TUint8*>(remainder.Mid(tokenLength, opaqueDataLength).Ptr()),opaqueDataLength*sizeof(TText)).Alloc();
   718 					if (opaqueData==NULL)
   759 					if (!opaqueData)
   719 						{
   760 						{
       
   761 						delete executableName;
   720 						delete documentName;
   762 						delete documentName;
   721 						delete executableName;
   763 						delete opaqueData;
   722 						delete tailEnd;
   764 						return KErrNoMemory;						
   723 						return KErrNoMemory;
       
   724 						}
   765 						}
       
   766 					
   725 					lex.Inc(tokenLength + opaqueDataLength);
   767 					lex.Inc(tokenLength + opaqueDataLength);
   726 					lex.Mark();
   768 					lex.Mark();
   727 					}
   769 					}
   728 				else
   770 				else
   729 					{
   771 					{
   736 					}
   778 					}
   737 				}
   779 				}
   738 			else
   780 			else
   739 				{
   781 				{
   740 				ASSERT(option.iResult);
   782 				ASSERT(option.iResult);
   741 				const TInt originalValue=*option.iResult;
   783 				const TInt originalValue = *option.iResult;
   742 				lex.Inc(tokenLength);
   784 				lex.Inc(tokenLength);
   743 				TUint16 val = static_cast<TUint16> (*option.iResult);
   785 				TUint16 val = static_cast<TUint16> (*option.iResult);
   744 				if (lex.Val(val, option.iRadix)==KErrNone)
   786 				if (lex.Val(val, option.iRadix) == KErrNone)
   745 					{
       
   746 					lex.Mark();
   787 					lex.Mark();
   747 					}
       
   748 				else
   788 				else
   749 					{
   789 					*option.iResult = originalValue;
   750 					*option.iResult=originalValue;
       
   751 					}
       
   752 				}
   790 				}
   753 			}
   791 			}
   754 		}
   792 		}
       
   793 		
   755 	lex.UnGetToMark();
   794 	lex.UnGetToMark();
   756 	lex.SkipSpace();
   795 	lex.SkipSpace();
       
   796 	
       
   797 	// Get the tail end
   757 	const TPtrC remainder(lex.Remainder());
   798 	const TPtrC remainder(lex.Remainder());
   758 	const TInt lengthOfRemainder=remainder.Length();
   799 	const TInt lengthOfRemainder = remainder.Length();
   759 	if (lengthOfRemainder>0)
   800 	if (lengthOfRemainder > 0)
   760 		{
   801 		{
   761 		tailEnd=TPtrC8(reinterpret_cast<const TUint8*>(remainder.Ptr()),lengthOfRemainder*sizeof(TText)).Alloc();
   802 		tailEnd = TPtrC8(reinterpret_cast<const TUint8*>(remainder.Ptr()),lengthOfRemainder*sizeof(TText)).Alloc();
   762 		if (tailEnd==NULL)
   803 		if (!tailEnd)
   763 			{
   804 			{
       
   805 			delete executableName;
   764 			delete documentName;
   806 			delete documentName;
   765 			delete executableName;
   807 			delete opaqueData;
   766 			delete tailEnd;
   808 			delete tailEnd;
   767 			delete opaqueData;
   809 			return KErrNoMemory;		
   768 			return KErrNoMemory;
       
   769 			}
   810 			}
   770 		}
   811 		}
   771 
   812 
   772 	// we can now set the member variables as all memory-allocation has succeeded
   813 	// Free any existing memory
   773 	delete iDocumentName;
   814 	iDocumentName.Close();
   774 	iDocumentName=documentName;
   815 	iExecutableName.Close();
   775 	delete iExecutableName;
   816 	iTailEnd.Close();
   776 	iExecutableName=executableName;
   817 	iOpaqueData.Close();
   777 	delete iTailEnd;
   818 	
   778 	iTailEnd=tailEnd;
   819 	// Set the member variables, as all memory-allocations have succeeded.
   779 	iCommand=command;
   820 	iDocumentName.Assign(documentName);
   780 	iServerDifferentiator=serverDifferentiator;
   821 	iExecutableName.Assign(executableName);
   781 	iDefaultScreenNumber=defaultScreenNumber;
   822 	iTailEnd.Assign(tailEnd);
   782 	iParentWindowGroupID=parentWindowGroupID;
   823 	iOpaqueData.Assign(opaqueData);
   783 	iDebugMemFail=debugMemFail;
   824 	iCommand = command;
   784 	iAppStartupInstrumentationEventIdBase=appStartupInstrumentationEventIdBase;
   825 	iServerDifferentiator = serverDifferentiator;
   785 	delete iOpaqueData;
   826 	iDefaultScreenNumber = defaultScreenNumber;
   786 	iOpaqueData = opaqueData;
   827 	iParentWindowGroupID = parentWindowGroupID;
       
   828 	iDebugMemFail = debugMemFail;
       
   829 	iAppStartupInstrumentationEventIdBase = appStartupInstrumentationEventIdBase;
       
   830 	
   787 	return KErrNone;
   831 	return KErrNone;
   788 	}
   832 	}
   789 
   833 
   790 TPtrC CApaCommandLine::StripQuotes(const TDesC& aDes) const
   834 /**
       
   835 Get the name of the executable from the command line string.
       
   836 @internalTechnology
       
   837 */
       
   838 HBufC* CApaCommandLine::NameOfExecutable(const TDesC& aCmdLine, TInt& aEndDocNameOffset)
       
   839 	{
       
   840 	const TInt cmdLength = aCmdLine.Length();
       
   841 
       
   842 	TBool openQuote = EFalse;
       
   843 	TBool foundEndLibName = EFalse;
       
   844 	for (TInt i = 0; i < cmdLength; ++i)
       
   845 		{
       
   846 		const TChar current = aCmdLine[i];
       
   847 		if (current=='"')
       
   848 			{
       
   849 			openQuote = !openQuote;
       
   850 			continue;
       
   851 			};
       
   852 			
       
   853 		if ((current==' ') && !openQuote)
       
   854 			{
       
   855 			// space found outside of quotes
       
   856 			if (foundEndLibName)
       
   857 				{
       
   858 				aEndDocNameOffset = i-1;
       
   859 				break; // parse no further
       
   860 				}
       
   861 				
       
   862 			aEndDocNameOffset = i-1;
       
   863 			foundEndLibName = ETrue;
       
   864 			}
       
   865 		}
       
   866 		
       
   867 	return (aEndDocNameOffset > -1 ? StripQuotes(aCmdLine.Left(aEndDocNameOffset+1)) : KNullDesC()).Alloc();
       
   868 	}
       
   869 
       
   870 /**
       
   871 Strip all quates from the string.
       
   872 */
       
   873 TPtrC CApaCommandLine::StripQuotes(const TDesC& aDes)
   791 	//
   874 	//
   792 	// return aDes stripped of any enclosing quotes 
   875 	// return aDes stripped of any enclosing quotes 
   793 	//
   876 	//
   794 	{
   877 	{
   795 	TInt start=0;
   878 	TInt start = 0;
   796 	TInt end=aDes.Length()-1;
   879 	TInt end = aDes.Length()-1;
   797 	TPtrC ret;
   880 	TPtrC ret;
   798 	if (end>=0)
   881 	if (end >= 0)
   799 		{
   882 		{
   800 		if (aDes[0]=='"')
   883 		if (aDes[0] == '"')
   801 			{
       
   802 			start++;
   884 			start++;
   803 			}
   885 
   804 		if (aDes[end]=='"')
   886 		if (aDes[end] == '"')
   805 			{
       
   806 			end--;
   887 			end--;
   807 			}
   888 
   808 		TInt length=end-start+1;
   889 		const TInt length = end-start+1;
   809 		if (length>0)
   890 		if (length > 0)
   810 			{
       
   811 			ret.Set(aDes.Mid(start, length));
   891 			ret.Set(aDes.Mid(start, length));
   812 			}
       
   813 		}
   892 		}
       
   893 	
   814 	return ret;
   894 	return ret;
   815 	}
   895 	}
       
   896