|
1 // cenrep.cpp |
|
2 // |
|
3 // Copyright (c) 2007 - 2010 Accenture. All rights reserved. |
|
4 // This component and the accompanying materials are made available |
|
5 // under the terms of the "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 // Accenture - Initial contribution |
|
11 // |
|
12 |
|
13 #include <fshell/ioutils.h> |
|
14 #include <centralrepository.h> |
|
15 #include <fshell/ltkutils.h> |
|
16 #include <fshell/descriptorutils.h> |
|
17 |
|
18 using namespace IoUtils; |
|
19 |
|
20 class CCmdCenrep : public CCommandBase |
|
21 { |
|
22 public: |
|
23 static CCommandBase* NewLC(); |
|
24 ~CCmdCenrep(); |
|
25 private: |
|
26 CCmdCenrep(); |
|
27 void PrintKeyL(TUint aKey, RBuf8& valDes); |
|
28 template <class KEYTYPE> |
|
29 void SetKeyL(const KEYTYPE& aVal); |
|
30 void ListRepositoriesL(); |
|
31 void ForceSetKeyL(TInt aVal); |
|
32 void ForceSetKeyL(const TDesC& aVal); |
|
33 void SudoL(TRefByValue<const TDesC> aFmt, ...); |
|
34 void AddFilesL(RArray<TUint>&, const TDesC& aMatch, const TDesC& aDir); |
|
35 |
|
36 private: // From CCommandBase. |
|
37 virtual const TDesC& Name() const; |
|
38 virtual void DoRunL(); |
|
39 virtual void ArgumentsL(RCommandArgumentList& aArguments); |
|
40 virtual void OptionsL(RCommandOptionList& aOptions); |
|
41 private: |
|
42 // Arguments |
|
43 TUint iRepository; |
|
44 TUint iKey; |
|
45 // Options |
|
46 HBufC* iStringVal; |
|
47 TInt iIntVal; |
|
48 TBool iForce; |
|
49 TBool iDelete; |
|
50 TBool iReset; |
|
51 CRepository* iRep; |
|
52 }; |
|
53 |
|
54 CCommandBase* CCmdCenrep::NewLC() |
|
55 { |
|
56 CCmdCenrep* self = new(ELeave) CCmdCenrep(); |
|
57 CleanupStack::PushL(self); |
|
58 self->BaseConstructL(); |
|
59 return self; |
|
60 } |
|
61 |
|
62 CCmdCenrep::~CCmdCenrep() |
|
63 { |
|
64 delete iStringVal; |
|
65 delete iRep; |
|
66 } |
|
67 |
|
68 CCmdCenrep::CCmdCenrep() |
|
69 { |
|
70 } |
|
71 |
|
72 const TDesC& CCmdCenrep::Name() const |
|
73 { |
|
74 _LIT(KName, "cenrep"); |
|
75 return KName; |
|
76 } |
|
77 |
|
78 void CCmdCenrep::DoRunL() |
|
79 { |
|
80 //__DEBUGGER(); |
|
81 if (iRepository == 0) |
|
82 { |
|
83 ListRepositoriesL(); |
|
84 return; |
|
85 } |
|
86 |
|
87 TRAPD(err, iRep = CRepository::NewL(TUid::Uid(iRepository))); |
|
88 if (err && iForce) |
|
89 { |
|
90 // force create a repository? |
|
91 } |
|
92 else |
|
93 { |
|
94 if (err == KErrNotFound) |
|
95 { |
|
96 PrintError(err, _L("Repository 0x%x not found"), iRepository); |
|
97 } |
|
98 User::LeaveIfError(err); |
|
99 } |
|
100 |
|
101 if (iDelete) |
|
102 { |
|
103 if (!iArguments.IsPresent(1)) |
|
104 { |
|
105 // Delete all |
|
106 if (iForce) |
|
107 { |
|
108 SudoL(_L("--delete")); |
|
109 } |
|
110 else |
|
111 { |
|
112 TUint32 errorKey = 0; |
|
113 err = iRep->Delete(0, 0, errorKey); |
|
114 if (err && errorKey && errorKey != NCentralRepositoryConstants::KUnspecifiedKey) |
|
115 { |
|
116 PrintError(err, _L("Delete failed due to key 0x%x"), errorKey); |
|
117 } |
|
118 } |
|
119 } |
|
120 else |
|
121 { |
|
122 if (iForce) |
|
123 { |
|
124 SudoL(_L("--delete %d"), iKey); |
|
125 } |
|
126 else |
|
127 { |
|
128 err = iRep->Delete(iKey); |
|
129 } |
|
130 } |
|
131 if (err == KErrPermissionDenied) |
|
132 { |
|
133 PrintError(err, _L("Delete failed, retry with --force")); |
|
134 } |
|
135 User::LeaveIfError(err); |
|
136 } |
|
137 else if (iReset) |
|
138 { |
|
139 if (iForce) |
|
140 { |
|
141 delete iRep; |
|
142 iRep = NULL; |
|
143 LtkUtils::RLtkBuf persistsName; |
|
144 CleanupClosePushL(persistsName); |
|
145 persistsName.AppendFormatL(_L("C:\\private\\10202be9\\persists\\%08x.cre"), iRepository); |
|
146 err = FsL().Delete(persistsName); |
|
147 LeaveIfErr(err, _L("Couldn't delete repository file %S"), &persistsName); |
|
148 CleanupStack::PopAndDestroy(&persistsName); |
|
149 } |
|
150 else |
|
151 { |
|
152 User::LeaveIfError(iRep->Reset()); |
|
153 } |
|
154 } |
|
155 else if (iOptions.IsPresent(&iIntVal)) |
|
156 { |
|
157 // Set int |
|
158 SetKeyL(iIntVal); |
|
159 } |
|
160 else if (iOptions.IsPresent(&iStringVal)) |
|
161 { |
|
162 // Set string |
|
163 //TPtrC8 data((TUint8*)iStringVal->Ptr(), iStringVal->Size()); |
|
164 //SetKeyL(data); |
|
165 SetKeyL(*iStringVal); |
|
166 } |
|
167 else if (!iArguments.IsPresent(1)) |
|
168 { |
|
169 // Get all |
|
170 if (iForce) |
|
171 { |
|
172 SudoL(KNullDesC); |
|
173 } |
|
174 else |
|
175 { |
|
176 RBuf8 valDes; |
|
177 CleanupClosePushL(valDes); |
|
178 valDes.CreateL(NCentralRepositoryConstants::KMaxBinaryLength); |
|
179 |
|
180 RArray<TUint32> keys; |
|
181 CleanupClosePushL(keys); |
|
182 iRep->FindL(0, 0, keys); |
|
183 for (TInt i = 0; i < keys.Count(); i++) |
|
184 { |
|
185 PrintKeyL(keys[i], valDes); |
|
186 } |
|
187 CleanupStack::PopAndDestroy(2, &valDes); // keys, valDes |
|
188 } |
|
189 } |
|
190 else |
|
191 { |
|
192 // Get |
|
193 RBuf8 valDes; |
|
194 CleanupClosePushL(valDes); |
|
195 valDes.CreateL(NCentralRepositoryConstants::KMaxBinaryLength * 3); // Because we also use this for hexifying |
|
196 PrintKeyL(iKey, valDes); |
|
197 CleanupStack::PopAndDestroy(&valDes); |
|
198 } |
|
199 } |
|
200 |
|
201 template <class KEYTYPE> |
|
202 void CCmdCenrep::SetKeyL(const KEYTYPE& aVal) |
|
203 { |
|
204 if (!iArguments.IsPresent(1)) |
|
205 { |
|
206 LeaveIfErr(KErrArgument, _L("You must specify a key to set")); |
|
207 } |
|
208 if (iForce) |
|
209 { |
|
210 ForceSetKeyL(aVal); |
|
211 } |
|
212 else |
|
213 { |
|
214 TInt err = iRep->Set(iKey, aVal); |
|
215 if (err == KErrArgument) |
|
216 { |
|
217 PrintError(err, _L("Key does not appear to be of the right type")); |
|
218 } |
|
219 User::LeaveIfError(err); |
|
220 } |
|
221 } |
|
222 |
|
223 void CCmdCenrep::ForceSetKeyL(TInt aVal) |
|
224 { |
|
225 SudoL(_L("%d --set-int %d"), iKey, aVal); |
|
226 } |
|
227 |
|
228 void CCmdCenrep::ForceSetKeyL(const TDesC& aVal) |
|
229 { |
|
230 SudoL(_L("%d --set-string '%S'"), iKey, &aVal); |
|
231 } |
|
232 |
|
233 void CCmdCenrep::PrintKeyL(TUint aKey, RBuf8& valDes) |
|
234 { |
|
235 TInt valInt; |
|
236 valDes.Zero(); |
|
237 enum TType { EUnknown, EInt, EDes }; |
|
238 TType type = EUnknown; |
|
239 TInt reallen = 0; |
|
240 |
|
241 TInt err = KErrNotFound; |
|
242 |
|
243 if (iForce) |
|
244 { |
|
245 SudoL(_L("%d"), aKey); |
|
246 } |
|
247 else |
|
248 { |
|
249 // Guess the value type |
|
250 // Int? |
|
251 if (type == EUnknown) |
|
252 { |
|
253 err = iRep->Get(aKey, valInt); |
|
254 if (err != KErrArgument) |
|
255 { |
|
256 type = EInt; |
|
257 } |
|
258 } |
|
259 |
|
260 if (type == EUnknown) |
|
261 { |
|
262 // Des? |
|
263 err = iRep->Get(aKey, valDes, reallen); |
|
264 if (err != KErrArgument) |
|
265 { |
|
266 type = EDes; |
|
267 } |
|
268 } |
|
269 } |
|
270 |
|
271 switch(err) |
|
272 { |
|
273 case KErrNotFound: |
|
274 PrintError(err, _L("Key not found")); |
|
275 break; |
|
276 case KErrArgument: |
|
277 PrintError(err, _L("Unknown key type, not int, des8 or des16")); |
|
278 break; |
|
279 case KErrPermissionDenied: |
|
280 PrintError(err, _L("Permission denied, retry with --force")); |
|
281 break; |
|
282 /* Won't happen because we now set our buffers to be the max size cenrep can handle |
|
283 case KErrOverflow: |
|
284 valDes16.ReallocL(reallen); |
|
285 valDes8.ReallocL(reallen); |
|
286 if (type == EDes8) |
|
287 { |
|
288 err = rep->Get(iKey, valDes8, reallen); // Better not fail this time! |
|
289 } |
|
290 else |
|
291 { |
|
292 err = rep->Get(iKey, valDes16, reallen); // Better not fail this time! |
|
293 } |
|
294 */ |
|
295 case KErrNone: |
|
296 // do nothing |
|
297 break; |
|
298 default: |
|
299 PrintError(err, _L("Unrecognised error returned from CRepository")); |
|
300 break; |
|
301 } |
|
302 |
|
303 if (err == KErrNone) |
|
304 { |
|
305 switch (type) |
|
306 { |
|
307 case EInt: |
|
308 Printf(_L("Key 0x%08x TInt: %d (0x%x)\r\n"), aKey, valInt, valInt); |
|
309 break; |
|
310 /*case EDes8: |
|
311 valDes16.Copy(valDes8); |
|
312 Printf(_L("Key 0x%x TDesC8 length=%d: %S\r\n"), aKey, valDes16.Length(), &valDes16); |
|
313 break;*/ |
|
314 case EDes: |
|
315 { |
|
316 TInt len = valDes.Length(); |
|
317 |
|
318 // Figure out if this string is likely to be 16bit ASCII, 8bit ASCII or just binary data |
|
319 TBool wide = ETrue; |
|
320 TBool ascii = ETrue; |
|
321 if (len&1) wide = EFalse; // Odd number of bytes can't be 16-bit |
|
322 for (TInt i = 0; i < len; i++) |
|
323 { |
|
324 TChar c(valDes[i]); |
|
325 if ((i&1) && valDes[i] != 0) wide = EFalse; |
|
326 if (!(c.IsPrint() && c < 127)) |
|
327 { |
|
328 if (!(i&1)) wide = EFalse; |
|
329 ascii = EFalse; |
|
330 } |
|
331 } |
|
332 |
|
333 if (wide) |
|
334 { |
|
335 TPtr16 widePtr((TUint16*)valDes.Ptr(), len/2, valDes.MaxLength()/2); |
|
336 Printf(_L("Key 0x%08x TDesC16 length=%d: %S\r\n"), aKey, widePtr.Length(), &widePtr); |
|
337 } |
|
338 else if (ascii) |
|
339 { |
|
340 Printf(_L8("Key 0x%08x TDesC8 length=%d: %S\r\n"), aKey, len, &valDes); |
|
341 } |
|
342 else |
|
343 { |
|
344 Printf(_L("Key 0x%08x TDesC8 hex dump:\r\n"), aKey); |
|
345 LtkUtils::HexDumpToOutput(valDes, Stdout()); |
|
346 } |
|
347 } |
|
348 break; |
|
349 default: |
|
350 break; |
|
351 } |
|
352 } |
|
353 } |
|
354 |
|
355 void CCmdCenrep::ArgumentsL(RCommandArgumentList& aArguments) |
|
356 { |
|
357 aArguments.AppendUintL(iRepository, _L("repository_uid")); |
|
358 aArguments.AppendUintL(iKey, _L("key")); |
|
359 } |
|
360 |
|
361 void CCmdCenrep::OptionsL(RCommandOptionList& aOptions) |
|
362 { |
|
363 aOptions.AppendIntL(iIntVal, _L("set-int")); |
|
364 aOptions.AppendStringL(iStringVal, _L("set-string")); |
|
365 aOptions.AppendBoolL(iForce, _L("force")); |
|
366 aOptions.AppendBoolL(iDelete, _L("delete")); |
|
367 aOptions.AppendBoolL(iReset, _L("reset")); |
|
368 } |
|
369 |
|
370 EXE_BOILER_PLATE(CCmdCenrep) |
|
371 |
|
372 void CCmdCenrep::ListRepositoriesL() |
|
373 { |
|
374 RArray<TUint> uids; |
|
375 CleanupClosePushL(uids); |
|
376 AddFilesL(uids, _L("*.cre"), _L("Y:\\private\\10202be9\\persists\\")); |
|
377 AddFilesL(uids, _L("*.cre"), _L("Y:\\private\\10202be9\\")); |
|
378 AddFilesL(uids, _L("*.txt"), _L("Y:\\private\\10202be9\\")); |
|
379 |
|
380 for (TInt i = 0; i < uids.Count(); i++) |
|
381 { |
|
382 Printf(_L("%08x\r\n"), uids[i]); |
|
383 } |
|
384 CleanupStack::PopAndDestroy(&uids); |
|
385 } |
|
386 |
|
387 void CCmdCenrep::AddFilesL(RArray<TUint>& aUids, const TDesC& aMatch, const TDesC& aDir) |
|
388 { |
|
389 TFindFile finder(FsL()); |
|
390 CDir* files = NULL; |
|
391 TInt err = finder.FindWildByDir(aMatch, aDir, files); |
|
392 |
|
393 while (err == KErrNone) |
|
394 { |
|
395 for (TInt i = 0; i < files->Count(); i++) |
|
396 { |
|
397 TUint uid; |
|
398 TLex lex((*files)[i].iName); |
|
399 err = lex.Val(uid, EHex); |
|
400 if (!err) |
|
401 { |
|
402 err = aUids.InsertInOrder(uid); |
|
403 if (err == KErrAlreadyExists) err = KErrNone; |
|
404 } |
|
405 } |
|
406 delete files; |
|
407 files = NULL; |
|
408 err = finder.FindWild(files); |
|
409 } |
|
410 |
|
411 if (err && err != KErrNotFound) LeaveIfErr(err, _L("Couldn't read directory %S"), &aDir); |
|
412 } |
|
413 |
|
414 void CCmdCenrep::SudoL(TRefByValue<const TDesC> aFmt, ...) |
|
415 { |
|
416 VA_LIST args; |
|
417 VA_START(args, aFmt); |
|
418 |
|
419 // We use sudo to give ourselves the SID of the repository, in the hope that will confer us more rights to access the data. |
|
420 // Some repos might be configured to deny access even from their own SID; there's nothing we can do in that case |
|
421 TBuf<256> commandLine; |
|
422 commandLine.AppendFormat(_L("--sid 0x%x cenrep.exe 0x%x "), iRepository, iRepository); |
|
423 commandLine.AppendFormatList(aFmt, args); |
|
424 VA_END(args); |
|
425 |
|
426 RChildProcess sudo; |
|
427 CleanupClosePushL(sudo); |
|
428 TRAPL(sudo.CreateL(_L("sudo.exe"), commandLine, IoSession(), Stdin(), Stdout(), Stderr()), _L("Couldn't create sudo process")); |
|
429 TRequestStatus logon; |
|
430 sudo.Run(logon); |
|
431 User::WaitForRequest(logon); |
|
432 LeaveIfErr(logon.Int(), _L("Error running sudo %S"), &commandLine); |
|
433 CleanupStack::PopAndDestroy(&sudo); |
|
434 } |