|
1 /* |
|
2 * Copyright (c) 2008-2009 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 the License "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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <usif/scr/scr.h> |
|
20 #include <usif/sif/sif.h> |
|
21 #include <e32cons.h> |
|
22 #include "command.h" |
|
23 |
|
24 using namespace Usif; |
|
25 |
|
26 _LIT(KTxtOptionPrefix, "--"); |
|
27 _LIT(KTxtDeleteCommand, "delete"); |
|
28 _LIT(KTxtListCommand, "list"); |
|
29 _LIT(KTxtListOptName, "name"); |
|
30 _LIT(KTxtListOptVendor, "vendor"); |
|
31 _LIT(KTxtListOptType, "type"); |
|
32 _LIT(KTxtListOptActivated, "activated"); |
|
33 _LIT(KTxtListOptDeactivated, "deactivated"); |
|
34 _LIT(KTxtListOptRemovable, "removable"); |
|
35 _LIT(KTxtListOptProperty, "property"); |
|
36 _LIT(KTxtListOptIntProperty, "intproperty"); |
|
37 _LIT(KTxtListOptDrives, "drives"); |
|
38 _LIT(KTxtListOptLocale, "locale"); |
|
39 _LIT(KTxtActivated, "Activated"); |
|
40 _LIT(KTxtDeactivated, "Deactivated"); |
|
41 _LIT(KTxtPressToContinue, "\nPress any key to continue..."); |
|
42 _LIT(KTxtSifConnectionFailure, "\nFailed to connect to the SIF server\n"); |
|
43 _LIT(KTxtDeleting, "Deleting...\n"); |
|
44 |
|
45 // ================================================================================== |
|
46 |
|
47 CConsoleCommand::CConsoleCommand() |
|
48 { |
|
49 } |
|
50 |
|
51 CConsoleCommand::~CConsoleCommand() |
|
52 { |
|
53 } |
|
54 |
|
55 // ================================================================================== |
|
56 |
|
57 CListCommand* CListCommand::NewLC() |
|
58 { |
|
59 |
|
60 CListCommand* self = new (ELeave) CListCommand; |
|
61 CleanupStack::PushL(self); |
|
62 self->iFilter = CComponentFilter::NewL(); |
|
63 return self; |
|
64 } |
|
65 |
|
66 CListCommand::CListCommand(): iLocale(KUnspecifiedLocale) |
|
67 { |
|
68 } |
|
69 |
|
70 CListCommand::~CListCommand() |
|
71 { |
|
72 delete iFilter; |
|
73 } |
|
74 |
|
75 const TDesC& CListCommand::Name() |
|
76 { |
|
77 return KTxtListCommand; |
|
78 } |
|
79 |
|
80 namespace |
|
81 { |
|
82 // Leave if the number of values differs from aCount |
|
83 void AssertNumValuesL(const RArray<TPtrC>& aValues, TInt aCount) |
|
84 { |
|
85 if (aValues.Count() != aCount) |
|
86 { |
|
87 User::Leave(KErrArgument); |
|
88 } |
|
89 } |
|
90 } |
|
91 |
|
92 void CListCommand::OptionHandlerL(const TPtrC& aName, const RArray<TPtrC>& aValues) |
|
93 { |
|
94 // Configure the component query filter: |
|
95 |
|
96 // Component name |
|
97 if (aName == KTxtListOptName) |
|
98 { |
|
99 AssertNumValuesL(aValues, 1); |
|
100 iFilter->SetNameL(aValues[0]); |
|
101 } |
|
102 |
|
103 // Vendor |
|
104 else if (aName == KTxtListOptVendor) |
|
105 { |
|
106 AssertNumValuesL(aValues, 1); |
|
107 iFilter->SetVendorL(aValues[0]); |
|
108 } |
|
109 |
|
110 // Software type |
|
111 else if (aName == KTxtListOptType) |
|
112 { |
|
113 AssertNumValuesL(aValues, 1); |
|
114 iFilter->SetSoftwareTypeL(aValues[0]); |
|
115 } |
|
116 |
|
117 // SCOMO state - Activated |
|
118 else if (aName == KTxtListOptActivated) |
|
119 { |
|
120 AssertNumValuesL(aValues, 0); |
|
121 |
|
122 // The activated and deactivated options are mutually exclusive |
|
123 if (iScomoStateSet) |
|
124 { |
|
125 User::Leave(KErrArgument); |
|
126 } |
|
127 iScomoStateSet = ETrue; |
|
128 |
|
129 iFilter->SetScomoStateL(EActivated); |
|
130 } |
|
131 |
|
132 // SCOMO state - Deactivated |
|
133 else if (aName == KTxtListOptDeactivated) |
|
134 { |
|
135 AssertNumValuesL(aValues, 0); |
|
136 |
|
137 // The activated and deactivated options are mutually exclusive |
|
138 if (iScomoStateSet) |
|
139 { |
|
140 User::Leave(KErrArgument); |
|
141 } |
|
142 iScomoStateSet = ETrue; |
|
143 |
|
144 iFilter->SetScomoStateL(EDeactivated); |
|
145 } |
|
146 |
|
147 // Removable |
|
148 else if (aName == KTxtListOptRemovable) |
|
149 { |
|
150 AssertNumValuesL(aValues, 0); |
|
151 iFilter->SetRemovable(ETrue); |
|
152 } |
|
153 |
|
154 // String property |
|
155 else if (aName == KTxtListOptProperty) |
|
156 { |
|
157 const TInt numValues = aValues.Count(); |
|
158 if (numValues < 2 || numValues > 3) |
|
159 { |
|
160 User::Leave(KErrArgument); |
|
161 } |
|
162 |
|
163 // Convert language from string to int if specified |
|
164 TInt language = KUnspecifiedLocale; |
|
165 if (numValues == 3) |
|
166 { |
|
167 TLex lex(aValues[2]); |
|
168 if (lex.Val(language) != KErrNone || language < ELangEnglish || language >= ELangMaximum) |
|
169 { |
|
170 User::Leave(KErrArgument); |
|
171 } |
|
172 } |
|
173 |
|
174 // Add the property to the filter |
|
175 iFilter->AddPropertyL(aValues[0], aValues[1], static_cast<TLanguage>(language)); |
|
176 } |
|
177 |
|
178 // Integer property |
|
179 else if (aName == KTxtListOptIntProperty) |
|
180 { |
|
181 AssertNumValuesL(aValues, 2); |
|
182 TLex lex(aValues[1]); |
|
183 TInt64 val; |
|
184 if (lex.Val(val) != KErrNone) |
|
185 { |
|
186 User::Leave(KErrArgument); |
|
187 } |
|
188 iFilter->AddPropertyL(aValues[0], val); |
|
189 } |
|
190 |
|
191 // Drives |
|
192 else if (aName == KTxtListOptDrives) |
|
193 { |
|
194 AssertNumValuesL(aValues, 1); |
|
195 TPtrC drives = aValues[0]; |
|
196 TDriveList driveList; |
|
197 driveList.FillZ(KMaxDrives); |
|
198 for (TInt i=0; i<drives.Length(); ++i) |
|
199 { |
|
200 TChar driveLetter = static_cast<TChar>(drives[i]); |
|
201 TInt driveNumber = 0; |
|
202 User::LeaveIfError(RFs::CharToDrive(driveLetter, driveNumber)); |
|
203 driveList[driveNumber] = ETrue; |
|
204 } |
|
205 iFilter->SetInstalledDrivesL(driveList); |
|
206 } |
|
207 |
|
208 // Locale |
|
209 else if (aName == KTxtListOptLocale) |
|
210 { |
|
211 AssertNumValuesL(aValues, 1); |
|
212 TLex lex(aValues[0]); |
|
213 TInt val; |
|
214 if (lex.Val(val) != KErrNone || val < ELangEnglish || val >= ELangNone) |
|
215 { |
|
216 User::Leave(KErrArgument); |
|
217 } |
|
218 iLocale = static_cast<TLanguage>(val); |
|
219 } |
|
220 |
|
221 // Unknown |
|
222 else |
|
223 { |
|
224 User::Leave(KErrArgument); |
|
225 } |
|
226 } |
|
227 |
|
228 void CListCommand::ExecuteL(CConsoleBase& aConsole) |
|
229 { |
|
230 // Connect to the SCR server |
|
231 RSoftwareComponentRegistry scr; |
|
232 TInt err = scr.Connect(); |
|
233 if (err != KErrNone) |
|
234 { |
|
235 aConsole.Printf(_L("\nFailed to connect to the SCR server")); |
|
236 User::Leave(err); |
|
237 } |
|
238 CleanupClosePushL(scr); |
|
239 |
|
240 // Create an SCR view |
|
241 RSoftwareComponentRegistryView scrView; |
|
242 scrView.OpenViewL(scr, iFilter); |
|
243 CleanupClosePushL(scrView); |
|
244 |
|
245 // Iterate over the matching components |
|
246 CComponentEntry* entry = CComponentEntry::NewLC(); |
|
247 TBool first(ETrue); |
|
248 while (scrView.NextComponentL(*entry, iLocale)) |
|
249 { |
|
250 if (first) |
|
251 { |
|
252 first = EFalse; |
|
253 } |
|
254 else |
|
255 { |
|
256 aConsole.Printf(KTxtPressToContinue); |
|
257 aConsole.Getch(); |
|
258 aConsole.ClearScreen(); |
|
259 } |
|
260 |
|
261 aConsole.Printf(_L("\n============= Component Info =============\n")); |
|
262 aConsole.Printf(_L("\nComponent ID : %d"), entry->ComponentId()); |
|
263 aConsole.Printf(_L("\nComponent name : %S"), &entry->Name()); |
|
264 aConsole.Printf(_L("\nVendor name : %S"), &entry->Vendor()); |
|
265 aConsole.Printf(_L("\nSoftware type : %S"), &entry->SoftwareType()); |
|
266 aConsole.Printf(_L("\nSCOMO state : %S"), entry->ScomoState() == EActivated ? &KTxtActivated : &KTxtDeactivated ); |
|
267 aConsole.Printf(_L("\nComponent size : %d"), entry->ComponentSize()); |
|
268 aConsole.Printf(_L("\nInstalled drives : %S"), &entry->InstalledDrives()); |
|
269 aConsole.Printf(_L("\nVersion : %S"), &entry->Version()); |
|
270 aConsole.Printf(_L("\n\n=========================================\n")); |
|
271 } |
|
272 |
|
273 // Disconnect from the SCR server and cleanup the entry |
|
274 CleanupStack::PopAndDestroy(3, &scr); |
|
275 } |
|
276 |
|
277 // ================================================================================== |
|
278 |
|
279 CDeleteCommand* CDeleteCommand::NewLC() |
|
280 { |
|
281 CDeleteCommand* self = new (ELeave) CDeleteCommand; |
|
282 CleanupStack::PushL(self); |
|
283 return self; |
|
284 } |
|
285 |
|
286 CDeleteCommand::CDeleteCommand(): iComponentId(EInvalidComponentId) |
|
287 { |
|
288 } |
|
289 |
|
290 CDeleteCommand::~CDeleteCommand() |
|
291 { |
|
292 } |
|
293 |
|
294 const TDesC& CDeleteCommand::Name() |
|
295 { |
|
296 return KTxtDeleteCommand; |
|
297 } |
|
298 |
|
299 void CDeleteCommand::OptionHandlerL(const TPtrC& aName, const RArray<TPtrC>& aValues) |
|
300 { |
|
301 // The delete command takes only the id of a component |
|
302 if (aName.Length() || aValues.Count() != 1) |
|
303 { |
|
304 User::Leave(KErrArgument); |
|
305 } |
|
306 |
|
307 // Convert the id of the component from string to int |
|
308 TLex lex(aValues[0]); |
|
309 if (lex.Val(iComponentId) != KErrNone) |
|
310 { |
|
311 User::Leave(KErrArgument); |
|
312 } |
|
313 } |
|
314 |
|
315 void CDeleteCommand::ExecuteL(CConsoleBase& aConsole) |
|
316 { |
|
317 // Connect to the SIF server |
|
318 RSoftwareInstall sif; |
|
319 TInt err = sif.Connect(); |
|
320 if (err != KErrNone) |
|
321 { |
|
322 aConsole.Printf(KTxtSifConnectionFailure); |
|
323 User::Leave(err); |
|
324 } |
|
325 CleanupClosePushL(sif); |
|
326 |
|
327 // Delete the component |
|
328 TRequestStatus status; |
|
329 sif.Uninstall(iComponentId, status); |
|
330 aConsole.Printf(KTxtDeleting); |
|
331 User::WaitForRequest(status); |
|
332 if (status.Int() != KErrNone) |
|
333 { |
|
334 User::Leave(status.Int()); |
|
335 } |
|
336 |
|
337 // Disconnect from the SIF server |
|
338 CleanupStack::PopAndDestroy(&sif); |
|
339 } |
|
340 |
|
341 // ================================================================================== |
|
342 |
|
343 CCommandLineParser* CCommandLineParser::NewLC() |
|
344 { |
|
345 CCommandLineParser* self = new (ELeave) CCommandLineParser; |
|
346 CleanupStack::PushL(self); |
|
347 self->iCmdLineArgs = CCommandLineArguments::NewL(); |
|
348 return self; |
|
349 } |
|
350 |
|
351 CCommandLineParser::CCommandLineParser() |
|
352 { |
|
353 } |
|
354 |
|
355 CCommandLineParser::~CCommandLineParser() |
|
356 { |
|
357 delete iCmdLineArgs; |
|
358 iCommands.Close(); |
|
359 } |
|
360 |
|
361 void CCommandLineParser::RegisterCommandL(CConsoleCommand& aCommand) |
|
362 { |
|
363 iCommands.Append(&aCommand); |
|
364 } |
|
365 |
|
366 CConsoleCommand& CCommandLineParser::ParseL() |
|
367 { |
|
368 const TInt numArgs = iCmdLineArgs->Count(); |
|
369 |
|
370 // There must be at least two arguments: the name of the program and the name of a command |
|
371 if (numArgs <= 1) |
|
372 { |
|
373 User::Leave(KErrArgument); |
|
374 } |
|
375 |
|
376 // Extract the name of the command |
|
377 TPtrC arg0 = iCmdLineArgs->Arg(1); |
|
378 if (arg0.Left(KTxtOptionPrefix.iTypeLength) != KTxtOptionPrefix) |
|
379 { |
|
380 User::Leave(KErrArgument); |
|
381 } |
|
382 TPtrC cmdName = arg0.Mid(KTxtOptionPrefix.iTypeLength); |
|
383 |
|
384 // Look for the command in iCommands |
|
385 CConsoleCommand* cmd = NULL; |
|
386 for (TInt i=0; i<iCommands.Count(); ++i) |
|
387 { |
|
388 if (cmdName == iCommands[i]->Name()) |
|
389 { |
|
390 cmd = iCommands[i]; |
|
391 } |
|
392 } |
|
393 if (cmd == NULL) |
|
394 { |
|
395 User::Leave(KErrArgument); |
|
396 } |
|
397 |
|
398 // Iterate over the command's options and build pairs of optName and optValues |
|
399 TPtrC optName; |
|
400 RArray<TPtrC> optValues; |
|
401 CleanupClosePushL(optValues); |
|
402 for (TInt i=2; i<numArgs; ++i) |
|
403 { |
|
404 TPtrC arg = iCmdLineArgs->Arg(i); |
|
405 // Option name |
|
406 if (arg.Left(KTxtOptionPrefix.iTypeLength) == KTxtOptionPrefix) |
|
407 { |
|
408 // Process the previous option |
|
409 if (optName.Length()) |
|
410 { |
|
411 cmd->OptionHandlerL(optName, optValues); |
|
412 } |
|
413 |
|
414 // Set new option |
|
415 optName.Set(arg.Mid(KTxtOptionPrefix.iTypeLength)); |
|
416 if (optName.Length() == 0) |
|
417 { |
|
418 User::Leave(KErrArgument); |
|
419 } |
|
420 optValues.Reset(); |
|
421 } |
|
422 else |
|
423 { |
|
424 // Store the option's value |
|
425 optValues.AppendL(arg); |
|
426 } |
|
427 } |
|
428 |
|
429 // Process the last option |
|
430 if (optName.Length() || optValues.Count()) |
|
431 { |
|
432 cmd->OptionHandlerL(optName, optValues); |
|
433 } |
|
434 |
|
435 CleanupStack::PopAndDestroy(&optValues); |
|
436 |
|
437 // Return the current command |
|
438 return *cmd; |
|
439 } |