private AppxPackage SelectCorrectMainPackage(List <AppxPackage> mainPackagesFromBundle) { AppxPackage returnPackage = null; foreach (AppxPackage package in mainPackagesFromBundle) { if (package.Manifest.ProcessorArchitecture == APPX_PACKAGE_ARCHITECTURE.APPX_PACKAGE_ARCHITECTURE_NEUTRAL) { returnPackage = package; break; } else if (package.Manifest.ProcessorArchitecture == APPX_PACKAGE_ARCHITECTURE.APPX_PACKAGE_ARCHITECTURE_X64 && Environment.Is64BitOperatingSystem) { returnPackage = package; break; } else if (package.Manifest.ProcessorArchitecture == APPX_PACKAGE_ARCHITECTURE.APPX_PACKAGE_ARCHITECTURE_X86) { returnPackage = package; break; } } return(returnPackage); }
private void Run_Async(object state) { try { IStream packageStream; // this function can be called from the bundle reader below or from external if (internalPackage) { packageStream = stream; } else { packageStream = StreamFactory.CreateFileStream(packagePath, STGM.STGM_READ); } AppxPackage package = GetAppxPackageFromStream(packageStream); if (package.PackageType == AppxPackage.PACKAGE_TYPE.PACKAGE_TYPE_APPX_BUNDLE) { List <AppxPackage> mainPackagesFromBundle = new List <AppxPackage>(); List <AppxPackage> resourcePackagesFrombundle = new List <AppxPackage>(); foreach (AppxPackage containedPackage in (package as AppxBundlePackage).ContainedPackages) { if (containedPackage.PackageType == AppxPackage.PACKAGE_TYPE.PACKAGE_TYPE_APPX_RESOUCE) { resourcePackagesFrombundle.Add(containedPackage); } else if (containedPackage.PackageType == AppxPackage.PACKAGE_TYPE.PACKAGE_TYPE_APPX_PACKAGE) { mainPackagesFromBundle.Add(containedPackage); } } MainPackages.Add(SelectCorrectMainPackage(mainPackagesFromBundle)); ResourcePackages.AddRange(resourcePackagesFrombundle); } else { MainPackages.Add(package); } } catch (System.Runtime.InteropServices.COMException ex) { errorEncountered = true; errorText = "Input package is corrupted. Error: '" + ex.HResult + "'"; } catch (Exception ex) { errorEncountered = true; errorText = "Error encoutered. Error: '" + ex.HResult + "'"; } // set the event mre.Set(); }
public AppxBlockMapFile() { FileName = string.Empty; UncompressedSize = 0; LocalFileHeaderSize = 0; Blocks = new List <AppxBlockMapBlock>(); FinalFileHash = string.Empty; ParentPackage = null; }
public bool IsInFamily(AppxPackage otherPackage) { if (Manifest.Name == otherPackage.Manifest.Name && Manifest.Publisher == otherPackage.Manifest.Publisher) { return(true); } return(false); }
private AppxPackage GetAppxPackageFromStream(IStream stream) { AppxPackage appxPackage; // determine the package type (bundle, resource or main) var packageType = GetAppxPackageTypeFromStream(stream); if (packageType == AppxPackage.PACKAGE_TYPE.PACKAGE_TYPE_APPX_BUNDLE) { appxPackage = new AppxBundlePackage(); (appxPackage as AppxBundlePackage).ContainedPackages = GetContainedPackagesFromBundle(stream); // remember that this package came from a bundle foreach (AppxPackage containedPackage in (appxPackage as AppxBundlePackage).ContainedPackages) { containedPackage.ParentPackage = appxPackage; } appxPackage.Manifest = GetManifestInformationForAppxBundle(stream); } else { if (packageType == AppxPackage.PACKAGE_TYPE.PACKAGE_TYPE_APPX_RESOUCE) { appxPackage = new AppxResourcePackage(); (appxPackage as AppxResourcePackage).ResourceList = GetResourceList(stream); } else if (packageType == AppxPackage.PACKAGE_TYPE.PACKAGE_TYPE_APPX_PACKAGE) { appxPackage = new AppxPackage(); } else { throw new ArgumentOutOfRangeException("Input Package is of unknown type"); } ulong uncompressedSize = 0; appxPackage.BlockMap = GetBlockMapObject(stream, appxPackage, out uncompressedSize); appxPackage.Manifest = GetManifestInformationForAppxPackage(stream); appxPackage.UncompressedSize = uncompressedSize; } return(appxPackage); }
private Dictionary <string, List <AppxBlockMapFile> > GetBlockMapObject(IStream stream, AppxPackage parentPackage, out ulong UncompressedSize) { UncompressedSize = 0; var appxFactory = (IAppxFactory) new AppxFactory(); var appxPackageReader = appxFactory.CreatePackageReader(stream); var appxBlockMapReader = appxPackageReader.GetBlockMap(); var blockMapFilesEnum = appxBlockMapReader.GetFiles(); var blockMapObject = new Dictionary <string, List <AppxBlockMapFile> >(); var blockMapFilesList = new List <AppxBlockMapFile>(); // walk through the entire block map file while (blockMapFilesEnum.GetHasCurrent()) { // get the file node and all containing block nodes var nextBlockMapFile = blockMapFilesEnum.GetCurrent(); var blockMapFile = new AppxBlockMapFile() { FileName = nextBlockMapFile.GetName(), UncompressedSize = nextBlockMapFile.GetUncompressedSize(), LocalFileHeaderSize = nextBlockMapFile.GetLocalFileHeaderSize(), ParentPackage = parentPackage }; UncompressedSize += blockMapFile.UncompressedSize; // retrieve enumerator for blocks var allBlockMapBlocksEnum = nextBlockMapFile.GetBlocks(); // well get the full file hash later for easy comparison var fullFileHashBuffer = new List <byte>(); // get all containing blocks while (allBlockMapBlocksEnum.GetHasCurrent()) { var nextBlock = allBlockMapBlocksEnum.GetCurrent(); UInt32 bufferSize; var hashBuffer = nextBlock.GetHash(out bufferSize); // convert the array from BYTE ** to a byte[] byte[] hashArray = new byte[bufferSize]; Marshal.Copy(hashBuffer, hashArray, 0, (int)bufferSize); Marshal.FreeCoTaskMem(hashBuffer); // add this byte range to our full file hash fullFileHashBuffer.AddRange(hashArray); // the array is base 64 encoded to save memory, decode var hashText = Convert.ToBase64String(hashArray); // capture blockmap data var blockMapBlock = new AppxBlockMapBlock() { Hash = hashText, CompressedSize = nextBlock.GetCompressedSize(), ParentFile = blockMapFile }; // save the block blockMapFile.Blocks.Add(blockMapBlock); allBlockMapBlocksEnum.MoveNext(); Marshal.ReleaseComObject(nextBlock); } Marshal.ReleaseComObject(allBlockMapBlocksEnum); Marshal.ReleaseComObject(nextBlockMapFile); // get file hash blockMapFile.FinalFileHash = Helpers.GetHash(fullFileHashBuffer); // add the finished file if (!blockMapObject.ContainsKey(blockMapFile.FinalFileHash)) { blockMapObject.Add(blockMapFile.FinalFileHash, new List <AppxBlockMapFile>()); } blockMapObject[blockMapFile.FinalFileHash].Add(blockMapFile); // add it to full bag - used for update comparison blockMapFilesList.Add(blockMapFile); blockMapFilesEnum.MoveNext(); } Marshal.ReleaseComObject(blockMapFilesEnum); Marshal.ReleaseComObject(appxBlockMapReader); Marshal.ReleaseComObject(appxPackageReader); Marshal.ReleaseComObject(appxFactory); return(blockMapObject); }