sl@0
|
1 |
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
//
|
sl@0
|
15 |
|
sl@0
|
16 |
// system includes
|
sl@0
|
17 |
#include <schtask.h>
|
sl@0
|
18 |
|
sl@0
|
19 |
// User includes
|
sl@0
|
20 |
#include "SCHEXEC.H"
|
sl@0
|
21 |
#include "SchLogger.h"
|
sl@0
|
22 |
#include "SCHLOG.h"
|
sl@0
|
23 |
#include "taskfile.h"
|
sl@0
|
24 |
|
sl@0
|
25 |
//Delay ensuring this thread is be preempted allowing client cleanup
|
sl@0
|
26 |
//in case task file cannot be deleted
|
sl@0
|
27 |
const TInt KClientCleanupDelay = 10000;
|
sl@0
|
28 |
|
sl@0
|
29 |
CTaskExecutor::CTaskExecutor(CSchLogManager& aSchLogManager)
|
sl@0
|
30 |
: CActive(EPriorityStandard),
|
sl@0
|
31 |
iSchLogManager(aSchLogManager)
|
sl@0
|
32 |
{
|
sl@0
|
33 |
CActiveScheduler::Add(this);
|
sl@0
|
34 |
}
|
sl@0
|
35 |
|
sl@0
|
36 |
|
sl@0
|
37 |
CTaskExecutor::~CTaskExecutor()
|
sl@0
|
38 |
{
|
sl@0
|
39 |
LOGSTRING("CTaskExecutor::~CTaskExecutor - start");
|
sl@0
|
40 |
iProcess.Close();
|
sl@0
|
41 |
|
sl@0
|
42 |
//
|
sl@0
|
43 |
delete iClientFileName;
|
sl@0
|
44 |
delete iTaskFileName;
|
sl@0
|
45 |
delete iLogErrorMessage;
|
sl@0
|
46 |
LOGSTRING("CTaskExecutor::~CTaskExecutor - end");
|
sl@0
|
47 |
}
|
sl@0
|
48 |
|
sl@0
|
49 |
|
sl@0
|
50 |
void CTaskExecutor::ConstructL(const TDesC& aTaskFileName,
|
sl@0
|
51 |
const TDesC& aClientFileName,
|
sl@0
|
52 |
const TDesC& aErrorMessage)
|
sl@0
|
53 |
{
|
sl@0
|
54 |
LOGSTRING("CTaskExecutor::ConstructL - start");
|
sl@0
|
55 |
// Store filename
|
sl@0
|
56 |
iTaskFileName = aTaskFileName.AllocL();
|
sl@0
|
57 |
iClientFileName = aClientFileName.AllocL();
|
sl@0
|
58 |
|
sl@0
|
59 |
// In case there is an error...
|
sl@0
|
60 |
iLogErrorMessage = aErrorMessage.AllocL();
|
sl@0
|
61 |
|
sl@0
|
62 |
LOGSTRING("CTaskExecutor::ConstructL - end");
|
sl@0
|
63 |
}
|
sl@0
|
64 |
|
sl@0
|
65 |
|
sl@0
|
66 |
CTaskExecutor* CTaskExecutor::NewLC(const TDesC& aErrorMessage,
|
sl@0
|
67 |
const TDesC& aTaskFileName,
|
sl@0
|
68 |
const TDesC& aClientFileName,
|
sl@0
|
69 |
CSchLogManager& aSchLogManager)
|
sl@0
|
70 |
{
|
sl@0
|
71 |
LOGSTRING("CTaskExecutor::NewLC");
|
sl@0
|
72 |
CTaskExecutor* self = new(ELeave) CTaskExecutor(aSchLogManager);
|
sl@0
|
73 |
CleanupStack::PushL(self);
|
sl@0
|
74 |
self->ConstructL(aTaskFileName, aClientFileName, aErrorMessage);
|
sl@0
|
75 |
return self;
|
sl@0
|
76 |
}
|
sl@0
|
77 |
|
sl@0
|
78 |
void CTaskExecutor::RunL()
|
sl@0
|
79 |
{
|
sl@0
|
80 |
LOGSTRING3("CTaskExecutor::RunL - task finished running [client: %S, task: %S]", iClientFileName, iTaskFileName);
|
sl@0
|
81 |
//
|
sl@0
|
82 |
// RunL is called when the process/thread terminates
|
sl@0
|
83 |
// so that any error conditions can be handled.
|
sl@0
|
84 |
TInt exitReason = iProcess.ExitReason();
|
sl@0
|
85 |
LOGSTRING2("CTaskExecutor::RunL - process exit reason was: %d", exitReason);
|
sl@0
|
86 |
|
sl@0
|
87 |
// Close the process/thread
|
sl@0
|
88 |
iProcess.Close();
|
sl@0
|
89 |
|
sl@0
|
90 |
// Check for error code
|
sl@0
|
91 |
if (exitReason != KErrNone)
|
sl@0
|
92 |
{
|
sl@0
|
93 |
// Submit a log entry to record the error.
|
sl@0
|
94 |
LOGSTRING2("CTaskExecutor::RunL - recording unclean process exit (%d) in the log engine", exitReason);
|
sl@0
|
95 |
if(iLogErrorMessage)
|
sl@0
|
96 |
iSchLogManager.LogError(*iLogErrorMessage,exitReason);
|
sl@0
|
97 |
else
|
sl@0
|
98 |
iSchLogManager.LogError(exitReason);
|
sl@0
|
99 |
}
|
sl@0
|
100 |
|
sl@0
|
101 |
// Clean up the file. Only delete it here once task process has finished.
|
sl@0
|
102 |
// If task process never started then file is deleted in CClientProxy code.
|
sl@0
|
103 |
User::LeaveIfError(iFsSession.Connect());
|
sl@0
|
104 |
CleanupClosePushL(iFsSession);
|
sl@0
|
105 |
|
sl@0
|
106 |
TInt fileDeleteErr = iFsSession.Delete(*iTaskFileName);
|
sl@0
|
107 |
|
sl@0
|
108 |
// If unable to delete file wait and try again
|
sl@0
|
109 |
if (fileDeleteErr != KErrNone)
|
sl@0
|
110 |
{
|
sl@0
|
111 |
|
sl@0
|
112 |
//Allow thread to be preempted to allow for cleanup of iProcess
|
sl@0
|
113 |
User::After(KClientCleanupDelay);
|
sl@0
|
114 |
|
sl@0
|
115 |
fileDeleteErr = iFsSession.Delete(*iTaskFileName);
|
sl@0
|
116 |
|
sl@0
|
117 |
// If still unable to delete file record the fact
|
sl@0
|
118 |
if (fileDeleteErr != KErrNone)
|
sl@0
|
119 |
{
|
sl@0
|
120 |
if(iLogErrorMessage)
|
sl@0
|
121 |
{
|
sl@0
|
122 |
iSchLogManager.LogError(*iLogErrorMessage, fileDeleteErr);
|
sl@0
|
123 |
}
|
sl@0
|
124 |
else
|
sl@0
|
125 |
{
|
sl@0
|
126 |
iSchLogManager.LogError(fileDeleteErr);
|
sl@0
|
127 |
}
|
sl@0
|
128 |
}
|
sl@0
|
129 |
}
|
sl@0
|
130 |
|
sl@0
|
131 |
//Calls iFsSession::Close() so no need to call explicitly
|
sl@0
|
132 |
CleanupStack::PopAndDestroy();
|
sl@0
|
133 |
|
sl@0
|
134 |
// Delete outselves since we've finished
|
sl@0
|
135 |
LOGSTRING("CTaskExecutor::RunL - deleting ourself");
|
sl@0
|
136 |
delete this;
|
sl@0
|
137 |
}
|
sl@0
|
138 |
|
sl@0
|
139 |
void CTaskExecutor::DoCancel()
|
sl@0
|
140 |
{
|
sl@0
|
141 |
LOGSTRING("CTaskExecutor::DoCancel - start");
|
sl@0
|
142 |
iProcess.LogonCancel(iStatus);
|
sl@0
|
143 |
// Delete file and ourselves since we can't do anything else.
|
sl@0
|
144 |
// We are in a bad state if we reach here but at least make the most of it.
|
sl@0
|
145 |
LOGSTRING("CTaskExecutor::DoCancel - deleting ourself");
|
sl@0
|
146 |
|
sl@0
|
147 |
//Connect to file session
|
sl@0
|
148 |
TInt err = iFsSession.Connect();
|
sl@0
|
149 |
|
sl@0
|
150 |
if(err == KErrNone)
|
sl@0
|
151 |
{
|
sl@0
|
152 |
err = iFsSession.Delete(*iTaskFileName);
|
sl@0
|
153 |
}
|
sl@0
|
154 |
|
sl@0
|
155 |
// If unable to delete file record the fact
|
sl@0
|
156 |
if (err != KErrNone)
|
sl@0
|
157 |
{
|
sl@0
|
158 |
if(iLogErrorMessage)
|
sl@0
|
159 |
{
|
sl@0
|
160 |
iSchLogManager.LogError(*iLogErrorMessage, err);
|
sl@0
|
161 |
}
|
sl@0
|
162 |
else
|
sl@0
|
163 |
{
|
sl@0
|
164 |
iSchLogManager.LogError(err);
|
sl@0
|
165 |
}
|
sl@0
|
166 |
}
|
sl@0
|
167 |
|
sl@0
|
168 |
//Close the file session
|
sl@0
|
169 |
iFsSession.Close();
|
sl@0
|
170 |
|
sl@0
|
171 |
delete this;
|
sl@0
|
172 |
LOGSTRING("CTaskExecutor::DoCancel - end");
|
sl@0
|
173 |
}
|
sl@0
|
174 |
|
sl@0
|
175 |
void CTaskExecutor::ExecuteL()
|
sl@0
|
176 |
{
|
sl@0
|
177 |
// If this leaves, CClientProxy should handle error....
|
sl@0
|
178 |
// CTaskScheduler::ExecuteClients() traps the leave and then calls
|
sl@0
|
179 |
// CClientProxy::FailToExecute() to handle the error.
|
sl@0
|
180 |
#ifdef __SCHLOGGING__
|
sl@0
|
181 |
{
|
sl@0
|
182 |
TTime time; time.HomeTime();
|
sl@0
|
183 |
TDateTime due = time.DateTime();
|
sl@0
|
184 |
LOGSTRING8("CTaskExecutor::ExecuteL - Executing tasks at: [%02d/%02d/%d] @ %02d:%02d:%02d.%05d", due.Day(), (TInt) due.Month() + 1, due.Year(), due.Hour(), due.Minute(), due.Second(), due.MicroSecond());
|
sl@0
|
185 |
}
|
sl@0
|
186 |
#endif
|
sl@0
|
187 |
|
sl@0
|
188 |
// Create a new process and pass the name of the task file as the command line argument
|
sl@0
|
189 |
// (data for the target exe).
|
sl@0
|
190 |
LOGSTRING("CTaskExecutor::ExecuteL - creating process");
|
sl@0
|
191 |
TInt err = iProcess.Create(*iClientFileName, KNullDesC);
|
sl@0
|
192 |
|
sl@0
|
193 |
// Will check the error, report the problem and leave (if err<KErrNone)
|
sl@0
|
194 |
// otherwise does nothing.
|
sl@0
|
195 |
LOGSTRING("CTaskExecutor::ExecuteL - checking process creation error code");
|
sl@0
|
196 |
CheckErrorAndLeaveL(err);
|
sl@0
|
197 |
|
sl@0
|
198 |
// connect to new file session to avoid possible security
|
sl@0
|
199 |
// consequences if lauched process tries to use passed file in
|
sl@0
|
200 |
// subversive way.
|
sl@0
|
201 |
User::LeaveIfError(iFsSession.Connect());
|
sl@0
|
202 |
CleanupClosePushL(iFsSession);
|
sl@0
|
203 |
User::LeaveIfError(iFsSession.ShareProtected());
|
sl@0
|
204 |
|
sl@0
|
205 |
User::LeaveIfError(iTaskFile.Open(iFsSession, *iTaskFileName, EFileRead));
|
sl@0
|
206 |
CleanupClosePushL(iTaskFile);
|
sl@0
|
207 |
|
sl@0
|
208 |
// transfer file handle to launched process
|
sl@0
|
209 |
err = iTaskFile.TransferToProcess(iProcess, KTaskFsHandleIndex, KTaskFileHandleIndex);
|
sl@0
|
210 |
|
sl@0
|
211 |
//Close task file and session handles
|
sl@0
|
212 |
//Calls iFsSession::Close() and iTaskFile::Close() so no need to call explicitly
|
sl@0
|
213 |
CleanupStack::PopAndDestroy(2);
|
sl@0
|
214 |
|
sl@0
|
215 |
CheckErrorAndLeaveL(err);
|
sl@0
|
216 |
|
sl@0
|
217 |
// Asynchronous logon: completes when process terminates with process exit code
|
sl@0
|
218 |
iProcess.Logon(iStatus);
|
sl@0
|
219 |
iProcess.Resume();
|
sl@0
|
220 |
|
sl@0
|
221 |
SetActive();
|
sl@0
|
222 |
LOGSTRING("CTaskExecutor::ExecuteL - end");
|
sl@0
|
223 |
|
sl@0
|
224 |
}
|
sl@0
|
225 |
|
sl@0
|
226 |
void CTaskExecutor::CheckErrorAndLeaveL(TInt aError)
|
sl@0
|
227 |
{
|
sl@0
|
228 |
if (aError < KErrNone)
|
sl@0
|
229 |
{
|
sl@0
|
230 |
if(iLogErrorMessage)
|
sl@0
|
231 |
iSchLogManager.LogError(*iLogErrorMessage,aError);
|
sl@0
|
232 |
else
|
sl@0
|
233 |
iSchLogManager.LogError(aError);
|
sl@0
|
234 |
User::Leave(aError);
|
sl@0
|
235 |
}
|
sl@0
|
236 |
}
|
sl@0
|
237 |
|