Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }