示例#1
0
        /// <summary>
        /// Ask the kernel which OS is installed, fail if it doesn't match the one in the file.
        /// </summary>
        public async Task <bool> IsSameOperatingSystemAccordingToKernel(FileValidator validator, CancellationToken cancellationToken)
        {
            Response <uint> osidResponse = await this.QueryOperatingSystemIdFromKernel(cancellationToken);

            if (osidResponse.Status != ResponseStatus.Success)
            {
                // The kernel seems broken. This shouldn't happen, but if it does, halt.
                this.logger.AddUserMessage("The kernel did not respond to operating system ID query.");
                return(false);
            }

            if (!validator.IsSameOperatingSystem(osidResponse.Value))
            {
                return(false);
            }

            return(true);
        }
示例#2
0
        /// <summary>
        /// Write changes to the PCM's flash memory.
        /// </summary>
        private async void write_BackgroundThread(WriteType writeType)
        {
            using (new AwayMode())
            {
                try
                {
                    this.currentWriteType = writeType;

                    if (this.Vehicle == null)
                    {
                        // This shouldn't be possible - it would mean the buttons
                        // were enabled when they shouldn't be.
                        return;
                    }

                    this.cancellationTokenSource = new CancellationTokenSource();

                    string path = null;
                    this.Invoke((MethodInvoker) delegate()
                    {
                        this.DisableUserInput();
                        this.cancelButton.Enabled = true;

                        path = this.ShowOpenDialog();
                    });

                    if (path == null)
                    {
                        return;
                    }

                    this.AddUserMessage(path);

                    byte[] image;
                    using (Stream stream = File.OpenRead(path))
                    {
                        image = new byte[stream.Length];
                        int bytesRead = await stream.ReadAsync(image, 0, (int)stream.Length);

                        if (bytesRead != stream.Length)
                        {
                            // If this happens too much, we should try looping rather than reading the whole file in one shot.
                            this.AddUserMessage("Unable to load file.");
                            return;
                        }
                    }

                    // Sanity checks.
                    FileValidator validator = new FileValidator(image, this);
                    if (!validator.IsValid())
                    {
                        this.AddUserMessage("This file is corrupt. It would render your PCM unusable.");
                        return;
                    }

                    UInt32 kernelVersion = 0;
                    bool   needUnlock;
                    int    keyAlgorithm               = 1;
                    UInt32 pcmOperatingSystemId       = 0;
                    bool   needToCheckOperatingSystem = writeType != WriteType.Full;

                    this.AddUserMessage("Requesting operating system ID...");
                    Response <uint> osidResponse = await this.Vehicle.QueryOperatingSystemId(this.cancellationTokenSource.Token);

                    if (osidResponse.Status == ResponseStatus.Success)
                    {
                        pcmOperatingSystemId = osidResponse.Value;
                        PcmInfo info = new PcmInfo(pcmOperatingSystemId);
                        keyAlgorithm = info.KeyAlgorithm;
                        needUnlock   = true;

                        if (needToCheckOperatingSystem && !validator.IsSameOperatingSystem(pcmOperatingSystemId))
                        {
                            this.AddUserMessage("Flashing this file could render your PCM unusable.");
                            return;
                        }

                        needToCheckOperatingSystem = false;
                    }
                    else
                    {
                        if (this.cancellationTokenSource.Token.IsCancellationRequested)
                        {
                            return;
                        }

                        this.AddUserMessage("Operating system request failed, checking for a live kernel...");

                        kernelVersion = await this.Vehicle.GetKernelVersion();

                        if (kernelVersion == 0)
                        {
                            this.AddUserMessage("Checking for recovery mode...");
                            bool recoveryMode = await this.Vehicle.IsInRecoveryMode();

                            if (recoveryMode)
                            {
                                this.AddUserMessage("PCM is in recovery mode.");
                                needUnlock = true;
                            }
                            else
                            {
                                this.AddUserMessage("PCM is not responding to OSID, kernel version, or recovery mode checks.");
                                this.AddUserMessage("Unlock may not work, but we'll try...");
                                needUnlock = true;
                            }
                        }
                        else
                        {
                            needUnlock = false;

                            this.AddUserMessage("Kernel version: " + kernelVersion.ToString("X8"));

                            this.AddUserMessage("Asking kernel for the PCM's operating system ID...");
                            if (needToCheckOperatingSystem && !await this.Vehicle.IsSameOperatingSystemAccordingToKernel(validator, this.cancellationTokenSource.Token))
                            {
                                this.AddUserMessage("Flashing this file could render your PCM unusable.");
                                return;
                            }

                            needToCheckOperatingSystem = false;
                        }
                    }

                    await this.Vehicle.SuppressChatter();

                    if (needUnlock)
                    {
                        bool unlocked = await this.Vehicle.UnlockEcu(keyAlgorithm);

                        if (!unlocked)
                        {
                            this.AddUserMessage("Unlock was not successful.");
                            return;
                        }

                        this.AddUserMessage("Unlock succeeded.");
                    }

                    DateTime start = DateTime.Now;

                    CKernelWriter writer = new CKernelWriter(
                        this.Vehicle,
                        new Protocol(),
                        this);

                    await writer.Write(
                        image,
                        writeType,
                        kernelVersion,
                        validator,
                        needToCheckOperatingSystem,
                        this.cancellationTokenSource.Token);

                    this.AddUserMessage("Elapsed time " + DateTime.Now.Subtract(start));
                }
                catch (IOException exception)
                {
                    this.AddUserMessage(exception.ToString());
                }
                finally
                {
                    this.currentWriteType = WriteType.None;

                    this.Invoke((MethodInvoker) delegate()
                    {
                        this.EnableUserInput();
                        this.cancelButton.Enabled = false;
                    });

                    // The token / token-source can only be cancelled once, so we need to make sure they won't be re-used.
                    this.cancellationTokenSource = null;
                }
            }
        }