1 /* |
|
2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Encapsulates an asynchronous operation |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "rsfwrfeasyncoperation.h" |
|
20 #include "rsfwrfemessagerequest.h" |
|
21 #include "rsfwrfestatemachine.h" |
|
22 #include "rsfwmountstatemachine.h" |
|
23 #include "rsfwmountconnectionstatemachine.h" |
|
24 #include "rsfwopenbypathstatemachine.h" |
|
25 #include "rsfwgetattributesstatemachine.h" |
|
26 #include "rsfwattributerefreshingstatemachine.h" |
|
27 #include "rsfwfetchandcachestatemachine.h" |
|
28 #include "rsfwfetchdatastatemachine.h" |
|
29 #include "rsfwlookupstatemachine.h" |
|
30 #include "rsfwclosestatemachine.h" |
|
31 #include "rsfwflushstatemachine.h" |
|
32 #include "rsfwmkdirstatemachine.h" |
|
33 #include "rsfwdeletestatemachine.h" |
|
34 #include "rsfwcreatefilestatemachine.h" |
|
35 #include "rsfwrenamefilestatemachine.h" |
|
36 #include "rsfwvolumetable.h" |
|
37 #include "mdebug.h" |
|
38 #include "rsfwcommon.h" |
|
39 #include "rsfwrfeserver.h" |
|
40 #include "rsfwinterface.h" |
|
41 |
|
42 |
|
43 // ---------------------------------------------------------------------------- |
|
44 // CRsfwRfeAsyncOperation::~CRsfwRfeAsyncOperation |
|
45 // ---------------------------------------------------------------------------- |
|
46 // |
|
47 CRsfwRfeAsyncOperation::~CRsfwRfeAsyncOperation() |
|
48 { |
|
49 delete iImplementation; |
|
50 iImplementation = NULL; |
|
51 } |
|
52 |
|
53 // ---------------------------------------------------------------------------- |
|
54 // CRsfwRfeAsyncOperation::Implementation |
|
55 // ---------------------------------------------------------------------------- |
|
56 // |
|
57 CRsfwRfeStateMachine* CRsfwRfeAsyncOperation::Implementation() |
|
58 { |
|
59 return iImplementation; |
|
60 } |
|
61 |
|
62 // ---------------------------------------------------------------------------- |
|
63 // CRsfwRfeAsyncOperation::SetImplementation |
|
64 // ---------------------------------------------------------------------------- |
|
65 // |
|
66 void CRsfwRfeAsyncOperation::SetImplementation(CRsfwRfeStateMachine* aImpl) |
|
67 { |
|
68 iImplementation = aImpl; |
|
69 } |
|
70 |
|
71 // ---------------------------------------------------------------------------- |
|
72 // CRsfwRfeAsyncOperation::SetL |
|
73 // Set asynchronous operation and its parameters |
|
74 // Leave if OOM etc. |
|
75 // ---------------------------------------------------------------------------- |
|
76 // |
|
77 void CRsfwRfeAsyncOperation::SetL(CRsfwRfeRequest* aRequest, TInt aOpCode) |
|
78 { |
|
79 CRsfwRfeMessageRequest* request = (CRsfwRfeMessageRequest*)aRequest; |
|
80 CRsfwRfeStateMachine::TState* initialState = NULL; |
|
81 CRsfwRfeStateMachine* operation = NULL; |
|
82 |
|
83 if (aRequest->iVolume) |
|
84 { |
|
85 DEBUGSTRING(("<<< Dispatch enter (operation=%d, volume=%d)", |
|
86 aOpCode, |
|
87 aRequest->iVolume->iMountInfo.iMountStatus.iVolumeId)); |
|
88 } |
|
89 else |
|
90 { |
|
91 DEBUGSTRING(("<<< Dispatch enter (operation=%d)", aOpCode)); |
|
92 } |
|
93 |
|
94 switch (aOpCode) |
|
95 { |
|
96 case EMount: |
|
97 case EMountByDriveLetter: |
|
98 { |
|
99 DEBUGSTRING(("EMount / EMountByDriveLetter")); |
|
100 TRsfwMountConfig* mountConfig = new (ELeave) TRsfwMountConfig; |
|
101 CleanupStack::PushL(mountConfig); |
|
102 TPckg<TRsfwMountConfig> mountConfigPackage(*mountConfig); |
|
103 if (aOpCode == EMount) |
|
104 { |
|
105 request->Message().ReadL(0, mountConfigPackage); |
|
106 // this is to satisfy IPC fuzz testing |
|
107 VerifyMountConfigL(*mountConfig); |
|
108 } |
|
109 else |
|
110 { |
|
111 // EMountByDriveLetter - create a stub TRsfwMountConfig |
|
112 TInt driveNumber = request->Message().Int0(); |
|
113 RFs fs = CRsfwRfeServer::Env()->iFs; |
|
114 fs.DriveToChar(driveNumber, mountConfig->iDriveLetter); |
|
115 mountConfig->iUri.SetLength(0); |
|
116 } |
|
117 |
|
118 // fetch mountconfig from mountStore |
|
119 if (!mountConfig->iUri.Length() || aOpCode == EMountByDriveLetter) |
|
120 { |
|
121 // the drive letter must be set |
|
122 User::LeaveIfError(aRequest->iVolumeTable->GetMountConfigL( |
|
123 *mountConfig)); |
|
124 } |
|
125 |
|
126 // If there is an existing mount, the configurations must match. |
|
127 // Otherwise we unmount the already existing mount. |
|
128 CRsfwVolume* volume = |
|
129 aRequest-> |
|
130 iVolumeTable-> |
|
131 VolumeByDriveLetter(mountConfig->iDriveLetter); |
|
132 if (volume) |
|
133 { |
|
134 if (volume->iMountInfo.iMountConfig.iUri.CompareF( |
|
135 mountConfig->iUri) != 0) |
|
136 { |
|
137 // We have a mismatch |
|
138 DEBUGSTRING16(("Dismounting an obsolete mount %S", |
|
139 &volume->iMountInfo.iMountConfig.iUri)); |
|
140 aRequest-> |
|
141 iVolumeTable-> |
|
142 DismountByDriveLetterL(mountConfig->iDriveLetter, |
|
143 ETrue); |
|
144 } |
|
145 } |
|
146 TInt mountState = |
|
147 aRequest->iVolumeTable->MountState(mountConfig->iDriveLetter); |
|
148 operation = CRsfwMountStateMachine::NewL(*mountConfig, |
|
149 mountState, |
|
150 aRequest->iVolumeTable); |
|
151 CleanupStack::PushL(operation); |
|
152 ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); |
|
153 initialState = |
|
154 new (ELeave) CRsfwMountStateMachine::TRequestConnectionState( |
|
155 (CRsfwMountStateMachine *)operation); |
|
156 |
|
157 CleanupStack::Pop(operation); |
|
158 DEBUGSTRING16(("EMount: name '%S' with URI='%S' as '%c' (state=%d)", |
|
159 &mountConfig->iName, |
|
160 &mountConfig->iUri, |
|
161 TUint(mountConfig->iDriveLetter), |
|
162 mountState)); |
|
163 CleanupStack::PopAndDestroy(mountConfig); |
|
164 } |
|
165 break; |
|
166 |
|
167 case ESetMountConnectionState: |
|
168 { |
|
169 DEBUGSTRING(("ESetMountConnectionState")); |
|
170 // Set the connection state of the mount |
|
171 TChar driveLetter = reinterpret_cast<TInt>(request->Message().Ptr0()); |
|
172 TUint state = reinterpret_cast<TUint>(request->Message().Ptr1()); |
|
173 DEBUGSTRING(("EMountConnectionState: drive '%c', state=%d", |
|
174 TUint(driveLetter), |
|
175 state)); |
|
176 |
|
177 operation = new(ELeave) CRsfwMountConnectionStateMachine(driveLetter, |
|
178 state); |
|
179 CleanupStack::PushL(operation); |
|
180 ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); |
|
181 initialState = |
|
182 new (ELeave) CRsfwMountConnectionStateMachine::TChangeConnectionState( |
|
183 (CRsfwMountConnectionStateMachine *)operation); |
|
184 CleanupStack::Pop(operation); |
|
185 } |
|
186 |
|
187 break; |
|
188 |
|
189 case EOpenByPath: |
|
190 { |
|
191 DEBUGSTRING(("OPENBYPATH")); |
|
192 operation = new (ELeave) CRsfwOpenByPathStateMachine(); |
|
193 CleanupStack::PushL(operation); |
|
194 operation->BaseConstructL(); |
|
195 // we need to refresh attributes first |
|
196 initialState = |
|
197 new (ELeave) CRsfwGetAttributesStateMachine::TRefreshAttributesState( |
|
198 (CRsfwAttributeRefreshingStateMachine *)operation); |
|
199 CleanupStack::Pop(operation); |
|
200 break; |
|
201 } |
|
202 |
|
203 case EFetch: |
|
204 { |
|
205 DEBUGSTRING(("FETCH")); |
|
206 operation = new (ELeave) CRsfwFetchAndCacheStateMachine(); |
|
207 CleanupStack::PushL(operation); |
|
208 ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); |
|
209 initialState = |
|
210 new (ELeave) CRsfwFetchAndCacheStateMachine::TFetchDataState( |
|
211 (CRsfwFetchAndCacheStateMachine *)operation); |
|
212 CleanupStack::Pop(operation); |
|
213 break; |
|
214 } |
|
215 |
|
216 case EFetchData: |
|
217 { |
|
218 DEBUGSTRING(("FETCHDATA")); |
|
219 operation = new (ELeave) CRsfwFetchDataStateMachine(); |
|
220 CleanupStack::PushL(operation); |
|
221 ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); |
|
222 initialState = new (ELeave) CRsfwFetchDataStateMachine::TFetchDataState( |
|
223 (CRsfwFetchDataStateMachine *)operation); |
|
224 CleanupStack::Pop(operation); |
|
225 break; |
|
226 } |
|
227 |
|
228 case ELookUp: |
|
229 { |
|
230 DEBUGSTRING(("LOOKUP")); |
|
231 operation = new (ELeave) CRsfwLookupStateMachine(); |
|
232 CleanupStack::PushL(operation); |
|
233 operation->BaseConstructL(); |
|
234 initialState = new (ELeave) |
|
235 CRsfwLookupStateMachine::TUpdateKidAttributesTryFirstTypeState( |
|
236 (CRsfwLookupStateMachine *)operation); |
|
237 CleanupStack::Pop(operation); |
|
238 break; |
|
239 } |
|
240 |
|
241 case EGetAttr: |
|
242 { |
|
243 DEBUGSTRING(("GETATTR")); |
|
244 operation = new (ELeave) CRsfwGetAttributesStateMachine(); |
|
245 CleanupStack::PushL(operation); |
|
246 operation->BaseConstructL(); |
|
247 initialState = |
|
248 new (ELeave) CRsfwGetAttributesStateMachine::TRefreshAttributesState( |
|
249 (CRsfwGetAttributesStateMachine *)operation); |
|
250 CleanupStack::Pop(operation); |
|
251 break; |
|
252 } |
|
253 |
|
254 case EClose: |
|
255 { |
|
256 DEBUGSTRING(("CLOSE")); |
|
257 operation = new (ELeave) CRsfwCloseStateMachine(); |
|
258 CleanupStack::PushL(operation); |
|
259 ((CRsfwWaitNoteStateMachine *) operation)->BaseConstructL(); |
|
260 initialState = |
|
261 new (ELeave) CRsfwCloseStateMachine::TReleaseLockState( |
|
262 (CRsfwCloseStateMachine *) operation); |
|
263 CleanupStack::Pop(operation); |
|
264 break; |
|
265 } |
|
266 case EFlush: |
|
267 { |
|
268 DEBUGSTRING(("FLUSH")); |
|
269 operation = new (ELeave) CRsfwFlushStateMachine(); |
|
270 CleanupStack::PushL(operation); |
|
271 ((CRsfwFlushStateMachine *) operation)->BaseConstructL(); |
|
272 initialState = |
|
273 new (ELeave) CRsfwFlushStateMachine::TFlushDataToServerState( |
|
274 (CRsfwFlushStateMachine *) operation); |
|
275 CleanupStack::Pop(operation); |
|
276 break; |
|
277 } |
|
278 |
|
279 case EMkDir: |
|
280 { |
|
281 DEBUGSTRING(("MKDIR")); |
|
282 operation = new (ELeave) CRsfwMkDirStateMachine(); |
|
283 CleanupStack::PushL(operation); |
|
284 operation->BaseConstructL(); |
|
285 initialState = new (ELeave) CRsfwMkDirStateMachine::TCheckIfExistsState( |
|
286 (CRsfwMkDirStateMachine *) operation); |
|
287 CleanupStack::Pop(operation); |
|
288 break; |
|
289 } |
|
290 |
|
291 case ERemoveDir: |
|
292 { |
|
293 DEBUGSTRING(("RMDIR")); |
|
294 operation = new (ELeave) CRsfwDeleteStateMachine(KNodeTypeDir); |
|
295 CleanupStack::PushL(operation); |
|
296 operation->BaseConstructL(); |
|
297 initialState = new (ELeave) CRsfwDeleteStateMachine::TCheckIfCanBeDeleted( |
|
298 (CRsfwDeleteStateMachine *) operation); |
|
299 CleanupStack::Pop(operation); |
|
300 break; |
|
301 } |
|
302 |
|
303 case ERemove: |
|
304 DEBUGSTRING(("REMOVE")); |
|
305 operation = new (ELeave) CRsfwDeleteStateMachine(KNodeTypeFile); |
|
306 CleanupStack::PushL(operation); |
|
307 operation->BaseConstructL(); |
|
308 initialState = new (ELeave) CRsfwDeleteStateMachine::TCheckIfCanBeDeleted( |
|
309 (CRsfwDeleteStateMachine *) operation); |
|
310 CleanupStack::Pop(operation); |
|
311 break; |
|
312 |
|
313 case ECreateFile: |
|
314 DEBUGSTRING(("CREATE")); |
|
315 operation = new (ELeave) CRsfwCreateFileStateMachine(); |
|
316 CleanupStack::PushL(operation); |
|
317 operation->BaseConstructL(); |
|
318 initialState = |
|
319 new (ELeave) CRsfwCreateFileStateMachine::TCheckIfExistsState( |
|
320 (CRsfwCreateFileStateMachine *) operation); |
|
321 CleanupStack::Pop(operation); |
|
322 break; |
|
323 |
|
324 case ERenameReplace: |
|
325 DEBUGSTRING(("RENAME")); |
|
326 operation = new (ELeave) CRsfwRenameFileStateMachine(); |
|
327 CleanupStack::PushL(operation); |
|
328 operation->BaseConstructL(); |
|
329 initialState = new (ELeave) CRsfwRenameFileStateMachine::TRenameFileState( |
|
330 (CRsfwRenameFileStateMachine *) operation); |
|
331 CleanupStack::Pop(operation); |
|
332 break; |
|
333 |
|
334 default: |
|
335 // request handler function not set, |
|
336 // would lead to accessing a NULL pointer |
|
337 User::Panic(KRfeServer, ENullRequestHandler); |
|
338 } |
|
339 |
|
340 SetImplementation(operation); |
|
341 Implementation()->SetNextState(initialState); |
|
342 |
|
343 // Set parameters |
|
344 iImplementation->SetVolumes(aRequest->iVolumeTable); |
|
345 |
|
346 if (aRequest->iVolume) |
|
347 { |
|
348 iImplementation->SetFileEngine(aRequest->iVolume->iFileEngine); |
|
349 } |
|
350 |
|
351 iImplementation->SetArguments(aRequest->iInArgs, aRequest->iOutArgs); |
|
352 |
|
353 // Set backpointer to the request we are running, |
|
354 // so that the state machine can easily complete it |
|
355 iImplementation->SetRequest(aRequest); |
|
356 |
|
357 iIsSync = EFalse; |
|
358 CRsfwRfeOperation::Set(aOpCode); |
|
359 } |
|
360 |
|
361 // ---------------------------------------------------------------------------- |
|
362 // CRsfwRfeAsyncOperation::VerifyMountConfigL |
|
363 // Checks whether mount config data is correct |
|
364 // ---------------------------------------------------------------------------- |
|
365 // |
|
366 void CRsfwRfeAsyncOperation::VerifyMountConfigL(TRsfwMountConfig& aMountConfig) |
|
367 { |
|
368 if (aMountConfig.iName.Length() > KMaxMountNameLength || |
|
369 aMountConfig.iUri.Length() > KMaxMountUriLength || |
|
370 aMountConfig.iUserName.Length() > KMaxMountUserNameLength || |
|
371 aMountConfig.iPassword.Length() > KMaxMountPasswordLength || |
|
372 aMountConfig.iAuxData.Length() > KMaxMountAuxDataLength) |
|
373 { |
|
374 DEBUGSTRING16(("CRsfwRfeAsyncOperation::VerifyMountConfigL bad aMountConfig argument")); |
|
375 User::Leave(KErrArgument); |
|
376 } |
|
377 } |
|
378 |
|