/*
* Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
* sisregistry - client registry entry interface implementation
*
*/
/**
@file
@publishedPartner
@released
*/
#include<s32mem.h>
#include <hash.h>
#include <swi/sistruststatus.h>
#include <x509cert.h>
#include "sisregistrydependency.h"
#include "sisregistryentry.h"
#include "sisregistrysession.h"
#include "sisregistryclientserver.h"
#include "sisregistrypackage.h"
#include "sisregistryobject.h"
#include "hashcontainer.h"
#include "arrayutils.h"
#include "cleanuputils.h"
using namespace Swi;
const TInt KMinBufferSize = 20;
EXPORT_C TInt RSisRegistryEntry::Open(RSisRegistrySession& aSession, TUid aUid)
{
TPckgC<TUid> uid(aUid);
return CreateSubSession(aSession, EOpenRegistryUid, TIpcArgs(&uid));
}
EXPORT_C TInt RSisRegistryEntry::OpenL(RSisRegistrySession& aSession,
const CSisRegistryPackage& aPackage)
{
// dynamic buffer since we don't know in advance the size required
CBufFlat* tempBuffer = CBufFlat::NewL(KDefaultBufferSize);
CleanupStack::PushL(tempBuffer);
RBufWriteStream stream(*tempBuffer);
CleanupClosePushL(stream);
aPackage.ExternalizeL(stream);
stream.CommitL();
// Now, create an HBufC8 from the stream buf's length, and copy
// the stream buffer into this descriptor
HBufC8* buffer = HBufC8::NewLC(tempBuffer->Size());
TPtr8 ptr(buffer->Des());
tempBuffer->Read(0, ptr, tempBuffer->Size());
TInt err = CreateSubSession(aSession, EOpenRegistryPackage, TIpcArgs(&ptr));
User::LeaveIfError(err);
CleanupStack::PopAndDestroy(3, tempBuffer); // tempBuffer, stream, buffer
return err;
}
EXPORT_C TInt RSisRegistryEntry::Open(RSisRegistrySession &aSession, const TDesC& aPackageName, const TDesC& aVendorName)
{
return CreateSubSession(aSession, EOpenRegistryNames, TIpcArgs(&aPackageName, &aVendorName));
}
EXPORT_C void RSisRegistryEntry::Close()
{
CloseSubSession(ECloseRegistryEntry);
}
EXPORT_C TBool RSisRegistryEntry::IsPresentL()
{
TBool isPresent = EFalse ;
TPckg<TBool> isPresentPkg(isPresent);
User::LeaveIfError(SendReceive(EUidPresent, TIpcArgs(&isPresentPkg)));
return isPresent;
}
EXPORT_C TBool RSisRegistryEntry::IsSignedL()
{
TBool isSigned = EFalse;
TPckg<TBool> isSignedPkg(isSigned);
User::LeaveIfError(SendReceive(ESigned, TIpcArgs(&isSignedPkg)));
return isSigned;
}
EXPORT_C TSisPackageTrust RSisRegistryEntry::TrustL() const
{
TSisPackageTrust trust;
TPckg<TSisPackageTrust> trustPkg(trust);
User::LeaveIfError(SendReceive(EGetTrust, TIpcArgs(&trustPkg)));
return trust;
}
EXPORT_C TTime RSisRegistryEntry::TrustTimeStampL() const
{
TTime trustTimeStamp;
TPckg<TTime> timePkg(trustTimeStamp);
User::LeaveIfError(SendReceive(ETrustTimeStamp, TIpcArgs(&timePkg)));
return trustTimeStamp;
}
EXPORT_C TSisTrustStatus RSisRegistryEntry::TrustStatusL()
{
HBufC8* buffer = SendReceiveBufferLC((TInt)ETrustStatus);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble from the stream
TSisTrustStatus trustStatus;
trustStatus.InternalizeL(stream);
CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
return trustStatus;
}
EXPORT_C TBool RSisRegistryEntry::IsInRomL()
{
TBool isInRom = EFalse;
TPckg<TBool> isInRomPkg(isInRom);
User::LeaveIfError(SendReceive(EInRom, TIpcArgs(&isInRomPkg)));
return isInRom;
}
EXPORT_C TBool RSisRegistryEntry::IsAugmentationL()
{
TBool isAugmentation = EFalse;
TPckg<TBool> isAugmentationPkg(isAugmentation);
User::LeaveIfError(SendReceive(EAugmentation, TIpcArgs(&isAugmentationPkg)));
return isAugmentation;
}
EXPORT_C TVersion RSisRegistryEntry::VersionL()
{
TVersion version;
TPckg<TVersion> packageVersion(version);
User::LeaveIfError(SendReceive(EVersion, TIpcArgs(&packageVersion)));
return version;
}
EXPORT_C TLanguage RSisRegistryEntry::LanguageL()
{
TLanguage language;
TPckg<TLanguage> packageLanguage(language);
User::LeaveIfError(SendReceive(ELanguage, TIpcArgs(&packageLanguage)));
return language;
}
EXPORT_C TUid RSisRegistryEntry::UidL()
{
TUid uid;
TPckg<TUid> packageUid(uid);
User::LeaveIfError(SendReceive(EUid, TIpcArgs(&packageUid)));
return uid;
}
EXPORT_C HBufC* RSisRegistryEntry::PackageNameL()
{
HBufC* buffer = HBufC::NewLC(KDefaultBufferSize);
TPtr ptr = buffer->Des();
User::LeaveIfError(SendReceive(EPackageName, TIpcArgs(&ptr)));
CleanupStack::Pop(buffer);
return buffer;
}
EXPORT_C HBufC* RSisRegistryEntry::UniqueVendorNameL()
{
HBufC* buffer = HBufC::NewLC(KDefaultBufferSize);
TPtr ptr = buffer->Des();
User::LeaveIfError(SendReceive(EUniqueVendorName, TIpcArgs(&ptr)));
CleanupStack::Pop(buffer);
return buffer;
}
EXPORT_C HBufC* RSisRegistryEntry::LocalizedVendorNameL()
{
HBufC* buffer = HBufC::NewLC(KDefaultBufferSize);
TPtr ptr=buffer->Des();
User::LeaveIfError(SendReceive(ELocalizedVendorName, TIpcArgs(&ptr)));
CleanupStack::Pop(buffer);
return buffer;
}
EXPORT_C void RSisRegistryEntry::SidsL(RArray<TUid>& aSids)
{
HBufC8* buffer = SendReceiveBufferLC(ESids);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizeArrayL(aSids, stream);
CleanupStack::PopAndDestroy(2, buffer);// buffer, stream
}
EXPORT_C void RSisRegistryEntry::FilesL(RPointerArray<HBufC>& aFiles)
{
TInt startingFile = 0;
TPckgBuf<TInt> filesCount;
TStubExtractionMode operationMode = EGetCount;
#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
TPckgC<TInt> pckgStartingFile(startingFile);
#endif
// Get the total file count.
TPckgC<TStubExtractionMode> packageMode(operationMode);
TInt result = SendReceive(EFiles, TIpcArgs(&packageMode, &filesCount));
User::LeaveIfError(result);
TInt totalFilesCount = filesCount();
operationMode = EGetFiles;
HBufC8* buffer = HBufC8::NewLC(KDefaultBufferSize);
TPtr8 pOutput(buffer->Des());
while (startingFile < totalFilesCount)
{
// Fetch the files.
#ifdef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
User::LeaveIfError(SendReceive(EFiles, TIpcArgs(&packageMode, &pOutput)));
#else
User::LeaveIfError(SendReceive(EFiles, TIpcArgs(&packageMode, &pckgStartingFile, &pOutput)));
#endif
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aFiles, stream);
CleanupStack::PopAndDestroy(&stream); //stream
startingFile = aFiles.Count();
}
CleanupStack::PopAndDestroy(buffer);
}
EXPORT_C void RSisRegistryEntry::CertificateChainsL(RPointerArray<HBufC8>& aCertificateChains)
{
HBufC8* buffer = SendReceiveBufferLC(ECertificateChains);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aCertificateChains, stream);
CleanupStack::PopAndDestroy(2, buffer);// buffer, stream
}
EXPORT_C CHashContainer* RSisRegistryEntry::HashL(const TDesC& aFileName)
{
HBufC8* buffer = SendReceiveBufferLC(EHashEntry, aFileName);
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the hash from the stream
CHashContainer* hash = CHashContainer::NewLC(stream);
CleanupStack::Pop(hash);
CleanupStack::PopAndDestroy(2, buffer);// buffer, stream
return hash;
}
EXPORT_C TInt RSisRegistryEntry::PropertyL(TInt aKey)
{
TInt value;
TPckg<TInt> propertyValuePckg(value);
User::LeaveIfError(SendReceive(EProperty, TIpcArgs(aKey, &propertyValuePckg)));
return value;
}
EXPORT_C void RSisRegistryEntry::AugmentationsL(RPointerArray<HBufC>& aPackageNames, RPointerArray<HBufC>& aVendorNames)
{
CleanupResetAndDestroyPushL(aPackageNames);
CleanupResetAndDestroyPushL(aVendorNames);
HBufC8* buffer = RSisRegistryEntry::SendReceiveBufferLC(EPackageAugmentations);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
RPointerArray<CSisRegistryPackage> packages;
CleanupResetAndDestroy<RPointerArray<CSisRegistryPackage> >::PushL(packages);
InternalizePointerArrayL(packages, stream);
aPackageNames.ResetAndDestroy();
aVendorNames.ResetAndDestroy();
for (TInt i = 0; i < packages.Count(); i++)
{
HBufC* package = packages[i]->Name().AllocLC();
HBufC* vendor = packages[i]->Vendor().AllocLC();
aPackageNames.AppendL(package);
aVendorNames.AppendL(vendor);
CleanupStack::Pop(2, vendor); //vendor package,
}
CleanupStack::PopAndDestroy(3, buffer);// buffer, stream, packages
CleanupStack::Pop(2, &aPackageNames);
}
EXPORT_C void RSisRegistryEntry::AugmentationsL(RPointerArray<CSisRegistryPackage>& aPackages)
{
HBufC8* buffer = RSisRegistryEntry::SendReceiveBufferLC(EPackageAugmentations);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aPackages, stream);
CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
}
EXPORT_C TInt RSisRegistryEntry::AugmentationsNumberL()
{
TInt numAugmentation = 0;
TPckg<TInt> numAugmentationPkg(numAugmentation);
User::LeaveIfError(SendReceive(EPackageAugmentationsNumber, TIpcArgs(&numAugmentationPkg)));
return numAugmentation;
}
EXPORT_C CSisRegistryPackage* RSisRegistryEntry::PackageL()
{
HBufC8* buffer = SendReceiveBufferLC(EPackage);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// Create the package from the stream
CSisRegistryPackage* package = CSisRegistryPackage::NewLC(stream);
CleanupStack::Pop(package);
CleanupStack::PopAndDestroy(2, buffer);// buffer, stream
return package;
}
EXPORT_C TInt64 RSisRegistryEntry::SizeL()
{
TInt64 size = 0;
TPckg<TInt64> packageSize(size);
User::LeaveIfError(SendReceive(ESize, TIpcArgs(&packageSize)));
return size;
}
EXPORT_C void RSisRegistryEntry::ControllersL(RPointerArray<HBufC8>& aControllers)
{
CleanupResetAndDestroyPushL(aControllers);
HBufC8* buffer = SendReceiveBufferLC(EControllers);
// this call returns pure data, so we don't incur the overheads of the streamstore
TInt len(0);
TPckg<TInt> lenPckg(len);
TInt pos(0);
TInt lenLen = lenPckg.Length();
TInt bufLen = buffer->Length();
while (pos != bufLen)
{
lenPckg.Copy(buffer->Mid(pos, lenLen));
pos += lenLen;
HBufC8* controller = buffer->Mid(pos, len).AllocLC();
aControllers.AppendL(controller);
CleanupStack::Pop(controller);
pos += len;
}
CleanupStack::PopAndDestroy(buffer);
CleanupStack::Pop(&aControllers);
}
EXPORT_C TChar RSisRegistryEntry::SelectedDriveL()
{
TInt drive;
TPckg<TInt> selectedDrive(drive);
User::LeaveIfError(SendReceive(ESelectedDrive, TIpcArgs(&selectedDrive)));
return drive;
}
EXPORT_C TUint RSisRegistryEntry::InstalledDrivesL()
{
TUint drive;
TPckg<TUint> installeddrives(drive);
User::LeaveIfError(SendReceive(EInstalledDrives, TIpcArgs(&installeddrives)));
return drive;
}
EXPORT_C TBool RSisRegistryEntry::ShutdownAllAppsL()
{
TBool shutdownAllApps = EFalse;
TPckg<TBool> packageShutdownAllApps(shutdownAllApps);
User::LeaveIfError(SendReceive(EShutdownAllApps, TIpcArgs(&packageShutdownAllApps)));
return shutdownAllApps;
}
EXPORT_C TBool RSisRegistryEntry::VerifyControllerSignatureL(RPointerArray<CX509Certificate>& aX509CertArray)
{
return VerifyControllerSignatureL(aX509CertArray, ETrue);
}
EXPORT_C TBool RSisRegistryEntry::VerifyControllerSignatureL(RPointerArray<CX509Certificate>& aX509CertArray, TBool aCheckDateAndTime)
{
TInt count = aX509CertArray.Count();
TInt bufferSize = Max(count * KDefaultBufferSize / 2, KMinBufferSize);
CBufFlat* tempBuffer = CBufFlat::NewL(bufferSize);
CleanupStack::PushL(tempBuffer);
RBufWriteStream stream(*tempBuffer);
CleanupClosePushL(stream);
// Externalise the pointer array
ExternalizePointerArrayL(aX509CertArray, stream);
stream.CommitL();
// Create an HBufC8 from the stream buf's length, and copy
// the stream buffer into this descriptor
bufferSize = tempBuffer->Size();
HBufC8* buffer = HBufC8::NewLC(bufferSize);
TPtr8 pbuffer(buffer->Des());
tempBuffer->Read(0, pbuffer, bufferSize);
TBool isVerified = EFalse;
TPckg<TBool> packagedResult(isVerified);
TPckgC<TBool> packagedDateCheck(aCheckDateAndTime);
User::LeaveIfError(SendReceive(EVerifyController, TIpcArgs(&packagedResult, &pbuffer, &packagedDateCheck)));
CleanupStack::PopAndDestroy(3, tempBuffer); // tempBuffer, stream, buffer
return isVerified;
}
EXPORT_C TInt RSisRegistryEntry::RemoveWithLastDependentL()
{
TInt isRemoveWithLastDependent = 0;
TPckg<TInt> isRemoveWithLastDependentPkg(isRemoveWithLastDependent);
User::LeaveIfError(SendReceive(ERemoveWithLastDependent, TIpcArgs(&isRemoveWithLastDependentPkg)));
return isRemoveWithLastDependent;
}
EXPORT_C void RSisRegistryEntry::SetRemoveWithLastDependentL(TUid uid)
{
TPckg<TUid> uidPkg(uid);
User::LeaveIfError(SendReceive(ESetRemoveWithLastDependent, TIpcArgs(&uidPkg)));
}
EXPORT_C TBool RSisRegistryEntry::RemovableL()
{
TBool isRemovable = ETrue;
TPckg<TBool> packageIsRemovable(isRemovable);
User::LeaveIfError(SendReceive(ENonRemovable, TIpcArgs(&packageIsRemovable)));
return isRemovable;
}
HBufC8* RSisRegistryEntry::SendReceiveBufferLC(TInt aMessage)
{
HBufC8* output = HBufC8::NewLC(KDefaultBufferSize);
TPtr8 pOutput(output->Des());
TInt result=SendReceive(aMessage, TIpcArgs(&pOutput));
if (result == KErrOverflow)
{
TInt sizeNeeded;
TPckg<TInt> sizeNeededPackage(sizeNeeded);
sizeNeededPackage.Copy(*output);
// Re-allocate buffer
CleanupStack::PopAndDestroy(output);
output = HBufC8::NewLC(sizeNeeded);
TPtr8 pResizedOutput(output->Des());
result=SendReceive(aMessage, TIpcArgs(&pResizedOutput));
}
User::LeaveIfError(result);
return output;
}
HBufC8* RSisRegistryEntry::SendReceiveBufferLC(TInt aMessage, const TDesC& aInputDescriptor)
{
HBufC8* output = HBufC8::NewLC(KDefaultBufferSize);
TPtr8 pOutput(output->Des());
TInt result=SendReceive(aMessage, TIpcArgs(&aInputDescriptor, &pOutput));
if (result == KErrOverflow)
{
TInt sizeNeeded;
TPckg<TInt> sizeNeededPackage(sizeNeeded);
sizeNeededPackage.Copy(*output);
// Re-allocate buffer
CleanupStack::PopAndDestroy(output);
output = HBufC8::NewLC(sizeNeeded);
TPtr8 pResizedOutput(output->Des());
result=SendReceive(aMessage, TIpcArgs(&aInputDescriptor, &pResizedOutput));
}
User::LeaveIfError(result);
return output;
}
EXPORT_C TBool RSisRegistryEntry::PreInstalledL()
{
TBool preInstalled = EFalse;
TPckg<TBool> isPreInstalled(preInstalled);
User::LeaveIfError(SendReceive(EPreInstalled, TIpcArgs(&isPreInstalled)));
return preInstalled;
}
EXPORT_C TBool RSisRegistryEntry::IsDeletablePreInstalledL()
{
TBool deletablePreInstalled = EFalse;
TPckg<TBool> deletablePreInstalledPckg(deletablePreInstalled);
User::LeaveIfError(SendReceive(EDeletablePreInstalled, TIpcArgs(&deletablePreInstalledPckg)));
return deletablePreInstalled;
}
EXPORT_C void RSisRegistryEntry::DependentPackagesL(RPointerArray<CSisRegistryPackage>& aPackages)
{
HBufC8* buffer = SendReceiveBufferLC(EDependentPackages);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aPackages, stream);
CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
}
EXPORT_C void RSisRegistryEntry::DependenciesL(RPointerArray<CSisRegistryDependency>& aDependencies)
{
HBufC8* buffer = SendReceiveBufferLC(EDependencies);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aDependencies, stream);
CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
}
EXPORT_C void RSisRegistryEntry::EmbeddedPackagesL(RPointerArray<CSisRegistryPackage>& aPackages)
{
HBufC8* buffer = SendReceiveBufferLC(EEmbeddedPackages);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aPackages, stream);
CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
}
EXPORT_C void RSisRegistryEntry::EmbeddingPackagesL(RPointerArray<CSisRegistryPackage>& aEmbeddingPackages)
{
HBufC8* buffer = SendReceiveBufferLC(EEmbeddingPackages);
// create a stream based on the buffer
RDesReadStream stream(*buffer);
CleanupClosePushL(stream);
// reassemble the array from the stream
InternalizePointerArrayL(aEmbeddingPackages, stream);
CleanupStack::PopAndDestroy(2, buffer); // buffer, stream
}
EXPORT_C TBool RSisRegistryEntry::IsSignedBySuCertL()
{
TBool signedSuCert = EFalse;
TPckg<TBool> signedSuCertPckg(signedSuCert);
User::LeaveIfError(SendReceive(ESignedBySuCert, TIpcArgs(&signedSuCertPckg)));
return signedSuCert;
}
EXPORT_C void RSisRegistryEntry::RegistryFilesL(RPointerArray<HBufC>& aRegistryFiles)
{
#ifndef SYMBIAN_UNIVERSAL_INSTALL_FRAMEWORK
HBufC8* outputBuffer = HBufC8::NewLC(KDefaultBufferSize);
TPtr8 outputPtr(outputBuffer->Des());
TInt result = SendReceive(ERegistryFiles, TIpcArgs(&outputPtr));
if (KErrOverflow == result)
{
TInt lenNeeded;
TPckg<TInt> lenNeededPckg(lenNeeded);
lenNeededPckg.Copy(*outputBuffer);
// Re-allocate output buffer
CleanupStack::PopAndDestroy(outputBuffer);
outputBuffer = HBufC8::NewLC(lenNeeded);
TPtr8 newOutputPtr(outputBuffer->Des());
result = SendReceive(ERegistryFiles, TIpcArgs(&newOutputPtr));
}
User::LeaveIfError(result);
// Reading the list of files from the buffer
RDesReadStream outputStream(*outputBuffer);
CleanupClosePushL(outputStream);
InternalizePointerArrayL(aRegistryFiles, outputStream);
CleanupStack::PopAndDestroy(2, outputBuffer); // outputStream
#else
// There is API is not currently supported with USIF
User::Leave(KErrNotSupported);
aRegistryFiles.Close(); // To remove the compiler warning: variable/argument 'aRegistryFiles' is not used in function
#endif
}