--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/testexecfw/statsrv/device/source/statapi/src/stat_comdecoder.cpp Mon Mar 08 15:03:44 2010 +0800
@@ -0,0 +1,2697 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+
+#include <hal.h>
+
+#ifndef LIGHT_MODE
+ #include <eikenv.h>
+ #include <apgtask.h> //for TApaTask usage
+ #include <apgwgnam.h> //for CApaWindowGroupName usage
+#endif
+#include "assert.h"
+#include "stat.h"
+#include "statapi_commanddecoder.h"
+#include "keycodes.h"
+#include "modifiers.h"
+#include "statapi_DeviceInformation.h"
+#include "datasupplier_memory.h"
+#include "datasupplier_file.h"
+#include "dataconsumer_memory.h"
+#include "testshareddata.h"
+#include "tefshareddata.h"
+
+#ifndef LIGHT_MODE
+#include <s32mem.h>
+#include "AppInstall.h"
+#endif // ifndef LIGHT_MODE
+// This redefinition is because CTRL ends in an L and so is picked up (incorrectly) by leavescan
+#define CTRLA CTRL
+
+#define ESTATNoMoreKeys (EStdKeyDecBrightness+1)
+
+#define ESMLShift 1
+#define ESMRShift 2
+#define ESMLAlt 4
+#define ESMRAlt 8
+#define ESMLCtrl 16
+#define ESMRCtrl 32
+#define ESMLFunc 64
+#define ESMRFunc 128
+
+const TInt KMaxSharedDataName = 128;
+const TInt KMaxSharedDataString = 1048;
+
+#ifndef LIGHT_MODE
+_LIT8( newLine, "\r\n" );
+_LIT8( driveFormat, "%c,%S,%Ld%S" );
+_LIT8( entryFormat, "%S,%d,%S,%d%S" );
+_LIT8( dateFormat, "%02d/%02d/%04d %02d:%02d" );
+
+#endif // ifndef LIGHT_MODE
+
+//-----------------------------------------------------------------------------------
+//constructor
+CStatApiCommandDecoder::CStatApiCommandDecoder()
+: iFs( NULL ), pMsg(NULL)
+{
+}
+
+//-----------------------------------------------------------------------------------
+
+CStatApiCommandDecoder* CStatApiCommandDecoder::NewL(RFs *const aSession, MNotifyLogMessage *const aMsg)
+{
+ CStatApiCommandDecoder* self = new(ELeave) CStatApiCommandDecoder();
+
+ CleanupStack::PushL(self);
+
+ self -> ConstructL(aSession, aMsg);
+
+ CleanupStack::Pop();
+
+ return self;
+}
+
+//-----------------------------------------------------------------------------------
+
+void CStatApiCommandDecoder::ConstructL(RFs *const aSession, MNotifyLogMessage *const aMsg)
+{
+#ifndef LIGHT_MODE
+ // Try to connect to the window session server.
+ // Do not leave if there is an error as we may be in a
+ // text only mode (text shell) and the window server is not
+ // available.
+ // We carry on for now but certain features of the command
+ // decoder will become 'unsupported' and will fail.
+ iWs.Connect(); //creation of a new windows server session
+ // This line is for debug purposes.
+ // It is replicated in the function 'IsWindowServerAvailable'.
+ // TInt wsHandle = iWs.WsHandle();
+#endif // ifndef LIGHT_MODE
+
+ iFs = aSession;
+ pMsg = aMsg;
+
+#ifndef LIGHT_MODE
+ if(IsWindowServerAvailable())
+ {
+ // Only start the font and bitmap server if we are in
+ // window shell mode.
+ User::LeaveIfError(FbsStartup());
+ User::LeaveIfError(RFbsSession::Connect()); //font and bitmap server
+
+ // Create the data we use for screen capture.
+ // Do this just once and re-use for each screen image.
+ iDevice = new(ELeave) CWsScreenDevice(iWs); //Create new bitmap
+ iDevice -> Construct();
+
+ // create new bitmap
+ screenBitmap = new(ELeave) CWsBitmap(iWs); //Create new bitmap
+
+ // set the display mode for the bitmap
+ TInt gray;
+ TInt color;
+ TDisplayMode mode = iWs.GetDefModeMaxNumColors(color, gray);
+
+ TSize size = iDevice -> SizeInPixels();
+
+ TInt ret = screenBitmap->Create(size, mode);
+
+ if (ret != KErrNone)
+ {
+ User::Leave(ret);
+ }
+ }
+#endif // ifndef LIGHT_MODE
+
+ HAL::Get(HALData::EMachineUid, iUIDValue);;
+
+ //set system drive
+
+ TDriveNumber defaultSysDrive(EDriveC);
+ RLibrary pluginLibrary;
+ TInt pluginErr = pluginLibrary.Load(KFileSrvDll);
+
+ if (pluginErr == KErrNone)
+ {
+ typedef TDriveNumber(*fun1)();
+ fun1 sysdrive;
+
+ #ifdef __EABI__
+ sysdrive = (fun1)pluginLibrary.Lookup(336);
+ #else
+ sysdrive = (fun1)pluginLibrary.Lookup(304);
+ #endif
+ if(sysdrive!=NULL)
+ {
+ defaultSysDrive = sysdrive();
+ }
+ }
+ pluginLibrary.Close();
+
+ iSystemDrive.Append(TDriveUnit(defaultSysDrive).Name());
+ iSystemDrive.Append(KFileSeparator);
+
+
+
+
+ RefreshStatus( );
+}
+
+//-----------------------------------------------------------------------------------
+//destructor
+CStatApiCommandDecoder::~CStatApiCommandDecoder()
+{
+#ifndef LIGHT_MODE
+ // Clean-up objects created for screen capture.
+ if(iDevice != NULL)
+ {
+ delete iDevice;
+ }
+
+ if(screenBitmap != NULL)
+ {
+ delete screenBitmap;
+ }
+
+ RFbsSession::Disconnect();
+ iWs.Close();
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+//
+// Do whatever the user requested
+//
+TInt CStatApiCommandDecoder::ExecuteCommand(TUint commandtype,
+ MDataConsumer *const aDataConsumer, MDataSupplier **aDataSupplier)
+{
+ TInt ret = KErrNone;
+ TInt exp = KErrNone;
+
+ TInt commandLength = 0;
+
+ if (aDataConsumer)
+ {
+ aDataConsumer->GetTotalSize(commandLength);
+ pMsg->Msg (_L("DECODER: Decoding [%c] with [%d] bytes of data"), commandtype, commandLength);
+ }
+ else
+ {
+ pMsg->Msg (_L("DECODER: Decoding [%c]"), commandtype);
+ }
+
+ // make local copy but not for raw data (Transfer file command), Keypress or WriteTEFSharedData
+ command.Zero();
+ if (commandtype != 'T' && commandtype != 'K' && commandtype != 'O' &&
+ aDataConsumer && commandLength)
+ {
+ command.Copy( *(aDataConsumer) );
+ }
+
+ // Screen saver activates regardless of activity.
+ // Will check for navigation and keypresses here and reset the
+ // inactivity timer.
+ // Ultimately, this should be handled by lower layer key
+ // event processing.
+ if (commandtype == 'K' || commandtype == 'L' ||
+ commandtype == 'M' || commandtype == 'H')
+ {
+ User::ResetInactivityTime();
+ }
+
+ // Check if we are doing a command that depends upon the
+ // window session server or the application architecture
+ // (which may not be available if we are in text shell mode).
+ // If there is no window server or application architecture
+ // then we do not support:
+ // SendText, SendSystemKey, SendCombinationKeys,
+ // SendKeyHold, StopApplicationL, OpenIcon,
+ // OpenFile, StartESHell, Screenshot and
+ // StartApplication.
+ if (commandtype == 'K' || commandtype == 'L' ||
+ commandtype == 'M' || commandtype == 'H' ||
+ commandtype == 'C' || commandtype == 'I' ||
+ commandtype == 'F' || commandtype == '!' ||
+ commandtype == 'A' || commandtype == 'S' )
+ {
+
+ if( ! IsWindowServerAvailable())
+ {
+ ret = KErrNotSupported;
+ }
+ }
+
+ if(ret == KErrNone)
+ {
+ //check message header type
+ switch (commandtype)
+ {
+
+ case ('K'):
+ {
+ if (aDataConsumer && commandLength)
+ {
+ ret = SendText(aDataConsumer, commandLength);
+ }
+ }
+ break;
+ case ('L'):
+ ret = SendSystemKeys();
+ break;
+ case ('M'):
+ ret = SendCombinationKeys();
+ break;
+ case ('H'):
+ ret = SendKeyHold();
+ break;
+ case ('A'):
+ TRAP( exp, (ret = StartApplicationL()) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+ case ('J'):
+ TRAP( exp, (ret = StartProgramL(aDataSupplier)) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+ case ('C'):
+ TRAP(ret, StopApplicationL());
+ break;
+ case ('F'):
+ TRAP( exp, (ret = OpenFileL()) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+ case ('I'):
+ ret = OpenIcon();
+ break;
+ case ('!'):
+ if(command.Length() == 0)
+ {
+ TRAP(ret, StartEShellL());
+ }
+ else
+ {
+ if(command == _L("!"))
+ {
+ TRAP(ret, StopEShellL());
+ }
+ }
+ break;
+ case ('U'):
+ TRAP( exp, ret = DeleteFileL() );
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+ case ('2'):
+ if(aDataConsumer)
+ {
+ TRAP( exp, ret = RenameFileL(aDataConsumer) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ }
+ break;
+ case ('1'):
+ if(aDataConsumer)
+ {
+ ret = CheckLocation(aDataConsumer);
+ }
+ break;
+ case ('Y'):
+ ret = CreateFolder();
+ break;
+ case ('Z'):
+ ret = RemoveFolder();
+ break;
+ case ('T'):
+ if(aDataConsumer)
+ {
+ ret = TransferFile(aDataConsumer);
+ }
+ break;
+ case ('R'):
+ if(aDataConsumer)
+ {
+ ret = ReceiveFile(commandtype, aDataConsumer, aDataSupplier);
+ }
+ break;
+ case ('X'):
+ case ('S'):
+ if(aDataConsumer)
+ {
+ ret = ReceiveFile(commandtype, aDataConsumer, aDataSupplier);
+ }
+ //DeleteLastFile();
+ break;
+ case ('D'):
+ ret = DeviceInfo(aDataSupplier);
+ break;
+ case ('G'):
+ SaveLogFile(aDataSupplier);
+ break;
+ case ('W'):
+ ret = GetDiskDriveInformationL(aDataSupplier);
+ break;
+ case ('V'):
+ if(aDataConsumer)
+ {
+ ret = GetDirectoryInformationL(aDataConsumer, aDataSupplier);
+ }
+ break;
+ case ('B'):
+ RefreshStatus( );
+ break;
+ case ('E'): // end of script
+ break;
+ case ('?'): // resync command
+ break;
+ case ('N'): // Retrieve TEF shared data
+ TRAP( exp, ret = ReadTEFSharedDataL( aDataSupplier ) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+ case ('O'): // Update TEF shared data
+ if(aDataConsumer)
+ {
+ TRAP( exp, ret = WriteTEFSharedDataL(aDataConsumer, commandLength) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ }
+ break;
+ case ('|'):
+ //emulator restart
+ HAL::Set(HAL::ECustomRestart,1);
+ break;
+ case ('3'):
+ TRAP( exp, (ret = ProgramStatusL(command, aDataSupplier)));
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+ case ('~'):
+ TRAP( exp, (ret = StopProgramL(command)) );
+ ret = ((exp != KErrNone) ? exp : ret);
+ break;
+
+#ifndef LIGHT_MODE
+ case ('+'): // install command
+ //modify the name in case doesn't contain drive
+ //if the filname starts with a back slash.
+// if( command.Find(KFileSeparator)== 0 )
+// {
+// //replace the filename with one refering to system drive
+// command.Delete(0,1);
+// command.Insert(0, iSystemDrive);
+// }
+ updatePathWithSysDrive(command) ;
+ ret = CAppInstall::Install(command);
+ break;
+ case ('-'): // uninstall command
+ ret = CAppInstall::Uninstall(command);
+ break;
+#endif // ifndef LIGHT_MODE
+
+ default:
+ ret = KErrNotSupported;
+ }
+ }
+
+ // put the error code into the response
+ if(ret != KErrNone)
+ {
+ if(*aDataSupplier)
+ {
+ (*aDataSupplier)->Delete( );
+ *aDataSupplier = NULL;
+ }
+ AppendErrorCode(ret, aDataSupplier);
+ }
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+//
+// Initialise our command handling status.
+//
+void CStatApiCommandDecoder::RefreshStatus(void)
+{
+ iName = 1;
+}
+
+
+//------------------------------------------------------------------------------
+//
+// Delete a file once we've finished with it
+//
+TInt CStatApiCommandDecoder::DeleteLastFile()
+{
+ TInt exp = KErrNone;
+ command = filename;
+ TRAP( exp, DeleteFileL(FALSE) );
+ return exp;
+}
+
+
+//------------------------------------------------------------------------------
+// Function used to decode data received and send text to an app
+// We need to avoid using 'command' buffer because we don't know
+// how big the actual data will be whereas the other commands all fit
+// easily into the 1024 length limit...
+//
+TInt CStatApiCommandDecoder::SendText(
+ MDataConsumer *const aDataConsumer, int commandLength)
+{
+ // Check we have a window server because it is needed by
+ // DoKeyEvent.
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt err = KErrNone;
+ TInt i = 0;
+
+ HBufC8 *keyData = HBufC8::New( commandLength );
+
+ if( ! keyData )
+ {
+ err = KErrNoMemory;
+ }
+
+ if( err == KErrNone )
+ {
+ err = aDataConsumer->GetData( *keyData );
+ }
+
+ if( err == KErrNone )
+ {
+ TBuf16<1> x;
+
+ for(i=0;i<commandLength;i++)
+ {
+ x.Zero();
+ x.Append((*keyData)[i]);
+ DoKeyEvent(static_cast<TInt>(x[0]));
+
+ // Do not delay this thread for any time but simply
+ // give up the rest of our time-slice to allow
+ // the system to process the key event.
+ User::After(0);
+ }
+
+ // Yield here to give the OS time to actually complete this command.
+ User::After(0);
+ }
+
+ if( keyData )
+ {
+ delete keyData;
+ keyData = NULL;
+ }
+
+ return (err);
+}
+
+
+//------------------------------------------------------------------------------
+//
+//Function used to decode data received and send system keys to an app (ie - Menu, LeftArrow etc)
+//
+
+TInt CStatApiCommandDecoder::SendSystemKeys()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt ret = KErrArgument;
+ TInt i = 0;
+ TBuf<140> scancodevalue = ENUM_TEXTSCANCODEArray[i]; //scancode strings stored here
+ TBuf<100> keycodevalue = ENUM_TEXTKEYArray[i]; //keycode strings entered here
+
+ // look for correct system command from scancodes first
+ while (scancodevalue.Compare(TPtrC(NO_MORE_SCANCODEKEYS)) != 0)
+ {
+ if (command.Compare(scancodevalue) == 0)
+ {
+ //send using SimulateRawEvent...
+ TRawEvent rawEventa;
+ rawEventa.Set(TRawEvent::EKeyDown, ENUM_VALSCANCODEArray[i]);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+
+ rawEventa.Set(TRawEvent::EKeyUp, ENUM_VALSCANCODEArray[i]);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+
+ ret = KErrNone;
+ break;
+ }
+
+ i++;
+ scancodevalue = ENUM_TEXTSCANCODEArray[i];
+ }
+
+ //if there is no scancode then now try the remaining key codes...
+ if(ret != KErrNone)
+ {
+ i = 0; //reinitialise
+
+ while (keycodevalue.Compare(TPtrC(NO_MORE_KEYS)) != 0)
+ {
+ if (command.Compare(keycodevalue) == 0)
+ {
+ // set the event
+ DoKeyEvent(ENUM_VALKEYArray[i]);
+ ret = KErrNone;
+ break;
+ }
+
+ i++;
+ keycodevalue = ENUM_TEXTKEYArray[i];
+ }
+ }
+
+ return (ret);
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+
+//------------------------------------------------------------------------------
+//
+//Function used to decode data received and send combination keys to the device (ie - Ctrl+S)
+//
+
+TInt CStatApiCommandDecoder::SendCombinationKeys()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt plusposition = 0; //used for combination key data
+ TInt i = 0;
+ TInt counter = 0;
+ TInt index = 0;
+
+ TBuf<100> input = _L("");
+
+ TBuf<20> myModifierKey[4]; //there are 4 maximum combination keys that can be used for one command - they will be stored here
+
+ TKeyEvent event; //the key event structure
+ TEventModifier em[5]; //modifier keys required for each of the modifiers available (shift, ctrl, func)
+ TKeyCode kp = EKeyNull;
+
+ //*****Initialisation section*****
+
+ int a = 0;
+ for (a=0;a<4;a++)
+ {
+ myModifierKey[a] = _L("");
+ myModifierKey[a].SetLength(0);
+ }
+
+ int b = 0;
+ for (b=0;b<5;b++)
+ {
+ em[b] = (TEventModifier)0;
+ }
+
+ //********************************
+
+ TInt DataLength = command.Length(); //copy passed data length into local variable
+
+ //The following section splits the data up and puts them into the array
+ while ((DataLength >= 1) && (counter <= 4)) //while length > 1
+ {
+ plusposition = command.Locate('+'); //search for this char
+
+ if (plusposition != KErrNotFound)
+ {
+ myModifierKey[counter] = command.Left(plusposition); //chars left of plus are stored
+ command.Delete(0, (plusposition + 1)); //delete all chars from pos 0 up to and including '+' with null terminator
+ counter++;
+ }
+ else //no more '+' in string
+ {
+ myModifierKey[counter] = command.Left(command.Length());//store remaining string into array
+ command.Delete(0, plusposition + 1); //delete remaining string
+ counter = 5; //make sure exits
+ }
+ }
+
+ counter = 0;
+ event.iCode = 0;
+ event.iScanCode = 0;
+ event.iRepeats = 0;
+ event.iModifiers = 0; //initialisation
+
+ //now check the new data in each of the elements in the array
+ while (counter <= 4)
+ {
+ input = myModifierKey[counter]; //assign value from string
+
+ if (input == _L("Ctrl") || input == _L("LeftCtrl") || input == _L("RightCtrl")
+ || input == _L("Shift") || input == _L("LeftShift") || input == _L("RightShift")
+ || input == _L("Func") || input == _L("LeftFunc") || input == _L("RightFunc")
+ || input == _L("Alt") || input == _L("LeftAlt") || input == _L("RightAlt"))
+ {
+ TBuf<100> value;
+ value = ENUM_TEXTMODIFIERSArray[i]; //assign initial data in array to value (element 0)
+
+ while (value.Compare(TPtrC(NO_MORE_MODIFIERKEYS)) != 0) //make sure not end of array
+ {
+ if (input.Compare(value) == 0) //if the string has been found in the text array
+ {
+ em[counter] = ENUM_VALMODIFIERSArray[i]; //assign em element with the same value from the val array by comparing counter num (location)
+ i = 0; //reinitialise so that the search can restart at the beginning of the enumerated type list
+ break;
+ }
+
+ i++;
+ value = ENUM_TEXTMODIFIERSArray[i]; //update contents of value for the next pass
+ } //end while
+ }
+ else //no combination keys left
+ {
+ if (input.Length() > 1) //if the remaining data is longer than 1 char (ie - could be 'LeftArrow')
+ {
+ TBuf<100> valuekey;
+ valuekey = ENUM_TEXTKEYArray[i]; //assign initial data in array to value (element 0)
+
+ while (valuekey.Compare(TPtrC(NO_MORE_KEYS)) != 0) //make sure not end of array
+ {
+ if (input.Compare(valuekey) == 0) //if the string has been found in the text array
+ {
+ //kp.iScanCode = ENUM_VALKEYArray[i];
+ kp = ENUM_VALKEYArray[i]; //assign kp with the same value from the val array
+
+ if(kp < ENonCharacterKeyBase)
+ {
+ event.iCode = kp;
+ em[2] = EModifierPureKeycode;
+ index = 3;
+ counter = 5;
+ }
+ else
+ {
+ event.iCode = kp;
+ index = 3;
+ counter = 5;
+ }
+
+ break;
+
+ } //end if
+
+ i++;
+ valuekey = ENUM_TEXTKEYArray[i]; //update contents of value for the next pass
+ }
+ }
+ else //must be single char combination, so pass into iCode and set counter to four to exit!
+ {
+ input.LowerCase();
+
+ while (index < 3) //need to check array and see if need to send CTRL or not
+ {
+ if ((em[index] == EModifierLeftCtrl) || (em[index] == EModifierRightCtrl) || (em[index] == EModifierCtrl))
+ {
+ event.iCode = CTRLA(input.Ptr()[0]);
+ counter = 4;
+ break;
+ }
+ else
+ {
+ event.iCode = input.Ptr()[0];
+ index++;
+ counter = 4;
+ }
+ }
+ }
+
+ event.iModifiers = em[0] | em[1] | em[2]; //used to set up Ctrl+Shift+...etc
+
+ } //end else
+
+ counter++;
+ input = _L(""); //reinitialise for next pass
+
+ } //end while
+
+
+ iWs.SimulateKeyEvent(event); // send keystroke
+ iWs.Flush(); // flush client-side window server buffer
+
+ return KErrNone;
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////
+//
+//Function used to hold down keys
+//
+////////////////////////////////////////////////////////////////////////////////////////////
+TInt CStatApiCommandDecoder::ConvertKeycodeToScancode( TDesC& key, TInt& scancode, TInt& modifiers )
+{
+ TInt i, j;
+ TBuf<20> base_punctuation( _L("`,./\\;'#[]-=/*-") );
+ TBuf<20> shift_punctuation( _L("?>?|:@~{}_+XX_") );
+ TBuf<20> numeric_punctuation( _L(")!\"?%^&*(") );
+
+ // clear the modifiers field
+ modifiers = 0;
+
+ // make sure the key is not completely empty
+ if( key.Length() == 0 ) {
+ return -1;
+ }
+
+ // If the key is longer than one char then it must be a special key that we need to
+ // lookup in the table. If it's not in the table then return error
+ if( key.Length() > 1 ) {
+ for( i = 0; ENUM_TEXTSCANCODEArray[i] != NO_MORE_SCANCODEKEYS; i++ ) {
+ if( key.Compare(TPtrC(ENUM_TEXTSCANCODEArray[i])) == 0 ) {
+ scancode = ENUM_VALSCANCODEArray[i];
+ return 0;
+ }
+ }
+ return -1;
+ }
+
+ // get the first key (saves getting it heaps of times)
+ TChar keycode( key.Ptr()[0] );
+
+ // handle lowercase alpha characters
+ if( keycode.IsAlpha() && keycode.IsLower() ) {
+ keycode.UpperCase();
+ scancode = keycode;
+ return 0;
+ }
+
+ // handle uppercase alpha characters
+ if( keycode.IsAlpha() && keycode.IsUpper() ) {
+ scancode = keycode;
+ modifiers = ESMLShift;
+ return 0;
+ }
+
+ // handle numbers
+ if( keycode.IsDigit() ) {
+ scancode = keycode;
+ return 0;
+ }
+
+ // handle punctuation -- just offset by 36 for some unknown reason
+ if( keycode.IsPunctuation() ) {
+
+ j = base_punctuation.Locate( keycode );
+ if( j != KErrNotFound ) {
+ scancode = 120 + j;
+ return 0;
+ }
+
+ j = shift_punctuation.Locate( keycode );
+ if( j != KErrNotFound ) {
+ scancode = 120 + j;
+ modifiers = ESMLShift;
+ return 0;
+ }
+
+ j = numeric_punctuation.Locate( keycode );
+ if( j != KErrNotFound ) {
+ scancode = '0' + j;
+ modifiers = ESMLShift;
+ return 0;
+ }
+
+ scancode = keycode;
+ return 0;
+ }
+
+ // For some reason certain characters are not recognized as punctuation though they
+ // should be. These are handled specifically here.
+ bool found = false;
+ switch( keycode ) {
+
+ case 0x24:
+ scancode = 0x34;
+ modifiers = ESMLShift;
+ found = true;
+ break;
+
+ case 0xa3:
+ scancode = 0x33;
+ modifiers = ESMLShift;
+ found = true;
+ break;
+
+ case 0x80:
+ scancode = 0x34;
+// modifiers = ESMRFunc | ESMLCtrl;
+ modifiers = ESMRAlt;
+ found = true;
+ break;
+
+ case 0xa6:
+ scancode = 0x78;
+ modifiers = ESMRFunc;
+ found = true;
+ break;
+ }
+
+ if (found)
+ return 0;
+ else
+ // key not found
+ return -1;
+}
+
+TInt CStatApiCommandDecoder::SendKeyHold()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TLex Lexcounter;
+ TInt key_action = 0;
+ TRawEvent rawEventa;
+ TInt scancodefound;
+ TInt scancode;
+ TInt modifiers;
+
+ // H commands must have the format <HC,N> where 'C' is the command to be executed and
+ // N is either -1 (key up) or 0 (key down)
+ TInt commaposition = command.Locate(',');
+ if( commaposition == KErrNotFound ) {
+ return KErrArgument;
+ }
+
+ // convert the key action from a string to an integer
+ Lexcounter = command.Mid( commaposition + 1 );
+ Lexcounter.Val( key_action );
+
+ // get the scancode for the key
+ command.SetLength( commaposition );
+ scancodefound = ConvertKeycodeToScancode( command, scancode, modifiers );
+ if( scancodefound == -1 ) {
+ return KErrArgument;
+ }
+
+ // set the appropriate modifier keys
+ if( modifiers & ESMLShift ) {
+ rawEventa.Set(TRawEvent::EKeyDown, EStdKeyLeftShift);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+ if( modifiers & ESMRFunc ) {
+ rawEventa.Set(TRawEvent::EKeyDown, EStdKeyRightFunc);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+ if( modifiers & ESMRAlt ) {
+ rawEventa.Set(TRawEvent::EKeyDown, EStdKeyRightAlt);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+ if( modifiers & ESMLCtrl ) {
+ rawEventa.Set(TRawEvent::EKeyDown, EStdKeyLeftCtrl);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+
+ // now handle the key_action -1 == key_up, 0 == key_down, > 0 == milliseconds to hold the key down
+ switch( key_action ) {
+
+ case -1:
+ rawEventa.Set(TRawEvent::EKeyUp, scancode);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ break;
+
+ case 0:
+ rawEventa.Set(TRawEvent::EKeyDown, scancode);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ break;
+
+ default:
+ rawEventa.Set(TRawEvent::EKeyDown, scancode);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+
+ key_action *= 1000;
+ User::After(TTimeIntervalMicroSeconds32(key_action));
+
+ rawEventa.Set(TRawEvent::EKeyUp, scancode);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ break;
+ }
+
+ // release appropriate function keys
+ if( modifiers & ESMLShift ) {
+ rawEventa.Set(TRawEvent::EKeyUp, EStdKeyLeftShift);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+ if( modifiers & ESMRFunc ) {
+ rawEventa.Set(TRawEvent::EKeyUp, EStdKeyRightFunc);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+ if( modifiers & ESMRAlt ) {
+ rawEventa.Set(TRawEvent::EKeyUp, EStdKeyRightAlt);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+ if( modifiers & ESMLCtrl ) {
+ rawEventa.Set(TRawEvent::EKeyUp, EStdKeyLeftCtrl);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ }
+
+ return KErrNone;
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+
+//------------------------------------------------------------------------------
+//
+//Function used to start application(s)
+//
+TInt CStatApiCommandDecoder::StartApplicationL()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt ret = KErrNone;
+
+ TBuf<KMaxFileName> docName;
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+
+ TInt commaposition = command.Locate(',');
+ if (commaposition != KErrNotFound)
+ {
+ // set the application name
+ cmdLine -> SetExecutableNameL(command.Mid(0, commaposition));
+
+ // use document name supplied in command string
+ docName = command.Mid(commaposition + 1);
+ }
+ else
+ {
+ TBuf<10> timestring;
+ TTime DateAndTime;
+ DateAndTime.HomeTime();
+ DateAndTime.FormatL(timestring, (_L("%J%T%S%*B")));
+
+ // create a default document name based on the system date and time
+
+ docName.Append(iSystemDrive);
+ docName.Append(timestring);
+
+ // set the application name
+ cmdLine -> SetExecutableNameL(command);
+ }
+
+ cmdLine -> SetDocumentNameL(docName);
+ cmdLine -> SetCommandL(EApaCommandCreate);
+
+ if( ret == KErrNone )
+ {
+ //initialise
+ ret = iApaS.Connect();
+ if(ret != KErrNone)
+ pMsg->Msg (_L("DECODER: Application Architecture server error [%c]"), ret);
+ }
+
+ if( ret == KErrNone )
+ {
+ // startup
+ ret = iApaS.StartApp(*cmdLine);
+ if(ret != KErrNone)
+ pMsg->Msg (_L("DECODER: Unable to start application [%c]"), ret);
+ }
+
+ //cleanup
+ iApaS.Close();
+ CleanupStack::PopAndDestroy();
+
+ if( ret == KErrNone )
+ {
+ // need to sleep a bit here to give the OS time to actually start the application
+ User::After(3000000);
+ }
+
+ return (ret);
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+//
+//Function used to start executables(s)
+//
+TInt CStatApiCommandDecoder::StartProgramL(MDataSupplier **aDataSupplier)
+{
+ TInt ret = KErrNone;
+
+ TBuf<KMaxFileName> programName;
+ TBuf<KMaxFileName> parameters;
+
+ TInt commaposition = command.Locate(',');
+ if (commaposition != KErrNotFound)
+ {
+ // set the program name
+ programName = command.Mid(0, commaposition);
+
+ // set the parameters
+ parameters = command.Mid(commaposition + 1);
+ }
+ else
+ {
+ programName = command;
+ }
+
+ updatePathWithSysDrive(programName) ;
+ updatePathWithSysDrive(parameters) ;
+ RProcess newProcess;
+ ret = newProcess.Create(programName,parameters);
+
+ if(ret == KErrNone)
+ {
+
+ TProcessId handle = newProcess.Id();
+
+ if(ret == KErrNone)
+ {
+ newProcess.Resume();
+ newProcess.Close(); // get rid of our handle
+ }
+
+ // Return the PID
+
+ CDataSupplierMemory *pDataSupplier = CDataSupplierMemory::NewL( );
+
+ TBuf8<50> handleNumber;
+
+ handleNumber.Num(handle.Id());
+
+ TInt err;
+
+ if (pDataSupplier)
+ {
+ // Set the data in the data supplier.
+ err = pDataSupplier->SetData( handleNumber );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+ else
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+
+ if (err == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+ }
+
+ return ret;
+}
+
+//------------------------------------------------------------------------------
+//
+//Function used to close application in foreground
+//
+void CStatApiCommandDecoder::StopApplicationL()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt AppIdentifier = 0;
+ TThreadId ThreadIdentifier;
+
+ AppIdentifier = iWs.GetFocusWindowGroup(); //retrieves identifier of the window group that currently has the keyboard focus
+
+ TInt ret = iWs.GetWindowGroupClientThreadId(AppIdentifier, ThreadIdentifier);
+ if(ret == KErrNone)
+ {
+ TInt prev = 0;
+ TInt winGid = iWs.FindWindowGroupIdentifier(prev, ThreadIdentifier); //Get identifier by thread ID
+
+ TApaTask task(iWs);
+ task.SetWgId(winGid);
+
+ if (task.Exists())
+ {
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWs, winGid);
+
+ // check if application is busy
+ if (wgName -> IsSystem() || wgName -> IsBusy() || !wgName -> RespondsToShutdownEvent())
+ ret = KErrAccessDenied;
+
+ CleanupStack::PopAndDestroy(); // wgName
+
+ if(ret == KErrNone)
+ task.SendSystemEvent(EApaSystemEventShutdown); //close app
+ }
+ else
+ {
+ ret = KErrNotFound; //return error if task is non-existent
+ }
+ }
+
+ User::Leave(ret);
+#endif // ifndef LIGHT_MODE
+}
+
+//
+//Function used to close application in foreground
+//
+void CStatApiCommandDecoder::StopEShellL()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt AppIdentifier = 0;
+ TThreadId ThreadIdentifier;
+
+ AppIdentifier = iWs.GetFocusWindowGroup(); //retrieves identifier of the window group that currently has the keyboard focus
+
+ TInt ret = iWs.GetWindowGroupClientThreadId(AppIdentifier, ThreadIdentifier);
+ if(ret == KErrNone)
+ {
+ TInt prev = 0;
+ TInt winGid = iWs.FindWindowGroupIdentifier(prev, ThreadIdentifier); //Get identifier by thread ID
+
+ TApaTask task(iWs);
+ task.SetWgId(winGid);
+
+ if (task.Exists())
+ {
+ CApaWindowGroupName* wgName = CApaWindowGroupName::NewLC(iWs, winGid);
+
+ // check if application is busy
+ if (wgName -> IsSystem())
+ ret = KErrAccessDenied;
+ else
+ {
+ RThread newThread;
+ RProcess newProcess;
+
+ ret = newThread.Open(ThreadIdentifier);
+ if(ret == KErrNone)
+ {
+ ret = newThread.Process(newProcess);
+ if(ret == KErrNone)
+ {
+ if(newProcess.FileName().Right(10).CompareF(_L("eshell.exe")) == 0)
+ {
+ newProcess.Kill(1);
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+ newProcess.Close();
+ }
+ newThread.Close();
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); // wgName
+ }
+ else
+ {
+ ret = KErrNotFound; //return error if task is non-existent
+ }
+ }
+
+ User::Leave(ret);
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+//
+//Function used to read some TEF shared data
+//
+
+TInt CStatApiCommandDecoder::ReadTEFSharedDataL( MDataSupplier **aDataSupplier )
+ {
+ TInt ret = KErrNone;
+
+ TBuf<KMaxSharedDataName> sharedDataName;
+
+ // Set the shared data name
+ TInt length = command.Length();
+ if( length > 0 && length < KMaxSharedDataName )
+ {
+ sharedDataName.Zero();
+ sharedDataName.Copy( command );
+ sharedDataName.ZeroTerminate();
+ }
+ else
+ {
+ ret = KErrArgument;
+ }
+
+ // Now read the shared data area
+ if( ret == KErrNone )
+ {
+ // Read the shared data from the global RChunk
+ HBufC* buffer = NULL;
+ CTestSharedData* sharedDataObject = NULL;
+ CTEFSharedData<CTestSharedData> *tefSharedData = CTEFSharedData<CTestSharedData>::NewLC( sharedDataObject,
+ sharedDataName );
+ if( sharedDataObject != NULL )
+ {
+ tefSharedData->EnterCriticalSection();
+ TRAP( ret, buffer = HBufC::NewL(sharedDataObject->TextLength()) );
+ if( ret == KErrNone )
+ {
+ TPtr bufferPtr( buffer->Des() );
+ sharedDataObject->GetText( bufferPtr );
+ tefSharedData->ExitCriticalSection();
+
+ // Create the response data supplier
+ CDataSupplierMemory *pDataSupplier = NULL;
+ TRAP( ret, pDataSupplier = CDataSupplierMemory::NewL() );
+ if( pDataSupplier && ret == KErrNone )
+ {
+ HBufC8 *buffer8 = NULL;
+ TRAP( ret, buffer8 = HBufC8::NewL(buffer->Length()) );
+ if( ret == KErrNone )
+ {
+ TPtr8 buffer8Ptr( buffer8->Des() );
+ buffer8Ptr.Copy( buffer->Des() );
+
+ // Set the data in the data supplier.
+ ret = pDataSupplier->SetData( *buffer8 );
+
+ // Cleanup
+ delete buffer8;
+ }
+
+ if( ret != KErrNone )
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+ else
+ {
+ ret = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+
+ if (ret == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+ }
+
+ delete buffer;
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+ CleanupStack::PopAndDestroy(tefSharedData);
+ }
+
+ return ret;
+ }
+
+//------------------------------------------------------------------------------
+//
+//Function used to write some TEF shared data
+//
+
+TInt CStatApiCommandDecoder::WriteTEFSharedDataL( MDataConsumer *const aDataConsumer, int commandLength )
+ {
+ TInt ret = KErrNone;
+
+ // Retrieve the data
+ if( commandLength <= KMaxSharedDataString )
+ {
+ HBufC8* sharedDataString = HBufC8::NewLC( commandLength );
+ if( aDataConsumer != NULL )
+ {
+ ret = aDataConsumer->GetData( *sharedDataString );
+
+ // Set the shared data name
+ if( ret == KErrNone )
+ {
+ TBuf<KMaxSharedDataName> sharedDataName;
+ TInt commaposition = sharedDataString->Locate(',');
+ if( commaposition != KErrNotFound )
+ {
+ if( commaposition < KMaxSharedDataName )
+ {
+ sharedDataName.Zero();
+ sharedDataName.Copy(sharedDataString->Mid(0, commaposition));
+ sharedDataName.ZeroTerminate();
+
+ // Set the shared data value
+ HBufC* sharedDataValue = HBufC::NewLC(commandLength-commaposition+1);
+ TPtr ptrSharedDataValue(sharedDataValue->Des());
+ ptrSharedDataValue.Zero();
+ ptrSharedDataValue.Copy(sharedDataString->Mid(commaposition+1));
+ ptrSharedDataValue.ZeroTerminate();
+
+ // Now update the shared data area
+ if( ret == KErrNone )
+ {
+ // Update the shared data with the data passed in
+ CTestSharedData* sharedDataObject = NULL;
+ CTEFSharedData<CTestSharedData> *tefSharedData = CTEFSharedData<CTestSharedData>::NewLC( sharedDataObject,
+ sharedDataName );
+ if( sharedDataObject != NULL )
+ {
+ tefSharedData->EnterCriticalSection();
+ // Copy the data contents across
+ // No need to check the data length as it was checked above
+ sharedDataObject->SetText( *sharedDataValue );
+ tefSharedData->ExitCriticalSection();
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+
+ CleanupStack::PopAndDestroy(tefSharedData);
+ }
+
+ // Cleanup
+ CleanupStack::PopAndDestroy(sharedDataValue);
+ }
+ else
+ {
+ ret = KErrArgument;
+ }
+ }
+ else
+ {
+ ret = KErrArgument;
+ }
+ }
+ }
+ else
+ {
+ ret = KErrArgument;
+ }
+ CleanupStack::PopAndDestroy(sharedDataString);
+ }
+ else
+ {
+ ret = KErrTooBig;
+ }
+
+ return ret;
+ }
+
+//------------------------------------------------------------------------------
+//
+//Function used to open file(s)
+//
+
+TInt CStatApiCommandDecoder::OpenFileL()
+{
+#ifndef LIGHT_MODE
+ TInt ret = KErrArgument;
+
+ TBuf<KMaxFileName> docName;
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC();
+
+ TInt commaposition = command.Locate(',');
+ if (commaposition != KErrNotFound)
+ {
+ // set the application name
+ cmdLine -> SetExecutableNameL(command.Mid(0, commaposition));
+
+ // use document name supplied in command string
+ docName = command.Mid(commaposition + 1);
+
+ updatePathWithSysDrive(docName);
+ cmdLine -> SetDocumentNameL(docName);
+ cmdLine -> SetCommandL(EApaCommandOpen);
+
+ //initialise
+ TRAP(ret, iApaS.Connect())
+ if(ret != KErrNone)
+ pMsg->Msg(_L("DECODER: Application Architecture server error...%d"), ret);
+
+ // startup
+ TRAP(ret, iApaS.StartApp(*cmdLine))
+ if(ret != KErrNone)
+ pMsg->Msg(_L("DECODER: Unable to start application...%d"), ret);
+
+ //cleanup
+ iApaS.Close();
+
+ // need to sleep a bit here to give the OS time to actually start the application
+ User::After(3000000);
+ }
+
+ CleanupStack::PopAndDestroy();
+ return ret;
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+//------------------------------------------------------------------------------
+//
+//Function used to capture screens
+//
+
+void CStatApiCommandDecoder::ScreenCaptureL()
+{
+#ifndef LIGHT_MODE
+
+ //_LIT(KDriveD, "d:\\");
+
+ // Optimize screen captures by only creating device objects
+ // once and re-using them.
+ // Create screen device object is now done in
+ // CStatApiCommandDecoder::ConstructL and removed
+ // in CStatApiCommandDecoder::~CStatApiCommandDecoder().
+
+ User::LeaveIfError(iDevice->CopyScreenToBitmap(screenBitmap));
+
+ // retrieve machine id information
+ TBuf<20> buffer;
+ buffer.Num(iUIDValue);
+
+ TBuf<KMaxFileName> tempfilename;
+
+ tempfilename.Append(iSystemDrive);
+ tempfilename.Append(buffer);
+ tempfilename.Append(_L("00")); //substation id
+
+ // create date/time string for filename
+ TBuf<25> datestring;
+ TTime DateAndTime;
+ DateAndTime.HomeTime();
+ DateAndTime.FormatL(datestring, (_L("%D%M%*Y%1%2%3%J%T%S")));
+ tempfilename.Append(datestring);
+
+ //bitmap image extension
+ tempfilename.Append(_L(".mbm"));
+
+ // save the image to file
+ User::LeaveIfError(screenBitmap->Save(tempfilename));
+ {
+ filename = tempfilename;
+ }
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+//function used to simulate a screen press using stylus
+
+TInt CStatApiCommandDecoder::OpenIcon()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TInt ret = KErrArgument;
+
+ TInt commaposition = command.Locate(',');
+ if (commaposition != KErrNotFound)
+ {
+ // get x coord
+ TInt x = 0;
+ TLex Lexcoord = command.Mid(0, commaposition);
+ Lexcoord.Val(x);
+
+ // get y coord
+ TInt y = 0;
+ Lexcoord = command.Mid(commaposition + 1);
+ Lexcoord.Val(y);
+
+ //mouse click down
+ TRawEvent rawEventa;
+ rawEventa.Set(TRawEvent::EButton1Down, x, y);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ User::After(TTimeIntervalMicroSeconds32(100000));
+
+ //mouse click up
+ rawEventa.Set(TRawEvent::EButton1Up, x, y);
+ iWs.SimulateRawEvent(rawEventa);
+ iWs.Flush();
+ User::After(TTimeIntervalMicroSeconds32(100000));
+ ret = KErrNone;
+ }
+
+ return (ret);
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+
+//------------------------------------------------------------------------------
+//function used to invoke the ESHELL command interpreter
+//
+// This is done alternatively to starting an app because the ESHELL
+// cannot be invoked from it's current location in z:
+//
+// So we copy it first to C: then start it...
+//
+void CStatApiCommandDecoder::StartEShellL()
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ _LIT(KNewFile, "z:\\sys\\bin\\EShell.exe");
+
+
+ // set command line
+ CApaCommandLine* cmdLine = CApaCommandLine::NewLC(); //creation of command line structure
+ cmdLine -> SetExecutableNameL(KNewFile);
+
+ // call it
+ User::LeaveIfError(iApaS.Connect()); //initialise
+ User::LeaveIfError(iApaS.StartApp(*cmdLine)); //start the app
+ iApaS.Close();
+
+ // clean up
+ CleanupStack::PopAndDestroy(1); // cmdLine
+
+ // need to sleep a bit here to give the OS time to actually start the application
+ User::After(3000000);
+
+ User::Leave(KErrNone);
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+//function used to delete file from the device
+//
+TInt CStatApiCommandDecoder::DeleteFileL(TInt bDisplayMessage)
+{
+ CFileMan *theFile = CFileMan::NewL(*iFs);
+ CleanupStack::PushL(theFile);
+
+ updatePathWithSysDrive(command) ;
+ TInt err = theFile->Delete(command);
+ if (err!= KErrNone && err!= KErrNotFound)
+ {
+ if (bDisplayMessage)
+ pMsg->Msg(_L("DECODER: Error deleting file %S...%d"), &command, err);
+ }
+
+ CleanupStack::PopAndDestroy();
+ return err;
+}
+
+//------------------------------------------------------------------------------
+//function used to rename file from the device
+//
+TInt CStatApiCommandDecoder::RenameFileL(MDataConsumer *const aDataConsumer)
+{
+
+ TInt err = KErrNone;
+
+ CFileMan *theFile = CFileMan::NewL(*iFs);
+ CleanupStack::PushL(theFile);
+
+ TBuf<KMaxPath> dataFiles;
+
+ TBuf<KMaxPath> dataFileNameFrom;
+ TBuf<KMaxPath> dataFileNameTo;
+
+ dataFiles.Copy( *aDataConsumer );
+
+ if( err == KErrNone )
+ {
+ // locate the destination part of the filename
+ TInt commaposition = dataFiles.Locate(',');
+ if (commaposition != KErrNotFound)
+ {
+ //name of existing file
+ dataFileNameFrom.Zero();
+ dataFileNameFrom.Copy(dataFiles.Left(commaposition));
+ filename.ZeroTerminate();
+
+ //name of destination file
+ dataFileNameTo.Zero();
+ dataFileNameTo.Copy(dataFiles.Right(dataFiles.Length()-commaposition-1));
+ dataFileNameTo.ZeroTerminate();
+
+ updatePathWithSysDrive(dataFileNameFrom) ;
+ updatePathWithSysDrive(dataFileNameTo) ;
+ err = theFile->Copy( dataFileNameFrom, dataFileNameTo );
+
+ if( err == KErrNone )
+ {
+ err = theFile->Delete(dataFileNameFrom);
+ }
+
+ }
+ else
+ {
+ err = KErrNotFound;
+ }
+ }
+
+ CleanupStack::PopAndDestroy();
+ return err;
+}
+
+
+
+//------------------------------------------------------------------------------
+//function used to check if a location exists on the device
+//
+TInt CStatApiCommandDecoder::CheckLocation(MDataConsumer *const aDataConsumer)
+{
+
+ TInt err = KErrNone;
+ TEntry aEntry;
+ TVolumeInfo aVolume;
+ TInt aDrive;
+ TBuf<KMaxPath> aPath;
+
+ aPath.Copy(*aDataConsumer);
+ updatePathWithSysDrive(aPath);
+
+ iFs->CharToDrive((char)aPath[0],aDrive);
+
+ //try to get drive info
+ err = iFs->Volume(aVolume,aDrive);
+
+ if(err == KErrNone && aPath.Length() > 3)
+ {
+ //try to get file info
+ err = iFs->Entry(aPath,aEntry);
+ }
+
+ return err;
+
+}
+
+
+
+
+//------------------------------------------------------------------------------
+//function used to create a folder on the device
+//
+TInt CStatApiCommandDecoder::CreateFolder()
+{
+ updatePathWithSysDrive(command);
+ TInt err = iFs->MkDirAll(command);
+
+ // no error or already exists are acceptable return codes
+ if (err == KErrAlreadyExists)
+ err = KErrNone;
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+//function used to remove a folder from the device
+//
+TInt CStatApiCommandDecoder::RemoveFolder()
+{
+
+ updatePathWithSysDrive(command) ;
+ TInt err = iFs->RmDir(command);
+
+ // no error or not found are acceptable return codes
+ if (err == KErrNotFound)
+ err = KErrNone;
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+
+TInt CStatApiCommandDecoder::TransferFile(MDataConsumer *const aDataConsumer)
+{
+ TInt err = KErrNone;
+
+ // the Transfer command comes in 2 parts - first the name, then the contents
+ if (iName)
+ {
+ pMsg->Msg(_L("DECODER: Saving filename..."));
+
+ TBuf<KMaxPath> dataFileName;
+ dataFileName.Copy(*aDataConsumer ) ;
+ updatePathWithSysDrive(dataFileName) ;
+
+ if( err == KErrNone )
+ {
+ // locate the destination part of the filename
+ TInt commaposition = dataFileName.Locate(',');
+ if (commaposition != KErrNotFound)
+ {
+ // use document name supplied in command string
+ filename.Zero();
+ filename.Copy(dataFileName.Mid(commaposition + 1));
+ filename.ZeroTerminate();
+ pMsg->Msg(_L("DECODER: File name (%S)."), &filename);
+ iName = 0;
+ err = KErrNone;
+ }
+ }
+ }
+ else
+ {
+ // save the file
+ pMsg->Msg(_L("DECODER: Saving file %S"), &filename);
+
+ if( aDataConsumer != NULL )
+ {
+ err = aDataConsumer->SaveData( filename );
+ }
+ else
+ {
+ CDataConsumerMemory *dataConsumer = NULL;
+ TRAP(err, dataConsumer = CDataConsumerMemory::NewL( ));
+
+ if( err == KErrNone )
+ {
+ err = dataConsumer->SaveData( filename );
+ }
+
+ if( NULL != dataConsumer )
+ {
+ dataConsumer->Delete();
+ dataConsumer = NULL;
+ }
+ }
+
+ iName = 1;
+ }
+
+ return err;
+}
+
+
+//------------------------------------------------------------------------------
+
+TInt CStatApiCommandDecoder::ReceiveFile(TUint commandtype,
+ MDataConsumer *const aDataConsumer, MDataSupplier **aDataSupplier)
+{
+ TInt err = KErrNone;
+
+ // take screenshot first? filename will be generated automatically
+ if (commandtype == 'S')
+ {
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TRAP(err, ScreenCaptureL());
+ }
+ else
+ {
+ TPath dataFileName;
+
+ dataFileName.Copy( *aDataConsumer );
+ updatePathWithSysDrive(dataFileName) ;
+ if( err == KErrNone )
+ {
+ // get the filename from the command
+ TInt commaposition = dataFileName.Locate(',');
+ if (commaposition != KErrNotFound)
+ filename.Copy(dataFileName.Mid(0, commaposition));
+ else
+ filename.Copy(dataFileName);
+ }
+ }
+
+ MDataSupplier *pDataSupplier = NULL;
+
+ // Use a data supplier class.
+ // Initialise it with the file name and allocate
+ // an initial data buffer.
+
+ if (err == KErrNone)
+ {
+ // Create the data supplier.
+ pDataSupplier = CDataSupplierFile::NewL( );
+
+ if (pDataSupplier)
+ {
+ // Set the data in the data supplier.
+ TBuf8<KMaxPath> filePath;
+ filePath.Copy( filename );
+
+ err = pDataSupplier->SetData( filePath );
+
+ if (err != KErrNone)
+ {
+ TBuf16<KMaxPath> wFilePath;
+ wFilePath.Copy( filePath );
+ pMsg->Msg(_L("Failed to set data in data supplier, (%d)."), err );
+ pMsg->Msg(_L("File path %S."), &wFilePath );
+ }
+ }
+ else
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+ }
+
+ // If we are sending a screen image file then we
+ // use another data supplier class as the file is to be deleted.
+ if (commandtype == 'S')
+ {
+ TInt size = 0;
+ HBufC8 *buffer = NULL;
+
+ if (err == KErrNone)
+ {
+ err = pDataSupplier->GetTotalSize( size );
+
+ if( err != KErrNone )
+ {
+ pMsg->Msg(_L("Failed to get total size of screen image file") );
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ buffer = HBufC8::New(size);
+
+ if( ! buffer )
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to allocate buffer for screen image file") );
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ err = pDataSupplier->GetData( *buffer, size, size );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to read data from screen image data supplier") );
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ pDataSupplier->Delete( );
+
+ pDataSupplier = CDataSupplierMemory::NewL( );
+
+ if( ! pDataSupplier )
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ err = pDataSupplier->SetData( *buffer );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+
+ if( NULL != buffer )
+ {
+ delete buffer;
+ buffer = NULL;
+ }
+ }
+
+ if (err == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+
+ return err;
+}
+
+
+//------------------------------------------------------------------------------
+
+TInt CStatApiCommandDecoder::DeviceInfo(MDataSupplier **aDataSupplier)
+{
+ TBuf8<20> buffer = _L8("");
+ TBuf8<150> finalbuffer = _L8("\r\n");
+
+ TInt DeviceInfoValue;
+ TInt err = KErrNone;
+ TInt i = 0;
+
+ //device info required: UID, manufacturer, ROM, RAM, etc
+ HALData::TAttribute AttribArray[14] = {
+ HALData::EMachineUid,
+ HALData::ECPU,
+ HALData::ECPUABI,
+ HALData::EDeviceFamily,
+ HALData::EManufacturer,
+
+ HALData::EModel,
+ HALData::EDeviceFamilyRev,
+ HALData::EManufacturerHardwareRev,
+ HALData::EManufacturerSoftwareRev,
+ HALData::EManufacturerSoftwareBuild,
+ HALData::EMemoryPageSize,
+ HALData::EMemoryRAM,
+ HALData::EMemoryRAMFree,
+ HALData::EMemoryROM
+ };
+
+ finalbuffer.Append(_L("STAT Version "));
+
+ buffer.Num(KVersionMajor);
+ finalbuffer.Append(buffer);
+ finalbuffer.Append(_L("."));
+
+ buffer.Num(KVersionMinor);
+ finalbuffer.Append(buffer);
+ finalbuffer.Append(_L("."));
+
+ buffer.Num(KVersionPatch);
+ finalbuffer.Append(buffer);
+ finalbuffer.Append(_L("\r\n"));
+
+ while(i < 14) //retrieve all the information and write to a buffer
+ {
+ // get the attribute value
+ HAL::Get(AttribArray[i], DeviceInfoValue);
+ buffer.Num(DeviceInfoValue);
+
+ // need to convert the value to a meaningful string
+ if (i < 5)
+ {
+ GetData(i, buffer);
+ }
+
+ finalbuffer.Append(buffer);
+ finalbuffer.Append(_L8("\r\n"));
+ i++;
+ }
+
+ CDataSupplierMemory *pDataSupplier = CDataSupplierMemory::NewL( );
+
+ if (pDataSupplier)
+ {
+ // Set the data in the data supplier.
+ err = pDataSupplier->SetData( finalbuffer );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+ else
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+
+ if (err == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+
+TInt CStatApiCommandDecoder::SaveLogFile(MDataSupplier **aDataSupplier)
+{
+ TInt err = KErrNone;
+
+ CDataConsumerMemory *data = NULL;
+
+ // if the log file is not enabled then we return an empty buffer
+ if( pMsg->IsInitialised() == EFalse )
+ {
+ return KErrNone;
+ }
+
+ //open the file an copy it into the return buffer
+ data = CDataConsumerMemory::NewL( );
+
+ if( ! data )
+ {
+ err = KErrNoMemory;
+ }
+
+ if( err == KErrNone )
+ {
+ pMsg->CloseFile();
+ }
+
+
+
+ TBuf<KMaxPath> filePath;
+ TBuf<17> statLogFile;
+ statLogFile.Append(iSystemDrive);
+ statLogFile.Append(KStatLogFile);
+ if( err == KErrNone )
+ {
+
+ RFile file;
+
+ err = file.Temp( *iFs, iSystemDrive,
+ filePath, EFileShareExclusive );
+
+ if( err == KErrNone )
+ {
+ file.Close( );
+
+ CFileMan* fileMan = CFileMan::NewL( *iFs );
+ err = fileMan->Copy(statLogFile,filePath);
+ delete fileMan;
+ fileMan = NULL;
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ TBuf8<KMaxPath> cFilePath;
+ cFilePath.Copy( filePath );
+ err = data->AddData( cFilePath );
+ }
+
+ if( err == KErrNone )
+ {
+ err = ReceiveFile('R', data, aDataSupplier);
+ }
+
+
+ if( err == KErrNone )
+ {
+ // reset the logger
+ pMsg->Init( *iFs, statLogFile, NULL );
+ }
+
+ if( data )
+ {
+ data->Delete( );
+ data = NULL;
+ }
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+
+#ifndef LIGHT_MODE
+TInt CStatApiCommandDecoder::GetDiskDriveInformationL(MDataSupplier **aDataSupplier)
+#else // ifndef LIGHT_MODE
+TInt CStatApiCommandDecoder::GetDiskDriveInformationL(MDataSupplier **)
+#endif // ifndef LIGHT_MODE
+{
+#ifndef LIGHT_MODE
+ TInt err = KErrNone;
+
+ // Get the disk drive information and save to the data supplier object
+ // as a text string.
+
+ static const TInt bufferGrow = (4*1024);
+ RBufWriteStream strWrite;
+ CBufFlat* dynBuffer = NULL;
+
+ if( err == KErrNone )
+ {
+ dynBuffer = CBufFlat::NewL(bufferGrow);
+
+ if( dynBuffer == NULL )
+ {
+ err = KErrNoMemory;
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ strWrite.Open( *dynBuffer, 0 );
+ }
+
+ if( err == KErrNone )
+ {
+ RFs fileSystem;
+
+ err = fileSystem.Connect();
+
+ if( err == KErrNone )
+ {
+ TDriveList driveList;
+
+ if( err == KErrNone )
+ {
+ err = fileSystem.DriveList( driveList );
+ }
+
+ if( err == KErrNone )
+ {
+ TBuf8<KMaxFileName> name; // Store volume name
+ // in 8 bit format.
+ TBuf8<KMaxFileName*2> buffer; // Store volume information.
+
+ TVolumeInfo volumeInfo;
+ TInt drive = 0;
+ for( drive = 0; drive < KMaxDrives; drive++ )
+ {
+ if( driveList[drive] )
+ {
+ err = fileSystem.Volume( volumeInfo, drive );
+
+ if( err == KErrNone )
+ {
+ // Copy the volume name to an 8 bit buffer.
+ name.Copy( volumeInfo.iName );
+ // Format the text string.
+ buffer.Format( driveFormat, drive + 'A',
+ &name, volumeInfo.iSize, &newLine );
+ // Add details of the current drive to our
+ // buffer.
+ TRAP( err, strWrite.WriteL( buffer ) );
+ }
+ }
+ }
+ }
+ fileSystem.Close();
+ }
+ }
+
+ if( err == KErrNone || err == KErrNotReady )
+ {
+ TRAP( err, strWrite.WriteL( newLine ) );
+
+ CDataSupplierMemory *pDataSupplier = CDataSupplierMemory::NewL( );
+
+ if (pDataSupplier)
+ {
+ // Set the data in the data supplier.
+ err = pDataSupplier->SetData( dynBuffer->Ptr( 0 ) );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+ else
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+
+ if (err == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+ }
+
+ strWrite.Close( );
+
+ if( dynBuffer != NULL )
+ {
+ delete dynBuffer;
+ dynBuffer = NULL;
+ }
+
+ return err;
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+
+#ifndef LIGHT_MODE
+TInt CStatApiCommandDecoder::GetDirectoryInformationL(MDataConsumer *const aDataConsumer,
+ MDataSupplier **aDataSupplier)
+#else // ifndef LIGHT_MODE
+TInt CStatApiCommandDecoder::GetDirectoryInformationL(MDataConsumer *const,
+ MDataSupplier **)
+#endif // ifndef LIGHT_MODE
+{
+#ifndef LIGHT_MODE
+ TInt err = KErrNone;
+
+ // Get the directory entries for a specified directory
+ // and save to the data supplier object as a text string.
+
+ TBuf<KMaxPath> directoryName;
+
+ static const TInt bufferGrow = (4*1024);
+ RBufWriteStream strWrite;
+ CBufFlat* dynBuffer = NULL;
+
+ if( err == KErrNone )
+ {
+ directoryName.Copy( *aDataConsumer );
+ }
+
+ if( err == KErrNone )
+ {
+ dynBuffer = CBufFlat::NewL(bufferGrow);
+
+ if( dynBuffer == NULL )
+ {
+ err = KErrNoMemory;
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ strWrite.Open( *dynBuffer, 0 );
+ }
+
+ if( err == KErrNone )
+ {
+ RFs fileSystem;
+
+ err = fileSystem.Connect();
+
+ if( err == KErrNone )
+ {
+ CDir *entryList = NULL;
+
+ if( err == KErrNone )
+ {
+ err = fileSystem.GetDir( directoryName, KEntryAttMaskSupported, EDirsFirst | ESortByName,
+ entryList );
+ }
+
+ if( err == KErrNone )
+ {
+ TBuf8<KMaxFileName> name; // Store entry name
+ // in 8 bit format.
+ TBuf8<KMaxFileName*2> buffer; // Store entry information.
+
+ static const TInt maxDateLength = 32;
+ TBuf8<maxDateLength> dateBuffer;
+
+ TDateTime dateTime;
+
+ TInt count = entryList->Count();
+ TInt entry = 0;
+ for( entry = 0; (entry < count) && (err == KErrNone); entry++ )
+ {
+ const TEntry &anEntry = entryList->operator[](entry);
+
+ // Format the date into readable text.
+ dateTime = anEntry.iModified.DateTime();
+ dateBuffer.Format( dateFormat, dateTime.Day() + 1, dateTime.Month() + 1,
+ dateTime.Year(), dateTime.Hour(), dateTime.Minute() );
+
+ // Copy the volume name to an 8 bit buffer.
+ name.Copy( anEntry.iName );
+ // Format the text string.
+ buffer.Format( entryFormat, &name,
+ anEntry.iAtt, &dateBuffer, anEntry.iSize, &newLine );
+ // Add details of the current drive to our
+ // buffer.
+ TRAP( err, strWrite.WriteL( buffer ) );
+ }
+ }
+
+ if( entryList != NULL )
+ {
+ delete entryList;
+ entryList = NULL;
+ }
+ fileSystem.Close();
+ }
+ }
+
+ if( err == KErrNone )
+ {
+ TRAP( err, strWrite.WriteL( newLine ) );
+
+ CDataSupplierMemory *pDataSupplier = CDataSupplierMemory::NewL( );
+
+ if (pDataSupplier)
+ {
+ // Set the data in the data supplier.
+ err = pDataSupplier->SetData( dynBuffer->Ptr( 0 ) );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+ else
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+
+ if (err == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+ }
+
+ strWrite.Close( );
+
+ if( dynBuffer != NULL )
+ {
+ delete dynBuffer;
+ dynBuffer = NULL;
+ }
+
+ return err;
+#else // ifndef LIGHT_MODE
+ return (KErrNotSupported);
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+
+#ifndef LIGHT_MODE
+void CStatApiCommandDecoder::DoKeyEvent(TInt key)
+#else // ifndef LIGHT_MODE
+void CStatApiCommandDecoder::DoKeyEvent(TInt)
+#endif // ifndef LIGHT_MODE
+{
+#ifndef LIGHT_MODE
+ // If this assert triggers it is because we are running in
+ // text shell mode without a window server and the call
+ // requires the window server to be available.
+ // A command filter in ExecuteCommand should have prevented
+ // this call from being made.
+ assert(IsWindowServerAvailable());
+
+ TKeyEvent event; //the key event structure
+ event.iCode = key; // pass character code into the struct value
+ event.iScanCode = 0;
+ event.iModifiers = 0;
+ event.iRepeats = 0; // no repeats for keypress
+
+ iWs.SimulateKeyEvent(event); // send keystroke
+ iWs.Flush(); // flush client-side window server buffer
+#endif // ifndef LIGHT_MODE
+}
+
+//------------------------------------------------------------------------------
+//Get the required device information
+TInt CStatApiCommandDecoder::GetData(TInt i, TDes8& info)
+{
+ TInt err = KErrNone;
+ TInt a = 0;
+ TBuf8<150> devicevalue = _L8("");
+ TBool found = EFalse;
+
+ devicevalue.Num(ENUM_VALDEVICEINFORMATIONArray[i][a]); //assign initial data in array to value (element 0)
+ while (ENUM_DEVICEINFORMATIONArray[i][a] != NULL)
+ {
+ if (info.Compare(devicevalue) == 0) //if the string has been found in the value array
+ {
+ info = ENUM_DEVICEINFORMATIONArray[i][a]; //set the value to the string equivalent
+ found = ETrue;
+ break;
+ }
+
+ a++;
+ devicevalue.Num(ENUM_VALDEVICEINFORMATIONArray[i][a]); //update contents of value for the next pass
+ } //end while
+
+ if (!found)
+ info = _L8("Not available");
+
+ return err;
+}
+
+//------------------------------------------------------------------------------
+void CStatApiCommandDecoder::AppendErrorCode(TInt ret, MDataSupplier **aDataSupplier)
+{
+ HBufC8 *buffer = HBufC8::New(10);
+ if (buffer)
+ {
+ // add the error code
+ TPtr8 pBuffer(buffer->Des());
+ pBuffer.Zero();
+ pBuffer.Num(ret);
+ pBuffer.ZeroTerminate();
+
+ *aDataSupplier = CDataSupplierMemory::NewL( );
+ if (*aDataSupplier)
+ {
+ // Set the data in the data supplier.
+ (*aDataSupplier)->SetData( *buffer );
+ }
+
+ delete buffer;
+ buffer = NULL;
+ }
+}
+
+TInt CStatApiCommandDecoder::StopProgramL(const TDesC& aHandleNumber)
+{
+ TLex conv(aHandleNumber);
+
+ TInt64 handleNumber;
+
+ TInt err = conv.Val(handleNumber);
+
+ if(err==KErrNone)
+ {
+ RProcess newProcess;
+ err = newProcess.Open(TProcessId(handleNumber));
+ if(err==KErrNone)
+ {
+ newProcess.Kill(1);
+ }
+ newProcess.Close();
+ }
+
+ return err;
+}
+
+
+TInt CStatApiCommandDecoder::ProgramStatusL(const TDesC& aHandleNumber, MDataSupplier **aDataSupplier)
+{
+
+ CDataSupplierMemory *pDataSupplier = CDataSupplierMemory::NewL( );
+
+ TBuf8<50> exitData;
+
+ TLex conv(aHandleNumber);
+
+ TInt64 handleNumber;
+
+ TInt err = conv.Val(handleNumber);
+
+ if(err==KErrNone)
+ {
+ RProcess newProcess;
+ TInt status = newProcess.Open(TProcessId(handleNumber));
+
+ switch(status)
+ {
+ case KErrNone:
+ exitData.Num(ETrue);
+ break;
+ default:
+ exitData.Num(EFalse);
+ }
+
+ if (pDataSupplier)
+ {
+ // Set the data in the data supplier.
+ err = pDataSupplier->SetData( exitData );
+
+ if (err != KErrNone)
+ {
+ pMsg->Msg(_L("Failed to set data in data supplier") );
+ }
+ }
+ else
+ {
+ err = KErrNoMemory;
+ pMsg->Msg(_L("Failed to create data supply object") );
+ }
+
+ if (err == KErrNone)
+ {
+ *aDataSupplier = pDataSupplier;
+ }
+ else
+ {
+ if (pDataSupplier)
+ {
+ pDataSupplier->Delete( );
+ pDataSupplier = NULL;
+ }
+ }
+
+ newProcess.Close();
+ }
+
+ return err;
+}
+
+
+void CStatApiCommandDecoder::updatePathWithSysDrive(TBuf<1024>& pathToChange )
+{
+ //try it here...
+ //check for the sysdrive being diff from C:
+ TBufC<KMaxPath> workingPath(pathToChange) ;
+ TInt indx = workingPath.Des().Find(KReDrive) ;
+ while( indx > KErrNotFound )
+ {
+ workingPath.Des().Replace(indx,2,getSystemDrive());
+ pathToChange = workingPath.Des() ;
+ indx = workingPath.Des().Find(KReDrive) ;
+ }
+
+}
+
+void CStatApiCommandDecoder::updatePathWithSysDrive(TBuf<KMaxPath>& pathToChange )
+ {
+ TBufC<KMaxPath> workingPath(pathToChange) ;
+ TInt indx = workingPath.Des().Find(KReDrive) ;
+ while( indx > KErrNotFound )
+ {
+ workingPath.Des().Replace(indx,2,getSystemDrive());
+ pathToChange = workingPath.Des() ;
+ indx = workingPath.Des().Find(KReDrive) ;
+ }
+
+ }
+
+TDriveName CStatApiCommandDecoder::getSystemDrive()
+{
+
+ TDriveNumber defaultSysDrive(EDriveC);
+ RLibrary pluginLibrary;
+ TInt pluginErr = pluginLibrary.Load(KFileSrvDll);
+ if (pluginErr == KErrNone)
+ {
+ typedef TDriveNumber(*fun1)();
+ fun1 sysdrive;
+
+ #ifdef __EABI__
+ sysdrive = (fun1)pluginLibrary.Lookup(336);
+ #else
+ sysdrive = (fun1)pluginLibrary.Lookup(304);
+ #endif
+
+ if(sysdrive!=NULL)
+ {
+ defaultSysDrive = sysdrive();
+ }
+ }
+ pluginLibrary.Close();
+
+ //TDriveName drive( TDriveUnit(defaultSysDrive).Name()) ;
+ return TDriveUnit(defaultSysDrive).Name() ;
+
+}