libraries/qr3/src/KernLbxModel.cpp
changeset 0 7f656887cf89
child 7 184a1eb85cf2
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // KernLbxModel.cpp
       
     2 // 
       
     3 // Copyright (c) 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 #include "KernLbxModel.h"
       
    13 #include "Utils.h"
       
    14 #include <fshell/memoryaccess.h>
       
    15 #include "QResources3.hrh"
       
    16 #include <HAL.h>
       
    17 #include <fshell/common.mmh>
       
    18 #include <fshell/clogger.h>
       
    19 
       
    20 #ifdef FSHELL_APPARC_SUPPORT
       
    21 #include <apgcli.h>
       
    22 #include <APGWGNAM.H>
       
    23 #include <APMREC.H>
       
    24 #endif
       
    25 #ifdef FSHELL_WSERV_SUPPPORT
       
    26 #include <W32STD.H>
       
    27 #endif
       
    28 
       
    29 #include <fshell/ltkutils.h>
       
    30 #include "sandbox.h"
       
    31 
       
    32 using namespace LtkUtils;
       
    33 
       
    34 CKernListBoxData::CKernListBoxData(CKernListBoxModel* aModel)
       
    35 	: /*CQikListBoxData(),*/ iModel(aModel)
       
    36 	{
       
    37 	}
       
    38 
       
    39 CKernListBoxData::~CKernListBoxData()
       
    40 	{
       
    41 	if (iDelegate)
       
    42 		{
       
    43 		iDelegate->DataObjectAboutToDestruct(this);
       
    44 		}
       
    45 	delete iInfo;
       
    46 	}
       
    47 
       
    48 
       
    49 CKernListBoxModel::CKernListBoxModel(RMemoryAccess& aMemoryAccess)
       
    50 	: iSort(NULL), iMemAccess(aMemoryAccess)
       
    51 	{
       
    52 	}
       
    53 
       
    54 void CKernListBoxModel::ConstructL()
       
    55 	{
       
    56 	iUnd = new(ELeave) CUndertaker(*this);
       
    57 	iUnd->Register();
       
    58 #ifdef FSHELL_WSERV_SUPPORT
       
    59 	iWsSession = new (ELeave) RWsSession;
       
    60 	TInt err = iWsSession->Connect();
       
    61 	if (err != KErrNone)
       
    62 		{
       
    63 		delete iWsSession;
       
    64 		iWsSession = NULL;
       
    65 		// Null pointer is used to indicate wserv not present
       
    66 		}
       
    67 #endif
       
    68 	iTempBuf1.CreateL(256);
       
    69 	iTempBuf2.CreateL(256);
       
    70 	}
       
    71 
       
    72 TInt CKernListBoxModel::Count() const
       
    73 	{
       
    74 	return iItemData.Count();
       
    75 	}
       
    76 
       
    77 TInt CKernListBoxModel::ItemIdIndex(TInt aItemId) const
       
    78 	{
       
    79 	const TInt count = iItemData.Count();
       
    80 	for (TInt i = 0; i < count; i++)
       
    81 		{
       
    82 		if (iItemData[i]->ItemId() == aItemId)
       
    83 			return i;
       
    84 		}
       
    85 	return KErrNotFound;
       
    86 	}
       
    87 
       
    88 CKernListBoxData* CKernListBoxModel::RetrieveDataL(TInt aItemIndex)
       
    89 	{
       
    90 	iItemData[aItemIndex]->Open();
       
    91 	return iItemData[aItemIndex];
       
    92 	}
       
    93 
       
    94 CKernListBoxData* CKernListBoxModel::RetrieveDataLC(TInt aItemIndex)
       
    95 	{
       
    96 	CKernListBoxData* data = iItemData[aItemIndex];
       
    97 	data->Open();
       
    98 	CleanupClosePushL(*data);
       
    99 	return data;
       
   100 	}
       
   101 
       
   102 void CKernListBoxModel::RemoveAllDataL()
       
   103 	{
       
   104 	const TInt count = iItemData.Count();
       
   105 	for (TInt i = 0; i < count; i++)
       
   106 		{
       
   107 		iItemData[i]->Close();
       
   108 		}
       
   109 	iItemData.Reset();
       
   110 	}
       
   111 
       
   112 void CKernListBoxModel::ModelBeginUpdateLC()
       
   113 	{
       
   114 	}
       
   115 
       
   116 void CKernListBoxModel::ModelEndUpdateL()
       
   117 	{
       
   118 	}
       
   119 
       
   120 void CKernListBoxModel::DataUpdatedL(TInt /*aIndex*/)
       
   121 	{
       
   122 	}
       
   123 
       
   124 TInt CKernListBoxModel::Compare(TInt aLeft, TInt aRight) const
       
   125 	{
       
   126 	const CKernListBoxData* left = iItemData[aLeft];
       
   127 	const CKernListBoxData* right = iItemData[aRight];
       
   128 	return (*iSort)(left, right);
       
   129 	}
       
   130 
       
   131 void CKernListBoxModel::Swap(TInt aLeft,TInt aRight) const
       
   132 	{
       
   133 	const_cast<CKernListBoxModel*>(this)->WtfSwap(aLeft, aRight);
       
   134 	}
       
   135 
       
   136 void CKernListBoxModel::WtfSwap(TInt aLeft,TInt aRight)
       
   137 	{
       
   138 	CKernListBoxData* temp = iItemData[aLeft];
       
   139 	iItemData[aLeft] = iItemData[aRight];
       
   140 	iItemData[aRight] = temp;
       
   141 	}
       
   142 
       
   143 void CKernListBoxModel::RemoveDataL(TInt aItemIndex)
       
   144 	{
       
   145 	iItemData[aItemIndex]->Close();
       
   146 	iItemData.Remove(aItemIndex);
       
   147 	}
       
   148 
       
   149 void CKernListBoxModel::SetCurrentListL(TInt aCurrentList)
       
   150 	{
       
   151 	if (iCurrentList != aCurrentList)
       
   152 		{
       
   153 		RemoveAllDataL();
       
   154 		}
       
   155 	iCurrentList = aCurrentList;
       
   156 	}
       
   157 
       
   158 TInt CKernListBoxModel::GetCurrentList() const
       
   159 	{
       
   160 	return iCurrentList;
       
   161 	}
       
   162 
       
   163 void CKernListBoxModel::NewKernDataL(TInt aType, TObjectKernelInfo* aInfo)
       
   164 	{
       
   165 	DoNewKernDataL(aType, aInfo, NULL);
       
   166 	}
       
   167 
       
   168 void CKernListBoxModel::DoNewKernDataL(TInt aType, TObjectKernelInfo* aInfo, MKernListBoxDataDelegate* aDelegate)
       
   169 	{
       
   170 	CKernListBoxData* data;
       
   171 	switch (aType)
       
   172 		{
       
   173 	case EListOpenFiles:
       
   174 		data = new(ELeave) COpenFilesListBoxData(this);
       
   175 		break;
       
   176 	case EListThread:
       
   177 		data = new(ELeave) CThreadsListBoxData(this);
       
   178 		break;
       
   179 	case EListFeatureReg:
       
   180 		data = new(ELeave) CFeatRegListBoxData(this);
       
   181 		break;
       
   182 	case EListServer:
       
   183 		data = new(ELeave) CServerListBoxData(this);
       
   184 		break;
       
   185 	case EListHal:
       
   186 		data = new(ELeave) CHalListBoxData(this);
       
   187 		break;
       
   188 	case EListWindowGroups:
       
   189 #ifdef FSHELL_WSERV_SUPPORT
       
   190 		data = new(ELeave) CWindowGroupListBoxData(this);
       
   191 #else
       
   192 		data = NULL; // Compiler shutter upper
       
   193 		User::Leave(KErrNotSupported);
       
   194 #endif
       
   195 		break;
       
   196 	case EListMessageQueue:
       
   197 		data = new(ELeave) CMsgQueListBoxData(this);
       
   198 		break;
       
   199 	case EListMutex:
       
   200 		data = new(ELeave) CMutexListBoxData(this);
       
   201 		break;
       
   202 	case EListSemaphore:
       
   203 		data = new(ELeave) CSemaphoreListBoxData(this);
       
   204 		break;
       
   205 	case EListTimer:
       
   206 		data = new(ELeave) CTimerListBoxData(this);
       
   207 		break;
       
   208 	default:
       
   209 		data = new(ELeave) CKernListBoxData(this);
       
   210 		break;
       
   211 		}
       
   212 	
       
   213 	data->SetDelegate(aDelegate);
       
   214 	CleanupStack::PushL(data);
       
   215 	data->iType = aType;
       
   216 	data->ConstructL();
       
   217 
       
   218 	data->FormatL(aInfo, iTempBuf1, iTempBuf2);
       
   219 
       
   220 	iItemData.AppendL(data);
       
   221 	CleanupStack::Pop(data);
       
   222 	data->Open(); // open for model
       
   223 
       
   224 	//data->Open(); // open for return
       
   225 	data->iInfo = aInfo;
       
   226 	//return data;
       
   227 	}
       
   228 
       
   229 
       
   230 // This function is used for the list box items
       
   231 void CKernListBoxData::FormatL(TObjectKernelInfo* aInfo, RBuf& aTempBuf1, RBuf& aTempBuf2)
       
   232 	{
       
   233 	RBuf& name = aTempBuf1;
       
   234 	RBuf& more = aTempBuf2;
       
   235 	name.Zero();
       
   236 	more.Zero();
       
   237 
       
   238 	TInt itemId = (TInt)aInfo; // By default use the ptr unless the type can suggest anything better
       
   239 	DoFormatL(aInfo, aTempBuf1, aTempBuf2, itemId);
       
   240 	SetItemId(itemId);
       
   241 
       
   242 	if (iDelegate)
       
   243 		{
       
   244 		iDelegate->FormatChangedL(this, name, more);
       
   245 		}
       
   246 	}
       
   247 
       
   248 
       
   249 void CKernListBoxData::DoFormatL(TObjectKernelInfo* aInfo, RBuf& name, RBuf& more, TInt& itemId)
       
   250 	{
       
   251 	switch (iType)
       
   252 		{
       
   253 	case EListChunk:
       
   254 		{
       
   255 		TChunkKernelInfo& info = *(TChunkKernelInfo*)aInfo;
       
   256 		name.Copy(info.iFullName);
       
   257 		PrettyName(iType, name);
       
   258 		TBuf<16> size, maxSize;
       
   259 		HR(size, info.iSize);
       
   260 		HR(maxSize, info.iMaxSize);
       
   261 		more.Format(_L("Size %S / %S"), &size, &maxSize);
       
   262 		break;
       
   263 		}
       
   264 	case EListProcess:
       
   265 		{
       
   266 		TProcessKernelInfo& info = *(TProcessKernelInfo*)aInfo;
       
   267 		name.Copy(info.iFullName);
       
   268 		PrettyName(iType, name);
       
   269 		TUint pid = info.iProcessId;
       
   270 		TUint sid = info.iProcessSecurityInfo.iSecureId;
       
   271 		TExitType exitType = EExitPending;
       
   272 		RProcess proc;
       
   273 		if (proc.Open(pid) == KErrNone)
       
   274 			{
       
   275 			exitType = proc.ExitType();
       
   276 			}
       
   277 		if (exitType == EExitPending)
       
   278 			{
       
   279 			more.Format(_L("Pid %i Sid 0x%x"), pid, sid);
       
   280 			}
       
   281 		else
       
   282 			{
       
   283 			TExitCategoryName cat = proc.ExitCategory();
       
   284 			more.Format(_L("Pid %i %S %i Sid 0x%x"), pid, &cat, proc.ExitReason(), sid);
       
   285 			}
       
   286 		proc.Close();
       
   287 		itemId = pid;
       
   288 		break;
       
   289 		}
       
   290 	case EListCodeSeg:
       
   291 		{
       
   292 		TTomsciCodeSegKernelInfo& info = *reinterpret_cast<TTomsciCodeSegKernelInfo*>(aInfo);
       
   293 		name.Copy(info.iName);
       
   294 
       
   295 		TBuf<16> size;
       
   296 		HR(size, info.iSize);
       
   297 		more.Format(_L("Size %S Ref count %i"), &size, info.iAccessCount);
       
   298 		break;
       
   299 		}
       
   300 	case EListMimeTypes:
       
   301 		{
       
   302 		SDataType& info = *reinterpret_cast<SDataType*>(aInfo);
       
   303 		name.Copy(info.iMime);
       
   304 		more.Format(_L("From: %S"), &info.iRecog);
       
   305 		break;
       
   306 		}
       
   307 	default:
       
   308 		break;
       
   309 		}
       
   310 	
       
   311 	}
       
   312 
       
   313 void CKernListBoxModel::DumpToCloggerL(RClogger& clogger)
       
   314 	{
       
   315 	TInt count = Count();
       
   316 
       
   317 #ifdef __WINS__
       
   318 	clogger.Log("NOTE: This data is from a WINS[CW] build so is not representative of a real device!");
       
   319 #endif
       
   320 
       
   321 	for (TInt i = 0; i < count; i++)
       
   322 		{
       
   323 		CKernListBoxData* data = static_cast<CKernListBoxData*>(RetrieveDataLC(i));
       
   324 		data->DumpToCloggerL(clogger, i, count);
       
   325 		CleanupStack::PopAndDestroy(data);
       
   326 		}
       
   327 	}
       
   328 
       
   329 void CKernListBoxData::DumpToCloggerL(RClogger& clogger, TInt i, TInt count)
       
   330 	{
       
   331 	_LIT8(KChunkDesc,"Chunk;FullName;Size;(SizeHumanReadable);MaxSize;(MaxSizeHumanReadable);CreatorPid;BaseAddr");
       
   332 	_LIT8(KChunkFmt,"Chunk;%S;%i;(%S);%i;(%S);%i;%08x");
       
   333 
       
   334 	_LIT8(KProcessDesc,"Process;FullName;Pid;Priority;(PriorityHumanReadable);Sid;Vid;CreatorSid;CreatorName;Capabilities;(CapsHumanReadable);ExitStatus;ExitCategory;ExitReason;FixedProcess;DProcessAddr");
       
   335 	_LIT8(KProcessFmt,"Process;%S;%i;%i;(%S);%x;%x;%x;%S;%x;(%S);%S;%S;%i;%S;%08x");
       
   336 
       
   337 	_LIT8(KCodesegDesc,"CodeSeg;FileName;Size;(SizeHumanReadable);RefCount;DepCount");
       
   338 	_LIT8(KCodesegFmt,"CodeSeg;%S;%i;%S;%i;%i");
       
   339 
       
   340 	_LIT(KMimeDesc,"MimeType;Name;Recogniser;AppUid;AppName");
       
   341 	_LIT(KMimeFmt, "MimeType;%S;%S;%x;%S");
       
   342 
       
   343 	CKernListBoxData* data = this;
       
   344 	TObjectKernelInfo* aInfo = data->iInfo;
       
   345 
       
   346 	switch (iType)
       
   347 		{
       
   348 	case EListChunk:
       
   349 		{
       
   350 		if (i == 0) clogger.Log(KChunkDesc);
       
   351 		if (i == 0)
       
   352 			{
       
   353 			// Also log free at the start, so we can tally up mem losses
       
   354 			TInt freeRam = -1, totalRam = -1;
       
   355 			TBuf8<16> free, total;
       
   356 			HAL::Get(HAL::EMemoryRAMFree, freeRam);
       
   357 			HAL::Get(HAL::EMemoryRAM, totalRam);
       
   358 			HR(free, freeRam);
       
   359 			HR(total, totalRam);
       
   360 			_LIT8(KFree, "FREE");
       
   361 			clogger.Log(KChunkFmt, &KFree, freeRam, &free, totalRam, &total, 0);
       
   362 			}
       
   363 
       
   364 		TChunkKernelInfo& info = *(TChunkKernelInfo*)aInfo;
       
   365 		TBuf8<16> size, maxSize;
       
   366 		HR(size, info.iSize);
       
   367 		HR(maxSize, info.iMaxSize);
       
   368 		clogger.Log(KChunkFmt, &info.iFullName, info.iSize, &size, info.iMaxSize, &maxSize, info.iControllingOwnerProcessId, info.iBase);
       
   369 
       
   370 		if (i == count-1)
       
   371 			{
       
   372 			// Also print out free RAM at end, so we can see if mem usage changed much during
       
   373 			TInt freeRam = -1, totalRam = -1;
       
   374 			TBuf8<16> free, total;
       
   375 			HAL::Get(HAL::EMemoryRAMFree, freeRam);
       
   376 			HAL::Get(HAL::EMemoryRAM, totalRam);
       
   377 			HR(free, freeRam);
       
   378 			HR(total, totalRam);
       
   379 			_LIT8(KFree, "FREE");
       
   380 			clogger.Log(KChunkFmt, &KFree, freeRam, &free, totalRam, &total, 0);
       
   381 			}
       
   382 		break;
       
   383 		}
       
   384 	case EListProcess:
       
   385 		{
       
   386 		if (i == 0) clogger.Log(KProcessDesc);
       
   387 		TProcessKernelInfo& info = *(TProcessKernelInfo*)aInfo;
       
   388 
       
   389 		TBuf<16> priority16 = ToString((TProcessPriority)info.iPriority);
       
   390 		TPtr8 priority = priority16.Collapse();
       
   391 		HBufC* caps16 = ToStringL(info.iProcessSecurityInfo.iCaps);
       
   392 		TPtr8 caps(caps16->Des().Collapse());
       
   393 		TPtrC exitStatus;
       
   394 		TInt exitReason = 0;
       
   395 		TExitCategoryName exitCategory;
       
   396 		RProcess handle;
       
   397 		if (handle.Open(info.iProcessId) == KErrNone)
       
   398 			{
       
   399 			exitStatus.Set(ToString(handle.ExitType()));
       
   400 			exitCategory = handle.ExitCategory();
       
   401 			exitReason = handle.ExitReason();
       
   402 			handle.Close();
       
   403 			}
       
   404 		TBuf8<16> exitStatus8;
       
   405 		exitStatus8.Copy(exitStatus);
       
   406 		TPtrC8 exitCategory8 = exitCategory.Collapse();
       
   407 		RBuf creatorName;
       
   408 		data->ExeNameForSid(info.iProcessCreatorSecurityInfo.iSecureId, creatorName);
       
   409 		TPtrC8 creatorName8 = creatorName.Collapse();
       
   410 		TBool fixed = info.iAttributes & 1; // TMemModelProcessAttributes::EFixedAddress
       
   411 		_LIT8(KFixed, "FIXED");
       
   412 		TPtrC8 fixedPtr = fixed ? KFixed() : KNullDesC8();
       
   413 		clogger.Log(KProcessFmt, &info.iFullName, info.iProcessId, info.iPriority, &priority, info.iProcessSecurityInfo.iSecureId, info.iProcessSecurityInfo.iVendorId, info.iProcessCreatorSecurityInfo.iSecureId, &creatorName8, info.iProcessSecurityInfo.iCaps[0], &caps, &exitStatus8, &exitCategory8, exitReason, &fixedPtr, info.iAddressOfKernelObject);
       
   414 		creatorName.Close();
       
   415 		delete caps16;
       
   416 		break;
       
   417 		}
       
   418 	case EListCodeSeg:
       
   419 		{
       
   420 		if (i == 0) clogger.Log(KCodesegDesc);
       
   421 		TTomsciCodeSegKernelInfo& info = *reinterpret_cast<TTomsciCodeSegKernelInfo*>(aInfo);
       
   422 		TBuf8<16> size;
       
   423 		HR(size, info.iSize);
       
   424 		clogger.Log(KCodesegFmt, &info.iName, info.iSize, &size, info.iAccessCount, info.iDepCount);
       
   425 		break;
       
   426 		}
       
   427 	case EListMimeTypes:
       
   428 		{
       
   429 		if (i == 0) clogger.Log(KMimeDesc);
       
   430 		SDataType& info = *reinterpret_cast<SDataType*>(aInfo);
       
   431 		clogger.Log(KMimeFmt, &info.iMime, &info.iRecog, info.iAppUid, &info.iApp);
       
   432 		break;
       
   433 		}
       
   434 	default:
       
   435 		break;
       
   436 		}
       
   437 	}
       
   438 
       
   439 void CKernListBoxData::InfoForDialogL(RBuf& aTitle, RBuf& aText, TBool aRefresh)
       
   440 	{
       
   441 	if (aRefresh)
       
   442 		{
       
   443 		// Figure out our index in the model
       
   444 		TInt index = iModel->ItemIdIndex(ItemId());
       
   445 		iModel->RefreshDataL(index);
       
   446 		}
       
   447 
       
   448 	aTitle.Zero();
       
   449 	aText.Zero();
       
   450 
       
   451 	if (aTitle.MaxLength() < 256)
       
   452 		{
       
   453 		aTitle.ReAllocL(256);
       
   454 		}
       
   455 	if (aText.MaxLength() < 1024)
       
   456 		{
       
   457 		aText.ReAllocL(1024);
       
   458 		}
       
   459 
       
   460 	RBuf& inf = aText;
       
   461 	TBuf<256>* name = new(ELeave) TBuf<256>;
       
   462 	CleanupStack::PushL(name);
       
   463 	DoInfoForDialogL(aTitle, inf, name);
       
   464 	CleanupStack::PopAndDestroy(name);
       
   465 	}
       
   466 
       
   467 void AppendProcessFlags(TDes& aBuf, TUint32 aFlags)
       
   468 	{
       
   469 	TInt len = aBuf.Length();
       
   470 
       
   471 	// 9.1/9.2 doesn't have these, it's easier to redefine them to the correct value than make all the code conditional
       
   472 	const TUint KThreadFlagRealtime = 0x00000040;
       
   473 	const TUint KThreadFlagRealtimeTest = 0x00000080;
       
   474 
       
   475 #define IF_MATCH(aBuf, aFlags, aFlag) if (aFlags&aFlag) { aBuf.Append(_L( #aFlag )); aBuf.Append('|'); }
       
   476 	IF_MATCH(aBuf, aFlags, KThreadFlagProcessCritical)
       
   477 	IF_MATCH(aBuf, aFlags, KThreadFlagProcessPermanent)
       
   478 	IF_MATCH(aBuf, aFlags, KThreadFlagSystemCritical)
       
   479 	IF_MATCH(aBuf, aFlags, KThreadFlagSystemPermanent)
       
   480 	IF_MATCH(aBuf, aFlags, KThreadFlagOriginal)
       
   481 	IF_MATCH(aBuf, aFlags, KThreadFlagLastChance)
       
   482 	IF_MATCH(aBuf, aFlags, KThreadFlagRealtime)
       
   483 	IF_MATCH(aBuf, aFlags, KThreadFlagRealtimeTest)
       
   484 	IF_MATCH(aBuf, aFlags, KProcessFlagPriorityControl)
       
   485 	IF_MATCH(aBuf, aFlags, KProcessFlagJustInTime)
       
   486 	if (aBuf.Length() > len)
       
   487 		{
       
   488 		// Remove trailing |
       
   489 		aBuf.SetLength(aBuf.Length() - 1);
       
   490 		}
       
   491 	}
       
   492 
       
   493 void CKernListBoxData::DoInfoForDialogL(RBuf& aTitle, RBuf& inf, TDes* aTemp)
       
   494 	{
       
   495 	TDes* name = aTemp;
       
   496 	switch (iType)
       
   497 		{
       
   498 		case EListProcess:
       
   499 			{
       
   500 			TProcessKernelInfo& info = *(TProcessKernelInfo*)iInfo;
       
   501 			RProcess process;
       
   502 			TInt err = process.Open(info.iProcessId);
       
   503 			CleanupClosePushL(process);
       
   504 
       
   505 			_LIT(KInfo, "Process info");
       
   506 			aTitle.Copy(KInfo);
       
   507 			inf.Copy(iInfo->iFullName);
       
   508 			if (!err)
       
   509 				{
       
   510 				inf.Append(Klf);
       
   511 				inf.Append(process.FileName());
       
   512 				}
       
   513 			if (info.iCommandLine.Length())
       
   514 				{
       
   515 				inf.Append(' ');
       
   516 				//aTemp->Copy(info.iCommandLine);
       
   517 				// Command line args are generally 16-bit descriptors even though they're represented in 8-bit kernel-side
       
   518 				TPtrC widePtr((const TUint16*)info.iCommandLine.Ptr(), info.iCommandLine.Size()/2);
       
   519 				inf.Append(widePtr);
       
   520 				}
       
   521 
       
   522 			//_LIT8(KProcessDesc, "Process\tFullName\tPid\tPriority\t(PriorityHumanReadable)\tSid\tVid\tCapabilities\t(CapsHumanReadable)\tExitStatus\tExitCategory\tExitReason");
       
   523 
       
   524 			_LIT(KProcess, "\n\nPid: %i %S\nSid: 0x%x Vid: 0x%x");
       
   525 			_LIT(KPriority, "\nPriority: %i (%S)");
       
   526 			_LIT(KOtherStuff, "\nCreator Sid: 0x%x (%S)\n\nCapabilities: %S");
       
   527 			_LIT(KKern, "\nKernel object address: 0x%08x");
       
   528 			_LIT(KFlags, "\nFlags: 0x%x (");
       
   529 			_LIT(KDied, "\n\nDied with: %S %S %i");
       
   530 
       
   531 			HBufC* caps = ToStringL(info.iProcessSecurityInfo.iCaps);
       
   532 			TUint creatorSid = info.iProcessCreatorSecurityInfo.iSecureId;
       
   533 			TBool fixed = info.iAttributes & 1; // TMemModelProcessAttributes::EFixedAddress
       
   534 			_LIT(KFixed, "(fixed process)");
       
   535 			TPtrC fixedPtr = fixed ? KFixed() : KNullDesC();
       
   536 			inf.AppendFormat(KProcess, info.iProcessId, &fixedPtr, info.iProcessSecurityInfo.iSecureId, info.iProcessSecurityInfo.iVendorId);
       
   537 			if (!err)
       
   538 				{
       
   539 				TPtrC priority = ToString(process.Priority());
       
   540 				inf.AppendFormat(KPriority, process.Priority(), &priority);
       
   541 				}
       
   542 			inf.AppendFormat(KKern, info.iAddressOfKernelObject);
       
   543 			if (info.iFlags)
       
   544 				{
       
   545 				inf.AppendFormat(KFlags, info.iFlags);
       
   546 				AppendProcessFlags(inf, info.iFlags);
       
   547 				inf.Append(')');
       
   548 				}
       
   549 
       
   550 			RBuf parentName;
       
   551 			ExeNameForSid(creatorSid, parentName);
       
   552 
       
   553 			inf.AppendFormat(KOtherStuff, creatorSid, &parentName, caps);
       
   554 			delete caps;
       
   555 			parentName.Close();
       
   556 
       
   557 			if (!err && process.ExitType() != EExitPending)
       
   558 				{
       
   559 				TPtrC exitStatus;
       
   560 				TInt exitReason = 0;
       
   561 				TExitCategoryName exitCategory;
       
   562 				exitStatus.Set(ToString(process.ExitType()));
       
   563 				if (process.ExitType() == EExitPanic)
       
   564 					{
       
   565 					exitCategory = process.ExitCategory();
       
   566 					}
       
   567 				exitReason = process.ExitReason();
       
   568 				inf.AppendFormat(KDied, &exitStatus, &exitCategory, exitReason);
       
   569 				}
       
   570 			CleanupStack::PopAndDestroy(&process);
       
   571 			break;
       
   572 			}
       
   573 		case EListChunk:
       
   574 			{
       
   575 			TChunkKernelInfo& info = *(TChunkKernelInfo*)iInfo;
       
   576 			_LIT(KInfo, "Chunk info");
       
   577 			aTitle.Copy(KInfo);
       
   578 			inf.Copy(iInfo->iFullName);
       
   579 			inf.Append(Klflf);
       
   580 
       
   581 			TBuf<16> size, maxSize;
       
   582 			HR(size, info.iSize);
       
   583 			HR(maxSize, info.iMaxSize);
       
   584 
       
   585 			RProcess creator;
       
   586 			TInt err = creator.Open(info.iControllingOwnerProcessId);
       
   587 			if (!err) 
       
   588 				{
       
   589 				*name = creator.FullName();
       
   590 				PrettyName(EListProcess, *name);
       
   591 				creator.Close();
       
   592 				}
       
   593 			_LIT(KKern, "Kernel object address: 0x%08x\n");
       
   594 			_LIT(KChunk, "Base: 0x%08x\nSize: %S\nMax Size: %S\nCreator pid: %i (%S)");
       
   595 			inf.AppendFormat(KKern, info.iAddressOfKernelObject);
       
   596 			inf.AppendFormat(KChunk, info.iBase, &size, &maxSize, info.iControllingOwnerProcessId, name);
       
   597 			break;
       
   598 			}
       
   599 		case EListCodeSeg:
       
   600 			{
       
   601 			TTomsciCodeSegKernelInfo& info = *reinterpret_cast<TTomsciCodeSegKernelInfo*>(iInfo);
       
   602 			_LIT(KInfo, "Code segment info");
       
   603 			aTitle.Copy(KInfo);
       
   604 			inf.Copy(info.iName);
       
   605 			inf.Append(Klflf);
       
   606 
       
   607 			TBuf<16> size;
       
   608 			HR(size, info.iSize);
       
   609 			_LIT(KCodesegFmt, "File name: %S\nSize %S\nRef count %i\nDependancy count %i\nRun address 0x%08x");
       
   610 			aTemp->Copy(info.iFileName);
       
   611 			inf.AppendFormat(KCodesegFmt, aTemp, &size, info.iAccessCount, info.iDepCount, info.iRunAddress);
       
   612 			break;
       
   613 			}
       
   614 		case EListMimeTypes:
       
   615 			{
       
   616 			SDataType& info = *reinterpret_cast<SDataType*>(iInfo);
       
   617 			_LIT(KInfo, "Mime type info");
       
   618 			aTitle.Copy(KInfo);
       
   619 
       
   620 			inf.AppendFormat(_L("%S\n\n%S\nApp UID: 0x%x\n%S"), &info.iMime, &info.iRecog, info.iAppUid, &info.iApp);
       
   621 			break;
       
   622 			}
       
   623 		default:
       
   624 			break;
       
   625 		}
       
   626 	}
       
   627 
       
   628 void CKernListBoxModel::SummaryInfoL(TDes& aBuf)
       
   629 	{
       
   630 	switch (iCurrentList)
       
   631 		{
       
   632 		case EListProcess:
       
   633 			{
       
   634 			_LIT(KFmt, "%i processes");
       
   635 			aBuf.Format(KFmt, Count());
       
   636 			break;
       
   637 			}
       
   638 		case EListThread:
       
   639 			{
       
   640 			_LIT(KFmt, "%i threads");
       
   641 			aBuf.Format(KFmt, Count());
       
   642 			break;
       
   643 			}
       
   644 		case EListChunk:
       
   645 			{
       
   646 			_LIT(KFmt, "%i chunks, free %S/%S");
       
   647 			TInt freeRam = -1, totalRam = -1;
       
   648 			TBuf<16> free, total;
       
   649 			HAL::Get(HAL::EMemoryRAMFree, freeRam);
       
   650 			HAL::Get(HAL::EMemoryRAM, totalRam);
       
   651 			HR(free, freeRam);
       
   652 			HR(total, totalRam);
       
   653 			aBuf.Format(KFmt, Count(), &free, &total);
       
   654 			break;
       
   655 			}
       
   656 		case EListCodeSeg:
       
   657 			{
       
   658 			_LIT(KFmt, "%i code segments");
       
   659 			aBuf.Format(KFmt, Count());
       
   660 			break;
       
   661 			}
       
   662 		case EListHal:
       
   663 			{
       
   664 			_LIT(KFmt, "%i HAL attributes");
       
   665 			aBuf.Format(KFmt, Count());
       
   666 			break;
       
   667 			}
       
   668 		case EListWindowGroups:
       
   669 			{
       
   670 			_LIT(KFmt, "%i window groups");
       
   671 			aBuf.Format(KFmt, Count());
       
   672 			break;
       
   673 			}
       
   674 		case EListMimeTypes:
       
   675 			{
       
   676 			_LIT(KFmt, "%i mime types");
       
   677 			aBuf.Format(KFmt, Count());
       
   678 			break;
       
   679 			}
       
   680 		case EListOpenFiles:
       
   681 			{
       
   682 			_LIT(KFmt, "%i open files");
       
   683 			aBuf.Format(KFmt, Count());
       
   684 			break;
       
   685 			}
       
   686 		case EListFeatureReg:
       
   687 			{
       
   688 			_LIT(KFmt, "%i features in registry");
       
   689 			aBuf.Format(KFmt, Count());
       
   690 			break;
       
   691 			}
       
   692 		case EListServer:
       
   693 			{
       
   694 			_LIT(KFmt, "%i servers");
       
   695 			aBuf.Format(KFmt, Count());
       
   696 			break;
       
   697 			}
       
   698 		case EListMessageQueue:
       
   699 			{
       
   700 			_LIT(KFmt, "%i message queues");
       
   701 			aBuf.Format(KFmt, Count());
       
   702 			break;
       
   703 			}
       
   704 		case EListMutex:
       
   705 			{
       
   706 			_LIT(KFmt, "%i mutexes");
       
   707 			aBuf.Format(KFmt, Count());
       
   708 			break;
       
   709 			}
       
   710 		case EListSemaphore:
       
   711 			{
       
   712 			_LIT(KFmt, "%i semaphores");
       
   713 			aBuf.Format(KFmt, Count());
       
   714 			break;
       
   715 			}
       
   716 		case EListTimer:
       
   717 			{
       
   718 			_LIT(KFmt, "%i timers");
       
   719 			aBuf.Format(KFmt, Count());
       
   720 			break;
       
   721 			}
       
   722 		default:
       
   723 			break;
       
   724 		}
       
   725 	}
       
   726 
       
   727 TBool CKernListBoxData::SupportsCommand(TInt aCommand)
       
   728 	{
       
   729 	switch (aCommand)
       
   730 		{
       
   731 		case ECmdPoll:
       
   732 		case ECmdHandleInfo:
       
   733 			{
       
   734 			if (iType == EListProcess || iType == EListChunk) return ETrue;
       
   735 			break;
       
   736 			}
       
   737 		case ECmdKill:
       
   738 			{
       
   739 			if (iType == EListProcess) return ETrue;
       
   740 			break;
       
   741 			}
       
   742 		default:
       
   743 			break;
       
   744 		}
       
   745 	return EFalse;
       
   746 	}
       
   747 
       
   748 void CKernListBoxData::KillL()
       
   749 	{
       
   750 	TUint8* addr = iInfo->iAddressOfKernelObject;
       
   751 	RMemoryAccess& mem = iModel->MemAccess();
       
   752 	User::LeaveIfError(mem.ObjectDie(iType == EListThread ? EThread : EProcess, 0, addr, EExitKill, 666999, KNullDesC));
       
   753 	// The undertaker should cause an update via ThreadDiedL
       
   754 	}
       
   755 
       
   756 TAny* CKernListBoxData::GetHandleL()
       
   757 	{
       
   758 	return iInfo->iAddressOfKernelObject;
       
   759 	}
       
   760 
       
   761 TInt CKernListBoxData::ExeNameForSid(TUint aSid, RBuf& aName)
       
   762 	{
       
   763 	// First try our list
       
   764 	TInt lserr = KErrNotFound;
       
   765 	if (aName.Create(256) != KErrNone) lserr = KErrNoMemory;
       
   766 	if (iModel && aName.MaxLength())
       
   767 		{
       
   768 		for (TInt i = 0; i < iModel->iItemData.Count(); i++)
       
   769 			{
       
   770 			CKernListBoxData* data = static_cast<CKernListBoxData*>(iModel->iItemData[i]);
       
   771 			TProcessKernelInfo* pinfo = static_cast<TProcessKernelInfo*>(data->iInfo);
       
   772 			if (data->iType == EListProcess && pinfo->iProcessSecurityInfo.iSecureId == aSid)
       
   773 				{
       
   774 				lserr = KErrNone;
       
   775 				aName.Copy(pinfo->iName);
       
   776 				PrettyName(EListProcess, aName);
       
   777 				break;
       
   778 				}
       
   779 			}
       
   780 		}
       
   781 #ifdef FSHELL_APPARC_SUPPORT
       
   782 	if (lserr == KErrNotFound)
       
   783 		{
       
   784 		// Didn't find the process in our process list. Must have already closed. Try
       
   785 		// apparc as a fallback - will only work for fully-fledged applications
       
   786 		RApaLsSession ls;
       
   787 		TInt lserr = ls.Connect();
       
   788 		TApaAppInfo* appinfo = new TApaAppInfo;
       
   789 		if (!appinfo ) lserr = KErrNoMemory;
       
   790 		if (!lserr)
       
   791 			{
       
   792 			lserr = ls.GetAppInfo(*appinfo , TUid::Uid(aSid));
       
   793 			}
       
   794 		if (!lserr)
       
   795 			{
       
   796 			TInt slash = appinfo->iFullName.LocateReverse('\\');
       
   797 			aName.Copy(appinfo->iFullName.Mid(slash+1));
       
   798 			}
       
   799 		delete appinfo;
       
   800 		ls.Close();
       
   801 		}
       
   802 #endif
       
   803 
       
   804 	if (aName.Length() == 0 && aSid == 0x10205c44)
       
   805 		{
       
   806 		// Special case this because sysstart isn't running & isn't an app, and appears
       
   807 		// enough as parent to be worth special-casing
       
   808 		aName.Copy(_L("SysStart"));
       
   809 		lserr = KErrNone;
       
   810 		}
       
   811 	return lserr;
       
   812 	}
       
   813 
       
   814 void CKernListBoxModel::ThreadDiedL(TInt aHandle)
       
   815 	{
       
   816 	RThread thread;
       
   817 	thread.SetHandle(aHandle);
       
   818 	TThreadId id = thread.Id();
       
   819 	iThreadHandleArray.Append(aHandle);
       
   820 
       
   821 	if (iCurrentList == EListThread)
       
   822 		{
       
   823 		TInt idx = ItemIdIndex(id);
       
   824 		if (idx != KErrNotFound)
       
   825 			{
       
   826 			ModelBeginUpdateLC();
       
   827 			CKernListBoxData* data = static_cast<CKernListBoxData*>(iItemData[idx]);
       
   828 			data->FormatL(data->iInfo, iTempBuf1, iTempBuf2); // Thread death info isn't stored in iInfo, so no need to update it
       
   829 			DataUpdatedL(idx);
       
   830 			ModelEndUpdateL();
       
   831 
       
   832 			if (iInfoChangedCallback.iFunction != NULL && data == iCallbackData)
       
   833 				{
       
   834 				iInfoChangedCallback.CallBack();
       
   835 				}
       
   836 
       
   837 			}
       
   838 		else
       
   839 			{
       
   840 			// We don't have an entry for this thread id. Oh well, just storing it in the tid list will guarantee it will still be there when the user hits refresh
       
   841 			}
       
   842 		}
       
   843 	else if (iCurrentList == EListProcess)
       
   844 		{
       
   845 		RProcess p;
       
   846 		if (thread.Process(p) == KErrNone)
       
   847 			{
       
   848 			TProcessId id = p.Id();
       
   849 			TInt idx = ItemIdIndex(id);
       
   850 			p.Close();
       
   851 			if (idx != KErrNotFound)
       
   852 				{
       
   853 				ModelBeginUpdateLC();
       
   854 				CKernListBoxData* data = static_cast<CKernListBoxData*>(iItemData[idx]);
       
   855 				data->FormatL(data->iInfo, iTempBuf1, iTempBuf2); // Process death info isn't stored in iInfo, so no need to update it
       
   856 				DataUpdatedL(idx);
       
   857 				ModelEndUpdateL();
       
   858 				if (iInfoChangedCallback.iFunction != NULL && data == iCallbackData)
       
   859 					{
       
   860 					iInfoChangedCallback.CallBack();
       
   861 					}
       
   862 
       
   863 				}
       
   864 			}
       
   865 		}
       
   866 	}
       
   867 
       
   868 void CKernListBoxModel::CloseAllThreadHandles()
       
   869 	{
       
   870 	for (TInt i = 0; i < iThreadHandleArray.Count(); i++)
       
   871 		{
       
   872 		RThread t;
       
   873 		t.SetHandle(iThreadHandleArray[i]);
       
   874 		t.Close();
       
   875 		}
       
   876 	iThreadHandleArray.Reset();
       
   877 	}
       
   878 
       
   879 CKernListBoxModel::~CKernListBoxModel()
       
   880 	{
       
   881 	CloseAllThreadHandles();
       
   882 	delete iUnd;
       
   883 #ifdef FSHELL_WSERV_SUPPORT
       
   884 	if (iWsSession)
       
   885 		{
       
   886 		iWsSession->Close();
       
   887 		delete iWsSession;
       
   888 		}
       
   889 #endif
       
   890 	iTempBuf1.Close();
       
   891 	iTempBuf2.Close();
       
   892 
       
   893 	for (TInt i = iItemData.Count()-1; i >= 0; i--)
       
   894 		{
       
   895 		iItemData[i]->Close();
       
   896 		}
       
   897 	iItemData.Close();
       
   898 	}
       
   899 
       
   900 CUndertaker::CUndertaker(CKernListBoxModel& aModel)
       
   901 	: CActive(EPriorityStandard), iModel(aModel)
       
   902 	{
       
   903 	CActiveScheduler::Add(this);
       
   904 	}
       
   905 
       
   906 CUndertaker::~CUndertaker()
       
   907 	{
       
   908 	Cancel();
       
   909 	iUnd.Close();
       
   910 	}
       
   911 
       
   912 void CUndertaker::Register()
       
   913 	{
       
   914 	TInt err = KErrNone;
       
   915 	if (!iUnd.Handle())
       
   916 		{
       
   917 		err = iUnd.Create();
       
   918 		}
       
   919 	if (!err)
       
   920 		{
       
   921 		iUnd.Logon(iStatus, iHandle);
       
   922 		SetActive();
       
   923 		}
       
   924 	}
       
   925 
       
   926 void CUndertaker::RunL()
       
   927 	{
       
   928 	if (iStatus == KErrDied)
       
   929 		{
       
   930 		iModel.ThreadDiedL(iHandle);
       
   931 		Register();
       
   932 		}
       
   933 	}
       
   934 
       
   935 void CUndertaker::DoCancel()
       
   936 	{
       
   937 	iUnd.LogonCancel();
       
   938 	}
       
   939 
       
   940 void CKernListBoxModel::RefreshDataL(TInt aIndex)
       
   941 	{
       
   942 	if (iCurrentList == EListWindowGroups && !iWsSession)
       
   943 		{
       
   944 		User::Leave(KErrNotSupported);
       
   945 		}
       
   946 
       
   947 	// Change some names so the code is the same
       
   948 	RMemoryAccess& mem(iMemAccess);
       
   949 	CKernListBoxModel& model(*this);
       
   950 
       
   951 	if (iCurrentList == EListCodeSeg)
       
   952 		{
       
   953 		// Code segs don't support random access
       
   954 		aIndex = -1;
       
   955 		}
       
   956 
       
   957 	if (aIndex == -1)
       
   958 		{
       
   959 		model.RemoveAllDataL();
       
   960 		}
       
   961 	model.ModelBeginUpdateLC();
       
   962 	
       
   963 	TObjectType type = EProcess; // Just set it to something to shut up compiler
       
   964 	switch (iCurrentList) {
       
   965 	case EListProcess: type = EProcess; break;
       
   966 	case EListThread: type = EThread; break;
       
   967 	case EListChunk: type = EChunk; break;
       
   968 	case EListServer: type = EServer; break;
       
   969 	case EListMessageQueue: type = EMsgQueue; break;
       
   970 	case EListMutex: type = EMutex; break;
       
   971 	case EListSemaphore: type = ESemaphore; break;
       
   972 	case EListTimer: type = ETimer; break;
       
   973 	default: break;
       
   974 		}
       
   975 
       
   976 	TPtr8 buf(0,0);
       
   977 	TObjectKernelInfo* info = NULL;
       
   978 	CKernListBoxData* data = NULL;
       
   979 	if (aIndex != -1)
       
   980 		{
       
   981 		data = static_cast<CKernListBoxData*>(model.RetrieveDataL(aIndex));
       
   982 		CleanupClosePushL(*data);
       
   983 		}
       
   984 
       
   985 	if (iCurrentList == EListCodeSeg)
       
   986 		{
       
   987 		mem.AcquireCodeSegMutex();
       
   988 		TTomsciCodeSegKernelInfo* inf = new(ELeave) TTomsciCodeSegKernelInfo;
       
   989 		info = reinterpret_cast<TObjectKernelInfo*>(inf); // These aren't actually related classes, just convenient
       
   990 		buf.Set(TPckg<TTomsciCodeSegKernelInfo>(*inf));
       
   991 		while (mem.GetNextCodeSegInfo(buf) == KErrNone)
       
   992 			{
       
   993 			TRAPD(err, model.NewKernDataL(iCurrentList, info));
       
   994 			if (err)
       
   995 				{
       
   996 				break;
       
   997 				}
       
   998 			inf = NULL;
       
   999 			inf = new(ELeave) TTomsciCodeSegKernelInfo;
       
  1000 			buf.Set(TPckg<TTomsciCodeSegKernelInfo>(*inf));
       
  1001 			info = reinterpret_cast<TObjectKernelInfo*>(inf); // These aren't actually related classes, just convenient
       
  1002 			}
       
  1003 		delete inf;
       
  1004 		mem.ReleaseCodeSegMutex();
       
  1005 		}
       
  1006 	else if (iCurrentList == EListHal)
       
  1007 		{
       
  1008 		// HAL isn't actually a kernel container type but from the PoV of this app it is treated similarly
       
  1009 		//HAL::SEntry* entry = new(ELeave) HAL::SEntry;
       
  1010 		if (aIndex == -1)
       
  1011 			{
       
  1012 			HAL::SEntry* ents = NULL;
       
  1013 			TInt numEntries = 0;
       
  1014 			User::LeaveIfError(HAL::GetAll(numEntries, ents));
       
  1015 			CleanupDeletePushL(ents);
       
  1016 			for (TInt i = 0; i < numEntries; i++)
       
  1017 				{
       
  1018 				SHalInfo* entry = new(ELeave) SHalInfo;
       
  1019 				entry->iProperties = ents[i].iProperties;
       
  1020 				entry->iValue = ents[i].iValue;
       
  1021 				entry->iAttribute = i;
       
  1022 				CleanupDeletePushL(entry);
       
  1023 				model.NewKernDataL(iCurrentList, reinterpret_cast<TObjectKernelInfo*>(entry));
       
  1024 				CleanupStack::Pop(entry);
       
  1025 				}
       
  1026 			CleanupStack::PopAndDestroy(ents);
       
  1027 			}
       
  1028 		else
       
  1029 			{
       
  1030 			SHalInfo* entry = reinterpret_cast<SHalInfo*>(data->iInfo);
       
  1031 			/*TInt err =*/ HAL::Get((HAL::TAttribute)entry->iAttribute, entry->iValue); // Nothing needs to be done if this fails
       
  1032 			}
       
  1033 		}
       
  1034 	else if (iCurrentList == EListWindowGroups)
       
  1035 		{
       
  1036 #if defined(FSHELL_WSERV_SUPPORT) && defined(FSHELL_APPARC_SUPPORT)
       
  1037 		if (aIndex == -1)
       
  1038 			{
       
  1039 			CArrayFixFlat<TInt>* wgIds = new(ELeave) CArrayFixFlat<TInt>(16);
       
  1040 			CleanupStack::PushL(wgIds);
       
  1041 			User::LeaveIfError(iWsSession->WindowGroupList(0, wgIds));
       
  1042 			TInt numEntries = wgIds->Count();
       
  1043 			for (TInt i = 0; i < numEntries; i++)
       
  1044 				{
       
  1045 				TInt handle = (*wgIds)[i];
       
  1046 				CApaWindowGroupName* name = CApaWindowGroupName::NewLC(*iWsSession, handle);
       
  1047 				SWgInfo* info = new(ELeave) SWgInfo;
       
  1048 				CleanupStack::PushL(info);
       
  1049 				info->iHandle = handle;
       
  1050 				info->iName = name;
       
  1051 				info->iSession = iWsSession;
       
  1052 				model.NewKernDataL(iCurrentList, reinterpret_cast<TObjectKernelInfo*>(info));
       
  1053 				CleanupStack::Pop(2, name); // info, name
       
  1054 				}
       
  1055 			CleanupStack::PopAndDestroy(wgIds);
       
  1056 			}
       
  1057 		else
       
  1058 			{
       
  1059 			SWgInfo* info = reinterpret_cast<SWgInfo*>(data->iInfo);
       
  1060 			info->iName->ConstructFromWgIdL(info->iHandle);
       
  1061 			}
       
  1062 #endif
       
  1063 		}
       
  1064 	else if (iCurrentList == EListMimeTypes)
       
  1065 		{
       
  1066 		if (aIndex == -1)
       
  1067 			{
       
  1068 #ifdef FSHELL_APPARC_SUPPORT
       
  1069 			RApaLsSession apparc;
       
  1070 			User::LeaveIfError(apparc.Connect());
       
  1071 			CleanupClosePushL(apparc);
       
  1072 			RImplInfoPtrArray array;
       
  1073 			CleanupResetAndDestroyPushL(array);
       
  1074 			REComSession::ListImplementationsL(TUid::Uid(0x101F7D87), array); // Recognisers ECOM interface UID
       
  1075 			TFileName* dllNamePtr = new(ELeave)TFileName;
       
  1076 			CleanupStack::PushL(dllNamePtr);
       
  1077 			TFileName& dllName = *dllNamePtr;
       
  1078 			RArray<TDataType> mimeTypes;
       
  1079 			CleanupClosePushL(mimeTypes);
       
  1080 			gPlugin->DisablePanicCheckPushL();
       
  1081 			for (TInt i = 0; i < array.Count(); i++)
       
  1082 				{
       
  1083 				dllName = _L("UnknownDll");
       
  1084 				
       
  1085 				TRAP_IGNORE(Sandbox::GetDllNameFromEcomUidL(mem, array[i]->ImplementationUid(), dllName));
       
  1086 				mimeTypes.Reset();
       
  1087 				Sandbox::GetRecogniserInfoL(array[i]->ImplementationUid(), mimeTypes);
       
  1088 
       
  1089 				TInt count = mimeTypes.Count();
       
  1090 				for (TInt j = 0; j < count; j++)
       
  1091 					{
       
  1092 					SDataType* info = new(ELeave) SDataType;
       
  1093 					CleanupStack::PushL(info);
       
  1094 					info->iMime.Copy(mimeTypes[j].Des8());
       
  1095 					info->iRecog = dllName;
       
  1096 					
       
  1097 					TInt err = apparc.AppForDataType(mimeTypes[j], info->iAppUid);
       
  1098 					if (!err)
       
  1099 						{
       
  1100 						TApaAppInfo appInfo;
       
  1101 						err = apparc.GetAppInfo(appInfo, info->iAppUid);
       
  1102 						if (!err)
       
  1103 							{
       
  1104 							info->iApp = appInfo.iFullName;
       
  1105 							}
       
  1106 						}
       
  1107 					model.NewKernDataL(iCurrentList, reinterpret_cast<TObjectKernelInfo*>(info));
       
  1108 					CleanupStack::Pop(info);
       
  1109 					}
       
  1110 				}
       
  1111 			CleanupStack::PopAndDestroy(); // reenables panic checks
       
  1112 			CleanupStack::PopAndDestroy(4, &apparc); // mimeTypes, dllNamePtr, array, apparc
       
  1113 #else
       
  1114 			User::Leave(KErrNotSupported);
       
  1115 #endif
       
  1116 			}
       
  1117 		else
       
  1118 			{
       
  1119 			// No refreshing necessary for mime types
       
  1120 			}
       
  1121 		}
       
  1122 	else if (iCurrentList == EListOpenFiles)
       
  1123 		{
       
  1124 		if (aIndex == -1)
       
  1125 			{
       
  1126 			RPtrHashMap<TDesC, SOpenFile> fileMap;
       
  1127 			CleanupClosePushL(fileMap);
       
  1128 			RFs fs;
       
  1129 			User::LeaveIfError(fs.Connect());
       
  1130 			CleanupClosePushL(fs);
       
  1131 			TOpenFileScan scan(fs);
       
  1132 			CFileList* fileList = NULL;
       
  1133 			FOREVER
       
  1134 				{
       
  1135 				scan.NextL(fileList);
       
  1136 				if (fileList == NULL)
       
  1137 					{
       
  1138 					break;
       
  1139 					}
       
  1140 				CleanupStack::PushL(fileList);
       
  1141 				const TInt numOpenFiles = fileList->Count();
       
  1142 				for (TInt i = 0; i < numOpenFiles; i++)
       
  1143 					{
       
  1144 					const TEntry& entry = (*fileList)[i];
       
  1145 					// See if we already have an SOpenFile for this filename
       
  1146 					SOpenFile* info = fileMap.Find(entry.iName);
       
  1147 					if (info)
       
  1148 						{
       
  1149 						if (info->iNumThreads < info->iThreadIds.Count())
       
  1150 							{
       
  1151 							info->iThreadIds[info->iNumThreads] = scan.ThreadId();
       
  1152 							}
       
  1153 						info->iNumThreads++; // Increment iNumThreads regardless - so we can see how many threads there actually are, rather than how many we can store
       
  1154 						CKernListBoxData* data = static_cast<CKernListBoxData*>(model.RetrieveDataLC(model.ItemIdIndex((TInt)info)));
       
  1155 						data->FormatL(reinterpret_cast<TObjectKernelInfo*>(info), iTempBuf1, iTempBuf2); // now we've updated the number of threads, that will have changed the Format view
       
  1156 						CleanupStack::PopAndDestroy(data);
       
  1157 						}
       
  1158 					else
       
  1159 						{
       
  1160 						SOpenFile* info = new(ELeave) SOpenFile;
       
  1161 						CleanupStack::PushL(info);
       
  1162 						info->iName = entry.iName;
       
  1163 						info->iNumThreads = 1;
       
  1164 						info->iThreadIds[0] = scan.ThreadId();
       
  1165 						model.NewKernDataL(iCurrentList, reinterpret_cast<TObjectKernelInfo*>(info));
       
  1166 						CleanupStack::Pop(info);
       
  1167 						fileMap.InsertL(&info->iName, info);
       
  1168 						}
       
  1169 					}
       
  1170 				CleanupStack::PopAndDestroy(fileList);
       
  1171 				fileList = NULL;
       
  1172 				}
       
  1173 			CleanupStack::PopAndDestroy(2, &fileMap); // fileMap, fs
       
  1174 			}
       
  1175 		else
       
  1176 			{
       
  1177 			// No refreshing possible for open files
       
  1178 			}
       
  1179 		}
       
  1180 	else if (iCurrentList == EListFeatureReg)
       
  1181 		{
       
  1182 		// Can't link directly against featreg.dll because it doesn't exist on generic 9.1
       
  1183 		RLibrary featLib;
       
  1184 		TInt err = featLib.Load(_L("featreg.dll"));
       
  1185 		if (err) return; // No feature registry, no features!
       
  1186 
       
  1187 		#ifdef __WINS__
       
  1188 			#define KQueryOrdinal 9
       
  1189 		#else
       
  1190 			#define KQueryOrdinal 4
       
  1191 		#endif
       
  1192 
       
  1193 		typedef TInt (*QueryFn)(TUid, TUint32&);
       
  1194 		QueryFn Query = (QueryFn)featLib.Lookup(KQueryOrdinal);
       
  1195 
       
  1196 		if (aIndex == -1)
       
  1197 			{
       
  1198 			RArray<TUid> features;
       
  1199 			CleanupClosePushL(features);
       
  1200 			gPlugin->GetFeatureUidsL(features);
       
  1201 
       
  1202 			for (TInt i = 0; i < features.Count(); i++)
       
  1203 				{
       
  1204 				SFeature* info = new(ELeave) SFeature;
       
  1205 				CleanupStack::PushL(info);
       
  1206 				info->iFeature = features[i].iUid;
       
  1207 				info->iErr = Query(features[i], info->iInfo);
       
  1208 				model.NewKernDataL(iCurrentList, reinterpret_cast<TObjectKernelInfo*>(info));
       
  1209 				CleanupStack::Pop(info);
       
  1210 				}
       
  1211 			CleanupStack::PopAndDestroy(&features);
       
  1212 			}
       
  1213 		else
       
  1214 			{
       
  1215 			SFeature* info = reinterpret_cast<SFeature*>(data->iInfo);
       
  1216 			info->iErr = Query(TUid::Uid(info->iFeature), info->iInfo);
       
  1217 			}
       
  1218 		featLib.Close();
       
  1219 		}
       
  1220 	else
       
  1221 		{
       
  1222 		// Generic code that works for all first-class Kernel objects (ie processes, threads, chunks. Despite appearances, code segs are not first-class kernel objects).
       
  1223 
       
  1224 		TInt sizeofObjectBuf = 0;
       
  1225 		switch(iCurrentList)
       
  1226 			{
       
  1227 			case EListProcess:
       
  1228 				sizeofObjectBuf = sizeof(TProcessKernelInfo); break;
       
  1229 			case EListThread:
       
  1230 				sizeofObjectBuf = sizeof(TThreadKernelInfo); break;
       
  1231 			case EListChunk:
       
  1232 				sizeofObjectBuf = sizeof(TChunkKernelInfo); break;
       
  1233 			case EListServer:
       
  1234 				sizeofObjectBuf = sizeof(TServerKernelInfo); break;
       
  1235 			case EListMessageQueue:
       
  1236 				sizeofObjectBuf = sizeof(TMsgQueueKernelInfo); break;
       
  1237 			case EListMutex:
       
  1238 				sizeofObjectBuf = sizeof(TMutexKernelInfo); break;
       
  1239 			case EListSemaphore:
       
  1240 				sizeofObjectBuf = sizeof(TSemaphoreKernelInfo); break;
       
  1241 			case EListTimer:
       
  1242 				sizeofObjectBuf = sizeof(TTimerKernelInfo); break;
       
  1243 			default:
       
  1244 				User::Panic(_L("QR3 Missing type"), iCurrentList);
       
  1245 			}
       
  1246 
       
  1247 		if (aIndex == -1)
       
  1248 			{
       
  1249 			// Be paranoid about releasing the mutexes, to avoid the risk of deadlocking. Only likely if we were looking through the chunk container AND needed to grow our chunk in NewKernDataL, but err on the side of caution
       
  1250 			//mem.AcquireContainerMutex(type);
       
  1251 			TUint count;
       
  1252 			mem.GetContainerCount(type, count);
       
  1253 			//mem.ReleaseContainerMutex(type);
       
  1254 			for (TUint i = 0; i < count; i++)
       
  1255 				{
       
  1256 				info = (TObjectKernelInfo*)User::AllocZL(sizeofObjectBuf);
       
  1257 				buf.Set((TUint8*)info, sizeofObjectBuf, sizeofObjectBuf);
       
  1258 
       
  1259 				CleanupStack::PushL(info);
       
  1260 				// Don't need to grab the lock any more
       
  1261 				//mem.AcquireContainerMutex(type);
       
  1262 				TInt err = mem.GetObjectInfo(type, i, buf);
       
  1263 				//mem.ReleaseContainerMutex(type);
       
  1264 				if (err == KErrNone)
       
  1265 					{
       
  1266 					model.NewKernDataL(iCurrentList, info);
       
  1267 					CleanupStack::Pop(info);
       
  1268 					}
       
  1269 				else
       
  1270 					{
       
  1271 					CleanupStack::PopAndDestroy(info);
       
  1272 					}
       
  1273 				}
       
  1274 			}
       
  1275 		else
       
  1276 			{
       
  1277 			buf.Set((TUint8*)data->iInfo, sizeofObjectBuf, sizeofObjectBuf);
       
  1278 			mem.GetObjectInfo(type, data->iInfo->iAddressOfKernelObject, buf); // Nothing required on error
       
  1279 			}
       
  1280 		}
       
  1281 	
       
  1282 	if (aIndex != -1)
       
  1283 		{
       
  1284 		data->FormatL(data->iInfo, iTempBuf1, iTempBuf2);
       
  1285 		model.DataUpdatedL(aIndex);
       
  1286 		CleanupStack::PopAndDestroy(data);
       
  1287 		}
       
  1288 	model.Sort(); // We can't do this in NewKernDataL because the things we sort on aren't setup until FormatL
       
  1289 	model.ModelEndUpdateL();
       
  1290 
       
  1291 	if (iInfoChangedCallback.iFunction != NULL && (aIndex == -1 || data == iCallbackData))
       
  1292 		{
       
  1293 		iInfoChangedCallback.CallBack();
       
  1294 		}
       
  1295 	}
       
  1296 
       
  1297 void CKernListBoxModel::Sort(TLinearOrder<CKernListBoxData> aOrder)
       
  1298 	{
       
  1299 	iSort = aOrder;
       
  1300 	Sort();
       
  1301 	}
       
  1302 
       
  1303 void CKernListBoxModel::Sort()
       
  1304 	{
       
  1305 	if (iSort)
       
  1306 		{
       
  1307 		User::QuickSort(Count(), *this, *this);
       
  1308 		}
       
  1309 	}
       
  1310 
       
  1311 void CKernListBoxModel::SetInfoChangedCallback(TInt aIndex, const TCallBack& aCallback)
       
  1312 	{
       
  1313 	iInfoChangedCallback = aCallback;
       
  1314 	if (aCallback.iFunction)
       
  1315 		{
       
  1316 		iCallbackData = iItemData[aIndex];
       
  1317 		iCallbackData->Open();
       
  1318 		}
       
  1319 	else
       
  1320 		{
       
  1321 		iCallbackData->Close();
       
  1322 		iCallbackData = NULL;
       
  1323 		}
       
  1324 	}
       
  1325 
       
  1326 void CKernListBoxData::Open()
       
  1327 	{
       
  1328 	iRefCount++;
       
  1329 	}
       
  1330 
       
  1331 void CKernListBoxData::Close()
       
  1332 	{
       
  1333 	iRefCount--;
       
  1334 	if (iRefCount == 0)
       
  1335 		delete this;
       
  1336 	}
       
  1337 
       
  1338 void CKernListBoxData::SetDelegate(MKernListBoxDataDelegate* aDelegate)
       
  1339 	{
       
  1340 	iDelegate = aDelegate;
       
  1341 	}
       
  1342 
       
  1343 MKernListBoxDataDelegate* CKernListBoxData::Delegate()
       
  1344 	{
       
  1345 	return iDelegate;
       
  1346 	}
       
  1347 
       
  1348 const MKernListBoxDataDelegate* CKernListBoxData::Delegate() const
       
  1349 	{
       
  1350 	return iDelegate;
       
  1351 	}
       
  1352 
       
  1353 TInt CKernListBoxData::ItemId() const
       
  1354 	{
       
  1355 	return iItemId;
       
  1356 	}
       
  1357 
       
  1358 void CKernListBoxData::SetItemId(TInt aItemId)
       
  1359 	{
       
  1360 	iItemId = aItemId;
       
  1361 	}
       
  1362 
       
  1363 void CKernListBoxData::ConstructL()
       
  1364 	{
       
  1365 	}
       
  1366 
       
  1367 CKernListBoxModel& CKernListBoxData::Model()
       
  1368 	{
       
  1369 	return *iModel;
       
  1370 	}