LyoKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDIgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDMtMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKiBDb3B5cmlnaHQgMjAwNi0yMDA3IEhlbnJpIFZlcmJlZXQKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfRkxPQVRfSAojIGluY2x1ZGUgPGZsb2F0Lmg+CiNlbmRpZgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2QpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAoKElXaW5lRDNESW1wbCAqKShUaGlzLT53aW5lRDNEKSktPmdsX2luZm8KCi8qIERlZmluZSB0aGUgZGVmYXVsdCBsaWdodCBwYXJhbWV0ZXJzIGFzIHNwZWNpZmllZCBieSBNU0ROICovCmNvbnN0IFdJTkVEM0RMSUdIVCBXSU5FRDNEX2RlZmF1bHRfbGlnaHQgPSB7CgogICAgV0lORUQzRExJR0hUX0RJUkVDVElPTkFMLCAvKiBUeXBlICovCiAgICB7IDEuMCwgMS4wLCAxLjAsIDAuMCB9LCAgIC8qIERpZmZ1c2UgcixnLGIsYSAqLwogICAgeyAwLjAsIDAuMCwgMC4wLCAwLjAgfSwgICAvKiBTcGVjdWxhciByLGcsYixhICovCiAgICB7IDAuMCwgMC4wLCAwLjAsIDAuMCB9LCAgIC8qIEFtYmllbnQgcixnLGIsYSwgKi8KICAgIHsgMC4wLCAwLjAsIDAuMCB9LCAgICAgICAgLyogUG9zaXRpb24geCx5LHogKi8KICAgIHsgMC4wLCAwLjAsIDEuMCB9LCAgICAgICAgLyogRGlyZWN0aW9uIHgseSx6ICovCiAgICAwLjAsICAgICAgICAgICAgICAgICAgICAgIC8qIFJhbmdlICovCiAgICAwLjAsICAgICAgICAgICAgICAgICAgICAgIC8qIEZhbGxvZmYgKi8KICAgIDAuMCwgMC4wLCAwLjAsICAgICAgICAgICAgLyogQXR0ZW51YXRpb24gMCwxLDIgKi8KICAgIDAuMCwgICAgICAgICAgICAgICAgICAgICAgLyogVGhldGEgKi8KICAgIDAuMCAgICAgICAgICAgICAgICAgICAgICAgLyogUGhpICovCn07CgovKiB4MTFkcnYgR0RJIGVzY2FwZXMgKi8KI2RlZmluZSBYMTFEUlZfRVNDQVBFIDY3ODkKZW51bSB4MTFkcnZfZXNjYXBlX2NvZGVzCnsKICAgIFgxMURSVl9HRVRfRElTUExBWSwgICAvKiBnZXQgWDExIGRpc3BsYXkgZm9yIGEgREMgKi8KICAgIFgxMURSVl9HRVRfRFJBV0FCTEUsICAvKiBnZXQgY3VycmVudCBkcmF3YWJsZSBmb3IgYSBEQyAqLwogICAgWDExRFJWX0dFVF9GT05ULCAgICAgIC8qIGdldCBjdXJyZW50IFggZm9udCBmb3IgYSBEQyAqLwp9OwoKLyogcmV0cmlldmUgdGhlIFggZGlzcGxheSB0byB1c2Ugb24gYSBnaXZlbiBEQyAqLwpzdGF0aWMgaW5saW5lIERpc3BsYXkgKmdldF9kaXNwbGF5KCBIREMgaGRjICkKewogICAgRGlzcGxheSAqZGlzcGxheTsKICAgIGVudW0geDExZHJ2X2VzY2FwZV9jb2RlcyBlc2NhcGUgPSBYMTFEUlZfR0VUX0RJU1BMQVk7CgogICAgaWYgKCFFeHRFc2NhcGUoIGhkYywgWDExRFJWX0VTQ0FQRSwgc2l6ZW9mKGVzY2FwZSksIChMUENTVFIpJmVzY2FwZSwKICAgICAgICAgICAgICAgICAgICBzaXplb2YoZGlzcGxheSksIChMUFNUUikmZGlzcGxheSApKSBkaXNwbGF5ID0gTlVMTDsKICAgIHJldHVybiBkaXNwbGF5Owp9CgovKiBzdGF0aWMgZnVuY3Rpb24gZGVjbGFyYXRpb25zICovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVzb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSk7CgovKiBoZWxwZXIgbWFjcm9zICovCiNkZWZpbmUgRDNETUVNQ0hFQ0sob2JqZWN0LCBwcFJlc3VsdCkgaWYoTlVMTCA9PSBvYmplY3QpIHsgKnBwUmVzdWx0ID0gTlVMTDsgV0FSTigiT3V0IG9mIG1lbW9yeVxuIik7IHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7fQoKI2RlZmluZSBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIHR5cGUpIHsgXAogICAgb2JqZWN0PUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0QjI3R5cGUjI0ltcGwpKTsgXAogICAgRDNETUVNQ0hFQ0sob2JqZWN0LCBwcCMjdHlwZSk7IFwKICAgIG9iamVjdC0+bHBWdGJsID0gJklXaW5lRDNEIyN0eXBlIyNfVnRibDsgIFwKICAgIG9iamVjdC0+d2luZUQzRERldmljZSA9IFRoaXM7IFwKICAgIG9iamVjdC0+cGFyZW50ICAgICAgID0gcGFyZW50OyBcCiAgICBvYmplY3QtPnJlZiAgICAgICAgICA9IDE7IFwKICAgICpwcCMjdHlwZSA9IChJV2luZUQzRCMjdHlwZSAqKSBvYmplY3Q7IFwKfQoKI2RlZmluZSBEM0RDUkVBVEVTSEFERVJPQkpFQ1RJTlNUQU5DRShvYmplY3QsIHR5cGUpIHsgXAogICAgb2JqZWN0PUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0QjI3R5cGUjI0ltcGwpKTsgXAogICAgRDNETUVNQ0hFQ0sob2JqZWN0LCBwcCMjdHlwZSk7IFwKICAgIG9iamVjdC0+bHBWdGJsID0gJklXaW5lRDNEIyN0eXBlIyNfVnRibDsgIFwKICAgIG9iamVjdC0+cGFyZW50ICAgICAgID0gcGFyZW50OyBcCiAgICBvYmplY3QtPnJlZiAgICAgICAgICA9IDE7IFwKICAgIG9iamVjdC0+YmFzZVNoYWRlci5kZXZpY2UgPSAoSVdpbmVEM0REZXZpY2UqKSBUaGlzOyBcCiAgICBsaXN0X2luaXQoJm9iamVjdC0+YmFzZVNoYWRlci5saW5rZWRfcHJvZ3JhbXMpOyBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCn0KCiNkZWZpbmUgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlLCBkM2R0eXBlLCBfc2l6ZSl7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPnJlc291cmNlLndpbmVEM0REZXZpY2UgICA9IFRoaXM7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucGFyZW50ICAgICAgICAgID0gcGFyZW50OyBcCiAgICBvYmplY3QtPnJlc291cmNlLnJlc291cmNlVHlwZSAgICA9IGQzZHR5cGU7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucmVmICAgICAgICAgICAgID0gMTsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5wb29sICAgICAgICAgICAgPSBQb29sOyBcCiAgICBvYmplY3QtPnJlc291cmNlLmZvcm1hdCAgICAgICAgICA9IEZvcm1hdDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS51c2FnZSAgICAgICAgICAgPSBVc2FnZTsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5zaXplICAgICAgICAgICAgPSBfc2l6ZTsgXAogICAgbGlzdF9pbml0KCZvYmplY3QtPnJlc291cmNlLnByaXZhdGVEYXRhKTsgXAogICAgLyogQ2hlY2sgdGhhdCB3ZSBoYXZlIGVub3VnaCB2aWRlbyByYW0gbGVmdCAqLyBcCiAgICBpZiAoUG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7IFwKICAgICAgICBpZiAoSVdpbmVEM0REZXZpY2VfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbShpZmFjZSkgPD0gX3NpemUpIHsgXAogICAgICAgICAgICBXQVJOKCJPdXQgb2YgJ2JvZ3VzJyB2aWRlbyBtZW1vcnlcbiIpOyBcCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAgICAgKnBwIyN0eXBlID0gTlVMTDsgXAogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZOyBcCiAgICAgICAgfSBcCiAgICAgICAgZ2xvYmFsQ2hhbmdlR2xSYW0oX3NpemUpOyBcCiAgICB9IFwKICAgIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gKDAgPT0gX3NpemUgPyBOVUxMIDogUG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUID8gTlVMTCA6IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBfc2l6ZSkpOyBcCiAgICBpZiAob2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTCAmJiBfc2l6ZSAhPSAwICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfREVGQVVMVCkgeyBcCiAgICAgICAgRklYTUUoIk91dCBvZiBtZW1vcnkhXG4iKTsgXAogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAqcHAjI3R5cGUgPSBOVUxMOyBcCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgfSBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCiAgICBJV2luZUQzRERldmljZUltcGxfQWRkUmVzb3VyY2UoaWZhY2UsIChJV2luZUQzRFJlc291cmNlICopb2JqZWN0KSA7XAogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIHJlc291cmNlICVwXG4iLCBUaGlzLCBvYmplY3QpOyBcCn0KCiNkZWZpbmUgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKF9iYXNldGV4dHVyZSkgeyBcCiAgICBfYmFzZXRleHR1cmUubGV2ZWxzICAgICA9IExldmVsczsgXAogICAgX2Jhc2V0ZXh0dXJlLmZpbHRlclR5cGUgPSAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCkgPyBXSU5FRDNEVEVYRl9MSU5FQVIgOiBXSU5FRDNEVEVYRl9OT05FOyBcCiAgICBfYmFzZXRleHR1cmUuTE9EICAgICAgICA9IDA7IFwKICAgIF9iYXNldGV4dHVyZS5kaXJ0eSAgICAgID0gVFJVRTsgXAp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHbG9iYWwgdmFyaWFibGUgLyBDb25zdGFudHMgZm9sbG93CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpjb25zdCBmbG9hdCBpZGVudGl0eVsxNl0gPSB7MSwwLDAsMCwgMCwxLDAsMCwgMCwwLDEsMCwgMCwwLDAsMX07ICAvKiBXaGVuIG5lZWRlZCBmb3IgY29tcGFyaXNvbnMgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElVbmtub3duIHBhcnRzIGZvbGxvd3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlKElXaW5lRDNERGV2aWNlICppZmFjZSxSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKQp7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKICAgIGlmIChJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0RCYXNlKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVdpbmVEM0REZXZpY2UpKSB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICAqcHBvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQogICAgKnBwb2JqID0gTlVMTDsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZWYoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWZDb3VudCA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcywgcmVmQ291bnQgLSAxKTsKICAgIHJldHVybiByZWZDb3VudDsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVsZWFzZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCkgOiBSZWxlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcywgcmVmQ291bnQgKyAxKTsKCiAgICBpZiAoIXJlZkNvdW50KSB7CiAgICAgICAgaWYgKFRoaXMtPmZibykgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlRnJhbWVidWZmZXJzRVhUKDEsICZUaGlzLT5mYm8pKTsKICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPnNyY19mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+c3JjX2ZibykpOwogICAgICAgIH0KICAgICAgICBpZiAoVGhpcy0+ZHN0X2ZibykgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlRnJhbWVidWZmZXJzRVhUKDEsICZUaGlzLT5kc3RfZmJvKSk7CiAgICAgICAgfQoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZW5kZXJfdGFyZ2V0cyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5kcmF3X2J1ZmZlcnMpOwoKICAgICAgICBpZiAoVGhpcy0+Z2xzbF9wcm9ncmFtX2xvb2t1cCkgaGFzaF90YWJsZV9kZXN0cm95KFRoaXMtPmdsc2xfcHJvZ3JhbV9sb29rdXApOwoKICAgICAgICAvKiBUT0RPOiBDbGVhbiB1cCBhbGwgdGhlIHN1cmZhY2VzIGFuZCB0ZXh0dXJlcyEgKi8KICAgICAgICAvKiBOT1RFOiBZb3UgbXVzdCByZWxlYXNlIHRoZSBwYXJlbnQgaWYgdGhlIG9iamVjdCB3YXMgY3JlYXRlZCB2aWEgYSBjYWxsYmFjawogICAgICAgICoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyogUmVsZWFzZSB0aGUgdXBkYXRlIHN0YXRlYmxvY2sgKi8KICAgICAgICBpZihJV2luZUQzRFN0YXRlQmxvY2tfUmVsZWFzZSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+dXBkYXRlU3RhdGVCbG9jaykgPiAwKXsKICAgICAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrKQogICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgVXBkYXRlIHN0YXRlYmxvY2tcbiIsVGhpcyk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBOVUxMOwogICAgICAgIHsgLyogYmVjYXVzZSB3ZXJlIG5vdCBkb2luZyBwcm9wZXIgaW50ZXJuYWwgcmVmY291bnRzIHJlbGVhc2luZyB0aGUgcHJpbWFyeSBzdGF0ZSBibG9jawogICAgICAgICAgICBjYXVzZXMgcmVjdXJzaW9uIHdpdGggdGhlIGV4dHJhIGNoZWNrcyBpbiBSZXNvdXJjZVJlbGVhc2VkLCB0byBhdm9pZCB0aGlzIHdlIGhhdmUKICAgICAgICAgICAgdG8gc2V0IHRoaXMtPnN0YXRlQmxvY2sgPSBOVUxMOyBmaXJzdCAqLwogICAgICAgICAgICBJV2luZUQzRFN0YXRlQmxvY2sgKnN0YXRlQmxvY2sgPSAoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+c3RhdGVCbG9jazsKICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jayA9IE5VTEw7CgogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBzdGF0ZWJsb2NrICovCiAgICAgICAgICAgIGlmKElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKHN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgVXBkYXRlIHN0YXRlYmxvY2tcbiIsVGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZXMgIT0gTlVMTCApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgRGV2aWNlIHJlbGVhc2VkIHdpdGggcmVzb3VyY2VzIHN0aWxsIGJvdW5kLCBhY2NlcHRhYmxlIGJ1dCB1bmV4cGVjdGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgZHVtcFJlc291cmNlcyhUaGlzLT5yZXNvdXJjZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+Y29udGV4dHMpIEVSUigiQ29udGV4dCBhcnJheSBub3QgZnJlZWQhXG4iKTsKCiAgICAgICAgSVdpbmVEM0RfUmVsZWFzZShUaGlzLT53aW5lRDNEKTsKICAgICAgICBUaGlzLT53aW5lRDNEID0gTlVMTDsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICBUUkFDRSgiRnJlZWQgZGV2aWNlICAlcFxuIiwgVGhpcyk7CiAgICAgICAgVGhpcyA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlIGltcGxlbWVudGF0aW9uIGZvbGxvd3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGFyZW50KElXaW5lRDNERGV2aWNlICppZmFjZSwgSVVua25vd24gKipwUGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAqcFBhcmVudCA9IFRoaXMtPnBhcmVudDsKICAgIElVbmtub3duX0FkZFJlZihUaGlzLT5wYXJlbnQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIENyZWF0ZVZCTyhJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKm9iamVjdCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gb2JqZWN0LT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOyAgLyogTmVlZGVkIGZvciBHTF9FWFRDQUxMICovCiAgICBHTGVudW0gZXJyb3IsIGdsVXNhZ2U7CiAgICBEV09SRCB2Ym9Vc2FnZSA9IG9iamVjdC0+cmVzb3VyY2UudXNhZ2U7CiAgICBpZihvYmplY3QtPkZsYWdzICYgVkJGTEFHX1ZCT0NSRUFURUZBSUwpIHsKICAgICAgICBXQVJOKCJDcmVhdGluZyBhIHZibyBmYWlsZWQgb25jZSwgbm90IHRyeWluZyBhZ2FpblxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIFRSQUNFKCJDcmVhdGluZyBhbiBPcGVuR0wgdmVydGV4IGJ1ZmZlciBvYmplY3QgZm9yIElXaW5lRDNEVmVydGV4QnVmZmVyICVwICBVc2FnZSglcylcbiIsIG9iamVjdCwgZGVidWdfZDNkdXNhZ2UodmJvVXNhZ2UpKTsKCiAgICBFTlRFUl9HTCgpOwogICAgLyogTWFrZSBzdXJlIHRoYXQgYSBjb250ZXh0IGlzIHRoZXJlLiBOZWVkZWQgaW4gYSBtdWx0aXRocmVhZGVkIGVudmlyb25tZW50LiBPdGhlcndpc2UgdGhpcyBjYWxsIGlzIGEgbm9wICovCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICAvKiBNYWtlIHN1cmUgdGhhdCB0aGUgZ2wgZXJyb3IgaXMgY2xlYXJlZC4gRG8gbm90IHVzZSBjaGVja0dMY2FsbAogICAgICAqIGhlcmUgYmVjYXVzZSBjaGVja0dMY2FsbCBqdXN0IHByaW50cyBhIGZpeG1lIGFuZCBjb250aW51ZXMuIEhvd2V2ZXIsCiAgICAgICogaWYgYW4gZXJyb3IgZHVyaW5nIFZCTyBjcmVhdGlvbiBvY2N1cnMgd2UgY2FuIGZhbGwgYmFjayB0byBub24tdmJvIG9wZXJhdGlvbgogICAgICAqIHdpdGggZnVsbCBmdW5jdGlvbmFsaXR5KGJ1dCBwZXJmb3JtYW5jZSBsb3NzKQogICAgICAqLwogICAgd2hpbGUoZ2xHZXRFcnJvcigpICE9IEdMX05PX0VSUk9SKTsKCiAgICAvKiBCYXNpY2FsbHkgdGhlIEZWRiBwYXJhbWV0ZXIgcGFzc2VkIHRvIENyZWF0ZVZlcnRleEJ1ZmZlciBpcyBubyBnb29kCiAgICAgICogSXQgaXMgdGhlIEZWRiBzZXQgd2l0aCBJV2luZUQzRERldmljZTo6U2V0RlZGIG9yIHRoZSBWZXJ0ZXggRGVjbGFyYXRpb24gc2V0IHdpdGgKICAgICAgKiBJV2luZUQzRERldmljZTo6U2V0VmVydGV4RGVjbGFyYXRpb24gdGhhdCBkZWNpZGVzIGhvdyB0aGUgdmVydGljZXMgaW4gdGhlIGJ1ZmZlcgogICAgICAqIGxvb2sgbGlrZS4gVGhpcyBtZWFucyB0aGF0IG9uIGVhY2ggRHJhd1ByaW1pdGl2ZSBjYWxsIHRoZSB2ZXJ0ZXggYnVmZmVyIGhhcyB0byBiZSB2ZXJpZmllZAogICAgICAqIHRvIGNoZWNrIGlmIHRoZSByaHcgYW5kIGNvbG9yIHZhbHVlcyBhcmUgaW4gdGhlIGNvcnJlY3QgZm9ybWF0LgogICAgICAqLwoKICAgIEdMX0VYVENBTEwoZ2xHZW5CdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihvYmplY3QtPnZibyA9PSAwIHx8IGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBhIFZCTyB3aXRoIGVycm9yICVzICglI3gpXG4iLCBkZWJ1Z19nbGVycm9yKGVycm9yKSwgZXJyb3IpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT52Ym8pKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gYmluZCB0aGUgVkJPIHdpdGggZXJyb3IgJXMgKCUjeClcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBEb24ndCB1c2Ugc3RhdGljLCBiZWNhdXNlIGR4IGFwcHMgdGVuZCB0byB1cGRhdGUgdGhlIGJ1ZmZlcgogICAgICogcXVpdGUgb2Z0ZW4gZXZlbiBpZiB0aGV5IHNwZWNpZnkgMCB1c2FnZS4gQmVjYXVzZSB3ZSBhbHdheXMga2VlcCB0aGUgbG9jYWwgY29weQogICAgICogd2UgbmV2ZXIgcmVhZCBmcm9tIHRoZSB2Ym8gYW5kIGNhbiBjcmVhdGUgYSB3cml0ZSBvbmx5IG9wZW5nbCBidWZmZXIuCiAgICAgKi8KICAgIHN3aXRjaCh2Ym9Vc2FnZSAmIChXSU5FRDNEVVNBR0VfV1JJVEVPTkxZIHwgV0lORUQzRFVTQUdFX0RZTkFNSUMpICkgewogICAgICAgIGNhc2UgV0lORUQzRFVTQUdFX1dSSVRFT05MWSB8IFdJTkVEM0RVU0FHRV9EWU5BTUlDOgogICAgICAgIGNhc2UgV0lORUQzRFVTQUdFX0RZTkFNSUM6CiAgICAgICAgICAgIFRSQUNFKCJHbCB1c2FnZSA9IEdMX1NUUkVBTV9EUkFXXG4iKTsKICAgICAgICAgICAgZ2xVc2FnZSA9IEdMX1NUUkVBTV9EUkFXX0FSQjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEVVNBR0VfV1JJVEVPTkxZOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRSQUNFKCJHbCB1c2FnZSA9IEdMX0RZTkFNSUNfRFJBV1xuIik7CiAgICAgICAgICAgIGdsVXNhZ2UgPSBHTF9EWU5BTUlDX0RSQVdfQVJCOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBSZXNlcnZlIG1lbW9yeSBmb3IgdGhlIGJ1ZmZlci4gVGhlIGFtb3VudCBvZiBkYXRhIHdvbid0IGNoYW5nZQogICAgICogc28gd2UgYXJlIHNhZmUgd2l0aCBjYWxsaW5nIGdsQnVmZmVyRGF0YSBvbmNlIHdpdGggYSBOVUxMIHB0ciBhbmQKICAgICAqIGNhbGxpbmcgZ2xCdWZmZXJTdWJEYXRhIG9uIHVwZGF0ZXMKICAgICAqLwogICAgR0xfRVhUQ0FMTChnbEJ1ZmZlckRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT5yZXNvdXJjZS5zaXplLCBOVUxMLCBnbFVzYWdlKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgV0FSTigiZ2xCdWZmZXJEYXRhQVJCIGZhaWxlZCB3aXRoIGVycm9yICVzICglI3gpXG4iLCBkZWJ1Z19nbGVycm9yKGVycm9yKSwgZXJyb3IpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm47CiAgICBlcnJvcjoKICAgIC8qIENsZWFuIHVwIGFsbCB2Ym8gaW5pdCwgYnV0IGNvbnRpbnVlIGJlY2F1c2Ugd2UgY2FuIHdvcmsgd2l0aG91dCBhIHZibyA6LSkgKi8KICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIGEgdmVydGV4IGJ1ZmZlciBvYmplY3QuIENvbnRpbnVpbmcsIGJ1dCBwZXJmb3JtYW5jZSBpc3N1ZXMgY2FuIG9jY3VyXG4iKTsKICAgIGlmKG9iamVjdC0+dmJvKSBHTF9FWFRDQUxMKGdsRGVsZXRlQnVmZmVyc0FSQigxLCAmb2JqZWN0LT52Ym8pKTsKICAgIG9iamVjdC0+dmJvID0gMDsKICAgIG9iamVjdC0+RmxhZ3MgfD0gVkJGTEFHX1ZCT0NSRUFURUZBSUw7CiAgICBMRUFWRV9HTCgpOwogICAgcmV0dXJuOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleEJ1ZmZlcihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU2l6ZSwgRFdPUkQgVXNhZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZWRiwgV0lORUQzRFBPT0wgUG9vbCwgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqKiBwcFZlcnRleEJ1ZmZlciwgSEFORExFICpzaGFyZWRIYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICpvYmplY3Q7CiAgICBXSU5FRDNERk9STUFUIEZvcm1hdCA9IFdJTkVEM0RGTVRfVkVSVEVYREFUQTsgLyogRHVtbXkgZm9ybWF0IGZvciBub3cgKi8KICAgIGludCBkeFZlcnNpb24gPSAoIChJV2luZUQzREltcGwgKikgVGhpcy0+d2luZUQzRCktPmR4VmVyc2lvbjsKICAgIEJPT0wgY29udjsKCiAgICBpZihTaXplID09IDApIHsKICAgICAgICBXQVJOKCJTaXplIDAgcmVxdWVzdGVkLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgKnBwVmVydGV4QnVmZmVyID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4QnVmZmVyLCBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSLCBTaXplKQoKICAgIFRSQUNFKCIoJXApIDogU2l6ZT0lZCwgVXNhZ2U9JWQsIEZWRj0leCwgUG9vbD0lZCAtIE1lbW9yeUAlcCwgSWZhY2VAJXBcbiIsIFRoaXMsIFNpemUsIFVzYWdlLCBGVkYsIFBvb2wsIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBvYmplY3QpOwogICAgKnBwVmVydGV4QnVmZmVyID0gKElXaW5lRDNEVmVydGV4QnVmZmVyICopb2JqZWN0OwoKICAgIGlmIChQb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQgKSB7IC8qIEFsbG9jYXRlIHNvbWUgc3lzdGVtIG1lbW9yeSBmb3Igbm93ICovCiAgICAgICAgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSk7CiAgICB9CiAgICBvYmplY3QtPmZ2ZiA9IEZWRjsKCiAgICAvKiBPYnNlcnZhdGlvbnMgc2hvdyB0aGF0IGRyYXdTdHJpZGVkU2xvdyBpcyBmYXN0ZXIgb24gZHluYW1pYyBWQnMgdGhhbiBjb252ZXJ0aW5nICsKICAgICAqIGRyYXdTdHJpZGVkRmFzdCAoaGFsZi1saWZlIDIpLgogICAgICoKICAgICAqIEJhc2ljYWxseSBjb252ZXJ0aW5nIHRoZSB2ZXJ0aWNlcyBpbiB0aGUgYnVmZmVyIGlzIHF1aXRlIGV4cGVuc2l2ZSwgYW5kIG9ic2VydmF0aW9ucwogICAgICogc2hvdyB0aGF0IGRyYXdTdHJpZGVkU2xvdyBpcyBmYXN0ZXIgdGhhbiBjb252ZXJ0aW5nICsgdXBsb2FkaW5nICsgZHJhd1N0cmlkZWRGYXN0LgogICAgICogVGhlcmVmb3JlIGRvIG5vdCBjcmVhdGUgYSBWQk8gZm9yIFdJTkVEM0RVU0FHRV9EWU5BTUlDIGJ1ZmZlcnMuCiAgICAgKgogICAgICogRGlyZWN0M0Q3IGhhcyBhbm90aGVyIHByb2JsZW06IEl0cyB2ZXJ0ZXhidWZmZXIgYXBpIGRvZXNuJ3Qgb2ZmZXIgYSB3YXkgdG8gc3BlY2lmeQogICAgICogdGhlIHJhbmdlIG9mIHZlcnRpY2VzIGJlaW5nIGxvY2tlZCwgc28gZWFjaCBsb2NrIHdpbGwgcmVxdWlyZSB0aGUgd2hvbGUgYnVmZmVyIHRvIGJlIHRyYW5zZm9ybWVkLgogICAgICogTW9yZW92ZXIgZ2VvbWV0cnkgZGF0YSBpbiBkeDcgaXMgcXVpdGUgc2ltcGxlLCBzbyBkcmF3U3RyaWRlZFNsb3cgaXNuJ3QgYSBiaWcgaGl0LiBBIHBsdXMKICAgICAqIGlzIHRoYXQgdGhlIHZlcnRleCBidWZmZXJzIGZ2ZiBjYW4gYmUgdHJ1c3RlZCBpbiBkeDcuIFNvIG9ubHkgY3JlYXRlIG5vbi1jb252ZXJ0ZWQgdmJvcyBmb3IKICAgICAqIGR4NyBhcHBzLgogICAgICogVGhlcmUgaXMgYSBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpPcHRpbWl6ZSBjYWxsIGFmdGVyIHdoaWNoIHRoZSBidWZmZXIgY2FuJ3QgYmUgbG9ja2VkIGFueQogICAgICogbW9yZS4gSW4gdGhpcyBjYWxsIHdlIGNhbiBjb252ZXJ0IGR4NyBidWZmZXJzIHRvby4KICAgICAqLwogICAgY29udiA9ICgoRlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVyApIHx8IChGVkYgJiAoV0lORUQzREZWRl9ESUZGVVNFIHwgV0lORUQzREZWRl9TUEVDVUxBUikpOwogICAgaWYoIEdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9CVUZGRVJfT0JKRUNUKSAmJiBQb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSAmJiAhKFVzYWdlICYgV0lORUQzRFVTQUdFX0RZTkFNSUMpICYmIAogICAgICAgIChkeFZlcnNpb24gPiA3IHx8ICFjb252KSApIHsKICAgICAgICBDcmVhdGVWQk8ob2JqZWN0KTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBDcmVhdGVJbmRleEJ1ZmZlclZCTyhJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICpvYmplY3QpIHsKICAgIEdMZW51bSBlcnJvciwgZ2xVc2FnZTsKICAgIFRSQUNFKCJDcmVhdGluZyBWQk8gZm9yIEluZGV4IEJ1ZmZlciAlcFxuIiwgb2JqZWN0KTsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGNvZGUgd2lsbCBtb2RpZnkgdGhlIEVMRU1FTlRfQVJSQVlfQlVGRkVSIGJpbmRpbmcsIG1ha2Ugc3VyZSBpdCBpcwogICAgICogcmVzdG9yZWQgb24gdGhlIG5leHQgZHJhdwogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwoKICAgIEVOVEVSX0dMKCk7CiAgICAvKiBNYWtlIHN1cmUgdGhhdCBhIGNvbnRleHQgaXMgdGhlcmUuIE5lZWRlZCBpbiBhIG11bHRpdGhyZWFkZWQgZW52aXJvbm1lbnQuIE90aGVyd2lzZSB0aGlzIGNhbGwgaXMgYSBub3AgKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwoKICAgIHdoaWxlKGdsR2V0RXJyb3IoKSk7CgogICAgR0xfRVhUQ0FMTChnbEdlbkJ1ZmZlcnNBUkIoMSwgJm9iamVjdC0+dmJvKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SIHx8IG9iamVjdC0+dmJvID09IDApIHsKICAgICAgICBFUlIoIkNyZWF0aW5nIGEgdmJvIGZhaWxlZCB3aXRoIGVycm9yICVzICglI3gpLCBjb250aW51aW5nIHdpdGhvdXQgdmJvIGZvciB0aGlzIGJ1ZmZlclxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9BUkIsIG9iamVjdC0+dmJvKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gYmluZCBpbmRleCBidWZmZXIgd2l0aCBlcnJvciAlcyAoJSN4KSwgY29udGludWluZyB3aXRob3V0IHZibyBmb3IgdGhpcyBidWZmZXJcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgLyogVXNlIHN0YXRpYyB3cml0ZSBvbmx5IHVzYWdlIGZvciBub3cuIER5bmFtaWMgaW5kZXggYnVmZmVycyBzdGF5IGluIHN5c21lbSwgYW5kIGR1ZSB0byB0aGUgc3lzbWVtCiAgICAgICAgKiBjb3B5IG5vIHJlYWRiYWNrIHdpbGwgYmUgbmVlZGVkCiAgICAgICAgKi8KICAgIGdsVXNhZ2UgPSBHTF9TVEFUSUNfRFJBV19BUkI7CiAgICBHTF9FWFRDQUxMKGdsQnVmZmVyRGF0YUFSQihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9BUkIsIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSwgTlVMTCwgZ2xVc2FnZSkpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGluaXRpYWxpemUgdGhlIGluZGV4IGJ1ZmZlciB3aXRoIGVycm9yICVzICglI3gpXG4iLCBkZWJ1Z19nbGVycm9yKGVycm9yKSwgZXJyb3IpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQogICAgTEVBVkVfR0woKTsKICAgIFRSQUNFKCJTdWNjZXNzZnVsbHkgY3JlYXRlZCB2Ym8gJWQgZm9yIGluZGV4IGJ1ZmZlciAlcFxuIiwgb2JqZWN0LT52Ym8sIG9iamVjdCk7CiAgICByZXR1cm47CgpvdXQ6CiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9BUkIsIDApKTsKICAgIEdMX0VYVENBTEwoZ2xEZWxldGVCdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgTEVBVkVfR0woKTsKICAgIG9iamVjdC0+dmJvID0gMDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVJbmRleEJ1ZmZlcihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgTGVuZ3RoLCBEV09SRCBVc2FnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwgSVdpbmVEM0RJbmRleEJ1ZmZlcioqIHBwSW5kZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKm9iamVjdDsKICAgIFRSQUNFKCIoJXApIENyZWF0aW5nIGluZGV4IGJ1ZmZlclxuIiwgVGhpcyk7CgogICAgLyogQWxsb2NhdGUgdGhlIHN0b3JhZ2UgZm9yIHRoZSBkZXZpY2UgKi8KICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LEluZGV4QnVmZmVyLFdJTkVEM0RSVFlQRV9JTkRFWEJVRkZFUiwgTGVuZ3RoKQoKICAgIGlmIChQb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQgKSB7IC8qIFdlIG5lZWQgYSBsb2NhbCBjb3B5IGZvciBkcmF3U3RyaWRlZFNsb3cgKi8KICAgICAgICBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSk7CiAgICB9CgogICAgaWYoUG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0gJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSAmJiBHTF9TVVBQT1JUKEFSQl9WRVJURVhfQlVGRkVSX09CSkVDVCkpIHsKICAgICAgICBDcmVhdGVJbmRleEJ1ZmZlclZCTyhUaGlzLCBvYmplY3QpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogTGVuPSVkLCBVc2U9JXgsIEZvcm1hdD0oJXUsJXMpLCBQb29sPSVkIC0gTWVtb3J5QCVwLCBJZmFjZUAlcFxuIiwgVGhpcywgTGVuZ3RoLCBVc2FnZSwgRm9ybWF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIFBvb2wsIG9iamVjdCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgKnBwSW5kZXhCdWZmZXIgPSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKSBvYmplY3Q7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3RhdGVCbG9jayhJV2luZUQzRERldmljZSogaWZhY2UsIFdJTkVEM0RTVEFURUJMT0NLVFlQRSBUeXBlLCBJV2luZUQzRFN0YXRlQmxvY2sqKiBwcFN0YXRlQmxvY2ssIElVbmtub3duICpwYXJlbnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqb2JqZWN0OwogICAgaW50IGksIGo7CiAgICBIUkVTVUxUIHRlbXBfcmVzdWx0OwoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgU3RhdGVCbG9jaykKICAgIG9iamVjdC0+YmxvY2tUeXBlICAgICA9IFR5cGU7CgogICAgZm9yKGkgPSAwOyBpIDwgTElHSFRNQVBfU0laRTsgaSsrKSB7CiAgICAgICAgbGlzdF9pbml0KCZvYmplY3QtPmxpZ2h0TWFwW2ldKTsKICAgIH0KCiAgICAvKiBTcGVjaWFsIGNhc2UgLSBVc2VkIGR1cmluZyBpbml0aWFsaXphdGlvbiB0byBwcm9kdWNlIGEgcGxhY2Vob2xkZXIgc3RhdGVibG9jawogICAgICAgICAgc28gb3RoZXIgZnVuY3Rpb25zIGNhbGxlZCBjYW4gdXBkYXRlIGEgc3RhdGUgYmxvY2sgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmIChUeXBlID09IFdJTkVEM0RTQlRfSU5JVCkgewogICAgICAgIC8qIERvbid0IGJvdGhlciBpbmNyZWFzaW5nIHRoZSByZWZlcmVuY2UgY291bnQgb3RoZXJ3aXNlIGEgZGV2aWNlIHdpbGwgbmV2ZXIKICAgICAgICAgICBiZSBmcmVlZCBkdWUgdG8gY2lyY3VsYXIgZGVwZW5kZW5jaWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQogICAgCiAgICB0ZW1wX3Jlc3VsdCA9IGFsbG9jYXRlX3NoYWRlcl9jb25zdGFudHMob2JqZWN0KTsKICAgIGlmIChXSU5FRDNEX09LICE9IHRlbXBfcmVzdWx0KQogICAgICAgIHJldHVybiB0ZW1wX3Jlc3VsdDsKCiAgICAvKiBPdGhlcndpc2UsIG1pZ2h0IGFzIHdlbGwgc2V0IHRoZSB3aG9sZSBzdGF0ZSBibG9jayB0byB0aGUgYXBwcm9wcmlhdGUgdmFsdWVzICAqLwogICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCkKICAgICAgICBzdGF0ZWJsb2NrX2NvcHkoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgKElXaW5lRDNEU3RhdGVCbG9jayopIFRoaXMtPnN0YXRlQmxvY2spOwogICAgZWxzZQogICAgICAgIG1lbXNldChvYmplY3QtPnN0cmVhbUZyZXEsIDEsIHNpemVvZihvYmplY3QtPnN0cmVhbUZyZXEpKTsKCiAgICAvKiBSZXNldCB0aGUgcmVmIGFuZCB0eXBlIGFmdGVyIGtsdWRnaW5nIGl0ICovCiAgICBvYmplY3QtPndpbmVEM0REZXZpY2UgPSBUaGlzOwogICAgb2JqZWN0LT5yZWYgICAgICAgICAgID0gMTsKICAgIG9iamVjdC0+YmxvY2tUeXBlICAgICA9IFR5cGU7CgogICAgVFJBQ0UoIlVwZGF0aW5nIGNoYW5nZWQgZmxhZ3MgYXBwcm9wcmlhdGUgZm9yIHR5cGUgJWRcbiIsIFR5cGUpOwoKICAgIGlmIChUeXBlID09IFdJTkVEM0RTQlRfQUxMKSB7CgogICAgICAgIFRSQUNFKCJBTEwgPT4gUHJldGVuZCBldmVyeXRoaW5nIGhhcyBjaGFuZ2VkXG4iKTsKICAgICAgICBzdGF0ZWJsb2NrX3NhdmVkc3RhdGVzX3NldCgoSVdpbmVEM0RTdGF0ZUJsb2NrKikgb2JqZWN0LCAmb2JqZWN0LT5jaGFuZ2VkLCBUUlVFKTsKCiAgICAgICAgLyogTGlnaHRzIGFyZSBub3QgcGFydCBvZiB0aGUgY2hhbmdlZCAvIHNldCBzdHJ1Y3R1cmUgKi8KICAgICAgICBmb3IoaiA9IDA7IGogPCBMSUdIVE1BUF9TSVpFOyBqKyspIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmU7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJm9iamVjdC0+bGlnaHRNYXBbal0pIHsKICAgICAgICAgICAgICAgIFBMSUdIVElORk9FTCAqbGlnaHQgPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgICAgICAgICAgbGlnaHQtPmNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgbGlnaHQtPmVuYWJsZWRDaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX1BJWEVMU1RBVEUpIHsKCiAgICAgICAgVFJBQ0UoIlBJWEVMU1RBVEUgPT4gUHJldGVuZCBhbGwgcGl4ZWwgc2hhdGVzIGhhdmUgY2hhbmdlZFxuIik7CiAgICAgICAgc3RhdGVibG9ja19zYXZlZHN0YXRlc19zZXQoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgJm9iamVjdC0+Y2hhbmdlZCwgRkFMU0UpOwoKICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXIgPSBUUlVFOwoKICAgICAgICAvKiBQaXhlbCBTaGFkZXIgQ29uc3RhbnRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpOyArK2kpCiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfQjsgKytpKQogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNCW2ldID0gVFJVRTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0k7ICsraSkKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzSVtpXSA9IFRSVUU7CiAgICAgICAgCiAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1I7IGkrKykgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucmVuZGVyU3RhdGVbU2F2ZWRQaXhlbFN0YXRlc19SW2ldXSA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDA7IGogPCBHTF9MSU1JVFModGV4dHVyZV9zdGFnZXMpOyBqKyspIHsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1Q7IGkrKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtqXVtTYXZlZFBpeGVsU3RhdGVzX1RbaV1dID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGogPSAwIDsgaiA8IDE2OyBqKyspIHsKICAgICAgICAgICAgZm9yIChpID0wOyBpIDwgTlVNX1NBVkVEUElYRUxTVEFURVNfUztpKyspIHsKCiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQuc2FtcGxlclN0YXRlW2pdW1NhdmVkUGl4ZWxTdGF0ZXNfU1tpXV0gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0gZWxzZSBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX1ZFUlRFWFNUQVRFKSB7CgogICAgICAgIFRSQUNFKCJWRVJURVhTVEFURSA9PiBQcmV0ZW5kIGFsbCB2ZXJ0ZXggc2hhdGVzIGhhdmUgY2hhbmdlZFxuIik7CiAgICAgICAgc3RhdGVibG9ja19zYXZlZHN0YXRlc19zZXQoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgJm9iamVjdC0+Y2hhbmdlZCwgRkFMU0UpOwoKICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyID0gVFJVRTsKCiAgICAgICAgLyogVmVydGV4IFNoYWRlciBDb25zdGFudHMgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7ICsraSkKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfQjsgKytpKQogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzQltpXSA9IFRSVUU7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9JOyArK2kpCiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNJW2ldID0gVFJVRTsKIAogICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURWRVJURVhTVEFURVNfUjsgaSsrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtTYXZlZFZlcnRleFN0YXRlc19SW2ldXSA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDA7IGogPCBHTF9MSU1JVFModGV4dHVyZV9zdGFnZXMpOyBqKyspIHsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19UOyBpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbal1bU2F2ZWRWZXJ0ZXhTdGF0ZXNfVFtpXV0gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDAgOyBqIDwgMTY7IGorKyl7CiAgICAgICAgICAgIGZvciAoaSA9MDsgaSA8IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19TO2krKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnNhbXBsZXJTdGF0ZVtqXVtTYXZlZFZlcnRleFN0YXRlc19TW2ldXSA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcihqID0gMDsgaiA8IExJR0hUTUFQX1NJWkU7IGorKykgewogICAgICAgICAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgICAgICAgICAgTElTVF9GT1JfRUFDSChlLCAmb2JqZWN0LT5saWdodE1hcFtqXSkgewogICAgICAgICAgICAgICAgUExJR0hUSU5GT0VMICpsaWdodCA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgICAgICAgICBsaWdodC0+Y2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgICAgICBsaWdodC0+ZW5hYmxlZENoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIHN0YXRlIGJsb2NrIHR5cGUgJWRcbiIsIFR5cGUpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIHJldHVybmluZyB0b2tlbiAocHRyIHRvIHN0YXRlYmxvY2spIG9mICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKTVNETjoKW2luXSBSZW5kZXIgdGFyZ2V0cyBhcmUgbm90IGxvY2thYmxlIHVubGVzcyB0aGUgYXBwbGljYXRpb24gc3BlY2lmaWVzIFRSVUUgZm9yIExvY2thYmxlLiBOb3RlIHRoYXQgbG9ja2FibGUgcmVuZGVyIHRhcmdldHMgcmVkdWNlIHBlcmZvcm1hbmNlIG9uIHNvbWUgZ3JhcGhpY3MgaGFyZHdhcmUuCgpEaXNjYXJkCiBbaW5dIFNldCB0aGlzIGZsYWcgdG8gVFJVRSB0byBlbmFibGUgei1idWZmZXIgZGlzY2FyZGluZywgYW5kIEZBTFNFIG90aGVyd2lzZS4gCgpJZiB0aGlzIGZsYWcgaXMgc2V0LCB0aGUgY29udGVudHMgb2YgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIHdpbGwgYmUgaW52YWxpZCBhZnRlciBjYWxsaW5nIGVpdGhlciBJRGlyZWN0M0REZXZpY2U5OjpQcmVzZW50IG9yIElEaXJlY3QzRERldmljZTk6OlNldERlcHRoU3RlbmNpbFN1cmZhY2Ugd2l0aCBhIGRpZmZlcmVudCBkZXB0aCBzdXJmYWNlLgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KIApzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdXJmYWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBCT09MIExvY2thYmxlLCBCT09MIERpc2NhcmQsIFVJTlQgTGV2ZWwsIElXaW5lRDNEU3VyZmFjZSAqKnBwU3VyZmFjZSxXSU5FRDNEUkVTT1VSQ0VUWVBFIFR5cGUsIERXT1JEIFVzYWdlLCBXSU5FRDNEUE9PTCBQb29sLCBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZSAsRFdPUkQgTXVsdGlzYW1wbGVRdWFsaXR5LCBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIFdJTkVEM0RTVVJGVFlQRSBJbXBsLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOyAgICAKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKm9iamVjdDsgLypOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKi8KICAgIHVuc2lnbmVkIGludCBwb3cyV2lkdGgsIHBvdzJIZWlnaHQ7CiAgICB1bnNpZ25lZCBpbnQgU2l6ZSAgICAgICA9IDE7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKnRhYmxlRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0KTsKICAgIFRSQUNFKCIoJXApIENyZWF0ZSBzdXJmYWNlXG4iLFRoaXMpOwogICAgCiAgICAvKiogRklYTUU6IENoZWNrIHJhbmdlcyBvbiB0aGUgaW5wdXRzIGFyZSB2YWxpZCAKICAgICAqIE1TRE4KICAgICAqICAgTXVsdGlzYW1wbGVRdWFsaXR5CiAgICAgKiAgICBbaW5dIFF1YWxpdHkgbGV2ZWwuIFRoZSB2YWxpZCByYW5nZSBpcyBiZXR3ZWVuIHplcm8gYW5kIG9uZSBsZXNzIHRoYW4gdGhlIGxldmVsCiAgICAgKiAgICByZXR1cm5lZCBieSBwUXVhbGl0eUxldmVscyB1c2VkIGJ5IElEaXJlY3QzRDk6OkNoZWNrRGV2aWNlTXVsdGlTYW1wbGVUeXBlLiAKICAgICAqICAgIFBhc3NpbmcgYSBsYXJnZXIgdmFsdWUgcmV0dXJucyB0aGUgZXJyb3IgV0lORUQzREVSUl9JTlZBTElEQ0FMTC4gVGhlIE11bHRpc2FtcGxlUXVhbGl0eQogICAgICogICAgdmFsdWVzIG9mIHBhaXJlZCByZW5kZXIgdGFyZ2V0cywgZGVwdGggc3RlbmNpbCBzdXJmYWNlcywgYW5kIHRoZSBNdWx0aVNhbXBsZSB0eXBlCiAgICAgKiAgICBtdXN0IGFsbCBtYXRjaC4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgogICAgLyoqCiAgICAqIFRPRE86IERpc2NhcmQgTVNETgogICAgKiBbaW5dIFNldCB0aGlzIGZsYWcgdG8gVFJVRSB0byBlbmFibGUgei1idWZmZXIgZGlzY2FyZGluZywgYW5kIEZBTFNFIG90aGVyd2lzZS4KICAgICoKICAgICogSWYgdGhpcyBmbGFnIGlzIHNldCwgdGhlIGNvbnRlbnRzIG9mIHRoZSBkZXB0aCBzdGVuY2lsIGJ1ZmZlciB3aWxsIGJlCiAgICAqIGludmFsaWQgYWZ0ZXIgY2FsbGluZyBlaXRoZXIgSURpcmVjdDNERGV2aWNlOTo6UHJlc2VudCBvciAgKiBJRGlyZWN0M0REZXZpY2U5OjpTZXREZXB0aFN0ZW5jaWxTdXJmYWNlCiAgICAqIHdpdGggYSBkaWZmZXJlbnQgZGVwdGggc3VyZmFjZS4KICAgICoKICAgICpUaGlzIGZsYWcgaGFzIHRoZSBzYW1lIGJlaGF2aW9yIGFzIHRoZSBjb25zdGFudCwgRDNEUFJFU0VOVEZMQUdfRElTQ0FSRF9ERVBUSFNURU5DSUwsIGluIEQzRFBSRVNFTlRGTEFHLgogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGlmKE11bHRpc2FtcGxlUXVhbGl0eSA8IDApIHsKICAgICAgICBGSVhNRSgiSW52YWxpZCBtdWx0aXNhbXBsZSBsZXZlbCAlZFxuIiwgTXVsdGlzYW1wbGVRdWFsaXR5KTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsgLyogVE9ETzogQ2hlY2sgdGhhdCB0aGlzIGlzIHRoZSBjYXNlISAqLwogICAgfQoKICAgIGlmKE11bHRpc2FtcGxlUXVhbGl0eSA+IDApIHsKICAgICAgICBGSVhNRSgiTXVsdGlzYW1wbGVRdWFsaXR5IHNldCB0byAlZCwgc3Vic3RpdHV0aW5nIDBcbiIsIE11bHRpc2FtcGxlUXVhbGl0eSk7CiAgICAgICAgTXVsdGlzYW1wbGVRdWFsaXR5PTA7CiAgICB9CgogICAgLyoqIEZJWE1FOiBDaGVjayB0aGF0IHRoZSBmb3JtYXQgaXMgc3VwcG9ydGVkCiAgICAqICAgIGJ5IHRoZSBkZXZpY2UuCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogTm9uLXBvd2VyMiBzdXBwb3J0ICovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHBvdzJXaWR0aCA9IFdpZHRoOwogICAgICAgIHBvdzJIZWlnaHQgPSBIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChwb3cyV2lkdGggPCBXaWR0aCkgcG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChwb3cySGVpZ2h0IDwgSGVpZ2h0KSBwb3cySGVpZ2h0IDw8PSAxOwogICAgfQoKICAgIGlmIChwb3cyV2lkdGggPiBXaWR0aCB8fCBwb3cySGVpZ2h0ID4gSGVpZ2h0KSB7CiAgICAgICAgIC8qKiBUT0RPOiBhZGQgc3VwcG9ydCBmb3Igbm9uIHBvd2VyIHR3byBjb21wcmVzc2VkIHRleHR1cmVzIChPcGVuR0wgMiBwcm92aWNlcyBzdXBwb3J0IGZvciAqIG5vbi1wb3dlci10d28gdGV4dHVyZXMgZ3JhdGlzKSAqKi8KICAgICAgICBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMKICAgICAgICAgICAgICAgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIENvbXByZXNzZWQgbm9uLXBvd2VyLXR3byB0ZXh0dXJlcyBhcmUgbm90IHN1cHBvcnRlZCB3KCVkKSBoKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgICBUaGlzLCBXaWR0aCwgSGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiogRFhUbiBtaXBtYXBzIHVzZSB0aGUgc2FtZSBudW1iZXIgb2YgJ2xldmVscycgZG93biB0byBlZy4gOHgxLCBidXQgc2luY2UKICAgICAqICBpdCBpcyBiYXNlZCBhcm91bmQgNHg0IHBpeGVsIGJsb2NrcyBpdCByZXF1aXJlcyBwYWRkaW5nLCBzbyBhbGxvY2F0ZSBlbm91Z2gKICAgICAqICBzcGFjZSEKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiA9PSBGb3JtYXQpIHsKICAgICAgICBTaXplID0gMDsKICAgIH0gZWxzZSBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgewogICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgU2l6ZSA9ICgobWF4KFdpZHRoLDQpICogdGFibGVFbnRyeS0+YnBwKSAqIG1heChIZWlnaHQsNCkpID4+IDE7CgogICAgfSBlbHNlIGlmIChGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICBTaXplID0gKChtYXgoV2lkdGgsNCkgKiB0YWJsZUVudHJ5LT5icHApICogbWF4KEhlaWdodCw0KSk7CiAgICB9IGVsc2UgewogICAgICAgLyogVGhlIHBpdGNoIGlzIGEgbXVsdGlwbGUgb2YgNCBieXRlcyAqLwogICAgICAgU2l6ZSA9ICgoV2lkdGggKiB0YWJsZUVudHJ5LT5icHApICsgU1VSRkFDRV9BTElHTk1FTlQgLSAxKSAmIH4oU1VSRkFDRV9BTElHTk1FTlQgLSAxKTsKICAgICAgIFNpemUgKj0gSGVpZ2h0OwogICAgfQoKICAgIC8qKiBDcmVhdGUgYW5kIGluaXRpYWxpc2UgdGhlIHN1cmZhY2UgcmVzb3VyY2UgKiovCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCxTdXJmYWNlLFdJTkVEM0RSVFlQRV9TVVJGQUNFLCBTaXplKQogICAgLyogIlN0YW5kYWxvbmUiIHN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKW9iamVjdCwgTlVMTCk7CgogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5XaWR0aCAgICAgID0gV2lkdGg7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkhlaWdodCAgICAgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlVHlwZSAgICA9IE11bHRpU2FtcGxlOwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSBNdWx0aXNhbXBsZVF1YWxpdHk7CgogICAgLyogU2V0dXAgc29tZSBnbGZvcm1hdCBkZWZhdWx0cyAqLwogICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSB0YWJsZUVudHJ5LT5nbEZvcm1hdDsKICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gdGFibGVFbnRyeS0+Z2xJbnRlcm5hbDsKICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gdGFibGVFbnRyeS0+Z2xUeXBlOwoKICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAgICAgID0gMDsKICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5sZXZlbCAgICAgICAgICAgID0gTGV2ZWw7CiAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24udGFyZ2V0ICAgICAgICAgICA9IEdMX1RFWFRVUkVfMkQ7CgogICAgLyogSW50ZXJuYWwgZGF0YSAqLwogICAgb2JqZWN0LT5wb3cyV2lkdGggID0gcG93MldpZHRoOwogICAgb2JqZWN0LT5wb3cySGVpZ2h0ID0gcG93MkhlaWdodDsKCiAgICAvKiBGbGFncyAqLwogICAgb2JqZWN0LT5GbGFncyAgICAgID0gU0ZMQUdfRFlOTE9DSzsKICAgIG9iamVjdC0+RmxhZ3MgICAgIHw9IChwb3cyV2lkdGggIT0gV2lkdGggfHwgcG93MkhlaWdodCAhPSBIZWlnaHQpID8gU0ZMQUdfTk9OUE9XMiA6IDA7CiAgICBvYmplY3QtPkZsYWdzICAgICB8PSBEaXNjYXJkID8gU0ZMQUdfRElTQ0FSRCA6IDA7CiAgICBvYmplY3QtPkZsYWdzICAgICB8PSAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gRm9ybWF0KSA/IFNGTEFHX0xPQ0tBQkxFIDogMDsKICAgIG9iamVjdC0+RmxhZ3MgICAgIHw9IExvY2thYmxlID8gU0ZMQUdfTE9DS0FCTEUgOiAwOwoKCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOICE9IEZvcm1hdCkgewogICAgICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCA9IHRhYmxlRW50cnktPmJwcDsKICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT5ieXRlc1BlclBpeGVsID0gMDsKICAgIH0KCiAgICAvKiogVE9ETzogY2hhbmdlIHRoaXMgaW50byBhIHRleHR1cmUgdHJhbnNmb3JtIG1hdHJpeCBzbyB0aGF0IGl0J3MgcHJvY2Vzc2VkIGluIGhhcmR3YXJlICoqLwoKICAgIFRSQUNFKCJQb29sICVkICVkICVkICVkXG4iLFBvb2wsIFdJTkVEM0RQT09MX0RFRkFVTFQsIFdJTkVEM0RQT09MX01BTkFHRUQsIFdJTkVEM0RQT09MX1NZU1RFTU1FTSk7CgogICAgLyoqIFF1aWNrIGxvY2thYmxlIHNhbml0eSBjaGVjayBUT0RPOiByZW1vdmUgdGhpcyBhZnRlciBzdXJmYWNlcywgdXNhZ2UgYW5kIGxvY2thYmlsaXR5IGhhdmUgYmVlbiBkZWJ1Z2dlZCBwcm9wZXJseQogICAgKiB0aGlzIGZ1bmN0aW9uIGlzIHRvbyBkZWVwIHRvIG5lZWQgdG8gY2FyZSBhYm91dCB0aGluZ3MgbGlrZSB0aGlzLgogICAgKiBMZXZlbHMgbmVlZCB0byBiZSBjaGVja2VkIHRvbywgYW5kIHBvc3NpYmx5IFR5cGUgc2luY2UgdGhleSBhbGwgYWZmZWN0IHdoYXQgY2FuIGJlIGRvbmUuCiAgICAqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBzd2l0Y2goUG9vbCkgewogICAgY2FzZSBXSU5FRDNEUE9PTF9TQ1JBVENIOgogICAgICAgIGlmKCFMb2NrYWJsZSkKICAgICAgICAgICAgRklYTUUoIkNyZWF0ZSBzdXJmYWNlIGNhbGxlZCB3aXRoIGEgcG9vbCBvZiBTQ1JBVENIIGFuZCBhIExvY2thYmxlIG9mIEZBTFNFICIKICAgICAgICAgICAgICAgICJ3aGljaCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLCBzZXR0aW5nIGxvY2thYmxlIHRvIFRSVUVcbiIpOwogICAgICAgICAgICAgICAgTG9ja2FibGUgPSBUUlVFOwogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RQT09MX1NZU1RFTU1FTToKICAgICAgICBpZighTG9ja2FibGUpIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgU1lTVEVNTUVNIGFuZCBhIExvY2thYmxlIG9mIEZBTFNFLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0aGlzIGlzIGFjY2VwdGFibGUgYnV0IHVuZXhwZWN0ZWQgKEkgY2FuJ3Qga25vdyBob3cgdGhlIHN1cmZhY2UgY2FuIGJlIHVzYWJsZSEpXG4iKTsKICAgIGNhc2UgV0lORUQzRFBPT0xfTUFOQUdFRDoKICAgICAgICBpZihVc2FnZSA9PSBXSU5FRDNEVVNBR0VfRFlOQU1JQykgRklYTUUoIkNyZWF0ZSBzdXJmYWNlIGNhbGxlZCB3aXRoIGEgcG9vbCBvZiBNQU5BR0VEIGFuZCBhICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVzYWdlIG9mIERZTkFNSUMgd2hpY2ggYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSwgbm90IGRvaW5nICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFueXRoaW5nIGp1c3QgdGVsbGluZyB5b3UuXG4iKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEUE9PTF9ERUZBVUxUOiAvKlRPRE86IENyZWF0ZSBvZmZzY3JlZW4gcGxhaW4gY2FuIGNhdXNlIHRoaXMgY2hlY2sgdG8gZmFpbC4uLiwgZmluZCBvdXQgaWYgaXQgc2hvdWxkICovCiAgICAgICAgaWYoIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSAmJiAhKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgICAgICAgICAmJiAhKFVzYWdlICYmIFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwgKSAmJiBMb2NrYWJsZSkKICAgICAgICAgICAgV0FSTigiQ3JlYXRpbmcgYSBzdXJmYWNlIHdpdGggYSBQT09MIG9mIERFRkFVTFQgd2l0aCBMb2NrYWJsZSB0cnVlLCB0aGF0IGRvZXNuJ3Qgc3BlY2lmeSBEWU5BTUlDIHVzYWdlLlxuIik7CiAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIiglcCkgVW5rbm93biBwb29sICVkXG4iLCBUaGlzLCBQb29sKTsKICAgIGJyZWFrOwogICAgfTsKCiAgICBpZiAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfREVGQVVMVCkgewogICAgICAgIEZJWE1FKCJUcnlpbmcgdG8gY3JlYXRlIGEgcmVuZGVyIHRhcmdldCB0aGF0IGlzbid0IGluIHRoZSBkZWZhdWx0IHBvb2xcbiIpOwogICAgfQoKICAgIC8qIG1hcmsgdGhlIHRleHR1cmUgYXMgZGlydHkgc28gdGhhdCBpdCBnZXRzIGxvYWRlZCBmaXJzdCB0aW1lIGFyb3VuZCovCiAgICBJV2luZUQzRFN1cmZhY2VfQWRkRGlydHlSZWN0KCpwcFN1cmZhY2UsIE5VTEwpOwogICAgVFJBQ0UoIiglcCkgOiB3KCVkKSBoKCVkKSBmbXQoJWQsJXMpIGxvY2thYmxlKCVkKSBzdXJmQCVwLCBzdXJmbWVtQCVwLCAlZCBieXRlc1xuIiwKICAgICAgICAgICBUaGlzLCBXaWR0aCwgSGVpZ2h0LCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLAogICAgICAgICAgIChXSU5FRDNERk1UX0QxNl9MT0NLQUJMRSA9PSBGb3JtYXQpLCAqcHBTdXJmYWNlLCBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgb2JqZWN0LT5yZXNvdXJjZS5zaXplKTsKCiAgICAvKiBTdG9yZSB0aGUgRGlyZWN0RHJhdyBwcmltYXJ5IHN1cmZhY2UuIFRoaXMgaXMgdGhlIGZpcnN0IHJlbmRlcnRhcmdldCBzdXJmYWNlIGNyZWF0ZWQgKi8KICAgIGlmKCAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSAmJiAoIVRoaXMtPmRkcmF3X3ByaW1hcnkpICkKICAgICAgICBUaGlzLT5kZHJhd19wcmltYXJ5ID0gKElXaW5lRDNEU3VyZmFjZSAqKSBvYmplY3Q7CgogICAgLyogTG9vayBhdCB0aGUgaW1wbGVtZW50YXRpb24gYW5kIHNldCB0aGUgY29ycmVjdCBWdGFibGUgKi8KICAgIHN3aXRjaChJbXBsKSB7CiAgICAgICAgY2FzZSBTVVJGQUNFX09QRU5HTDoKICAgICAgICAgICAgLyogTm90aGluZyB0byBkbywgaXQncyBzZXQgYWxyZWFkeSAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTVVJGQUNFX0dESToKICAgICAgICAgICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVHRElTdXJmYWNlX1Z0Ymw7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAvKiBUbyBiZSBzdXJlIHRvIGNhdGNoIHRoaXMgKi8KICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlcXVlc3RlZCBzdXJmYWNlIGltcGxlbWVudGF0aW9uICVkIVxuIiwgSW1wbCk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgbGlzdF9pbml0KCZvYmplY3QtPnJlbmRlcmJ1ZmZlcnMpOwoKICAgIC8qIENhbGwgdGhlIHByaXZhdGUgc2V0dXAgcm91dGluZSAqLwogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9Qcml2YXRlU2V0dXAoIChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0ICk7Cgp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgTGV2ZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlKiogcHBUZXh0dXJlLCBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVGV4dHVyZUltcGwgKm9iamVjdDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgVUlOVCB0bXBXOwogICAgVUlOVCB0bXBIOwogICAgSFJFU1VMVCBocjsKICAgIHVuc2lnbmVkIGludCBwb3cyV2lkdGg7CiAgICB1bnNpZ25lZCBpbnQgcG93MkhlaWdodDsKCgogICAgVFJBQ0UoIiglcCkgOiBXaWR0aCAlZCwgSGVpZ2h0ICVkLCBMZXZlbHMgJWQsIFVzYWdlICUjeFxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgTGV2ZWxzLCBVc2FnZSk7CiAgICBUUkFDRSgiRm9ybWF0ICUjeCAoJXMpLCBQb29sICUjeCwgcHBUZXh0dXJlICVwLCBwU2hhcmVkSGFuZGxlICVwLCBwYXJlbnQgJXBcbiIsCiAgICAgICAgICAgIEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIFBvb2wsIHBwVGV4dHVyZSwgcFNoYXJlZEhhbmRsZSwgcGFyZW50KTsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBUZXh0dXJlLCBXSU5FRDNEUlRZUEVfVEVYVFVSRSwgMCk7CiAgICBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUob2JqZWN0LT5iYXNlVGV4dHVyZSk7ICAgIAogICAgb2JqZWN0LT53aWR0aCAgPSBXaWR0aDsKICAgIG9iamVjdC0+aGVpZ2h0ID0gSGVpZ2h0OwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHBvdzJXaWR0aCA9IFdpZHRoOwogICAgICAgIHBvdzJIZWlnaHQgPSBIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChwb3cyV2lkdGggPCBXaWR0aCkgcG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChwb3cySGVpZ2h0IDwgSGVpZ2h0KSBwb3cySGVpZ2h0IDw8PSAxOwogICAgfQoKICAgIC8qKiBGSVhNRTogYWRkIHN1cHBvcnQgZm9yIHJlYWwgbm9uLXBvd2VyLXR3byBpZiBpdCdzIHByb3ZpZGVkIGJ5IHRoZSB2aWRlbyBjYXJkICoqLwogICAgLyogUHJlY2FsY3VsYXRlZCBzY2FsaW5nIGZvciAnZmFrZWQnIG5vbiBwb3dlciBvZiB0d28gdGV4dHVyZSBjb29yZHMgKi8KICAgIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3JYICA9ICAoKChmbG9hdClXaWR0aCkgIC8gKChmbG9hdClwb3cyV2lkdGgpKTsKICAgIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3JZICA9ICAoKChmbG9hdClIZWlnaHQpIC8gKChmbG9hdClwb3cySGVpZ2h0KSk7CiAgICBUUkFDRSgiIHhmKCVmKSB5ZiglZilcbiIsIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3JYLCBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yWSk7CgogICAgLyogQ2FsY3VsYXRlIGxldmVscyBmb3IgbWlwIG1hcHBpbmcgKi8KICAgIGlmIChMZXZlbHMgPT0gMCkgewogICAgICAgIFRSQUNFKCJjYWxjdWxhdGluZyBsZXZlbHMgJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBXaWR0aDsKICAgICAgICB0bXBIID0gSGVpZ2h0OwogICAgICAgIHdoaWxlICh0bXBXID4gMSB8fCB0bXBIID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIHRtcEggPSBtYXgoMSwgdG1wSCA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gV2lkdGg7CiAgICB0bXBIID0gSGVpZ2h0OwogICAgZm9yIChpID0gMDsgaSA8IG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzOyBpKyspCiAgICB7CiAgICAgICAgLyogdXNlIHRoZSBjYWxsYmFjayB0byBjcmVhdGUgdGhlIHRleHR1cmUgc3VyZmFjZSAqLwogICAgICAgIGhyID0gRDNEQ0JfQ3JlYXRlU3VyZmFjZShUaGlzLT5wYXJlbnQsIHBhcmVudCwgdG1wVywgdG1wSCwgRm9ybWF0LCBVc2FnZSwgUG9vbCwgaSwgV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YLCAmb2JqZWN0LT5zdXJmYWNlc1tpXSxOVUxMKTsKICAgICAgICBpZiAoaHIhPSBXSU5FRDNEX09LIHx8ICggKElXaW5lRDNEU3VyZmFjZUltcGwgKikgb2JqZWN0LT5zdXJmYWNlc1tpXSktPkZsYWdzICYgU0ZMQUdfT1ZFUlNJWkUpIHsKICAgICAgICAgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgc3VyZmFjZSAgJXBcbiIsIG9iamVjdCk7CiAgICAgICAgICAgIC8qIGNsZWFuIHVwICovCiAgICAgICAgICAgIG9iamVjdC0+c3VyZmFjZXNbaV0gPSBOVUxMOwogICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RUZXh0dXJlICopb2JqZWN0KTsKCiAgICAgICAgICAgICpwcFRleHR1cmUgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQoKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKG9iamVjdC0+c3VyZmFjZXNbaV0sIChJV2luZUQzREJhc2UgKilvYmplY3QpOwogICAgICAgIFRSQUNFKCJDcmVhdGVkIHN1cmZhY2UgbGV2ZWwgJWQgQCAlcFxuIiwgaSwgb2JqZWN0LT5zdXJmYWNlc1tpXSk7CiAgICAgICAgLyogY2FsY3VsYXRlIHRoZSBuZXh0IG1pcG1hcCBsZXZlbCAqLwogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkICB0ZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBVSU5UIERlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIExldmVscywgRFdPUkQgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmUgKipwcFZvbHVtZVRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSAqcFNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFVk9MVU1FRk4gRDNEQ0JfQ3JlYXRlVm9sdW1lKSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZUltcGwgKm9iamVjdDsKICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICAgIGk7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICB0bXBXOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgdG1wSDsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHRtcEQ7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVm9sdW1lVGV4dHVyZSwgV0lORUQzRFJUWVBFX1ZPTFVNRVRFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIDogVyglZCkgSCglZCkgRCglZCksIEx2bCglZCkgVXNhZ2UoJWQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBMZXZlbHMsIFVzYWdlLCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBkZWJ1Z19kM2Rwb29sKFBvb2wpKTsKCiAgICBvYmplY3QtPndpZHRoICA9IFdpZHRoOwogICAgb2JqZWN0LT5oZWlnaHQgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmRlcHRoICA9IERlcHRoOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBXaWR0aDsKICAgICAgICB0bXBIID0gSGVpZ2h0OwogICAgICAgIHRtcEQgPSBEZXB0aDsKICAgICAgICB3aGlsZSAodG1wVyA+IDEgfHwgdG1wSCA+IDEgfHwgdG1wRCA+IDEpIHsKICAgICAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gV2lkdGg7CiAgICB0bXBIID0gSGVpZ2h0OwogICAgdG1wRCA9IERlcHRoOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKQogICAgewogICAgICAgIEhSRVNVTFQgaHI7CiAgICAgICAgLyogQ3JlYXRlIHRoZSB2b2x1bWUgKi8KICAgICAgICBociA9IEQzRENCX0NyZWF0ZVZvbHVtZShUaGlzLT5wYXJlbnQsIHBhcmVudCwgdG1wVywgdG1wSCwgdG1wRCwgRm9ybWF0LCBQb29sLCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RWb2x1bWUgKiopJm9iamVjdC0+dm9sdW1lc1tpXSwgcFNoYXJlZEhhbmRsZSk7CgogICAgICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICAgICAgRVJSKCJDcmVhdGluZyBhIHZvbHVtZSBmb3IgdGhlIHZvbHVtZSB0ZXh0dXJlIGZhaWxlZCglMDh4KVxuIiwgaHIpOwogICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RWb2x1bWVUZXh0dXJlICopIG9iamVjdCk7CiAgICAgICAgICAgICpwcFZvbHVtZVRleHR1cmUgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQoKICAgICAgICAvKiBTZXQgaXRzIGNvbnRhaW5lciB0byB0aGlzIG9iamVjdCAqLwogICAgICAgIElXaW5lRDNEVm9sdW1lX1NldENvbnRhaW5lcihvYmplY3QtPnZvbHVtZXNbaV0sIChJV2luZUQzREJhc2UgKilvYmplY3QpOwoKICAgICAgICAvKiBjYWxjdWFsdGUgdGhlIG5leHQgbWlwbWFwIGxldmVsICovCiAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgIHRtcEggPSBtYXgoMSwgdG1wSCA+PiAxKTsKICAgICAgICB0bXBEID0gbWF4KDEsIHRtcEQgPj4gMSk7CiAgICB9CgogICAgKnBwVm9sdW1lVGV4dHVyZSA9IChJV2luZUQzRFZvbHVtZVRleHR1cmUgKikgb2JqZWN0OwogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIHZvbHVtZSB0ZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgVUlOVCBEZXB0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZSoqIHBwVm9sdW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSogcFNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZvbHVtZUltcGwgICAgICAgICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCk7CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFZvbHVtZSwgV0lORUQzRFJUWVBFX1ZPTFVNRSwgKChXaWR0aCAqIGZvcm1hdERlc2MtPmJwcCkgKiBIZWlnaHQgKiBEZXB0aCkpCgogICAgVFJBQ0UoIiglcCkgOiBXKCVkKSBIKCVkKSBEKCVkKSwgVXNhZ2UoJWQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBVc2FnZSwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwgZGVidWdfZDNkcG9vbChQb29sKSk7CgogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5XaWR0aCAgID0gV2lkdGg7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkhlaWdodCAgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkRlcHRoICAgPSBEZXB0aDsKICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCAgICAgICA9IGZvcm1hdERlc2MtPmJwcDsKCiAgICAvKiogTm90ZTogVm9sdW1lIHRleHR1cmVzIGNhbm5vdCBiZSBkeHRuLCBoZW5jZSBubyBuZWVkIHRvIGNoZWNrIGhlcmUgKiovCiAgICBvYmplY3QtPmxvY2thYmxlICAgICAgICAgICAgPSBUUlVFOwogICAgb2JqZWN0LT5sb2NrZWQgICAgICAgICAgICAgID0gRkFMU0U7CiAgICBtZW1zZXQoJm9iamVjdC0+bG9ja2VkQm94LCAwLCBzaXplb2YoV0lORUQzREJPWCkpOwogICAgb2JqZWN0LT5kaXJ0eSAgICAgICAgICAgICAgID0gVFJVRTsKCiAgICByZXR1cm4gSVdpbmVEM0RWb2x1bWVfQWRkRGlydHlCb3goKElXaW5lRDNEVm9sdW1lICopIG9iamVjdCwgTlVMTCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQ3ViZVRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEVkZ2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIExldmVscywgRFdPUkQgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEQ3ViZVRleHR1cmUgKipwcEN1YmVUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFU1VSRkFDRUZOIEQzRENCX0NyZWF0ZVN1cmZhY2UpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQ3ViZVRleHR1cmVJbXBsICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgaSwgajsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICB0bXBXOwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgIGhyOwogICAgdW5zaWduZWQgaW50IHBvdzJFZGdlTGVuZ3RoICA9IEVkZ2VMZW5ndGg7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoIUdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfQ1VCRV9NQVApICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfU0NSQVRDSCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUcmllZCB0byBjcmVhdGUgbm90IHN1cHBvcnRlZCBjdWJlIHRleHR1cmVcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBDdWJlVGV4dHVyZSwgV0lORUQzRFJUWVBFX0NVQkVURVhUVVJFLCAwKTsKICAgIEQzRElOSVRJQUxJWkVCQVNFVEVYVFVSRShvYmplY3QtPmJhc2VUZXh0dXJlKTsKCiAgICBUUkFDRSgiKCVwKSBDcmVhdGUgQ3ViZSBUZXh0dXJlXG4iLCBUaGlzKTsKCiAgICAvKiogTm9uLXBvd2VyMiBzdXBwb3J0ICoqLwoKICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgcG93MkVkZ2VMZW5ndGggPSAxOwogICAgd2hpbGUgKHBvdzJFZGdlTGVuZ3RoIDwgRWRnZUxlbmd0aCkgcG93MkVkZ2VMZW5ndGggPDw9IDE7CgogICAgb2JqZWN0LT5lZGdlTGVuZ3RoICAgICAgICAgICA9IEVkZ2VMZW5ndGg7CiAgICAvKiBUT0RPOiBzdXBwb3J0IGZvciBuYXRpdmUgbm9uLXBvd2VyIDIgKi8KICAgIC8qIFByZWNhbGN1bGF0ZWQgc2NhbGluZyBmb3IgJ2Zha2VkJyBub24gcG93ZXIgb2YgdHdvIHRleHR1cmUgY29vcmRzICovCiAgICBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yICAgID0gKChmbG9hdClFZGdlTGVuZ3RoKSAvICgoZmxvYXQpcG93MkVkZ2VMZW5ndGgpOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBFZGdlTGVuZ3RoOwogICAgICAgIHdoaWxlICh0bXBXID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IEVkZ2VMZW5ndGg7CiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHM7IGkrKykgewoKICAgICAgICAvKiBDcmVhdGUgdGhlIDYgZmFjZXMgKi8KICAgICAgICBmb3IgKGogPSAwOyBqIDwgNjsgaisrKSB7CgogICAgICAgICAgICBocj1EM0RDQl9DcmVhdGVTdXJmYWNlKFRoaXMtPnBhcmVudCwgcGFyZW50LCB0bXBXLCB0bXBXLCBGb3JtYXQsIFVzYWdlLCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLyogTGV2ZWwgKi8sIGosICZvYmplY3QtPnN1cmZhY2VzW2pdW2ldLHBTaGFyZWRIYW5kbGUpOwoKICAgICAgICAgICAgaWYoaHIhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICAgICAgaW50IGs7CiAgICAgICAgICAgICAgICBpbnQgbDsKICAgICAgICAgICAgICAgIGZvciAobCA9IDA7IGwgPCBqOyBsKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShvYmplY3QtPnN1cmZhY2VzW2pdW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgPSAwOyBsIDwgNjsgbCsrKSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uob2JqZWN0LT5zdXJmYWNlc1tsXVtqXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIEZhaWxlZCB0byBjcmVhdGUgc3VyZmFjZVxuIixvYmplY3QpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLG9iamVjdCk7CiAgICAgICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2pdW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgVFJBQ0UoIkNyZWF0ZWQgc3VyZmFjZSBsZXZlbCAlZCBAICVwLFxuIiwgaSwgb2JqZWN0LT5zdXJmYWNlc1tqXVtpXSk7CiAgICAgICAgfQogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgQ3ViZSBUZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgKnBwQ3ViZVRleHR1cmUgPSAoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKSBvYmplY3Q7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVRdWVyeShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RRVUVSWVRZUEUgVHlwZSwgSVdpbmVEM0RRdWVyeSAqKnBwUXVlcnksIElVbmtub3duKiBwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUXVlcnlJbXBsICpvYmplY3Q7IC8qTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICovCiAgICBIUkVTVUxUIGhyID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CgogICAgLyogSnVzdCBhIGNoZWNrIHRvIHNlZSBpZiB3ZSBzdXBwb3J0IHRoaXMgdHlwZSBvZiBxdWVyeSAqLwogICAgc3dpdGNoKFR5cGUpIHsKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgVFJBQ0UoIiglcCkgb2NjbHVzaW9uIHF1ZXJ5XG4iLCBUaGlzKTsKICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfT0NDTFVTSU9OX1FVRVJZKSkKICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0FSTigiVW5zdXBwb3J0ZWQgaW4gbG9jYWwgT3BlbkdMIGltcGxlbWVudGF0aW9uOiBBUkJfT0NDTFVTSU9OX1FVRVJZL05WX09DQ0xVU0lPTl9RVUVSWVxuIik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0VWRU5UOgogICAgICAgIGlmKCEoR0xfU1VQUE9SVChOVl9GRU5DRSkgfHwgR0xfU1VQUE9SVChBUFBMRV9GRU5DRSkgKSkgewogICAgICAgICAgICAvKiBIYWxmLUxpZmUgMiBuZWVkcyB0aGlzIHF1ZXJ5LiBJdCBkb2VzIG5vdCByZW5kZXIgdGhlIG1haW4gbWVudSBjb3JyZWN0bHkgb3RoZXJ3aXNlCiAgICAgICAgICAgICAqIFByZXRlbmQgdG8gc3VwcG9ydCBpdCwgZmFraW5nIHRoaXMgcXVlcnkgZG9lcyBub3QgZG8gbXVjaCBoYXJtIGV4Y2VwdCBwb3RlbnRpYWxseSBsb3dlcmluZyBwZXJmb3JtYW5jZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgRXZlbnQgcXVlcnk6IFVuaW1wbGVtZW50ZWQsIGJ1dCBwcmV0ZW5kaW5nIHRvIGJlIHN1cHBvcnRlZFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGhyID0gV0lORUQzRF9PSzsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkNBQ0hFOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1JFU09VUkNFTUFOQUdFUjoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhTVEFUUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVA6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRElTSk9JTlQ6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRlJFUToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVBFTElORVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfSU5URVJGQUNFVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJWEVMVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9CQU5EV0lEVEhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0NBQ0hFVVRJTElaQVRJT046CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIFVuaGFuZGxlZCBxdWVyeSB0eXBlICVkXG4iLCBUaGlzLCBUeXBlKTsKICAgIH0KICAgIGlmKE5VTEwgPT0gcHBRdWVyeSB8fCBociAhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgUXVlcnkpCiAgICBvYmplY3QtPnR5cGUgICAgICAgICA9IFR5cGU7CiAgICAvKiBhbGxvY2F0ZWQgdGhlICdleHRlbmRlZCcgZGF0YSBiYXNlZCBvbiB0aGUgdHlwZSBvZiBxdWVyeSByZXF1ZXN0ZWQgKi8KICAgIHN3aXRjaChUeXBlKXsKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfT0NDTFVTSU9OX1FVRVJZKSkgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBBbGxvY2F0aW5nIGRhdGEgZm9yIGFuIG9jY2x1c2lvbiBxdWVyeVxuIiwgVGhpcyk7CiAgICAgICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lUXVlcnlPY2NsdXNpb25EYXRhKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5RdWVyaWVzQVJCKDEsICYoKFdpbmVRdWVyeU9jY2x1c2lvbkRhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+cXVlcnlJZCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfRVZFTlQ6CiAgICAgICAgLyogVE9ETzogR0xfQVBQTEVfZmVuY2UgKi8KICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0ZFTkNFKSkgewogICAgICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5RXZlbnREYXRhKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5GZW5jZXNBUFBMRSgxLCAmKChXaW5lUXVlcnlFdmVudERhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+ZmVuY2VJZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GZW5jZXNBUFBMRSIpOwogICAgICAgIH0gZWxzZSBpZihHTF9TVVBQT1JUKE5WX0ZFTkNFKSkgewogICAgICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5RXZlbnREYXRhKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5GZW5jZXNOVigxLCAmKChXaW5lUXVlcnlFdmVudERhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+ZmVuY2VJZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GZW5jZXNOViIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkNBQ0hFOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1JFU09VUkNFTUFOQUdFUjoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhTVEFUUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVA6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRElTSk9JTlQ6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRlJFUToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVBFTElORVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfSU5URVJGQUNFVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJWEVMVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9CQU5EV0lEVEhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0NBQ0hFVVRJTElaQVRJT046CiAgICBkZWZhdWx0OgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gMDsKICAgICAgICBGSVhNRSgiKCVwKSBVbmhhbmRsZWQgcXVlcnkgdHlwZSAlZFxuIixUaGlzICwgVHlwZSk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgUXVlcnkgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3cKICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgbW9kaWZpZXMgYSBIV05EJ3MgU3R5bGUgYW5kIEV4U3R5bGUgZm9yIHByb3BlcgogKiBmdWxsc2NyZWVuIHVzZS4KICoKICogUGFyYW1zOgogKiAgaWZhY2U6IFBvaW50ZXIgdG8gdGhlIElXaW5lRDNERGV2aWNlIGludGVyZmFjZQogKiAgd2luZG93OiBXaW5kb3cgdG8gc2V0dXAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgTE9ORyBzdHlsZSwgZXhTdHlsZTsKICAgIC8qIERvbid0IGRvIGFueXRoaW5nIGlmIGFuIG9yaWdpbmFsIHN0eWxlIGlzIHN0b3JlZC4KICAgICAqIFRoYXQgc2hvdWxkbid0IGhhcHBlbgogICAgICovCiAgICBUUkFDRSgiKCVwKTogU2V0dGluZyB1cCB3aW5kb3cgJXAgZm9yIGV4Y2x1c2l2ZSBtb2RlXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgaWYgKFRoaXMtPnN0eWxlIHx8IFRoaXMtPmV4U3R5bGUpIHsKICAgICAgICBFUlIoIiglcCk6IFdhbnQgdG8gY2hhbmdlIHRoZSB3aW5kb3cgcGFyYW1ldGVycyBvZiBIV05EICVwLCBidXQgIgogICAgICAgICAgICAiYW5vdGhlciBzdHlsZSBpcyBzdG9yZWQgZm9yIHJlc3RvcmF0aW9uIGFmdGVyd2FyZHNcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICB9CgogICAgLyogR2V0IHRoZSBwYXJhbWV0ZXJzIGFuZCBzYXZlIHRoZW0gKi8KICAgIHN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUpOwogICAgZXhTdHlsZSA9IEdldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUpOwogICAgVGhpcy0+c3R5bGUgPSBzdHlsZTsKICAgIFRoaXMtPmV4U3R5bGUgPSBleFN0eWxlOwoKICAgIC8qIEZpbHRlciBvdXQgd2luZG93IGRlY29yYXRpb25zICovCiAgICBzdHlsZSAmPSB+V1NfQ0FQVElPTjsKICAgIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwogICAgZXhTdHlsZSAmPSB+V1NfRVhfV0lORE9XRURHRTsKICAgIGV4U3R5bGUgJj0gfldTX0VYX0NMSUVOVEVER0U7CgogICAgLyogTWFrZSBzdXJlIHRoZSB3aW5kb3cgaXMgbWFuYWdlZCwgb3RoZXJ3aXNlIHdlIHdvbid0IGdldCBrZXlib2FyZCBpbnB1dCAqLwogICAgc3R5bGUgfD0gV1NfUE9QVVAgfCBXU19TWVNNRU5VOwoKICAgIFRSQUNFKCJPbGQgc3R5bGUgd2FzICUwOHgsJTA4eCwgc2V0dGluZyB0byAlMDh4LCUwOHhcbiIsCiAgICAgICAgICBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSwgc3R5bGUsIGV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBzdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBleFN0eWxlKTsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlLiAqLwogICAgU2V0V2luZG93UG9zKHdpbmRvdywgSFdORF9UT1AsIDAsIDAsCiAgICAgICAgICAgIFRoaXMtPmRkcmF3X3dpZHRoLCBUaGlzLT5kZHJhd19oZWlnaHQsIFNXUF9GUkFNRUNIQU5HRUQpOwogICAgU2hvd1dpbmRvdyh3aW5kb3csIFNXX05PUk1BTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCByZXN0b3JlcyBhIHdpbmRvd3MnIHByb3BlcnRpZXMgd2hlbiB0YWtpbmcgaXQgb3V0CiAqIG9mIGZ1bGxzY3JlZW4gbW9kZQogKgogKiBQYXJhbXM6CiAqICBpZmFjZTogUG9pbnRlciB0byB0aGUgSVdpbmVEM0REZXZpY2UgaW50ZXJmYWNlCiAqICB3aW5kb3c6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgLyogVGhpcyBjb3VsZCBiZSBhIEREU0NMX05PUk1BTCAtPiBERFNDTF9OT1JNQUwKICAgICAqIHN3aXRjaCwgZG8gbm90aGluZwogICAgICovCiAgICBpZiAoIVRoaXMtPnN0eWxlICYmICFUaGlzLT5leFN0eWxlKSByZXR1cm47CgogICAgVFJBQ0UoIiglcCk6IFJlc3RvcmluZyB3aW5kb3cgc2V0dGluZ3Mgb2Ygd2luZG93ICVwIHRvICUwOHgsICUwOHhcbiIsCiAgICAgICAgICBUaGlzLCB3aW5kb3csIFRoaXMtPnN0eWxlLCBUaGlzLT5leFN0eWxlKTsKCiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9TVFlMRSwgVGhpcy0+c3R5bGUpOwogICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSwgVGhpcy0+ZXhTdHlsZSk7CgogICAgLyogRGVsZXRlIHRoZSBvbGQgdmFsdWVzICovCiAgICBUaGlzLT5zdHlsZSA9IDA7CiAgICBUaGlzLT5leFN0eWxlID0gMDsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlICovCiAgICBTZXRXaW5kb3dQb3Mod2luZG93LCAwIC8qIEluc2VydEFmdGVyLCBpZ25vcmVkICovLAogICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8qIFBvcywgU2l6ZSwgaWdub3JlZCAqLwogICAgICAgICAgICAgICAgIFNXUF9GUkFNRUNIQU5HRUQgfCBTV1BfTk9NT1ZFIHwgU1dQX05PU0laRSB8IFNXUF9OT1pPUkRFUik7Cn0KCi8qIGV4YW1wbGUgYXQgaHR0cDovL3d3dy5mYWlyeWVuZ2luZS5jb20vYXJ0aWNsZXMvZHhtdWx0aXZpZXdzLmh0bSAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluKiogcHBTd2FwQ2hhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duKiBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVJFTkRFUlRBUkdFVEZOIEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFREVQVEhTVEVOQ0lMU1VSRkFDRUZOIEQzRENCX0NyZWF0ZURlcHRoU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgSERDICAgICAgICAgICAgICAgICAgICAgaERjOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICAqb2JqZWN0OyAvKiogTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICoqLwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgSVVua25vd24gICAgICAgICAgICAgICAqYnVmZmVyUGFyZW50OwogICAgRGlzcGxheSAgICAgICAgICAgICAgICAqZGlzcGxheTsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgQWRpdGlvbmFsIFN3YXAgQ2hhaW5cbiIsIFRoaXMpOwoKICAgLyoqIEZJWE1FOiBUZXN0IHVuZGVyIHdpbmRvd3MgdG8gZmluZCBvdXQgd2hhdCB0aGUgbGlmZSBjeWNsZSBvZiBhIHN3YXAgY2hhaW4gaXMsCiAgICogZG9lcyBhIGRldmljZSBob2xkIGEgcmVmZXJlbmNlIHRvIGEgc3dhcCBjaGFpbiBnaXZpbmcgdGhlbSBhIGxpZmV0aW1lIG9mIHRoZSBkZXZpY2UKICAgKiBvciBkb2VzIHRoZSBzd2FwIGNoYWluIG5vdGlmeSB0aGUgZGV2aWNlIG9mIGl0cyBkZXN0cnVjdGlvbi4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogQ2hlY2sgdGhlIHBhcmFtcyAqLwogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCA+IFdJTkVEM0RQUkVTRU5UX0JBQ0tfQlVGRkVSX01BWCkgewogICAgICAgIEVSUigiQXBwIHJlcXVlc3RlZCAlZCBiYWNrIGJ1ZmZlcnMsIHRoaXMgaXMgbm90IHN1cHBvcnRlZCBmb3Igbm93XG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50KTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCA+IDEpIHsKICAgICAgICBGSVhNRSgiVGhlIGFwcCByZXF1ZXN0cyBtb3JlIHRoYW4gb25lIGJhY2sgYnVmZmVyLCB0aGlzIGNhbid0IGJlIHN1cHBvcnRlZCBwcm9wZXJseS4gUGxlYXNlIGNvbmZpZ3VyZSB0aGUgYXBwbGljYXRpb24gdG8gdXNlIGRvdWJsZSBidWZmZXJpbmcoPTEgYmFjayBidWZmZXIpIGlmIHBvc3NpYmxlXG4iKTsKICAgIH0KCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFN3YXBDaGFpbikKCiAgICAvKioqKioqKioqKioqKioqKioqKioqCiAgICAqIExvb2t1cCB0aGUgd2luZG93IEhhbmRsZSBhbmQgdGhlIHJlbGF0aW5nIFggd2luZG93IGhhbmRsZQogICAgKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogU2V0dXAgaHduZCB3ZSBhcmUgdXNpbmcsIHBsdXMgd2hpY2ggZGlzcGxheSB0aGlzIGVxdWF0ZXMgdG8gKi8KICAgIG9iamVjdC0+d2luX2hhbmRsZSA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93OwogICAgaWYgKCFvYmplY3QtPndpbl9oYW5kbGUpIHsKICAgICAgICBvYmplY3QtPndpbl9oYW5kbGUgPSBUaGlzLT5jcmVhdGVQYXJtcy5oRm9jdXNXaW5kb3c7CiAgICB9CgogICAgb2JqZWN0LT53aW5faGFuZGxlID0gR2V0QW5jZXN0b3Iob2JqZWN0LT53aW5faGFuZGxlLCBHQV9ST09UKTsKICAgIGlmICggISggb2JqZWN0LT53aW4gPSAoV2luZG93KUdldFByb3BBKG9iamVjdC0+d2luX2hhbmRsZSwgIl9fd2luZV94MTFfd2hvbGVfd2luZG93IikgKSApIHsKICAgICAgICBFUlIoIkNhbid0IGdldCBkcmF3YWJsZSAod2luZG93KSwgSFdORDolcCBkb2Vzbid0IGhhdmUgdGhlIHByb3BlcnR5IF9fd2luZV94MTFfd2hvbGVfd2luZG93XG4iLCBvYmplY3QtPndpbl9oYW5kbGUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KICAgIGhEYyAgICAgICAgICAgICAgICA9IEdldERDKG9iamVjdC0+d2luX2hhbmRsZSk7CiAgICBkaXNwbGF5ICAgICAgICAgICAgPSBnZXRfZGlzcGxheShoRGMpOwogICAgUmVsZWFzZURDKG9iamVjdC0+d2luX2hhbmRsZSwgaERjKTsKICAgIFRSQUNFKCJVc2luZyBhIGRpc3BsYXkgb2YgJXAgJXBcbiIsIGRpc3BsYXksIGhEYyk7CgogICAgaWYgKE5VTEwgPT0gZGlzcGxheSB8fCBOVUxMID09IGhEYykgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBnZXQgYSBkaXNwbGF5IGFuZCBIRGMgZm9yIFdpbmRvdyAlcFxuIiwgb2JqZWN0LT53aW5faGFuZGxlKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CgogICAgaWYgKG9iamVjdC0+d2luID09IDApIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gZ2V0IGEgdmFsaWQgWFZpc3VpYWwgSUQgZm9yIHRoZSB3aW5kb3cgJXBcbiIsIG9iamVjdC0+d2luX2hhbmRsZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgfQoKICAgIG9iamVjdC0+b3JpZ193aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pOwogICAgb2JqZWN0LT5vcmlnX2hlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pOwogICAgb2JqZWN0LT5vcmlnX2ZtdCA9IHBpeGVsZm9ybWF0X2Zvcl9kZXB0aChHZXREZXZpY2VDYXBzKGhEYywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaERjLCBQTEFORVMpKTsKCiAgICAvKiogTVNETjogSWYgV2luZG93ZWQgaXMgVFJVRSBhbmQgZWl0aGVyIG9mIHRoZSBCYWNrQnVmZmVyV2lkdGgvSGVpZ2h0IHZhbHVlcyBpcyB6ZXJvLAogICAgICogIHRoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZGltZW5zaW9uIG9mIHRoZSBjbGllbnQgYXJlYSBvZiB0aGUgaERldmljZVdpbmRvdwogICAgICogIChvciB0aGUgZm9jdXMgd2luZG93LCBpZiBoRGV2aWNlV2luZG93IGlzIE5VTEwpIGlzIHRha2VuLgogICAgICAqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQgJiYKICAgICAgICAoKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPT0gMCkgfHwKICAgICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ID09IDApKSkgewoKICAgICAgICBSRUNUIFJlY3Q7CiAgICAgICAgR2V0Q2xpZW50UmVjdChvYmplY3QtPndpbl9oYW5kbGUsICZSZWN0KTsKCiAgICAgICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPT0gMCkgewogICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPSBSZWN0LnJpZ2h0OwogICAgICAgICAgIFRSQUNFKCJVcGRhdGluZyB3aWR0aCB0byAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCk7CiAgICAgICAgfQogICAgICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCA9PSAwKSB7CiAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgPSBSZWN0LmJvdHRvbTsKICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgaGVpZ2h0IHRvICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFB1dCB0aGUgY29ycmVjdCBmaWd1cmVzIGluIHRoZSBwcmVzZW50YXRpb24gcGFyYW1ldGVycyAqLwogICAgVFJBQ0UoIkNvcHlpbmcgYWNyb3NzIHByZXNlbnRhdGlvbiBwYXJhbWV0ZXJzXG4iKTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zID0gKnBQcmVzZW50YXRpb25QYXJhbWV0ZXJzOwoKICAgIFRSQUNFKCJjYWxsaW5nIHJlbmRlcnRhcmdldCBDQlxuIik7CiAgICBociA9IEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCgoSVVua25vd24gKikgVGhpcy0+cGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5mcm9udEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovKTsKICAgIGlmIChvYmplY3QtPmZyb250QnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKG9iamVjdC0+ZnJvbnRCdWZmZXIsIChJV2luZUQzREJhc2UgKilvYmplY3QpOwogICAgfSBlbHNlIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgdGhlIGZyb250IGJ1ZmZlclxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKioKICAgICogQ3JlYXRlIGFuIG9wZW5nbCBjb250ZXh0IGZvciB0aGUgZGlzcGxheSB2aXN1YWwKICAgICogIE5PVEU6IHRoZSB2aXN1YWwgaXMgY2hvc2VuIGFzIHRoZSB3aW5kb3cgaXMgY3JlYXRlZCBhbmQgdGhlIGdsY29udGV4dCBjYW5ub3QKICAgICogICAgIHVzZSBkaWZmZXJlbnQgcHJvcGVydGllcyBhZnRlciB0aGF0IHBvaW50IGluIHRpbWUuIEZJWE1FOiBIb3cgdG8gaGFuZGxlIHdoZW4gcmVxdWVzdGVkIGZvcm1hdAogICAgKiAgICAgZG9lc24ndCBtYXRjaCBhY3R1YWwgdmlzdWFsPyBDYW5ub3QgY2hvb3NlIG9uZSBoZXJlIC0gY29kZSByZW1vdmVkIGFzIGl0IE9OTFkgd29ya3MgaWYgdGhlIG9uZQogICAgKiAgICAgaXQgY2hvb3NlcyBpcyBpZGVudGljYWwgdG8gdGhlIG9uZSBhbHJlYWR5IGJlaW5nIHVzZWQhCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIC8qKiBGSVhNRTogSGFuZGxlIHN0ZW5jaWwgYXBwcm9wcmlhdGVseSB2aWEgRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCAvIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgKiovCgogICAgb2JqZWN0LT5jb250ZXh0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihvYmplY3QtPmNvbnRleHQpKTsKICAgIGlmKCFvYmplY3QtPmNvbnRleHQpIHsKICAgIH0KICAgIG9iamVjdC0+bnVtX2NvbnRleHRzID0gMTsKCiAgICBFTlRFUl9HTCgpOwogICAgb2JqZWN0LT5jb250ZXh0WzBdID0gQ3JlYXRlQ29udGV4dChUaGlzLCAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBvYmplY3QtPmZyb250QnVmZmVyLCBkaXNwbGF5LCBvYmplY3QtPndpbik7CiAgICBMRUFWRV9HTCgpOwoKICAgIGlmICghb2JqZWN0LT5jb250ZXh0KSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgbmV3IGNvbnRleHRcbiIpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkNvbnRleHQgY3JlYXRlZCAoSFdORD0lcCwgZ2xDb250ZXh0PSVwLCBXaW5kb3c9JWxkKVxuIiwKICAgICAgICAgICAgICAgb2JqZWN0LT53aW5faGFuZGxlLCBvYmplY3QtPmNvbnRleHRbMF0tPmdsQ3R4LCBvYmplY3QtPndpbik7CiAgICB9CgogICAvKioqKioqKioqKioqKioqKioqKioqCiAgICogV2luZG93ZWQgLyBGdWxsc2NyZWVuCiAgICoqKioqKioqKioqKioqKioqKiovCgogICAvKioKICAgKiBUT0RPOiBNU0ROIHNheXMgdGhhdCB3ZSBhcmUgb25seSBhbGxvd2VkIG9uZSBmdWxsc2NyZWVuIHN3YXBjaGFpbiBwZXIgZGV2aWNlLAogICAqIHNvIHdlIHNob3VsZCByZWFsbHkgY2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGEgZnVsbHNjcmVlbiBzd2FwY2hhaW4gYWxyZWFkeQogICAqIEkgdGhpbmsgV2luZG93cyBhbmQgWCBoYXZlIGRpZmZlcmVudCBpZGVhcyBhYm91dCBmdWxsc2NyZWVuLCBkb2VzIGEgc2luZ2xlIGhlYWQgY291bnQgYXMgZnVsbCBzY3JlZW4/CiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgIGlmICghcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CgogICAgICAgIERFVk1PREVXIGRldm1vZGU7CiAgICAgICAgSERDICAgICAgaGRjOwogICAgICAgIGludCAgICAgIGJwcCA9IDA7CiAgICAgICAgUkVDVCAgICAgY2xpcF9yYzsKCiAgICAgICAgLyogR2V0IGluZm8gb24gdGhlIGN1cnJlbnQgZGlzcGxheSBzZXR1cCAqLwogICAgICAgIGhkYyA9IEdldERDKDApOwogICAgICAgIGJwcCA9IEdldERldmljZUNhcHMoaGRjLCBCSVRTUElYRUwpOwogICAgICAgIFJlbGVhc2VEQygwLCBoZGMpOwoKICAgICAgICAvKiBDaGFuZ2UgdGhlIGRpc3BsYXkgc2V0dGluZ3MgKi8KICAgICAgICBtZW1zZXQoJmRldm1vZGUsIDAsIHNpemVvZihERVZNT0RFVykpOwogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgICAgID0gRE1fQklUU1BFUlBFTCB8IERNX1BFTFNXSURUSCB8IERNX1BFTFNIRUlHSFQ7CiAgICAgICAgZGV2bW9kZS5kbUJpdHNQZXJQZWwgPSAoYnBwID49IDI0KSA/IDMyIDogYnBwOyAvKiBTdHVwaWQgWFZpZE1vZGUgY2Fubm90IGNoYW5nZSBicHAgKi8KICAgICAgICBkZXZtb2RlLmRtUGVsc1dpZHRoICA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgIkdhbWVycyBDRyIsIC0xLCBkZXZtb2RlLmRtRGV2aWNlTmFtZSwgQ0NIREVWSUNFTkFNRSk7CiAgICAgICAgQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKGRldm1vZGUuZG1EZXZpY2VOYW1lLCAmZGV2bW9kZSwgb2JqZWN0LT53aW5faGFuZGxlLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCk7CgogICAgICAgIC8qIEZvciBHZXREaXNwbGF5TW9kZSAqLwogICAgICAgIFRoaXMtPmRkcmF3X3dpZHRoID0gZGV2bW9kZS5kbVBlbHNXaWR0aDsKICAgICAgICBUaGlzLT5kZHJhd19oZWlnaHQgPSBkZXZtb2RlLmRtUGVsc0hlaWdodDsKICAgICAgICBUaGlzLT5kZHJhd19mb3JtYXQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdDsKCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RnVsbHNjcmVlbihpZmFjZSwgVFJVRSk7CgogICAgICAgIC8qIEFuZCBmaW5hbGx5IGNsaXAgbW91c2UgdG8gb3VyIHNjcmVlbiAqLwogICAgICAgIFNldFJlY3QoJmNsaXBfcmMsIDAsIDAsIGRldm1vZGUuZG1QZWxzV2lkdGgsIGRldm1vZGUuZG1QZWxzSGVpZ2h0KTsKICAgICAgICBDbGlwQ3Vyc29yKCZjbGlwX3JjKTsKICAgIH0KCiAgIC8qKioqKioqKioqKioqKioqKioqKioKICAgKiBDcmVhdGUgdGhlIGJhY2ssIGZyb250IGFuZCBzdGVuY2lsIGJ1ZmZlcnMKICAgKioqKioqKioqKioqKioqKioqKi8KICAgIGlmKG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA+IDApIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikgKiBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQpOwogICAgICAgIGlmKCFvYmplY3QtPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgVFJBQ0UoImNhbGxpbmcgcmVuZGVydGFyZ2V0IENCXG4iKTsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVSZW5kZXJUYXJnZXQoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIExvY2thYmxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5iYWNrQnVmZmVyW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovKTsKICAgICAgICAgICAgaWYoaHIgPT0gV0lORUQzRF9PSyAmJiBvYmplY3QtPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5iYWNrQnVmZmVyW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBuZXcgYmFjayBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+YmFja0J1ZmZlciA9IE5VTEw7CgogICAgICAgIC8qIFNpbmdsZSBidWZmZXJpbmcgLSBkcmF3IHRvIGZyb250IGJ1ZmZlciAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CgogICAgLyogVW5kZXIgZGlyZWN0WCBzd2FwY2hhaW5zIHNoYXJlIHRoZSBkZXB0aCBzdGVuY2lsLCBzbyBvbmx5IGNyZWF0ZSBvbmUgZGVwdGgtc3RlbmNpbCAqLwogICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsICYmIGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgZGVwdGggc3RlbmNpbCBidWZmZXJcbiIpOwogICAgICAgIGlmIChUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIgPT0gTlVMTCApIHsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVEZXB0aFN0ZW5jaWwoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBGSVhNRTogRGlzY2FyZCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBwU2hhcmVkIChhbHdheXMgbnVsbCkqLyAgKTsKICAgICAgICAgICAgaWYgKFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlciAhPSBOVUxMKQogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIsIDApOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRPRE86IEEgY2hlY2sgb24gd2lkdGgsIGhlaWdodCBhbmQgbXVsdGlzYW1wbGUgdHlwZXMKICAgICAgICAqKHNpbmNlIHRoZSB6YnVmZmVyIG11c3QgYmUgYXQgbGVhc3QgYXMgbGFyZ2UgYXMgdGhlIHJlbmRlciB0YXJnZXQgYW5kIGhhdmUgdGhlIHNhbWUgbXVsdGlzYW1wbGUgcGFyYW1ldGVycykKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyID0gVFJVRTsKICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT53YW50c0RlcHRoU3RlbmNpbEJ1ZmZlciA9IEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJDcmVhdGVkIHN3YXBjaGFpbiAlcFxuIiwgb2JqZWN0KTsKICAgIFRSQUNFKCJGcm9udEJ1ZiBAICVwLCBCYWNrQnVmIEAgJXAsIERlcHRoU3RlbmNpbCAlZFxuIixvYmplY3QtPmZyb250QnVmZmVyLCBvYmplY3QtPmJhY2tCdWZmZXIgPyBvYmplY3QtPmJhY2tCdWZmZXJbMF0gOiBOVUxMLCBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKZXJyb3I6CiAgICBpZiAob2JqZWN0LT5iYWNrQnVmZmVyKSB7CiAgICAgICAgaW50IGk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5iYWNrQnVmZmVyW2ldKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KG9iamVjdC0+YmFja0J1ZmZlcltpXSwgJmJ1ZmZlclBhcmVudCk7CiAgICAgICAgICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgICAgICAgICBpZiAoSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpID4gMCkgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIGJhY2sgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdC0+YmFja0J1ZmZlcik7CiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gTlVMTDsKICAgIH0KICAgIGlmKG9iamVjdC0+Y29udGV4dCkgewogICAgICAgIERlc3Ryb3lDb250ZXh0KFRoaXMsIG9iamVjdC0+Y29udGV4dFswXSk7CiAgICB9CiAgICBpZihvYmplY3QtPmZyb250QnVmZmVyKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChvYmplY3QtPmZyb250QnVmZmVyLCAmYnVmZmVyUGFyZW50KTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgaWYgKElVbmtub3duX1JlbGVhc2UoYnVmZmVyUGFyZW50KSA+IDApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZnJvbnQgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgIH0KICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKiBOT1RFOiBUaGVzZSBhcmUgYWhlYWQgb2YgdGhlIG90aGVyIGdldHRlcnMgYW5kIHNldHRlcnMgdG8gc2F2ZSB1c2luZyBhIGZvcndhcmQgZGVjbGFyYXRpb24gKiovCnN0YXRpYyBVSU5UICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIFRoaXMtPk51bWJlck9mU3dhcENoYWluczsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgSVdpbmVEM0RTd2FwQ2hhaW4gKipwU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHN3YXBjaGFpbiAlZFxuIiwgVGhpcywgaVN3YXBDaGFpbik7CgogICAgaWYoaVN3YXBDaGFpbiA8IFRoaXMtPk51bWJlck9mU3dhcENoYWlucykgewogICAgICAgICpwU3dhcENoYWluID0gVGhpcy0+c3dhcGNoYWluc1tpU3dhcENoYWluXTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9BZGRSZWYoKnBTd2FwQ2hhaW4pOwogICAgICAgIFRSQUNFKCIoJXApIHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBTd2FwQ2hhaW4pOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiU3dhcGNoYWluIG91dCBvZiByYW5nZVxuIik7CiAgICAgICAgKnBTd2FwQ2hhaW4gPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgovKioqKioKICogVmVydGV4IERlY2xhcmF0aW9uCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qKiBwcFZlcnRleERlY2xhcmF0aW9uLAogICAgICAgIElVbmtub3duICpwYXJlbnQsIGNvbnN0IFdJTkVEM0RWRVJURVhFTEVNRU5UICplbGVtZW50cywgc2l6ZV90IGVsZW1lbnRfY291bnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgICAgICpUaGlzICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uSW1wbCAqb2JqZWN0ID0gTlVMTDsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwoKICAgIFRSQUNFKCIoJXApIDogZGlyZWN0WFZlcnNpb24gJXUsIGVsZW1lbnRzICVwLCBlbGVtZW50X2NvdW50ICVkLCBwcERlY2w9JXBcbiIsCiAgICAgICAgICAgIFRoaXMsICgoSVdpbmVEM0RJbXBsICopVGhpcy0+d2luZUQzRCktPmR4VmVyc2lvbiwgZWxlbWVudHMsIGVsZW1lbnRfY291bnQsIHBwVmVydGV4RGVjbGFyYXRpb24pOwoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4RGVjbGFyYXRpb24pCgogICAgaHIgPSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uX1NldERlY2xhcmF0aW9uKChJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uICopb2JqZWN0LCBlbGVtZW50cywgZWxlbWVudF9jb3VudCk7CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgc2l6ZV90IENvbnZlcnRGdmZUb0RlY2xhcmF0aW9uKERXT1JEIGZ2ZiwgV0lORUQzRFZFUlRFWEVMRU1FTlQqKiBwcFZlcnRleEVsZW1lbnRzKSB7CgogICAgdW5zaWduZWQgaW50IGlkeCwgaWR4MjsKICAgIHVuc2lnbmVkIGludCBvZmZzZXQ7CiAgICBCT09MIGhhc19wb3MgPSAoZnZmICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSAhPSAwOwogICAgQk9PTCBoYXNfYmxlbmQgPSAoZnZmICYgV0lORUQzREZWRl9YWVpCNSkgPiBXSU5FRDNERlZGX1hZWlJIVzsKICAgIEJPT0wgaGFzX2JsZW5kX2lkeCA9IGhhc19ibGVuZCAmJgogICAgICAgKCgoZnZmICYgV0lORUQzREZWRl9YWVpCNSkgPT0gV0lORUQzREZWRl9YWVpCNSkgfHwKICAgICAgICAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9EM0RDT0xPUikgfHwKICAgICAgICAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9VQllURTQpKTsKICAgIEJPT0wgaGFzX25vcm1hbCA9IChmdmYgJiBXSU5FRDNERlZGX05PUk1BTCkgIT0gMDsKICAgIEJPT0wgaGFzX3BzaXplID0gKGZ2ZiAmIFdJTkVEM0RGVkZfUFNJWkUpICE9IDA7CiAgICBCT09MIGhhc19kaWZmdXNlID0gKGZ2ZiAmIFdJTkVEM0RGVkZfRElGRlVTRSkgIT0gMDsKICAgIEJPT0wgaGFzX3NwZWN1bGFyID0gKGZ2ZiAmIFdJTkVEM0RGVkZfU1BFQ1VMQVIpICE9MDsKCiAgICBEV09SRCBudW1fdGV4dHVyZXMgPSAoZnZmICYgV0lORUQzREZWRl9URVhDT1VOVF9NQVNLKSA+PiBXSU5FRDNERlZGX1RFWENPVU5UX1NISUZUOwogICAgRFdPUkQgdGV4Y29vcmRzID0gKGZ2ZiAmIDB4MDBGRjAwMDApID4+IDE2OwoKICAgIFdJTkVEM0RWRVJURVhFTEVNRU5UIGVuZF9lbGVtZW50ID0gV0lORUQzRERFQ0xfRU5EKCk7CiAgICBXSU5FRDNEVkVSVEVYRUxFTUVOVCAqZWxlbWVudHMgPSBOVUxMOwoKICAgIHVuc2lnbmVkIGludCBzaXplOwogICAgRFdPUkQgbnVtX2JsZW5kcyA9IDEgKyAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSAtIFdJTkVEM0RGVkZfWFlaQjEpID4+IDEpOwogICAgaWYgKGhhc19ibGVuZF9pZHgpIG51bV9ibGVuZHMtLTsKCiAgICAvKiBDb21wdXRlIGRlY2xhcmF0aW9uIHNpemUgKi8KICAgIHNpemUgPSBoYXNfcG9zICsgKGhhc19ibGVuZCAmJiBudW1fYmxlbmRzID4gMCkgKyBoYXNfYmxlbmRfaWR4ICsgaGFzX25vcm1hbCArCiAgICAgICAgICAgaGFzX3BzaXplICsgaGFzX2RpZmZ1c2UgKyBoYXNfc3BlY3VsYXIgKyBudW1fdGV4dHVyZXMgKyAxOwoKICAgIC8qIGNvbnZlcnQgdGhlIGRlY2xhcmF0aW9uICovCiAgICBlbGVtZW50cyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplICogc2l6ZW9mKFdJTkVEM0RWRVJURVhFTEVNRU5UKSk7CiAgICBpZiAoIWVsZW1lbnRzKQogICAgICAgIHJldHVybiAwOwoKICAgIG1lbWNweSgmZWxlbWVudHNbc2l6ZS0xXSwgJmVuZF9lbGVtZW50LCBzaXplb2YoV0lORUQzRFZFUlRFWEVMRU1FTlQpKTsKICAgIGlkeCA9IDA7CiAgICBpZiAoaGFzX3BvcykgewogICAgICAgIGlmICghaGFzX2JsZW5kICYmIChmdmYgJiBXSU5FRDNERlZGX1hZWlJIVykpIHsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUNDsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT05UOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT047CiAgICAgICAgfQogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX2JsZW5kICYmIChudW1fYmxlbmRzID4gMCkpIHsKICAgICAgICBpZiAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA9PSBXSU5FRDNERlZGX1hZWkIyKSAmJiAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9EM0RDT0xPUikpCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDEgKyBudW1fYmxlbmRzIC0gMTsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9CTEVORFdFSUdIVDsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19ibGVuZF9pZHgpIHsKICAgICAgICBpZiAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9VQllURTQgfHwKICAgICAgICAgICAgKCgoZnZmICYgV0lORUQzREZWRl9YWVpCNSkgPT0gV0lORUQzREZWRl9YWVpCMikgJiYgKGZ2ZiAmIFdJTkVEM0RGVkZfTEFTVEJFVEFfRDNEQ09MT1IpKSkKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX1VCWVRFNDsKICAgICAgICBlbHNlIGlmIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX0QzRENPTE9SKQogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRDNEQ09MT1I7CiAgICAgICAgZWxzZQogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0JMRU5ESU5ESUNFUzsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19ub3JtYWwpIHsKICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX05PUk1BTDsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19wc2l6ZSkgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfUFNJWkU7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZUluZGV4ID0gMDsKICAgICAgICBpZHgrKzsKICAgIH0KICAgIGlmIChoYXNfZGlmZnVzZSkgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9DT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19zcGVjdWxhcikgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9DT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAxOwogICAgICAgIGlkeCsrOwogICAgfQogICAgZm9yIChpZHgyID0gMDsgaWR4MiA8IG51bV90ZXh0dXJlczsgaWR4MisrKSB7CiAgICAgICAgdW5zaWduZWQgaW50IG51bWNvb3JkcyA9ICh0ZXhjb29yZHMgPj4gKGlkeDIqMikpICYgMHgwMzsKICAgICAgICBzd2l0Y2ggKG51bWNvb3JkcykgewogICAgICAgICAgICBjYXNlIFdJTkVEM0RGVkZfVEVYVFVSRUZPUk1BVDE6CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZWRl9URVhUVVJFRk9STUFUMjoKICAgICAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQzOgogICAgICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGVkZfVEVYVFVSRUZPUk1BVDQ6CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX1RFWENPT1JEOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IGlkeDI7CiAgICAgICAgaWR4Kys7CiAgICB9CgogICAgLyogTm93IGNvbXB1dGUgb2Zmc2V0cywgYW5kIGluaXRpYWxpemUgdGhlIHJlc3Qgb2YgdGhlIGZpZWxkcyAqLwogICAgZm9yIChpZHggPSAwLCBvZmZzZXQgPSAwOyBpZHggPCBzaXplLTE7IGlkeCsrKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5TdHJlYW0gPSAwOwogICAgICAgIGVsZW1lbnRzW2lkeF0uTWV0aG9kID0gV0lORUQzRERFQ0xNRVRIT0RfREVGQVVMVDsKICAgICAgICBlbGVtZW50c1tpZHhdLk9mZnNldCA9IG9mZnNldDsKICAgICAgICBvZmZzZXQgKz0gV0lORUQzRF9BVFJfU0laRShlbGVtZW50c1tpZHhdLlR5cGUpICogV0lORUQzRF9BVFJfVFlQRVNJWkUoZWxlbWVudHNbaWR4XS5UeXBlKTsKICAgIH0KCiAgICAqcHBWZXJ0ZXhFbGVtZW50cyA9IGVsZW1lbnRzOwogICAgcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb25Gcm9tRlZGKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbioqIHBwVmVydGV4RGVjbGFyYXRpb24sIElVbmtub3duICpQYXJlbnQsIERXT1JEIEZ2ZikgewogICAgV0lORUQzRFZFUlRFWEVMRU1FTlQqIGVsZW1lbnRzID0gTlVMTDsKICAgIHNpemVfdCBzaXplOwogICAgRFdPUkQgaHI7CgogICAgc2l6ZSA9IENvbnZlcnRGdmZUb0RlY2xhcmF0aW9uKEZ2ZiwgJmVsZW1lbnRzKTsKICAgIGlmIChzaXplID09IDApIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbihpZmFjZSwgcHBWZXJ0ZXhEZWNsYXJhdGlvbiwgUGFyZW50LCBlbGVtZW50cywgc2l6ZSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbGVtZW50cyk7CiAgICBpZiAoaHIgIT0gU19PSykgcmV0dXJuIGhyOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2FyY2hpdmUvZGVmYXVsdC5hc3A/dXJsPS9hcmNoaXZlL2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL3Byb2dyYW1tYWJsZS92ZXJ0ZXhzaGFkZXJzL3ZzY3JlYXRlLmFzcCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKnZlcnRleF9kZWNsYXJhdGlvbiwgQ09OU1QgRFdPUkQgKnBGdW5jdGlvbiwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIgKipwcFZlcnRleFNoYWRlciwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICpvYmplY3Q7ICAvKiBOT1RFOiBpbXBsIHVzYWdlIGlzIG9rLCB0aGlzIGlzIGEgY3JlYXRlICovCiAgICBIUkVTVUxUIGhyID0gV0lORUQzRF9PSzsKICAgIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4U2hhZGVyKQogICAgb2JqZWN0LT5iYXNlU2hhZGVyLnNoYWRlcl9pbnMgPSBJV2luZUQzRFZlcnRleFNoYWRlckltcGxfc2hhZGVyX2luczsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgVmVydGV4IHNoYWRlciAlcFxuIiwgVGhpcywgKnBwVmVydGV4U2hhZGVyKTsKCiAgICBpZiAodmVydGV4X2RlY2xhcmF0aW9uKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfRmFrZVNlbWFudGljcygqcHBWZXJ0ZXhTaGFkZXIsIHZlcnRleF9kZWNsYXJhdGlvbik7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFZlcnRleFNoYWRlcl9TZXRGdW5jdGlvbigqcHBWZXJ0ZXhTaGFkZXIsIHBGdW5jdGlvbik7CgogICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBzZXQgdGhlIGZ1bmN0aW9uLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgaWZhY2UpOwogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX1JlbGVhc2UoKnBwVmVydGV4U2hhZGVyKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQaXhlbFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIERXT1JEICpwRnVuY3Rpb24sIElXaW5lRDNEUGl4ZWxTaGFkZXIgKipwcFBpeGVsU2hhZGVyLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqb2JqZWN0OyAvKiBOT1RFOiBpbXBsIGFsbG93ZWQsIHRoaXMgaXMgYSBjcmVhdGUgKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwoKICAgIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgUGl4ZWxTaGFkZXIpCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2lucyA9IElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsX3NoYWRlcl9pbnM7CiAgICBociA9IElXaW5lRDNEUGl4ZWxTaGFkZXJfU2V0RnVuY3Rpb24oKnBwUGl4ZWxTaGFkZXIsIHBGdW5jdGlvbik7CiAgICBpZiAoV0lORUQzRF9PSyA9PSBocikgewogICAgICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBQaXhlbCBzaGFkZXIgJXBcbiIsIFRoaXMsICpwcFBpeGVsU2hhZGVyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgV0FSTigiKCVwKSA6IEZhaWxlZCB0byBjcmVhdGUgcGl4ZWwgc2hhZGVyXG4iLCBUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBQQUxFVFRFRU5UUlkgKlBhbEVudCwgSVdpbmVEM0RQYWxldHRlICoqUGFsZXR0ZSwgSVVua25vd24gKlBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKm9iamVjdDsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCV4LCAlcCwgJXAsICVwKVxuIiwgVGhpcywgRmxhZ3MsIFBhbEVudCwgUGFsZXR0ZSwgUGFyZW50KTsKCiAgICAvKiBDcmVhdGUgdGhlIG5ldyBvYmplY3QgKi8KICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RQYWxldHRlSW1wbCkpOwogICAgaWYoIW9iamVjdCkgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIElXaW5lRDNEUGFsZXR0ZSBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0RQYWxldHRlX1Z0Ymw7CiAgICBvYmplY3QtPnJlZiA9IDE7CiAgICBvYmplY3QtPkZsYWdzID0gRmxhZ3M7CiAgICBvYmplY3QtPnBhcmVudCA9IFBhcmVudDsKICAgIG9iamVjdC0+d2luZUQzRERldmljZSA9IFRoaXM7CiAgICBvYmplY3QtPnBhbE51bUVudHJpZXMgPSBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRmxhZ3MpOwoJCiAgICBvYmplY3QtPmhwYWwgPSBDcmVhdGVQYWxldHRlKChjb25zdCBMT0dQQUxFVFRFKikmKG9iamVjdC0+cGFsVmVyc2lvbikpOwoKICAgIGlmKCFvYmplY3QtPmhwYWwpIHsKICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBociA9IElXaW5lRDNEUGFsZXR0ZV9TZXRFbnRyaWVzKChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0LCAwLCAwLCBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRmxhZ3MpLCBQYWxFbnQpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIElXaW5lRDNEUGFsZXR0ZV9SZWxlYXNlKChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0KTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgKlBhbGV0dGUgPSAoSVdpbmVEM0RQYWxldHRlICopIG9iamVjdDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgRDNEQ0JfQ1JFQVRFQURESVRJT05BTFNXQVBDSEFJTiBEM0RDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW47CiAgICBEV09SRCBzdGF0ZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIEQzRENCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4pOwogICAgaWYoVGhpcy0+ZDNkX2luaXRpYWxpemVkKSByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICAvKiBUT0RPOiBUZXN0IGlmIE9wZW5HTCBpcyBjb21waWxlZCBpbiBhbmQgbG9hZGVkICovCgogICAgLyogSW5pdGlhbGl6ZSB0aGUgdGV4dHVyZSB1bml0IG1hcHBpbmcgdG8gYSAxOjEgbWFwcGluZyAqLwogICAgZm9yKHN0YXRlID0gMDsgc3RhdGUgPCBNQVhfU0FNUExFUlM7IHN0YXRlKyspIHsKICAgICAgICBUaGlzLT50ZXhVbml0TWFwW3N0YXRlXSA9IHN0YXRlOwogICAgfQogICAgVGhpcy0+b25lVG9PbmVUZXhVbml0TWFwID0gVFJVRTsKCiAgICAvKiBTZXR1cCB0aGUgaW1wbGljaXQgc3dhcGNoYWluICovCiAgICBUUkFDRSgiQ3JlYXRpbmcgaW1wbGljaXQgc3dhcGNoYWluXG4iKTsKICAgIGlmIChGQUlMRUQoRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbigoSVVua25vd24gKikgVGhpcy0+cGFyZW50LCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwY2hhaW4pKSB8fCAhc3dhcGNoYWluKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyA9IDE7CiAgICBUaGlzLT5zd2FwY2hhaW5zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyAqIHNpemVvZihJV2luZUQzRFN3YXBDaGFpbiAqKSk7CiAgICBpZighVGhpcy0+c3dhcGNoYWlucykgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoIChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQogICAgVGhpcy0+c3dhcGNoYWluc1swXSA9IChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW47CgogICAgaWYoIVRoaXMtPmRkcmF3X3dpbmRvdykgSVdpbmVEM0REZXZpY2VfU2V0SFdORChpZmFjZSwgc3dhcGNoYWluLT53aW5faGFuZGxlKTsKCiAgICBpZihzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgVFJBQ0UoIlNldHRpbmcgcmVuZGVydGFyZ2V0IHRvICVwXG4iLCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF07CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBUUkFDRSgiU2V0dGluZyByZW5kZXJ0YXJnZXQgdG8gJXBcbiIsIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgICAgICBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgIH0KICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pOwogICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IHN3YXBjaGFpbi0+Y29udGV4dFswXTsKCiAgICAvKiBEZXB0aCBTdGVuY2lsIHN1cHBvcnQgKi8KICAgIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPSBUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXI7CiAgICBpZiAoTlVMTCAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgIH0KCiAgICAvKiBTZXQgdXAgc29tZSBzdGFydGluZyBHTCBzZXR1cCAqLwogICAgRU5URVJfR0woKTsKICAgIC8qCiAgICAqIEluaXRpYWxpemUgb3BlbkdMIGV4dGVuc2lvbiByZWxhdGVkIHZhcmlhYmxlcwogICAgKiAgd2l0aCBEZWZhdWx0IHZhbHVlcwogICAgKi8KCiAgICAoKElXaW5lRDNESW1wbCAqKSBUaGlzLT53aW5lRDNEKS0+aXNHTEluZm9WYWxpZCA9IElXaW5lRDNESW1wbF9GaWxsR0xDYXBzKFRoaXMtPndpbmVEM0QsIHN3YXBjaGFpbi0+Y29udGV4dFswXS0+ZGlzcGxheSk7CiAgICAvKiBTZXR1cCBhbGwgdGhlIGRldmljZXMgZGVmYXVsdHMgKi8KICAgIElXaW5lRDNEU3RhdGVCbG9ja19Jbml0U3RhcnR1cFN0YXRlQmxvY2soKElXaW5lRDNEU3RhdGVCbG9jayAqKVRoaXMtPnN0YXRlQmxvY2spOwojaWYgMAogICAgSVdpbmVEM0RJbXBsX0NoZWNrR3JhcGhpY3NNZW1vcnkoKTsKI2VuZGlmCgogICAgeyAvKiBTZXQgYSBkZWZhdWx0IHZpZXdwb3J0ICovCiAgICAgICAgV0lORUQzRFZJRVdQT1JUIHZwOwogICAgICAgIHZwLlggICAgICA9IDA7CiAgICAgICAgdnAuWSAgICAgID0gMDsKICAgICAgICB2cC5XaWR0aCAgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIHZwLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIHZwLk1pblogICA9IDAuMGY7CiAgICAgICAgdnAuTWF4WiAgID0gMS4wZjsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRWaWV3cG9ydCgoSVdpbmVEM0REZXZpY2UgKilUaGlzLCAmdnApOwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgdGhlIGN1cnJlbnQgdmlldyBzdGF0ZSAqLwogICAgVGhpcy0+dmlld19pZGVudCA9IDE7CiAgICBUaGlzLT5jb250ZXh0c1swXS0+bGFzdF93YXNfcmh3ID0gMDsKICAgIGdsR2V0SW50ZWdlcnYoR0xfTUFYX0xJR0hUUywgJlRoaXMtPm1heENvbmN1cnJlbnRMaWdodHMpOwogICAgY2hlY2tHTGNhbGwoImdsR2V0SW50ZWdlcnYoR0xfTUFYX0xJR0hUUywgJlRoaXMtPm1heENvbmN1cnJlbnRMaWdodHMpIik7CgogICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlKSB7CiAgICAgICAgY2FzZSBPUk1fRkJPOgogICAgICAgIGNhc2UgT1JNX1BCVUZGRVI6CiAgICAgICAgICAgIFRoaXMtPm9mZnNjcmVlbkJ1ZmZlciA9IEdMX0JBQ0s7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE9STV9CQUNLQlVGRkVSOgogICAgICAgIHsKICAgICAgICAgICAgaWYoR0xfTElNSVRTKGF1eF9idWZmZXJzKSA+IDApIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBhdXhpbGxpYXJ5IGJ1ZmZlciBmb3Igb2Zmc2NyZWVuIHJlbmRlcmluZ1xuIik7CiAgICAgICAgICAgICAgICBUaGlzLT5vZmZzY3JlZW5CdWZmZXIgPSBHTF9BVVgwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIGJhY2sgYnVmZmVyIGZvciBvZmZzY3JlZW4gcmVuZGVyaW5nXG4iKTsKICAgICAgICAgICAgICAgIFRoaXMtPm9mZnNjcmVlbkJ1ZmZlciA9IEdMX0JBQ0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIiglcCkgQWxsIGRlZmF1bHRzIG5vdyBzZXQgdXAsIGxlYXZpbmcgSW5pdDNEIHdpdGggJXBcbiIsIFRoaXMsIFRoaXMpOwogICAgTEVBVkVfR0woKTsKCiAgICAvKiBDbGVhciB0aGUgc2NyZWVuICovCiAgICBJV2luZUQzRERldmljZV9DbGVhcigoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEQ0xFQVJfVEFSR0VUIHwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgPyBXSU5FRDNEQ0xFQVJfWkJVRkZFUiB8IFdJTkVEM0RDTEVBUl9TVEVOQ0lMIDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAweDAwLCAxLjAsIDApOwoKICAgIFRoaXMtPmQzZF9pbml0aWFsaXplZCA9IFRSVUU7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9VbmluaXQzRChJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRENCX0RFU1RST1lTVVJGQUNFRk4gRDNEQ0JfRGVzdHJveURlcHRoU3RlbmNpbFN1cmZhY2UsIEQzRENCX0RFU1RST1lTV0FQQ0hBSU5GTiBEM0RDQl9EZXN0cm95U3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgaW50IHNhbXBsZXI7CiAgICB1aW50IGk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoIVRoaXMtPmQzZF9pbml0aWFsaXplZCkgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgRU5URVJfR0woKTsKICAgIC8qIEkgZG9uJ3QgdGhpbmsgdGhhdCB0aGUgaW50ZXJmYWNlIGd1YXJhbnRzIHRoYXQgdGhlIGRldmljZSBpcyBkZXN0cm95ZWQgZnJvbSB0aGUgc2FtZSB0aHJlYWQKICAgICAqIGl0IHdhcyBjcmVhdGVkLiBUaHVzIG1ha2Ugc3VyZSBhIGNvbnRleHQgaXMgYWN0aXZlIGZvciB0aGUgZ2xEZWxldGUqIGNhbGxzCiAgICAgKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgTEVBVkVfR0woKTsKCiAgICAvKiBEZWxldGUgdGhlIHBidWZmZXIgY29udGV4dCBpZiB0aGVyZSBpcyBhbnkgKi8KICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0KSBEZXN0cm95Q29udGV4dChUaGlzLCBUaGlzLT5wYnVmZmVyQ29udGV4dCk7CgogICAgLyogRGVsZXRlIHRoZSBtb3VzZSBjdXJzb3IgdGV4dHVyZSAqLwogICAgaWYoVGhpcy0+Y3Vyc29yVGV4dHVyZSkgewogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+Y3Vyc29yVGV4dHVyZSk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICBUaGlzLT5jdXJzb3JUZXh0dXJlID0gMDsKICAgIH0KCiAgICBmb3Ioc2FtcGxlciA9IDA7IHNhbXBsZXIgPCBHTF9MSU1JVFMoc2FtcGxlcl9zdGFnZXMpOyArK3NhbXBsZXIpIHsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRUZXh0dXJlKGlmYWNlLCBzYW1wbGVyLCBOVUxMKTsKICAgIH0KCiAgICAvKiBSZWxlYXNlIHRoZSBidWZmZXJzICh3aXRoIHNhbml0eSBjaGVja3MpKi8KICAgIFRSQUNFKCJSZWxlYXNpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIGF0ICVwXG4iLCBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgIGlmKFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgIT0gTlVMTCAmJiAoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgPjApKXsKICAgICAgICBpZihUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIgIT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZGVwdGhTdGVuY2lsQnVmZmVyXG4iLFRoaXMpOwogICAgfQogICAgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9IE5VTEw7CgogICAgVFJBQ0UoIlJlbGVhc2luZyB0aGUgcmVuZGVyIHRhcmdldCBhdCAlcFxuIiwgVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pOwogICAgaWYoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pID4wKXsKICAgICAgICAgIC8qIFRoaXMgY2hlY2sgaXMgYSBiaXQgc2lsbHksIGl0c2hvdWxkIGJlIGluIHN3YXBjaGFpbl9yZWxlYXNlIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIHJlbmRlclRhcmdldFxuIixUaGlzKTsgKi8KICAgIH0KICAgIFRSQUNFKCJTZXR0aW5nIHJlbmRlcnRhcmdldCB0byBOVUxMXG4iKTsKICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gTlVMTDsKCiAgICBpZiAoVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyKSB7CiAgICAgICAgaWYoRDNEQ0JfRGVzdHJveURlcHRoU3RlbmNpbFN1cmZhY2UoVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyKSA+IDApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZGVwdGhTdGVuY2lsQnVmZmVyXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyID0gTlVMTDsKICAgIH0KCiAgICBmb3IoaT0wOyBpIDwgVGhpcy0+TnVtYmVyT2ZTd2FwQ2hhaW5zOyBpKyspIHsKICAgICAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSBpbXBsaWNpdCBzd2FwY2hhaW4gJWRcbiIsIGkpOwogICAgICAgIGlmIChEM0RDQl9EZXN0cm95U3dhcENoYWluKFRoaXMtPnN3YXBjaGFpbnNbaV0pICA+IDApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgaW1wbGljaXQgc3dhcGNoYWluXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+c3dhcGNoYWlucyk7CiAgICBUaGlzLT5zd2FwY2hhaW5zID0gTlVMTDsKICAgIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyA9IDA7CgogICAgVGhpcy0+ZDNkX2luaXRpYWxpemVkID0gRkFMU0U7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGdWxsc2NyZWVuKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBmdWxsc2NyZWVuKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgU2V0dGluZyBERHJhdyBmdWxsc2NyZWVuIG1vZGUgdG8gJXNcbiIsIFRoaXMsIGZ1bGxzY3JlZW4gPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCiAgICAvKiBTZXR1cCB0aGUgd2luZG93IGZvciBmdWxsc2NyZWVuIG1vZGUgKi8KICAgIGlmKGZ1bGxzY3JlZW4gJiYgIVRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KGlmYWNlLCBUaGlzLT5kZHJhd193aW5kb3cpOwogICAgfSBlbHNlIGlmKCFmdWxsc2NyZWVuICYmIFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhpZmFjZSwgVGhpcy0+ZGRyYXdfd2luZG93KTsKICAgIH0KCiAgICAvKiBEaXJlY3REcmF3IGFwcHMgY2FuIGNoYW5nZSBiZXR3ZWVuIGZ1bGxzY3JlZW4gYW5kIHdpbmRvd2VkIG1vZGUgYWZ0ZXIgZGV2aWNlIGNyZWF0aW9uIHdpdGgKICAgICAqIElEaXJlY3REcmF3Nzo6U2V0Q29vcGVyYXRpdmVMZXZlbC4gVGhlIEdESSBzdXJmYWNlIGltcGxlbWVudGF0aW9uIG5lZWRzIHRvIGtub3cgdGhpcy4KICAgICAqIEREcmF3IGRvZXNuJ3QgbmVjZXNzYXJpbHkgaGF2ZSBhIHN3YXBjaGFpbiwgc28gd2UgaGF2ZSB0byBzdG9yZSB0aGUgZnVsbHNjcmVlbiBmbGFnCiAgICAgKiBzZXBhcmF0ZWx5LgogICAgICovCiAgICBUaGlzLT5kZHJhd19mdWxsc2NyZWVuID0gZnVsbHNjcmVlbjsKfQoKLyogRW5hYmxlcyB0aGVhZCBzYWZldHkgaW4gdGhlIHdpbmVkM2QgZGV2aWNlIGFuZCBpdHMgcmVzb3VyY2VzLiBDYWxsZWQgYnkgRGlyZWN0RHJhdwogKiBmcm9tIFNldENvb3BlcmF0aXZlTGV2ZW4gaWYgRERTQ0xfTVVMVElUSFJFQURFRCBpcyBzcGVjaWZpZWQsIGFuZCBieSBkM2Q4LzkgZnJvbQogKiBDcmVhdGVEZXZpY2UgaWYgRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQgaXMgcGFzc2VkLgogKgogKiBUaGVyZSBpcyBubyB3YXkgdG8gZGVhY3RpdmF0ZSB0aHJlYWQgc2FmZXR5IG9uY2UgaXQgaXMgZW5hYmxlZAogKi8Kc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNdWx0aXRocmVhZGVkKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIEZJWE1FKCJObyB0aHJlYWQgc2FmZXR5IGluIHdpbmVkM2QgeWV0XG4iKTsKCiAgICAvKkZvciBub3cganVzdCBzdG9yZSB0aGUgZmxhZyhuZWVkZWQgaW4gY2FzZSBvZiBkZHJhdykgKi8KICAgIFRoaXMtPmNyZWF0ZVBhcm1zLkJlaGF2aW9yRmxhZ3MgfD0gV0lORUQzRENSRUFURV9NVUxUSVRIUkVBREVEOwoKICAgIHJldHVybjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXREaXNwbGF5TW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzRERJU1BMQVlNT0RFKiBwTW9kZSkgewogICAgREVWTU9ERVcgZGV2bW9kZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIExPTkcgcmV0OwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICpmb3JtYXREZXNjICA9IGdldEZvcm1hdERlc2NFbnRyeShwTW9kZS0+Rm9ybWF0KTsKICAgIFJFQ1QgY2xpcF9yYzsKCiAgICBUUkFDRSgiKCVwKS0+KCVkLCVwKSBNb2RlPSVkeCVkeEAlZCwgJXNcbiIsIFRoaXMsIGlTd2FwQ2hhaW4sIHBNb2RlLCBwTW9kZS0+V2lkdGgsIHBNb2RlLT5IZWlnaHQsIHBNb2RlLT5SZWZyZXNoUmF0ZSwgZGVidWdfZDNkZm9ybWF0KHBNb2RlLT5Gb3JtYXQpKTsKCiAgICAvKiBSZXNpemUgdGhlIHNjcmVlbiBldmVuIHdpdGhvdXQgYSB3aW5kb3c6CiAgICAgKiBUaGUgYXBwIGNvdWxkIGhhdmUgdW5zZXQgaXQgd2l0aCBTZXRDb29wZXJhdGl2ZUxldmVsLCBidXQgbm90IGNhbGxlZAogICAgICogUmVzdG9yZURpc3BsYXlNb2RlIGZpcnN0LiBUaGVuIHRoZSByZWxlYXNlIHdpbGwgY2FsbCBSZXN0b3JlRGlzcGxheU1vZGUsCiAgICAgKiBidXQgd2UgZG9uJ3QgaGF2ZSBhbnkgaHduZAogICAgICovCgogICAgZGV2bW9kZS5kbUZpZWxkcyA9IERNX0JJVFNQRVJQRUwgfCBETV9QRUxTV0lEVEggfCBETV9QRUxTSEVJR0hUOwogICAgZGV2bW9kZS5kbUJpdHNQZXJQZWwgPSBmb3JtYXREZXNjLT5icHAgKiA4OwogICAgaWYoZGV2bW9kZS5kbUJpdHNQZXJQZWwgPT0gMjQpIGRldm1vZGUuZG1CaXRzUGVyUGVsID0gMzI7CiAgICBkZXZtb2RlLmRtUGVsc1dpZHRoICA9IHBNb2RlLT5XaWR0aDsKICAgIGRldm1vZGUuZG1QZWxzSGVpZ2h0ID0gcE1vZGUtPkhlaWdodDsKCiAgICBkZXZtb2RlLmRtRGlzcGxheUZyZXF1ZW5jeSA9IHBNb2RlLT5SZWZyZXNoUmF0ZTsKICAgIGlmIChwTW9kZS0+UmVmcmVzaFJhdGUgIT0gMCkgIHsKICAgICAgICBkZXZtb2RlLmRtRmllbGRzIHw9IERNX0RJU1BMQVlGUkVRVUVOQ1k7CiAgICB9CgogICAgLyogT25seSBjaGFuZ2UgdGhlIG1vZGUgaWYgbmVjZXNzYXJ5ICovCiAgICBpZiggKFRoaXMtPmRkcmF3X3dpZHRoID09IHBNb2RlLT5XaWR0aCkgJiYKICAgICAgICAoVGhpcy0+ZGRyYXdfaGVpZ2h0ID09IHBNb2RlLT5IZWlnaHQpICYmCiAgICAgICAgKFRoaXMtPmRkcmF3X2Zvcm1hdCA9PSBwTW9kZS0+Rm9ybWF0KSAmJgogICAgICAgIChwTW9kZS0+UmVmcmVzaFJhdGUgPT0gMCkgKSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgcmV0ID0gQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKE5VTEwsICZkZXZtb2RlLCBOVUxMLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCk7CiAgICBpZiAocmV0ICE9IERJU1BfQ0hBTkdFX1NVQ0NFU1NGVUwpIHsKICAgICAgICBpZihkZXZtb2RlLmRtRGlzcGxheUZyZXF1ZW5jeSAhPSAwKSB7CiAgICAgICAgICAgIFdBUk4oIkNoYW5nZURpc3BsYXlTZXR0aW5nc0V4VyBmYWlsZWQsIHRyeWluZyB3aXRob3V0IHRoZSByZWZyZXNoIHJhdGVcbiIpOwogICAgICAgICAgICBkZXZtb2RlLmRtRmllbGRzICY9IH5ETV9ESVNQTEFZRlJFUVVFTkNZOwogICAgICAgICAgICBkZXZtb2RlLmRtRGlzcGxheUZyZXF1ZW5jeSA9IDA7CiAgICAgICAgICAgIHJldCA9IENoYW5nZURpc3BsYXlTZXR0aW5nc0V4VyhOVUxMLCAmZGV2bW9kZSwgTlVMTCwgQ0RTX0ZVTExTQ1JFRU4sIE5VTEwpICE9IERJU1BfQ0hBTkdFX1NVQ0NFU1NGVUw7CiAgICAgICAgfQogICAgICAgIGlmKHJldCAhPSBESVNQX0NIQU5HRV9TVUNDRVNTRlVMKSB7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICB9CiAgICB9CgogICAgLyogU3RvcmUgdGhlIG5ldyB2YWx1ZXMgKi8KICAgIFRoaXMtPmRkcmF3X3dpZHRoID0gcE1vZGUtPldpZHRoOwogICAgVGhpcy0+ZGRyYXdfaGVpZ2h0ID0gcE1vZGUtPkhlaWdodDsKICAgIFRoaXMtPmRkcmF3X2Zvcm1hdCA9IHBNb2RlLT5Gb3JtYXQ7CgogICAgLyogT25seSBkbyB0aGlzIHdpdGggYSB3aW5kb3cgb2YgY291cnNlICovCiAgICBpZihUaGlzLT5kZHJhd193aW5kb3cpCiAgICAgIE1vdmVXaW5kb3coVGhpcy0+ZGRyYXdfd2luZG93LCAwLCAwLCBwTW9kZS0+V2lkdGgsIHBNb2RlLT5IZWlnaHQsIFRSVUUpOwoKICAgIC8qIEFuZCBmaW5hbGx5IGNsaXAgbW91c2UgdG8gb3VyIHNjcmVlbiAqLwogICAgU2V0UmVjdCgmY2xpcF9yYywgMCwgMCwgcE1vZGUtPldpZHRoLCBwTW9kZS0+SGVpZ2h0KTsKICAgIENsaXBDdXJzb3IoJmNsaXBfcmMpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpcmVjdDNEKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0QgKipwcEQzRCkgewogICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICpwcEQzRD0gVGhpcy0+d2luZUQzRDsKICAgVFJBQ0UoIiglcCkgOiB3aW5lRDNEIHJldHVybmluZyAlcFxuIiwgVGhpcywgICpwcEQzRCk7CiAgIElXaW5lRDNEX0FkZFJlZigqcHBEM0QpOwogICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIFVJTlQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRBdmFpbGFibGVUZXh0dXJlTWVtKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgLyoqIE5PVEU6IFRoZXJlJ3MgYSBwcm9iYWJseSAgYSBoYWNrLWFyb3VuZCBmb3IgdGhpcyBvbmUgYnkgcHV0dGluZyBhcyBtYW55IHBidWZmZXJzLCBWQk9zIChvciB3aGF0ZXZlcikKICAgICogaW50byB0aGUgdmlkZW8gcmFtIGFzIHBvc3NpYmxlIGFuZCBzZWVpbmcgaG93IG1hbnkgZml0CiAgICAqIHlvdSBjYW4gYWxzbyBnZXQgdGhlIGNvcnJlY3QgaW5pdGlhbCB2YWx1ZSBmcm9tIG52aWRpYSBhbmQgQVRJJ3MgZHJpdmVyIHZpYSBYCiAgICAqIHRleHR1cmUgbWVtb3J5IGlzIHZpZGVvIG1lbW9yeSArIEFHUCBtZW1vcnkKICAgICoqKioqKioqKioqKioqKioqKiovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmIChzaG93Zml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViLCBzaW11bGF0aW5nICVkTUIgZm9yIG5vdywgcmV0dXJuaW5nICVkTUIgbGVmdFxuIiwgVGhpcywKICAgICAgICAgKHdpbmVkM2Rfc2V0dGluZ3MuZW11bGF0ZWRfdGV4dHVyZXJhbS8oMTAyNCoxMDI0KSksCiAgICAgICAgICgod2luZWQzZF9zZXR0aW5ncy5lbXVsYXRlZF90ZXh0dXJlcmFtIC0gd2luZUQzREdsb2JhbFN0YXRpc3RpY3MtPmdsc3VyZmFjZXJhbSkgLyAoMTAyNCoxMDI0KSkpOwogICAgICAgICBzaG93Zml4bWVzID0gRkFMU0U7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IHNpbXVsYXRpbmcgJWRNQiwgcmV0dXJuaW5nICVkTUIgbGVmdFxuIiwgIFRoaXMsCiAgICAgICAgICh3aW5lZDNkX3NldHRpbmdzLmVtdWxhdGVkX3RleHR1cmVyYW0vKDEwMjQqMTAyNCkpLAogICAgICAgICAoKHdpbmVkM2Rfc2V0dGluZ3MuZW11bGF0ZWRfdGV4dHVyZXJhbSAtIHdpbmVEM0RHbG9iYWxTdGF0aXN0aWNzLT5nbHN1cmZhY2VyYW0pIC8gKDEwMjQqMTAyNCkpKTsKICAgIC8qIHJldHVybiBzaW11bGF0ZWQgdGV4dHVyZSBtZW1vcnkgbGVmdCAqLwogICAgcmV0dXJuICh3aW5lZDNkX3NldHRpbmdzLmVtdWxhdGVkX3RleHR1cmVyYW0gLSB3aW5lRDNER2xvYmFsU3RhdGlzdGljcy0+Z2xzdXJmYWNlcmFtKTsKfQoKCgovKioqKioKICogR2V0IC8gU2V0IEZWRgogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RlZGKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgZnZmKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgLyogVXBkYXRlIHRoZSBjdXJyZW50IHN0YXRlIGJsb2NrICovCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLmZ2ZiAgICAgID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5mdmYgICAgICAgICAgPSBUUlVFOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmZ2ZiA9PSBmdmYpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIGZ2ZiBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5mdmYgICAgICAgICAgICAgID0gZnZmOwogICAgVFJBQ0UoIiglcCkgOiBGVkYgU2hhZGVyIEZWRiBzZXQgdG8gJXhcbiIsIFRoaXMsIGZ2Zik7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZWRihJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEICpwZnZmKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IEdldEZWRiByZXR1cm5pbmcgJXhcbiIsIFRoaXMsIFRoaXMtPnN0YXRlQmxvY2stPmZ2Zik7CiAgICAqcGZ2ZiA9IFRoaXMtPnN0YXRlQmxvY2stPmZ2ZjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFN0cmVhbSBTb3VyY2UKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RyZWFtTnVtYmVyLElXaW5lRDNEVmVydGV4QnVmZmVyKiBwU3RyZWFtRGF0YSwgVUlOVCBPZmZzZXRJbkJ5dGVzLCBVSU5UIFN0cmlkZSkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVyICAgICAqb2xkU3JjOwoKICAgIGlmIChTdHJlYW1OdW1iZXIgPj0gTUFYX1NUUkVBTVMpIHsKICAgICAgICBXQVJOKCJTdHJlYW0gb3V0IG9mIHJhbmdlICVkXG4iLCBTdHJlYW1OdW1iZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIG9sZFNyYyA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdOwogICAgVFJBQ0UoIiglcCkgOiBTdHJlYW1ObzogJXUsIE9sZFN0cmVhbSAoJXApLCBOZXdTdHJlYW0gKCVwKSwgT2Zmc2V0SW5CeXRlcyAldSwgTmV3U3RyaWRlICV1XG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIG9sZFNyYywgcFN0cmVhbURhdGEsIE9mZnNldEluQnl0ZXMsIFN0cmlkZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuc3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl0gICAgID0gVFJVRTsKCiAgICBpZihvbGRTcmMgPT0gcFN0cmVhbURhdGEgJiYKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdID09IFN0cmlkZSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0W1N0cmVhbU51bWJlcl0gPT0gT2Zmc2V0SW5CeXRlcykgewogICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCB2YWx1ZXMgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSAgICAgICAgID0gcFN0cmVhbURhdGE7CiAgICBpZiAocFN0cmVhbURhdGEpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbU3RyZWFtTnVtYmVyXSAgICAgPSBTdHJpZGU7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0W1N0cmVhbU51bWJlcl0gICAgID0gT2Zmc2V0SW5CeXRlczsKICAgIH0KCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBOZWVkIHRvIGRvIGEgZ2V0UGFyZW50IGFuZCBwYXNzIHRoZSByZWZmcyB1cCAqLwogICAgLyogTVNETiBzYXlzIC4uLi4uIFdoZW4gYW4gYXBwbGljYXRpb24gbm8gbG9uZ2VyIGhvbGRzIGEgcmVmZXJlbmNlcyB0byB0aGlzIGludGVyZmFjZSwgdGhlIGludGVyZmFjZSB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZnJlZWQuCiAgICB3aGljaCBzdWdnZXN0cyB0aGF0IHdlIHNob3VsZG4ndCBiZSByZWYgY291bnRpbmc/IGFuZCBkbyBuZWVkIGEgX3JlbGVhc2Ugb24gdGhlIHN0cmVhbSBzb3VyY2UgdG8gcmVzZXQgdGhlIHN0cmVhbSBzb3VyY2UKICAgIHNvIGZvciBub3csIGp1c3QgY291bnQgaW50ZXJuYWxseSAgICovCiAgICBpZiAocFN0cmVhbURhdGEgIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqdmJJbXBsID0gKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBwU3RyZWFtRGF0YTsKICAgICAgICBJbnRlcmxvY2tlZEluY3JlbWVudCgmdmJJbXBsLT5iaW5kQ291bnQpOwogICAgfQogICAgaWYgKG9sZFNyYyAhPSBOVUxMKSB7CiAgICAgICAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJigoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIG9sZFNyYyktPmJpbmRDb3VudCk7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTdHJlYW1OdW1iZXIsSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqKiBwU3RyZWFtLCBVSU5UICpwT2Zmc2V0LCBVSU5UKiBwU3RyaWRlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBTdHJlYW1ObzogJXUsIFN0cmVhbSAoJXApLCBPZmZzZXQgJXUsIFN0cmlkZSAldVxuIiwgVGhpcywgU3RyZWFtTnVtYmVyLAogICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdLAogICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldFtTdHJlYW1OdW1iZXJdLAogICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdKTsKCiAgICBpZiAoU3RyZWFtTnVtYmVyID49IE1BWF9TVFJFQU1TKSB7CiAgICAgICAgV0FSTigiU3RyZWFtIG91dCBvZiByYW5nZSAlZFxuIiwgU3RyZWFtTnVtYmVyKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgICpwU3RyZWFtID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl07CiAgICAqcFN0cmlkZSA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdOwogICAgaWYgKHBPZmZzZXQpIHsKICAgICAgICAqcE9mZnNldCA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldFtTdHJlYW1OdW1iZXJdOwogICAgfQoKICAgIGlmICgqcFN0cmVhbSAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfQWRkUmVmKCpwU3RyZWFtKTsgLyogV2UgaGF2ZSBjcmVhdGVkIGEgbmV3IHJlZmVyZW5jZSB0byB0aGUgVkIgKi8KICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZUZyZXEoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCAgVUlOVCBTdHJlYW1OdW1iZXIsIFVJTlQgRGl2aWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUlOVCBvbGRGbGFncyA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl07CiAgICBVSU5UIG9sZEZyZXEgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl07CgogICAgVFJBQ0UoIiglcCkgU3RyZWFtTnVtYmVyKCVkKSwgRGl2aWRlciglZClcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwgRGl2aWRlcik7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdID0gRGl2aWRlciAmIChXSU5FRDNEU1RSRUFNU09VUkNFX0lOU1RBTkNFREFUQSAgfCBXSU5FRDNEU1RSRUFNU09VUkNFX0lOREVYRUREQVRBICk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gICAgICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gICAgICAgICAgPSBEaXZpZGVyICYgMHg3RkZGRkY7CgogICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdICE9IG9sZEZyZXEgfHwKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl0gIT0gb2xkRmxhZ3MpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2VGcmVxKElXaW5lRDNERGV2aWNlICppZmFjZSwgIFVJTlQgU3RyZWFtTnVtYmVyLCBVSU5UKiBEaXZpZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgU3RyZWFtTnVtYmVyKCVkKSwgRGl2aWRlciglcClcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwgRGl2aWRlcik7CiAgICAqRGl2aWRlciA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSB8IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl07CgogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJWRcbiIsIFRoaXMsICpEaXZpZGVyKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCAmIE11bHRpcGx5IFRyYW5zZm9ybQogKioqKiovCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUcmFuc2Zvcm0oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEVFJBTlNGT1JNU1RBVEVUWVBFIGQzZHRzLCBDT05TVCBXSU5FRDNETUFUUklYKiBscG1hdHJpeCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIE1vc3Qgb2YgdGhpcyByb3V0aW5lLCBjb21tZW50cyBpbmNsdWRlZCBjb3BpZWQgZnJvbSBkZHJhdyB0cmVlIGluaXRpYWxseTogKi8KICAgIFRSQUNFKCIoJXApIDogVHJhbnNmb3JtIFN0YXRlPSVzXG4iLCBUaGlzLCBkZWJ1Z19kM2R0c3R5cGUoZDNkdHMpKTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnRyYW5zZm9ybVtkM2R0c10gPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC50cmFuc2Zvcm1bZDNkdHNdICAgICA9IFRSVUU7CiAgICAgICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW2QzZHRzXSwgbHBtYXRyaXgsIHNpemVvZihXSU5FRDNETUFUUklYKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyoKICAgICAqIElmIHRoZSBuZXcgbWF0cml4IGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IG9uZSwKICAgICAqIHdlIGN1dCBvZmYgYW55IGZ1cnRoZXIgcHJvY2Vzc2luZy4gdGhpcyBzZWVtcyB0byBiZSBhIHJlYXNvbmFibGUKICAgICAqIG9wdGltaXphdGlvbiBiZWNhdXNlIGFzIHdhcyBub3RpY2VkLCBzb21lIGFwcHMgKHdhcmNyYWZ0MyBmb3IgZXhhbXBsZSkKICAgICAqIHRlbmQgdG93YXJkcyBzZXR0aW5nIHRoZSBzYW1lIG1hdHJpeCByZXBlYXRlZGx5IGZvciBzb21lIHJlYXNvbi4KICAgICAqCiAgICAgKiBGcm9tIGhlcmUgb24gd2UgYXNzdW1lIHRoYXQgdGhlIG5ldyBtYXRyaXggaXMgZGlmZmVyZW50LCB3aGVyZXZlciBpdCBtYXR0ZXJzLgogICAgICovCiAgICBpZiAoIW1lbWNtcCgmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10udS5tWzBdWzBdLCBscG1hdHJpeCwgc2l6ZW9mKFdJTkVEM0RNQVRSSVgpKSkgewogICAgICAgIFRSQUNFKCJUaGUgYXBwIGlzIHNldHRpbmcgdGhlIHNhbWUgbWF0cml4IG92ZXIgYWdhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIHsKICAgICAgICBjb252X21hdChscG1hdHJpeCwgJlRoaXMtPnN0YXRlQmxvY2stPnRyYW5zZm9ybXNbZDNkdHNdLnUubVswXVswXSk7CiAgICB9CgogICAgLyoKICAgICAgIFNjcmVlbkNvb3JkID0gUHJvamVjdGlvbk1hdCAqIFZpZXdNYXQgKiBXb3JsZE1hdCAqIE9iamVjdENvb3JkCiAgICAgICB3aGVyZSBWaWV3TWF0ID0gQ2FtZXJhIHNwYWNlLCBXb3JsZE1hdCA9IHdvcmxkIHNwYWNlLgoKICAgICAgIEluIE9wZW5HTCwgY2FtZXJhIGFuZCB3b3JsZCBzcGFjZSBpcyBjb21iaW5lZCBpbnRvIEdMX01PREVMVklFVwogICAgICAgbWF0cml4LiAgVGhlIFByb2plY3Rpb24gbWF0cml4IHN0YXkgcHJvamVjdGlvbiBtYXRyaXguCiAgICAgKi8KCiAgICAvKiBDYXB0dXJlIHRoZSB0aW1lcyB3ZSBjYW4ganVzdCBpZ25vcmUgdGhlIGNoYW5nZSBmb3Igbm93ICovCiAgICBpZiAoZDNkdHMgPT0gV0lORUQzRFRTX1ZJRVcpIHsgLyogaGFuZGxlIHRoZSBWSUVXIG1hdHJpY2UgKi8KICAgICAgICBUaGlzLT52aWV3X2lkZW50ID0gIW1lbWNtcChscG1hdHJpeCwgaWRlbnRpdHksIDE2ICogc2l6ZW9mKGZsb2F0KSk7CiAgICAgICAgLyogSGFuZGxlZCBieSB0aGUgc3RhdGUgbWFuYWdlciAqLwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9UUkFOU0ZPUk0oZDNkdHMpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKfQpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRyYW5zZm9ybShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RUUkFOU0ZPUk1TVEFURVRZUEUgU3RhdGUsIFdJTkVEM0RNQVRSSVgqIHBNYXRyaXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogZm9yIFRyYW5zZm9ybSBTdGF0ZSAlc1xuIiwgVGhpcywgZGVidWdfZDNkdHN0eXBlKFN0YXRlKSk7CiAgICBtZW1jcHkocE1hdHJpeCwgJlRoaXMtPnN0YXRlQmxvY2stPnRyYW5zZm9ybXNbU3RhdGVdLCBzaXplb2YoV0lORUQzRE1BVFJJWCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfTXVsdGlwbHlUcmFuc2Zvcm0oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFN0YXRlLCBDT05TVCBXSU5FRDNETUFUUklYKiBwTWF0cml4KSB7CiAgICBXSU5FRDNETUFUUklYICptYXQgPSBOVUxMOwogICAgV0lORUQzRE1BVFJJWCB0ZW1wOwoKICAgIC8qIE5vdGU6IFVzaW5nICd1cGRhdGVTdGF0ZUJsb2NrJyByYXRoZXIgdGhhbiAnc3RhdGVibG9jaycgaW4gdGhlIGNvZGUKICAgICAqIGJlbG93IG1lYW5zIGl0IHdpbGwgYmUgcmVjb3JkZWQgaW4gYSBzdGF0ZSBibG9jayBjaGFuZ2UsIGJ1dCBpdAogICAgICogd29ya3MgcmVnYXJkbGVzcyB3aGVyZSBpdCBpcyByZWNvcmRlZC4KICAgICAqIElmIHRoaXMgaXMgZm91bmQgdG8gYmUgd3JvbmcsIGNoYW5nZSB0byBTdGF0ZUJsb2NrLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IEZvciBzdGF0ZSAlc1xuIiwgVGhpcywgZGVidWdfZDNkdHN0eXBlKFN0YXRlKSk7CgogICAgaWYgKFN0YXRlIDwgSElHSEVTVF9UUkFOU0ZPUk1TVEFURSkKICAgIHsKICAgICAgICBtYXQgPSAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tTdGF0ZV07CiAgICB9IGVsc2UgewogICAgICAgIEZJWE1FKCJVbmhhbmRsZWQgdHJhbnNmb3JtIHN0YXRlISFcbiIpOwogICAgfQoKICAgIG11bHRpcGx5X21hdHJpeCgmdGVtcCwgbWF0LCAoY29uc3QgV0lORUQzRE1BVFJJWCAqKSBwTWF0cml4KTsKCiAgICAvKiBBcHBseSBjaGFuZ2UgdmlhIHNldCB0cmFuc2Zvcm0gLSB3aWxsIHJlYXBwbHkgdG8gZWcuIGxpZ2h0cyB0aGlzIHdheSAqLwogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUcmFuc2Zvcm0oaWZhY2UsIFN0YXRlLCAmdGVtcCk7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgTGlnaHQKICoqKioqLwovKiBOb3RlIGxpZ2h0cyBhcmUgcmVhbCBzcGVjaWFsIGNhc2VzLiBBbHRob3VnaCB0aGUgZGV2aWNlIGNhcHMgc3RhdGUgb25seSBlZy4gOCBhcmUgc3VwcG9ydGVkLAogICB5b3UgY2FuIHJlZmVyZW5jZSBhbnkgaW5kZXhlcyB5b3Ugd2FudCBhcyBsb25nIGFzIHRoYXQgbnVtYmVyIG1heCBhcmUgZW5hYmxlZCBhdCBhbnkKICAgb25lIHBvaW50IGluIHRpbWUhIFRoZXJlZm9yZSBzaW5jZSB0aGUgaW5kZXhlcyBjYW4gYmUgYW55dGhpbmcsIHdlIG5lZWQgYSBoYXNobWFwIG9mIHRoZW0uCiAgIEhvd2V2ZXIsIHRoaXMgY2F1c2VzIHN0YXRlYmxvY2sgcHJvYmxlbXMuIFdoZW4gY2FwdHVyaW5nIHRoZSBzdGF0ZSBibG9jaywgSSBkdXBsaWNhdGUgdGhlIGhhc2htYXAsCiAgIGJ1dCB3aGVuIHJlY29yZGluZywganVzdCBidWlsZCBhIGNoYWluIHByZXR0eSBtdWNoIG9mIGNvbW1hbmRzIHRvIGJlIHJlcGxheWVkLiAgICAgICAgICAgICAgICAgICovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIENPTlNUIFdJTkVEM0RMSUdIVCogcExpZ2h0KSB7CiAgICBmbG9hdCByaG87CiAgICBQTElHSFRJTkZPRUwgKm9iamVjdCA9IE5VTEw7CiAgICBVSU5UIEhpID0gTElHSFRNQVBfSEFTSEZVTkMoSW5kZXgpOwogICAgc3RydWN0IGxpc3QgKmU7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBJZHgoJWQpLCBwTGlnaHQoJXApLiBIYXNoIGluZGV4IGlzICVkXG4iLCBUaGlzLCBJbmRleCwgcExpZ2h0LCBIaSk7CgogICAgLyogQ2hlY2sgdGhlIHBhcmFtZXRlciByYW5nZS4gTmVlZCBmb3Igc3BlZWQgbW9zdCB3YW50ZWQgc2V0cyBqdW5rIGxpZ2h0cyB3aGljaCBjb25mdXNlCiAgICAgKiB0aGUgZ2wgZHJpdmVyLgogICAgICovCiAgICBpZighcExpZ2h0KSB7CiAgICAgICAgV0FSTigiTGlnaHQgcG9pbnRlciA9IE5VTEwsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBzd2l0Y2gocExpZ2h0LT5UeXBlKSB7CiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfUE9JTlQ6CiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfU1BPVDoKICAgICAgICBjYXNlIFdJTkVEM0RMSUdIVF9QQVJBTExFTFBPSU5UOgogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX0dMU1BPVDoKICAgICAgICAgICAgLyogSW5jb3JyZWN0IGF0dGVudWF0aW9uIHZhbHVlcyBjYW4gY2F1c2UgdGhlIGdsIGRyaXZlciB0byBjcmFzaC4gSGFwcGVucyB3aXRoIE5lZWQgZm9yIHNwZWVkCiAgICAgICAgICAgICAqIG1vc3Qgd2FudGVkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihwTGlnaHQtPkF0dGVudWF0aW9uMCA8IDAuMCB8fCBwTGlnaHQtPkF0dGVudWF0aW9uMSA8IDAuMCB8fCBwTGlnaHQtPkF0dGVudWF0aW9uMiA8IDAuMCkgewogICAgICAgICAgICAgICAgV0FSTigiQXR0ZW51YXRpb24gaXMgbmVnYXRpdmUsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RMSUdIVF9ESVJFQ1RJT05BTDoKICAgICAgICAgICAgLyogSWdub3JlcyBhdHRlbnVhdGlvbiAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICBXQVJOKCJMaWdodCB0eXBlIG91dCBvZiByYW5nZSwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSkgewogICAgICAgIG9iamVjdCA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgaWYob2JqZWN0LT5PcmlnaW5hbEluZGV4ID09IEluZGV4KSBicmVhazsKICAgICAgICBvYmplY3QgPSBOVUxMOwogICAgfQoKICAgIGlmKCFvYmplY3QpIHsKICAgICAgICBUUkFDRSgiQWRkaW5nIG5ldyBsaWdodFxuIik7CiAgICAgICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZigqb2JqZWN0KSk7CiAgICAgICAgaWYoIW9iamVjdCkgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgZXJyb3Igd2hlbiBhbGxvY2F0aW5nIGEgbGlnaHRcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRNYXBbSGldLCAmb2JqZWN0LT5lbnRyeSk7CiAgICAgICAgb2JqZWN0LT5nbEluZGV4ID0gLTE7CiAgICAgICAgb2JqZWN0LT5PcmlnaW5hbEluZGV4ID0gSW5kZXg7CiAgICAgICAgb2JqZWN0LT5jaGFuZ2VkID0gVFJVRTsKICAgIH0KCiAgICAvKiBJbml0aWFsaXplIHRoZSBvYmplY3QgKi8KICAgIFRSQUNFKCJMaWdodCAlZCBzZXR0aW5nIHRvIHR5cGUgJWQsIERpZmZ1c2UoJWYsJWYsJWYsJWYpLCBTcGVjdWxhciglZiwlZiwlZiwlZiksIEFtYmllbnQoJWYsJWYsJWYsJWYpXG4iLCBJbmRleCwgcExpZ2h0LT5UeXBlLAogICAgICAgICAgcExpZ2h0LT5EaWZmdXNlLnIsIHBMaWdodC0+RGlmZnVzZS5nLCBwTGlnaHQtPkRpZmZ1c2UuYiwgcExpZ2h0LT5EaWZmdXNlLmEsCiAgICAgICAgICBwTGlnaHQtPlNwZWN1bGFyLnIsIHBMaWdodC0+U3BlY3VsYXIuZywgcExpZ2h0LT5TcGVjdWxhci5iLCBwTGlnaHQtPlNwZWN1bGFyLmEsCiAgICAgICAgICBwTGlnaHQtPkFtYmllbnQuciwgcExpZ2h0LT5BbWJpZW50LmcsIHBMaWdodC0+QW1iaWVudC5iLCBwTGlnaHQtPkFtYmllbnQuYSk7CiAgICBUUkFDRSgiLi4uIFBvcyglZiwlZiwlZiksIERpcm4oJWYsJWYsJWYpXG4iLCBwTGlnaHQtPlBvc2l0aW9uLngsIHBMaWdodC0+UG9zaXRpb24ueSwgcExpZ2h0LT5Qb3NpdGlvbi56LAogICAgICAgICAgcExpZ2h0LT5EaXJlY3Rpb24ueCwgcExpZ2h0LT5EaXJlY3Rpb24ueSwgcExpZ2h0LT5EaXJlY3Rpb24ueik7CiAgICBUUkFDRSgiLi4uIFJhbmdlKCVmKSwgRmFsbG9mZiglZiksIFRoZXRhKCVmKSwgUGhpKCVmKVxuIiwgcExpZ2h0LT5SYW5nZSwgcExpZ2h0LT5GYWxsb2ZmLCBwTGlnaHQtPlRoZXRhLCBwTGlnaHQtPlBoaSk7CgogICAgLyogU2F2ZSBhd2F5IHRoZSBpbmZvcm1hdGlvbiAqLwogICAgbWVtY3B5KCZvYmplY3QtPk9yaWdpbmFsUGFybXMsIHBMaWdodCwgc2l6ZW9mKFdJTkVEM0RMSUdIVCkpOwoKICAgIHN3aXRjaCAocExpZ2h0LT5UeXBlKSB7CiAgICBjYXNlIFdJTkVEM0RMSUdIVF9QT0lOVDoKICAgICAgICAvKiBQb3NpdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzBdID0gcExpZ2h0LT5Qb3NpdGlvbi54OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzFdID0gcExpZ2h0LT5Qb3NpdGlvbi55OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzJdID0gcExpZ2h0LT5Qb3NpdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzNdID0gMS4wZjsKICAgICAgICBvYmplY3QtPmN1dG9mZiA9IDE4MC4wZjsKICAgICAgICAvKiBGSVhNRTogUmFuZ2UgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RMSUdIVF9ESVJFQ1RJT05BTDoKICAgICAgICAvKiBEaXJlY3Rpb24gKi8KICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblswXSA9IC1wTGlnaHQtPkRpcmVjdGlvbi54OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzFdID0gLXBMaWdodC0+RGlyZWN0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMl0gPSAtcExpZ2h0LT5EaXJlY3Rpb24uejsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblszXSA9IDAuMDsKICAgICAgICBvYmplY3QtPmV4cG9uZW50ICAgICA9IDAuMGY7CiAgICAgICAgb2JqZWN0LT5jdXRvZmYgICAgICAgPSAxODAuMGY7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNETElHSFRfU1BPVDoKICAgICAgICAvKiBQb3NpdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzBdID0gcExpZ2h0LT5Qb3NpdGlvbi54OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzFdID0gcExpZ2h0LT5Qb3NpdGlvbi55OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzJdID0gcExpZ2h0LT5Qb3NpdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzNdID0gMS4wOwoKICAgICAgICAvKiBEaXJlY3Rpb24gKi8KICAgICAgICBvYmplY3QtPmxpZ2h0RGlyblswXSA9IHBMaWdodC0+RGlyZWN0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bMV0gPSBwTGlnaHQtPkRpcmVjdGlvbi55OwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzJdID0gcExpZ2h0LT5EaXJlY3Rpb24uejsKICAgICAgICBvYmplY3QtPmxpZ2h0RGlyblszXSA9IDEuMDsKCiAgICAgICAgLyoKICAgICAgICAgKiBvcGVuZ2wtaXNoIGFuZCBkM2QtaXNoIHNwb3QgbGlnaHRzIHVzZSB0b28gZGlmZmVyZW50IG1vZGVscyBmb3IgdGhlCiAgICAgICAgICogbGlnaHQgImludGVuc2l0eSIgYXMgYSBmdW5jdGlvbiBvZiB0aGUgYW5nbGUgdG93YXJkcyB0aGUgbWFpbiBsaWdodCBkaXJlY3Rpb24sCiAgICAgICAgICogc28gd2Ugb25seSBjYW4gYXBwcm94aW1hdGUgdmVyeSByb3VnaGx5LgogICAgICAgICAqIGhvd2V2ZXIgc3BvdCBsaWdodHMgYXJlIHJhdGhlciByYXJlbHkgdXNlZCBpbiBnYW1lcyAoaWYgZXZlciB1c2VkIGF0IGFsbCkuCiAgICAgICAgICogZnVydGhlcm1vcmUgaWYgc3RpbGwgdXNlZCwgcHJvYmFibHkgbm9ib2R5IHBheXMgYXR0ZW50aW9uIHRvIHN1Y2ggZGV0YWlscy4KICAgICAgICAgKi8KICAgICAgICBpZiAocExpZ2h0LT5GYWxsb2ZmID09IDApIHsKICAgICAgICAgICAgcmhvID0gNi4yOGY7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmhvID0gcExpZ2h0LT5UaGV0YSArIChwTGlnaHQtPlBoaSAtIHBMaWdodC0+VGhldGEpLygyKnBMaWdodC0+RmFsbG9mZik7CiAgICAgICAgfQogICAgICAgIGlmIChyaG8gPCAwLjAwMDEpIHJobyA9IDAuMDAwMWY7CiAgICAgICAgb2JqZWN0LT5leHBvbmVudCA9IC0wLjMvbG9nKGNvcyhyaG8vMikpOwoJaWYgKG9iamVjdC0+ZXhwb25lbnQgPiAxMjguMCkgewoJCW9iamVjdC0+ZXhwb25lbnQgPSAxMjguMDsKCX0KICAgICAgICBvYmplY3QtPmN1dG9mZiA9IHBMaWdodC0+UGhpKjkwL01fUEk7CgogICAgICAgIC8qIEZJWE1FOiBSYW5nZSAqLwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBsaWdodCB0eXBlICVkXG4iLCBwTGlnaHQtPlR5cGUpOwogICAgfQoKICAgIC8qIFVwZGF0ZSB0aGUgbGl2ZSBkZWZpbml0aW9ucyBpZiB0aGUgbGlnaHQgaXMgY3VycmVudGx5IGFzc2lnbmVkIGEgZ2xJbmRleCAqLwogICAgaWYgKG9iamVjdC0+Z2xJbmRleCAhPSAtMSAmJiAhVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9BQ1RJVkVMSUdIVChvYmplY3QtPmdsSW5kZXgpKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIFdJTkVEM0RMSUdIVCogcExpZ2h0KSB7CiAgICBQTElHSFRJTkZPRUwgKmxpZ2h0SW5mbyA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBEV09SRCBIaSA9IExJR0hUTUFQX0hBU0hGVU5DKEluZGV4KTsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgVFJBQ0UoIiglcCkgOiBJZHgoJWQpLCBwTGlnaHQoJXApXG4iLCBUaGlzLCBJbmRleCwgcExpZ2h0KTsKCiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT5zdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICBsaWdodEluZm8gPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgIGlmKGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgbGlnaHRJbmZvID0gTlVMTDsKICAgIH0KCiAgICBpZiAobGlnaHRJbmZvID09IE5VTEwpIHsKICAgICAgICBUUkFDRSgiTGlnaHQgaW5mb3JtYXRpb24gcmVxdWVzdGVkIGJ1dCBsaWdodCBub3QgZGVmaW5lZFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgbWVtY3B5KHBMaWdodCwgJmxpZ2h0SW5mby0+T3JpZ2luYWxQYXJtcywgc2l6ZW9mKFdJTkVEM0RMSUdIVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgTGlnaHQgRW5hYmxlCiAqICAgKE5vdGUgZm9yIGNvbnNpc3RlbmN5LCByZW5hbWVkIGQzZHggZnVuY3Rpb24gYnkgYWRkaW5nIHRoZSAnc2V0JyBwcmVmaXgpCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodEVuYWJsZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBCT09MIEVuYWJsZSkgewogICAgUExJR0hUSU5GT0VMICpsaWdodEluZm8gPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUlOVCBIaSA9IExJR0hUTUFQX0hBU0hGVU5DKEluZGV4KTsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgVFJBQ0UoIiglcCkgOiBJZHgoJWQpLCBlbmFibGU/ICVkXG4iLCBUaGlzLCBJbmRleCwgRW5hYmxlKTsKCiAgICAvKiBUZXN0cyBzaG93IHRydWUgPSAxMjguLi5ub3QgY2xlYXIgd2h5ICovCiAgICBFbmFibGUgPSBFbmFibGU/IDEyODogMDsKCiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICBsaWdodEluZm8gPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgIGlmKGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgbGlnaHRJbmZvID0gTlVMTDsKICAgIH0KICAgIFRSQUNFKCJGb3VuZCBsaWdodDogJXBcbiIsIGxpZ2h0SW5mbyk7CgogICAgLyogU3BlY2lhbCBjYXNlIC0gZW5hYmxpbmcgYW4gdW5kZWZpbmVkIGxpZ2h0IGNyZWF0ZXMgb25lIHdpdGggYSBzdHJpY3Qgc2V0IG9mIHBhcm1zISAqLwogICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CgogICAgICAgIFRSQUNFKCJMaWdodCBlbmFibGVkIHJlcXVlc3RlZCBidXQgbGlnaHQgbm90IGRlZmluZWQsIHNvIGRlZmluaW5nIG9uZSFcbiIpOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodChpZmFjZSwgSW5kZXgsICZXSU5FRDNEX2RlZmF1bHRfbGlnaHQpOwoKICAgICAgICAvKiBTZWFyY2ggZm9yIGl0IGFnYWluISBTaG91bGQgYmUgZmFpcmx5IHF1aWNrIGFzIG5lYXIgaGVhZCBvZiBsaXN0ICovCiAgICAgICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgICAgIGxpZ2h0SW5mbyA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgICAgIGlmKGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgICAgIGxpZ2h0SW5mbyA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewogICAgICAgICAgICBGSVhNRSgiQWRkaW5nIGRlZmF1bHQgbGlnaHRzIGhhcyBmYWlsZWQgZGlzbWFsbHlcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICB9CgogICAgbGlnaHRJbmZvLT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CiAgICBpZighRW5hYmxlKSB7CiAgICAgICAgaWYobGlnaHRJbmZvLT5nbEluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIGlmKCFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfQUNUSVZFTElHSFQobGlnaHRJbmZvLT5nbEluZGV4KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmFjdGl2ZUxpZ2h0c1tsaWdodEluZm8tPmdsSW5kZXhdID0gTlVMTDsKICAgICAgICAgICAgbGlnaHRJbmZvLT5nbEluZGV4ID0gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIkxpZ2h0IGFscmVhZHkgZGlzYWJsZWQsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGxpZ2h0SW5mby0+Z2xJbmRleCAhPSAtMSkgewogICAgICAgICAgICAvKiBub3AgKi8KICAgICAgICAgICAgVFJBQ0UoIk5vdGhpbmcgdG8gZG8gYXMgbGlnaHQgd2FzIGVuYWJsZWRcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAvKiBGaW5kIGEgZnJlZSBnbCBsaWdodCAqLwogICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5tYXhDb25jdXJyZW50TGlnaHRzOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPmFjdGl2ZUxpZ2h0c1tpXSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+YWN0aXZlTGlnaHRzW2ldID0gbGlnaHRJbmZvOwogICAgICAgICAgICAgICAgICAgIGxpZ2h0SW5mby0+Z2xJbmRleCA9IGk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYobGlnaHRJbmZvLT5nbEluZGV4ID09IC0xKSB7CiAgICAgICAgICAgICAgICBFUlIoIlRvbyBtYW55IGNvbmN1cnJlbnRseSBhY3RpdmUgbGlnaHRzXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBpID09IGxpZ2h0SW5mby0+Z2xJbmRleCAqLwogICAgICAgICAgICBpZighVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0FDVElWRUxJR0hUKGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodEVuYWJsZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LEJPT0wqIHBFbmFibGUpIHsKCiAgICBQTElHSFRJTkZPRUwgKmxpZ2h0SW5mbyA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIFVJTlQgSGkgPSBMSUdIVE1BUF9IQVNIRlVOQyhJbmRleCk7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBpZHgoJWQpXG4iLCBUaGlzLCBJbmRleCk7CgogICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+c3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgbGlnaHRJbmZvID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICBpZihsaWdodEluZm8tPk9yaWdpbmFsSW5kZXggPT0gSW5kZXgpIGJyZWFrOwogICAgICAgIGxpZ2h0SW5mbyA9IE5VTEw7CiAgICB9CgogICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoIkxpZ2h0IGVuYWJsZWQgc3RhdGUgcmVxdWVzdGVkIGJ1dCBsaWdodCBub3QgZGVmaW5lZFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKiB0cnVlIGlzIDEyOCBhY2NvcmRpbmcgdG8gU2V0TGlnaHRFbmFibGUgKi8KICAgICpwRW5hYmxlID0gbGlnaHRJbmZvLT5nbEluZGV4ICE9IC0xID8gMTI4IDogMDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IENsaXAgUGxhbmVzCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDbGlwUGxhbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgQ09OU1QgZmxvYXQgKnBQbGFuZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBmb3IgaWR4ICVkLCAlcFxuIiwgVGhpcywgSW5kZXgsIHBQbGFuZSk7CgogICAgLyogVmFsaWRhdGUgSW5kZXggKi8KICAgIGlmIChJbmRleCA+PSBHTF9MSU1JVFMoY2xpcHBsYW5lcykpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaGFzIHJlcXVlc3RlZCBjbGlwcGxhbmUgdGhpcyBkZXZpY2UgZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLmNsaXBwbGFuZVtJbmRleF0gPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LmNsaXBwbGFuZVtJbmRleF0gPSBUUlVFOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMF0gPT0gcFBsYW5lWzBdICYmCiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzFdID09IHBQbGFuZVsxXSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsyXSA9PSBwUGxhbmVbMl0gJiYKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bM10gPT0gcFBsYW5lWzNdKSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgb2xkIHZhbHVlcyBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzBdID0gcFBsYW5lWzBdOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsxXSA9IHBQbGFuZVsxXTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMl0gPSBwUGxhbmVbMl07CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzNdID0gcFBsYW5lWzNdOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9DTElQUExBTkUoSW5kZXgpKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwUGxhbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgZmxvYXQgKnBQbGFuZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBmb3IgaWR4ICVkXG4iLCBUaGlzLCBJbmRleCk7CgogICAgLyogVmFsaWRhdGUgSW5kZXggKi8KICAgIGlmIChJbmRleCA+PSBHTF9MSU1JVFMoY2xpcHBsYW5lcykpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaGFzIHJlcXVlc3RlZCBjbGlwcGxhbmUgdGhpcyBkZXZpY2UgZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBwUGxhbmVbMF0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzBdOwogICAgcFBsYW5lWzFdID0gVGhpcy0+c3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsxXTsKICAgIHBQbGFuZVsyXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMl07CiAgICBwUGxhbmVbM10gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzNdOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgQ2xpcCBQbGFuZSBTdGF0dXMKICogICBXQVJOSU5HOiBUaGlzIGNvZGUgcmVsaWVzIG9uIHRoZSBmYWN0IHRoYXQgRDNEQ0xJUFNUQVRVUzggPT0gRDNEQ0xJUFNUQVRVUzkKICoqKioqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFdJTkVEM0RDTElQU1RBVFVTKiBwQ2xpcFN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIGlmIChOVUxMID09IHBDbGlwU3RhdHVzKSB7CiAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcFVuaW9uID0gcENsaXBTdGF0dXMtPkNsaXBVbmlvbjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBJbnRlcnNlY3Rpb24gPSBwQ2xpcFN0YXR1cy0+Q2xpcEludGVyc2VjdGlvbjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RDTElQU1RBVFVTKiBwQ2xpcFN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIGlmIChOVUxMID09IHBDbGlwU3RhdHVzKSB7CiAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgcENsaXBTdGF0dXMtPkNsaXBVbmlvbiA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBVbmlvbjsKICAgIHBDbGlwU3RhdHVzLT5DbGlwSW50ZXJzZWN0aW9uID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcEludGVyc2VjdGlvbjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IE1hdGVyaWFsCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNYXRlcmlhbChJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFdJTkVEM0RNQVRFUklBTCogcE1hdGVyaWFsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5tYXRlcmlhbCA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQubWF0ZXJpYWwgPSBUUlVFOwogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbCwgcE1hdGVyaWFsLCBzaXplb2YoV0lORUQzRE1BVEVSSUFMKSk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgRU5URVJfR0woKTsKICAgIFRSQUNFKCIoJXApIDogRGlmZnVzZSAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuciwgcE1hdGVyaWFsLT5EaWZmdXNlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5EaWZmdXNlLmIsIHBNYXRlcmlhbC0+RGlmZnVzZS5hKTsKICAgIFRSQUNFKCIoJXApIDogQW1iaWVudCAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkFtYmllbnQuciwgcE1hdGVyaWFsLT5BbWJpZW50LmcsCiAgICAgICAgcE1hdGVyaWFsLT5BbWJpZW50LmIsIHBNYXRlcmlhbC0+QW1iaWVudC5hKTsKICAgIFRSQUNFKCIoJXApIDogU3BlY3VsYXIgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5TcGVjdWxhci5yLCBwTWF0ZXJpYWwtPlNwZWN1bGFyLmcsCiAgICAgICAgcE1hdGVyaWFsLT5TcGVjdWxhci5iLCBwTWF0ZXJpYWwtPlNwZWN1bGFyLmEpOwogICAgVFJBQ0UoIiglcCkgOiBFbWlzc2l2ZSAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLnIsIHBNYXRlcmlhbC0+RW1pc3NpdmUuZywKICAgICAgICBwTWF0ZXJpYWwtPkVtaXNzaXZlLmIsIHBNYXRlcmlhbC0+RW1pc3NpdmUuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFBvd2VyICglZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+UG93ZXIpOwoKICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfQU1CSUVOVCwgKGZsb2F0KikgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPm1hdGVyaWFsLkFtYmllbnQpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmdihHTF9BTUJJRU5UKSIpOwogICAgZ2xNYXRlcmlhbGZ2KEdMX0ZST05UX0FORF9CQUNLLCBHTF9ESUZGVVNFLCAoZmxvYXQqKSAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwuRGlmZnVzZSk7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGZ2KEdMX0RJRkZVU0UpIik7CgogICAgLyogT25seSBjaGFuZ2UgbWF0ZXJpYWwgY29sb3IgaWYgc3BlY3VsYXIgaXMgZW5hYmxlZCwgb3RoZXJ3aXNlIGl0IGlzIHNldCB0byBibGFjayAqLwogICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TUEVDVUxBUkVOQUJMRV0pIHsKICAgICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfU1BFQ1VMQVIsIChmbG9hdCopICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5TcGVjdWxhcik7CiAgICAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGZ2KEdMX1NQRUNVTEFSIik7CiAgICB9IGVsc2UgewogICAgICAgZmxvYXQgYmxhY2tbNF0gPSB7MC4wZiwgMC4wZiwgMC4wZiwgMC4wZn07CiAgICAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX1NQRUNVTEFSLCAmYmxhY2tbMF0pOwogICAgICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmdihHTF9TUEVDVUxBUiIpOwogICAgfQogICAgZ2xNYXRlcmlhbGZ2KEdMX0ZST05UX0FORF9CQUNLLCBHTF9FTUlTU0lPTiwgKGZsb2F0KikgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPm1hdGVyaWFsLkVtaXNzaXZlKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdGVyaWFsZnYoR0xfRU1JU1NJT04pIik7CiAgICBnbE1hdGVyaWFsZihHTF9GUk9OVF9BTkRfQkFDSywgR0xfU0hJTklORVNTLCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5Qb3dlcik7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGYoR0xfU0hJTklORVNTIik7CgogICAgTEVBVkVfR0woKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldE1hdGVyaWFsKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRE1BVEVSSUFMKiBwTWF0ZXJpYWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIG1lbWNweShwTWF0ZXJpYWwsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbCwgc2l6ZW9mIChXSU5FRDNETUFURVJJQUwpKTsKICAgIFRSQUNFKCIoJXApIDogRGlmZnVzZSAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuciwgcE1hdGVyaWFsLT5EaWZmdXNlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5EaWZmdXNlLmIsIHBNYXRlcmlhbC0+RGlmZnVzZS5hKTsKICAgIFRSQUNFKCIoJXApIDogQW1iaWVudCAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkFtYmllbnQuciwgcE1hdGVyaWFsLT5BbWJpZW50LmcsCiAgICAgICAgcE1hdGVyaWFsLT5BbWJpZW50LmIsIHBNYXRlcmlhbC0+QW1iaWVudC5hKTsKICAgIFRSQUNFKCIoJXApIDogU3BlY3VsYXIgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5TcGVjdWxhci5yLCBwTWF0ZXJpYWwtPlNwZWN1bGFyLmcsCiAgICAgICAgcE1hdGVyaWFsLT5TcGVjdWxhci5iLCBwTWF0ZXJpYWwtPlNwZWN1bGFyLmEpOwogICAgVFJBQ0UoIiglcCkgOiBFbWlzc2l2ZSAoJWYsJWYsJWYsJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLnIsIHBNYXRlcmlhbC0+RW1pc3NpdmUuZywKICAgICAgICBwTWF0ZXJpYWwtPkVtaXNzaXZlLmIsIHBNYXRlcmlhbC0+RW1pc3NpdmUuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFBvd2VyICglZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+UG93ZXIpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IEluZGljZXMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEluZGljZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzREluZGV4QnVmZmVyKiBwSW5kZXhEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIEJhc2VWZXJ0ZXhJbmRleCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNESW5kZXhCdWZmZXIgKm9sZElkeHM7CiAgICBVSU5UIG9sZEJhc2VJbmRleCA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleDsKCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgdG8gJXAsIGJhc2UgJWRcbiIsIFRoaXMsIHBJbmRleERhdGEsIEJhc2VWZXJ0ZXhJbmRleCk7CiAgICBvbGRJZHhzID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLmluZGljZXMgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LmluZGljZXMgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9IHBJbmRleERhdGE7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSBCYXNlVmVydGV4SW5kZXg7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogVGhlIGJhc2UgdmVydGV4IGluZGV4IGFmZmVjdHMgdGhlIHN0cmVhbSBzb3VyY2VzLCB3aGlsZQogICAgICogVGhlIGluZGV4IGJ1ZmZlciBpcyBhIHNlcGVyYXRlIGluZGV4IGJ1ZmZlciBzdGF0ZQogICAgICovCiAgICBpZihCYXNlVmVydGV4SW5kZXggIT0gb2xkQmFzZUluZGV4KSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CiAgICB9CiAgICBpZihvbGRJZHhzICE9IHBJbmRleERhdGEpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0SW5kaWNlcyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNESW5kZXhCdWZmZXIqKiBwcEluZGV4RGF0YSwgVUlOVCogcEJhc2VWZXJ0ZXhJbmRleCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgICpwcEluZGV4RGF0YSA9IFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGE7CgogICAgLyogdXAgcmVmIGNvdW50IG9uIHBwaW5kZXhkYXRhICovCiAgICBpZiAoKnBwSW5kZXhEYXRhKSB7CiAgICAgICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9BZGRSZWYoKnBwSW5kZXhEYXRhKTsKICAgICAgICAqcEJhc2VWZXJ0ZXhJbmRleCA9IFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleDsKICAgICAgICBUUkFDRSgiKCVwKSBpbmRleCBkYXRhIHNldCB0byAlcCArICV1XG4iLCBUaGlzLCBwcEluZGV4RGF0YSwgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4KTsKICAgIH1lbHNlewogICAgICAgIFRSQUNFKCIoJXApIE5vIGluZGV4IGRhdGEgc2V0XG4iLCBUaGlzKTsKICAgIH0KICAgIFRSQUNFKCJSZXR1cm5pbmcgJXAgJWRcbiIsICpwcEluZGV4RGF0YSwgKnBCYXNlVmVydGV4SW5kZXgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBNZXRob2QgdG8gb2ZmZXIgZDNkOSBhIHNpbXBsZSB3YXkgdG8gc2V0IHRoZSBiYXNlIHZlcnRleCBpbmRleCB3aXRob3V0IG1lc3Npbmcgd2l0aCB0aGUgaW5kZXggYnVmZmVyICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0QmFzZXZlcnRleEluZGV4KElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBCYXNlSW5kZXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJWQpXG4iLCBUaGlzLCBCYXNlSW5kZXgpOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCA9PSBCYXNlSW5kZXgpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIHZhbHVlIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCA9IEJhc2VJbmRleDsKCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBWaWV3cG9ydHMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0KElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgV0lORUQzRFZJRVdQT1JUKiBwVmlld3BvcnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZpZXdwb3J0ID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC52aWV3cG9ydCA9IFRSVUU7CiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZpZXdwb3J0LCBwVmlld3BvcnQsIHNpemVvZihXSU5FRDNEVklFV1BPUlQpKTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IHg9JWQsIHk9JWQsIHdpZD0lZCwgaGVpPSVkLCBtaW56PSVmLCBtYXh6PSVmXG4iLCBUaGlzLAogICAgICAgICAgcFZpZXdwb3J0LT5YLCBwVmlld3BvcnQtPlksIHBWaWV3cG9ydC0+V2lkdGgsIHBWaWV3cG9ydC0+SGVpZ2h0LCBwVmlld3BvcnQtPk1pblosIHBWaWV3cG9ydC0+TWF4Wik7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZJRVdQT1JUKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWaWV3cG9ydChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RWSUVXUE9SVCogcFZpZXdwb3J0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICBtZW1jcHkocFZpZXdwb3J0LCAmVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQsIHNpemVvZihXSU5FRDNEVklFV1BPUlQpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFJlbmRlciBTdGF0ZXMKICogVE9ETzogVmVyaWZ5IGFnYWluc3QgZHg5IGRlZmluaXRpb25zCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RSRU5ERVJTVEFURVRZUEUgU3RhdGUsIERXT1JEIFZhbHVlKSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBEV09SRCBvbGRWYWx1ZSA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1N0YXRlXTsKCiAgICBUUkFDRSgiKCVwKS0+c3RhdGUgPSAlcyglZCksIHZhbHVlID0gJWRcbiIsIFRoaXMsIGRlYnVnX2QzZHJlbmRlcnN0YXRlKFN0YXRlKSwgU3RhdGUsIFZhbHVlKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnJlbmRlclN0YXRlW1N0YXRlXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQucmVuZGVyU3RhdGVbU3RhdGVdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1N0YXRlXSA9IFZhbHVlOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIENvbXBhcmVkIGhlcmUgYW5kIG5vdCBiZWZvcmUgdGhlIGFzc2lnbm1lbnQgdG8gYWxsb3cgcHJvcGVyIHN0YXRlYmxvY2sgcmVjb3JkaW5nICovCiAgICBpZihWYWx1ZSA9PSBvbGRWYWx1ZSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICB9IGVsc2UgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoU3RhdGUpKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RSRU5ERVJTVEFURVRZUEUgU3RhdGUsIERXT1JEICpwVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIGZvciBTdGF0ZSAlZCA9ICVkXG4iLCBUaGlzLCBTdGF0ZSwgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdKTsKICAgICpwVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV07CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBTYW1wbGVyIFN0YXRlcwogKiBUT0RPOiBWZXJpZnkgYWdhaW5zdCBkeDkgZGVmaW5pdGlvbnMKICoqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTYW1wbGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTYW1wbGVyLCBXSU5FRDNEU0FNUExFUlNUQVRFVFlQRSBUeXBlLCBEV09SRCBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgb2xkVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV07CgogICAgLyoqCiAgICAqIFNldFNhbXBsZXIgaXMgZGVzaWduZWQgdG8gYWxsb3cgZm9yIG1vcmUgdGhhbiB0aGUgc3RhbmRhcmQgdXAgdG8gOCB0ZXh0dXJlcwogICAgKiAgYW5kIEdlZm9yY2UgaGFzIHN0b3BwZWQgc3VwcG9ydGluZyBtb3JlIHRoYW4gNiBzdGFuZGFyZCB0ZXh0dXJlcyBpbiBvcGVuR0wuCiAgICAqIFNvIEkgaGF2ZSB0byB1c2UgQVJCIGZvciBHZm9yY2UuIChtYXliZSBpZiB0aGUgc2FtcGxlciA+IDQgdGhlbiB1c2UgQVJCPykKICAgICoKICAgICogaHR0cDovL2RldmVsb3Blci5udmlkaWEuY29tL29iamVjdC9HZW5lcmFsX0ZBUS5odG1sI3Q2CiAgICAqCiAgICAqIFRoZXJlIGFyZSB0d28gbmV3IHNldHRpbmdzIGZvciBHRm9yY2UKICAgICogdGhlIHNhbXBsZXIgb25lOgogICAgKiBHTF9NQVhfVEVYVFVSRV9JTUFHRV9VTklUU19BUkIKICAgICogYW5kIHRoZSB0ZXh0dXJlIG9uZToKICAgICogR0xfTUFYX1RFWFRVUkVfQ09PUkRTX0FSQi4KICAgICogT2sgR0ZvcmNlIHNheSBpdCdzIG9rIHRvIHVzZSBnbFRleFBhcmFtZXRlci9nbEdldFRleFBhcmFtZXRlciguLi4pLgogICAgICoqKioqKioqKioqKioqKioqKi8KCiAgICBUUkFDRSgiKCVwKSA6IFNhbXBsZXI9JWQsIFR5cGU9JXMoJWQpLCBWYWx1ZT0lZFxuIiwgVGhpcywgU2FtcGxlciwKICAgICAgICBkZWJ1Z19kM2RzYW1wbGVyc3RhdGUoVHlwZSksIFR5cGUsIFZhbHVlKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZVtTYW1wbGVyXVtUeXBlXSAgICAgICAgID0gVmFsdWU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuc2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdICAgICA9IFZhbHVlOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV0gPSBWYWx1ZTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihvbGRWYWx1ZSA9PSBWYWx1ZSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoU2FtcGxlcikpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFNhbXBsZXIsIFdJTkVEM0RTQU1QTEVSU1RBVEVUWVBFIFR5cGUsIERXT1JEKiBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgKlZhbHVlID0gVGhpcy0+c3RhdGVCbG9jay0+c2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdOwogICAgVFJBQ0UoIiglcCkgOiBTYW1wbGVyICVkIFR5cGUgJXUgUmV0dXJuaW5nICVkXG4iLCBUaGlzLCBTYW1wbGVyLCBUeXBlLCAqVmFsdWUpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNjaXNzb3JSZWN0KElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgUkVDVCogcFJlY3QpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuc2Npc3NvclJlY3QgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zY2lzc29yUmVjdCA9IFRSVUU7CiAgICBpZihFcXVhbFJlY3QoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNjaXNzb3JSZWN0LCBwUmVjdCkpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIG9sZCBzY2lzc29yIHJlY3RhbmdsZSBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIENvcHlSZWN0KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zY2lzc29yUmVjdCwgcFJlY3QpOwoKICAgIGlmKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0NJU1NPUlJFQ1QpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNjaXNzb3JSZWN0KElXaW5lRDNERGV2aWNlICppZmFjZSwgUkVDVCogcFJlY3QpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBtZW1jcHkocFJlY3QsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zY2lzc29yUmVjdCwgc2l6ZW9mKHBSZWN0KSk7CiAgICBUUkFDRSgiKCVwKVJldHVybmluZyBhIFNjaXNzb3IgUmVjdCBvZiAlZDolZC0lZDolZFxuIiwgVGhpcywgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qIHBEZWNsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiAqb2xkRGVjbCA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleERlY2w7CgogICAgVFJBQ0UoIiglcCkgOiBwRGVjbD0lcFxuIiwgVGhpcywgcERlY2wpOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleERlY2wgPSBwRGVjbDsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4RGVjbCA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudmVydGV4RGVjbCA9IFRSVUU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSBpZihwRGVjbCA9PSBvbGREZWNsKSB7CiAgICAgICAgLyogQ2hlY2tlZCBhZnRlciB0aGUgYXNzaWdubWVudCB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIGRlY2xhcmF0aW9uIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WREVDTCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qKiBwcERlY2wpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IHBwRGVjbD0lcFxuIiwgVGhpcywgcHBEZWNsKTsKCiAgICAqcHBEZWNsID0gVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4RGVjbDsKICAgIGlmIChOVUxMICE9ICpwcERlY2wpIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25fQWRkUmVmKCpwcERlY2wpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqIHBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlciogb2xkU2hhZGVyID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4U2hhZGVyOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlciAgICAgICAgID0gcFNoYWRlcjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4U2hhZGVyID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC52ZXJ0ZXhTaGFkZXIgICAgID0gVFJVRTsKCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIGlmKG9sZFNoYWRlciA9PSBwU2hhZGVyKSB7CiAgICAgICAgLyogQ2hlY2tlZCBoZXJlIHRvIGFsbG93IHByb3BlciBzdGF0ZWJsb2NrIHJlY29yZGluZyAqLwogICAgICAgIFRSQUNFKCJBcHAgaXMgc2V0dGluZyB0aGUgb2xkIHNoYWRlciBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgcFNoYWRlciglcClcbiIsIFRoaXMsIHBTaGFkZXIpOwoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WU0hBREVSKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFZlcnRleFNoYWRlcioqIHBwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKE5VTEwgPT0gcHBTaGFkZXIpIHsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgICpwcFNoYWRlciA9IFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlcjsKICAgIGlmKCBOVUxMICE9ICpwcFNoYWRlcikKICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9BZGRSZWYoKnBwU2hhZGVyKTsKCiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBwU2hhZGVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50QigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBCT09MICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpLCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9CIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50QltzdGFydF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihCT09MKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBCT09MIGNvbnN0YW50ICV1IHRvICVzXG4iLCBzdGFydCArIGksIHNyY0RhdGFbaV0/ICJ0cnVlIjoiZmFsc2UiKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNCW2ldICAgICA9IFRSVUU7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZFUlRFWFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQk9PTCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfQiAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEJbc3RhcnRdLCBjbnQgKiBzaXplb2YoQk9PTCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIGludCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfSSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudElbc3RhcnQgKiA0XSwgc3JjRGF0YSwgY250ICogc2l6ZW9mKGludCkgKiA0KTsKICAgIGZvciAoaSA9IDA7IGkgPCBjbnQ7IGkrKykKICAgICAgICBUUkFDRSgiU2V0IElOVCBjb25zdGFudCAldSB0byB7ICVkLCAlZCwgJWQsICVkIH1cbiIsIHN0YXJ0ICsgaSwKICAgICAgICAgICBzcmNEYXRhW2kqNF0sIHNyY0RhdGFbaSo0KzFdLCBzcmNEYXRhW2kqNCsyXSwgc3JjRGF0YVtpKjQrM10pOwoKICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY250ICsgc3RhcnQ7ICsraSkgewogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzSVtpXSA9IFRSVUU7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleFNoYWRlckNvbnN0YW50c0lbaV0gICAgID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkVSVEVYU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50SSgKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBpbnQgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0kgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCAoKHNpZ25lZCBpbnQpIE1BWF9DT05TVF9JIC0gKHNpZ25lZCBpbnQpIHN0YXJ0KSA8PSAoc2lnbmVkIGludCkgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIGZsb2F0ICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIC8qIFNwZWNpZmljYWxseSB0ZXN0IHN0YXJ0ID4gbGltaXQgdG8gY2F0Y2ggTUFYX1VJTlQgb3ZlcmZsb3dzIHdoZW4gYWRkaW5nIHN0YXJ0ICsgY291bnQgKi8KICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgc3RhcnQgKyBjb3VudCA+IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpIHx8IHN0YXJ0ID4gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEZbc3RhcnQgKiA0XSwgc3JjRGF0YSwgY291bnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICBpZihUUkFDRV9PTihkM2QpKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCiAgICAgICAgICAgIFRSQUNFKCJTZXQgRkxPQVQgY29uc3RhbnQgJXUgdG8geyAlZiwgJWYsICVmLCAlZiB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgICAgICBzcmNEYXRhW2kqNF0sIHNyY0RhdGFbaSo0KzFdLCBzcmNEYXRhW2kqNCsyXSwgc3JjRGF0YVtpKjQrM10pOwogICAgfQoKICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY291bnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgaWYgKCFUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudmVydGV4U2hhZGVyQ29uc3RhbnRzRltpXSkgewogICAgICAgICAgICBjb25zdGFudHNfZW50cnkgKnB0ciA9IExJU1RfRU5UUlkobGlzdF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXRfdmNvbnN0YW50c0YpLCBjb25zdGFudHNfZW50cnksIGVudHJ5KTsKICAgICAgICAgICAgaWYgKCFwdHIgfHwgcHRyLT5jb3VudCA+PSBzaXplb2YocHRyLT5pZHgpIC8gc2l6ZW9mKCpwdHItPmlkeCkpIHsKICAgICAgICAgICAgICAgIHB0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoY29uc3RhbnRzX2VudHJ5KSk7CiAgICAgICAgICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXRfdmNvbnN0YW50c0YsICZwdHItPmVudHJ5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdHItPmlkeFtwdHItPmNvdW50KytdID0gaTsKICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WRVJURVhTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIGZsb2F0ICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIGlubGluZSB2b2lkIG1hcmtUZXh0dXJlU3RhZ2VzRGlydHkoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBEV09SRCBzdGFnZSkgewogICAgRFdPUkQgaTsKICAgIGZvcihpID0gMDsgaSA8IFdJTkVEM0RfSElHSEVTVF9URVhUVVJFX1NUQVRFOyBpKyspIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKHN0YWdlLCBpKSk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIElXaW5lRDNERGV2aWNlSW1wbF9GaW5kVGV4VW5pdE1hcChJV2luZUQzRERldmljZUltcGwgKlRoaXMpIHsKICAgIERXT1JEIGksIHRleDsKICAgIC8qIFRoaXMgY29kZSBjYW4gYXNzdW1lIHRoYXQgR0xfTlZfcmVnaXN0ZXJfY29tYmluZXJzIGFyZSBzdXBwb3J0ZWQsIG90aGVyd2lzZQogICAgICogaXQgaXMgbmV2ZXIgY2FsbGVkLgogICAgICoKICAgICAqIFJ1bGVzIGFyZToKICAgICAqIC0+IFBpeGVsIHNoYWRlcnMgbmVlZCBhIDE6MSBtYXAuIEluIHRoZW9yeSB0aGUgc2hhZGVyIGlucHV0IGNvdWxkIGJlIG1hcHBlZCB0b28sIGJ1dAogICAgICogdGhhdCB3b3VsZCBiZSByZWFsbHkgbWVzc3kgYW5kIHJlcXVpcmUgc2hhZGVyIHJlY29tcGlsYXRpb24KICAgICAqIC0+IFdoZW4gdGhlIG1hcHBpbmcgb2YgYSBzdGFnZSBpcyBjaGFuZ2VkLCBzYW1wbGVyIGFuZCBBTEwgdGV4dHVyZSBzdGFnZSBzdGF0ZXMgaGF2ZQogICAgICogdG8gYmUgcmVzZXQuIEJlY2F1c2Ugb2YgdGhhdCB0cnkgdG8gd29yayB3aXRoIGEgMToxIG1hcHBpbmcgYXMgbXVjaCBhcyBwb3NzaWJsZQogICAgICogLT4gV2hpdGggYSAxOjEgbWFwcGluZyBvbmVUb09uZVRleFVuaXRNYXAgaXMgc2V0IHRvIGF2b2lkIGNoZWNraW5nIE1BWF9TQU1QTEVSUyBhcnJheQogICAgICogZW50cmllcyB0byBtYWtlIHBpeGVsIHNoYWRlcnMgY2hlYXBlci4gTUFYX1NBTVBMRVJTIHdpbGwgYmUgMTI4IGluIGR4MTAKICAgICAqLwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIgfHwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlIDw9IEdMX0xJTUlUUyh0ZXh0dXJlcykpIHsKICAgICAgICBpZihUaGlzLT5vbmVUb09uZVRleFVuaXRNYXApIHsKICAgICAgICAgICAgVFJBQ0UoIk5vdCB0b3VjaGluZyAxOjEgbWFwXG4iKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiUmVzdG9yaW5nIDE6MSB0ZXh0dXJlIHVuaXQgbWFwcGluZ1xuIik7CiAgICAgICAgLyogUmVzdG9yZSBhIDE6MSBtYXBwaW5nICovCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX1NBTVBMRVJTOyBpKyspIHsKICAgICAgICAgICAgaWYoVGhpcy0+dGV4VW5pdE1hcFtpXSAhPSBpKSB7CiAgICAgICAgICAgICAgICBUaGlzLT50ZXhVbml0TWFwW2ldID0gaTsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKGkpKTsKICAgICAgICAgICAgICAgIG1hcmtUZXh0dXJlU3RhZ2VzRGlydHkoVGhpcywgaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgVGhpcy0+b25lVG9PbmVUZXhVbml0TWFwID0gVFJVRTsKICAgICAgICByZXR1cm47CiAgICB9IGVsc2UgewogICAgICAgIC8qIE5vIHBpeGVsIHNoYWRlciwgYW5kIHdlIGRvIG5vdCBoYXZlIGVub3VnaCB0ZXh0dXJlIHVuaXRzIGF2YWlsYWJsZS4gVHJ5IHRvIHNraXAgTlVMTCB0ZXh0dXJlcwogICAgICAgICAqIEZpcnN0LCBzZWUgaWYgd2UgY2FuIHN1Y2NlZWQgYXQgYWxsCiAgICAgICAgICovCiAgICAgICAgdGV4ID0gMDsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2U7IGkrKykgewogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tpXSA9PSBOVUxMKSB0ZXgrKzsKICAgICAgICB9CgogICAgICAgIGlmKEdMX0xJTUlUUyh0ZXh0dXJlcykgKyB0ZXggPCBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UpIHsKICAgICAgICAgICAgRklYTUUoIlRvbyBtYW55IGJvdW5kIHRleHR1cmVzIHRvIHN1cHBvcnQgdGhlIGNvbWJpbmVyIHNldHRpbmdzXG4iKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgLyogTm93IHdvcmsgb3V0IHRoZSBtYXBwaW5nICovCiAgICAgICAgdGV4ID0gMDsKICAgICAgICBUaGlzLT5vbmVUb09uZVRleFVuaXRNYXAgPSBGQUxTRTsKICAgICAgICBXQVJOKCJOb24gMToxIG1hcHBpbmcgVU5URVNURUQhXG4iKTsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2U7IGkrKykgewogICAgICAgICAgICAvKiBTa2lwIE5VTEwgdGV4dHVyZXMgKi8KICAgICAgICAgICAgaWYgKCFUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tpXSkgewogICAgICAgICAgICAgICAgLyogTWFwIHRvIC0xLCBzbyB0aGUgY2hlY2sgYmVsb3cgZG9lc24ndCBmYWlsIGlmIGEgbm9uLU5VTEwKICAgICAgICAgICAgICAgICAqIHRleHR1cmUgaXMgc2V0IG9uIHRoaXMgc3RhZ2UgKi8KICAgICAgICAgICAgICAgIFRSQUNFKCJNYXBwaW5nIHRleHR1cmUgc3RhZ2UgJWQgdG8gLTFcbiIsIGkpOwogICAgICAgICAgICAgICAgVGhpcy0+dGV4VW5pdE1hcFtpXSA9IC0xOwoKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiTWFwcGluZyB0ZXh0dXJlIHN0YWdlICVkIHRvIHVuaXQgJWRcbiIsIGksIHRleCk7CiAgICAgICAgICAgIGlmKFRoaXMtPnRleFVuaXRNYXBbaV0gIT0gdGV4KSB7CiAgICAgICAgICAgICAgICBUaGlzLT50ZXhVbml0TWFwW2ldID0gdGV4OwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoaSkpOwogICAgICAgICAgICAgICAgbWFya1RleHR1cmVTdGFnZXNEaXJ0eShUaGlzLCBpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgKyt0ZXg7CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RQaXhlbFNoYWRlciAqcFNoYWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzICAgICAgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXIgKm9sZFNoYWRlciAgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlcjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyICAgICAgICAgPSBwU2hhZGVyOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlciA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQucGl4ZWxTaGFkZXIgICAgID0gVFJVRTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgIH0KCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKHBTaGFkZXIgPT0gb2xkU2hhZGVyKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgcGl4ZWwgc2hhZGVyIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogc2V0dGluZyBwU2hhZGVyKCVwKVxuIiwgVGhpcywgcFNoYWRlcik7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUElYRUxTSEFERVIpOwoKICAgIC8qIFJlYnVpbGQgdGhlIHRleHR1cmUgdW5pdCBtYXBwaW5nIGlmIG52cmMncyBhcmUgc3VwcG9ydGVkICovCiAgICBpZihHTF9TVVBQT1JUKE5WX1JFR0lTVEVSX0NPTUJJTkVSUykpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfRmluZFRleFVuaXRNYXAoVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFBpeGVsU2hhZGVyICoqcHBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoTlVMTCA9PSBwcFNoYWRlcikgewogICAgICAgIFdBUk4oIiglcCkgOiBQU2hhZGVyIGlzIE5VTEwsIHJldHVybmluZyBJTlZBTElEQ0FMTFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgKnBwU2hhZGVyID0gIFRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwogICAgaWYgKE5VTEwgIT0gKnBwU2hhZGVyKSB7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYoKnBwU2hhZGVyKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAqcHBTaGFkZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEIoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgQk9PTCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfQiAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50QltzdGFydF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihCT09MKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBCT09MIGNvbnN0YW50ICV1IHRvICVzXG4iLCBzdGFydCArIGksIHNyY0RhdGFbaV0/ICJ0cnVlIjoiZmFsc2UiKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzQltpXSA9IFRSVUU7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnBpeGVsU2hhZGVyQ29uc3RhbnRzQltpXSAgICAgPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50QigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBCT09MICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9CIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRCW3N0YXJ0XSwgY250ICogc2l6ZW9mKEJPT0wpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRJKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIGludCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfSSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgSU5UIGNvbnN0YW50ICV1IHRvIHsgJWQsICVkLCAlZCwgJWQgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgIHNyY0RhdGFbaSo0XSwgc3JjRGF0YVtpKjQrMV0sIHNyY0RhdGFbaSo0KzJdLCBzcmNEYXRhW2kqNCszXSk7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5waXhlbFNoYWRlckNvbnN0YW50c0lbaV0gICAgID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUElYRUxTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEkoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgaW50ICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9JIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRJW3N0YXJ0ICogNF0sIGNudCAqIHNpemVvZihpbnQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50RigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBmbG9hdCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICAvKiBTcGVjaWZpY2FsbHkgdGVzdCBzdGFydCA+IGxpbWl0IHRvIGNhdGNoIE1BWF9VSU5UIG92ZXJmbG93cyB3aGVuIGFkZGluZyBzdGFydCArIGNvdW50ICovCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IHN0YXJ0ICsgY291bnQgPiBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSB8fCBzdGFydCA+IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEZbc3RhcnQgKiA0XSwgc3JjRGF0YSwgY291bnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICBpZihUUkFDRV9PTihkM2QpKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCiAgICAgICAgICAgIFRSQUNFKCJTZXQgRkxPQVQgY29uc3RhbnQgJXUgdG8geyAlZiwgJWYsICVmLCAlZiB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgICAgICBzcmNEYXRhW2kqNF0sIHNyY0RhdGFbaSo0KzFdLCBzcmNEYXRhW2kqNCsyXSwgc3JjRGF0YVtpKjQrM10pOwogICAgfQoKICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY291bnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgaWYgKCFUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldKSB7CiAgICAgICAgICAgIGNvbnN0YW50c19lbnRyeSAqcHRyID0gTElTVF9FTlRSWShsaXN0X2hlYWQoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldF9wY29uc3RhbnRzRiksIGNvbnN0YW50c19lbnRyeSwgZW50cnkpOwogICAgICAgICAgICBpZiAoIXB0ciB8fCBwdHItPmNvdW50ID49IHNpemVvZihwdHItPmlkeCkgLyBzaXplb2YoKnB0ci0+aWR4KSkgewogICAgICAgICAgICAgICAgcHRyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihjb25zdGFudHNfZW50cnkpKTsKICAgICAgICAgICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldF9wY29uc3RhbnRzRiwgJnB0ci0+ZW50cnkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB0ci0+aWR4W3B0ci0+Y291bnQrK10gPSBpOwogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBmbG9hdCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2RlZmluZSBjb3B5X2FuZF9uZXh0KGRlc3QsIHNyYywgc2l6ZSkgbWVtY3B5KGRlc3QsIHNyYywgc2l6ZSk7IGRlc3QgKz0gKHNpemUpCnN0YXRpYyBIUkVTVUxUCnByb2Nlc3NfdmVydGljZXNfc3RyaWRlZChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEIGR3RGVzdEluZGV4LCBEV09SRCBkd0NvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqbHBTdHJpZGVEYXRhLCBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKmRlc3QsIERXT1JEIGR3RmxhZ3MpIHsKICAgIGNoYXIgKmRlc3RfcHRyLCAqZGVzdF9jb252ID0gTlVMTCwgKmRlc3RfY29udl9hZGRyID0gTlVMTDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgRFdPUkQgRGVzdEZWRiA9IGRlc3QtPmZ2ZjsKICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKICAgIFdJTkVEM0RNQVRSSVggbWF0LCBwcm9qX21hdCwgdmlld19tYXQsIHdvcmxkX21hdDsKICAgIEJPT0wgZG9DbGlwOwogICAgaW50IG51bVRleHR1cmVzOwoKICAgIGlmIChscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSB7CiAgICAgICAgV0FSTigiIGxpZ2h0aW5nIHN0YXRlIG5vdCBzYXZlZCB5ZXQuLi4gU29tZSBzdHJhbmdlIHN0dWZmIG1heSBoYXBwZW4gIVxuIik7CiAgICB9CgogICAgaWYgKGxwU3RyaWRlRGF0YS0+dS5zLnBvc2l0aW9uLmxwRGF0YSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJTb3VyY2UgaGFzIG5vIHBvc2l0aW9uIG1hc2tcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIFdlIG1pZ2h0IGFjY2VzcyBWQk9zIGZyb20gdGhpcyBjb2RlLCBzbyBob2xkIHRoZSBsb2NrICovCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTCkgewogICAgICAgIC8qIFRoaXMgbWF5IGhhcHBlbiBpZiB3ZSBkbyBkaXJlY3QgbG9ja2luZyBpbnRvIGEgdmJvLiBVbmxpa2VseSwKICAgICAgICAgKiBidXQgdGhlb3JldGljYWxseSBwb3NzaWJsZShkZHJhdyBwcm9jZXNzdmVydGljZXMgdGVzdCkKICAgICAgICAgKi8KICAgICAgICBkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGVzdC0+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgaWYoIWRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgaWYoZGVzdC0+dmJvKSB7CiAgICAgICAgICAgIHZvaWQgKnNyYzsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZGVzdC0+dmJvKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICAgICAgc3JjID0gR0xfRVhUQ0FMTChnbE1hcEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBHTF9SRUFEX09OTFlfQVJCKSk7CiAgICAgICAgICAgIGlmKHNyYykgewogICAgICAgICAgICAgICAgbWVtY3B5KGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgc3JjLCBkZXN0LT5yZXNvdXJjZS5zaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5tYXBCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbm1hcEJ1ZmZlckFSQiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHZXQgYSBwb2ludGVyIGludG8gdGhlIGRlc3RpbmF0aW9uIHZibyhjcmVhdGUgb25lIGlmIG5vbmUgZXhpc3RzKSBhbmQKICAgICAqIHdyaXRlIGNvcnJlY3Qgb3BlbmdsIGRhdGEgaW50byBpdC4gSXQncyBjaGVhcCBhbmQgYWxsb3dzIHVzIHRvIHJ1biBkcmF3U3RyaWRlZEZhc3QKICAgICAqLwogICAgaWYoIWRlc3QtPnZibyAmJiBHTF9TVVBQT1JUKEFSQl9WRVJURVhfQlVGRkVSX09CSkVDVCkpIHsKICAgICAgICBDcmVhdGVWQk8oZGVzdCk7CiAgICB9CgogICAgaWYoZGVzdC0+dmJvKSB7CiAgICAgICAgdW5zaWduZWQgY2hhciBleHRyYWJ5dGVzID0gMDsKICAgICAgICAvKiBJZiB0aGUgZGVzdGluYXRpb24gdmVydGV4IGJ1ZmZlciBoYXMgRDNERlZGX1hZWiBwb3NpdGlvbihub24tcmh3KSwgbmF0aXZlIGQzZCB3cml0ZXMgUkhXIHBvc2l0aW9uLCB3aGVyZSB0aGUgUkhXCiAgICAgICAgICogZ2V0cyB3cml0dGVuIGludG8gdGhlIDQgYnl0ZXMgYWZ0ZXIgdGhlIFogcG9zaXRpb24uIEluIHRoZSBjYXNlIG9mIGEgZGVzdCBidWZmZXIgdGhhdCBvbmx5IGhhcyBEM0RGVkZfWFlaIGRhdGEsCiAgICAgICAgICogdGhpcyBtYXkgd3JpdGUgNCBleHRyYSBieXRlcyBiZXlvbmQgdGhlIGFyZWEgdGhhdCBzaG91bGQgYmUgd3JpdHRlbgogICAgICAgICAqLwogICAgICAgIGlmKERlc3RGVkYgPT0gV0lORUQzREZWRl9YWVopIGV4dHJhYnl0ZXMgPSA0OwogICAgICAgIGRlc3RfY29udl9hZGRyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGR3Q291bnQgKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRikgKyBleHRyYWJ5dGVzKTsKICAgICAgICBpZighZGVzdF9jb252X2FkZHIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgLyogQ29udGludWUgd2l0aG91dCBzdG9yaW5nIGNvbnZlcnRlZCB2ZXJ0aWNlcyAqLwogICAgICAgIH0KICAgICAgICBkZXN0X2NvbnYgPSBkZXN0X2NvbnZfYWRkcjsKICAgIH0KCiAgICAvKiBTaG91bGQgSSBjbGlwPwogICAgICogYSkgV0lORUQzRFJTX0NMSVBQSU5HIGlzIGVuYWJsZWQKICAgICAqIGIpIFdJTkVEM0RWT1BfQ0xJUCBpcyBwYXNzZWQKICAgICAqLwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0NMSVBQSU5HXSkgewogICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgIC8qCiAgICAgICAgICogVGhlIGNsaXBwaW5nIGNvZGUgaXMgbm90IHF1aXRlIGNvcnJlY3QuIFNvbWUgdGhpbmdzIG5lZWQKICAgICAgICAgKiB0byBiZSBjaGVja2VkIGFnYWluc3QgSURpcmVjdDNERGV2aWNlMyAoISksIGQzZDggYW5kIGQzZDksCiAgICAgICAgICogc28gZGlzYWJsZSBjbGlwcGluZyBmb3Igbm93LgogICAgICAgICAqIChUaGUgZ3JhcGhpY3MgaW4gSGFsZi1MaWZlIGFyZSBicm9rZW4sIGFuZCBteSBwcm9jZXNzdmVydGljZXMKICAgICAgICAgKiAgdGVzdCBjcmFzaGVzIHdpdGggSURpcmVjdDNERGV2aWNlMykKICAgICAgICBkb0NsaXAgPSBUUlVFOwogICAgICAgICAqLwogICAgICAgIGRvQ2xpcCA9IEZBTFNFOwogICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgIEZJWE1FKCJDbGlwcGluZyBpcyBicm9rZW4gYW5kIGRpc2FibGVkIGZvciBub3dcbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBkb0NsaXAgPSBGQUxTRTsKICAgIGRlc3RfcHRyID0gKChjaGFyICopIGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgKyBkd0Rlc3RJbmRleCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKTsKCiAgICBJV2luZUQzRERldmljZV9HZXRUcmFuc2Zvcm0oIChJV2luZUQzRERldmljZSAqKSBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVFNfVklFVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZpZXdfbWF0KTsKICAgIElXaW5lRDNERGV2aWNlX0dldFRyYW5zZm9ybSggKElXaW5lRDNERGV2aWNlICopIFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RUU19QUk9KRUNUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJval9tYXQpOwogICAgSVdpbmVEM0REZXZpY2VfR2V0VHJhbnNmb3JtKCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1dPUkxETUFUUklYKDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd29ybGRfbWF0KTsKCiAgICBUUkFDRSgiVmlldyBtYXQ6XG4iKTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl8xMSwgdmlld19tYXQudS5zLl8xMiwgdmlld19tYXQudS5zLl8xMywgdmlld19tYXQudS5zLl8xNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHZpZXdfbWF0LnUucy5fMjEsIHZpZXdfbWF0LnUucy5fMjIsIHZpZXdfbWF0LnUucy5fMjMsIHZpZXdfbWF0LnUucy5fMjQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB2aWV3X21hdC51LnMuXzMxLCB2aWV3X21hdC51LnMuXzMyLCB2aWV3X21hdC51LnMuXzMzLCB2aWV3X21hdC51LnMuXzM0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl80MSwgdmlld19tYXQudS5zLl80Miwgdmlld19tYXQudS5zLl80Mywgdmlld19tYXQudS5zLl80NCk7CgogICAgVFJBQ0UoIlByb2ogbWF0OlxuIik7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fMTEsIHByb2pfbWF0LnUucy5fMTIsIHByb2pfbWF0LnUucy5fMTMsIHByb2pfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCBwcm9qX21hdC51LnMuXzIxLCBwcm9qX21hdC51LnMuXzIyLCBwcm9qX21hdC51LnMuXzIzLCBwcm9qX21hdC51LnMuXzI0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgcHJval9tYXQudS5zLl8zMSwgcHJval9tYXQudS5zLl8zMiwgcHJval9tYXQudS5zLl8zMywgcHJval9tYXQudS5zLl8zNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fNDEsIHByb2pfbWF0LnUucy5fNDIsIHByb2pfbWF0LnUucy5fNDMsIHByb2pfbWF0LnUucy5fNDQpOwoKICAgIFRSQUNFKCJXb3JsZCBtYXQ6XG4iKTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fMTEsIHdvcmxkX21hdC51LnMuXzEyLCB3b3JsZF9tYXQudS5zLl8xMywgd29ybGRfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB3b3JsZF9tYXQudS5zLl8yMSwgd29ybGRfbWF0LnUucy5fMjIsIHdvcmxkX21hdC51LnMuXzIzLCB3b3JsZF9tYXQudS5zLl8yNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHdvcmxkX21hdC51LnMuXzMxLCB3b3JsZF9tYXQudS5zLl8zMiwgd29ybGRfbWF0LnUucy5fMzMsIHdvcmxkX21hdC51LnMuXzM0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fNDEsIHdvcmxkX21hdC51LnMuXzQyLCB3b3JsZF9tYXQudS5zLl80Mywgd29ybGRfbWF0LnUucy5fNDQpOwoKICAgIC8qIEdldCB0aGUgdmlld3BvcnQgKi8KICAgIElXaW5lRDNERGV2aWNlX0dldFZpZXdwb3J0KCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgJnZwKTsKICAgIFRSQUNFKCJWaWV3cG9ydDogWD0lZCwgWT0lZCwgV2lkdGg9JWQsIEhlaWdodD0lZCwgTWluWj0lZiwgTWF4Wj0lZlxuIiwKICAgICAgICAgIHZwLlgsIHZwLlksIHZwLldpZHRoLCB2cC5IZWlnaHQsIHZwLk1pblosIHZwLk1heFopOwoKICAgIG11bHRpcGx5X21hdHJpeCgmbWF0LCZ2aWV3X21hdCwmd29ybGRfbWF0KTsKICAgIG11bHRpcGx5X21hdHJpeCgmbWF0LCZwcm9qX21hdCwmbWF0KTsKCiAgICBudW1UZXh0dXJlcyA9IChEZXN0RlZGICYgV0lORUQzREZWRl9URVhDT1VOVF9NQVNLKSA+PiBXSU5FRDNERlZGX1RFWENPVU5UX1NISUZUOwoKICAgIGZvciAoaSA9IDA7IGkgPCBkd0NvdW50OyBpKz0gMSkgewogICAgICAgIHVuc2lnbmVkIGludCB0ZXhfaW5kZXg7CgogICAgICAgIGlmICggKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWiApIHx8CiAgICAgICAgICAgICAoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXICkgKSB7CiAgICAgICAgICAgIC8qIFRoZSBwb3NpdGlvbiBmaXJzdCAqLwogICAgICAgICAgICBmbG9hdCAqcCA9CiAgICAgICAgICAgICAgKGZsb2F0ICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMucG9zaXRpb24ubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5wb3NpdGlvbi5kd1N0cmlkZSk7CiAgICAgICAgICAgIGZsb2F0IHgsIHksIHosIHJodzsKICAgICAgICAgICAgVFJBQ0UoIkluOiAoICUwNi4yZiAlMDYuMmYgJTA2LjJmIClcbiIsIHBbMF0sIHBbMV0sIHBbMl0pOwoKICAgICAgICAgICAgLyogTXVsdGlwbGljYXRpb24gd2l0aCB3b3JsZCwgdmlldyBhbmQgcHJvamVjdGlvbiBtYXRyaXggKi8KICAgICAgICAgICAgeCA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMSkgKyAocFsxXSAqIG1hdC51LnMuXzIxKSArIChwWzJdICogbWF0LnUucy5fMzEpICsgKDEuMCAqIG1hdC51LnMuXzQxKTsKICAgICAgICAgICAgeSA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMikgKyAocFsxXSAqIG1hdC51LnMuXzIyKSArIChwWzJdICogbWF0LnUucy5fMzIpICsgKDEuMCAqIG1hdC51LnMuXzQyKTsKICAgICAgICAgICAgeiA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMykgKyAocFsxXSAqIG1hdC51LnMuXzIzKSArIChwWzJdICogbWF0LnUucy5fMzMpICsgKDEuMCAqIG1hdC51LnMuXzQzKTsKICAgICAgICAgICAgcmh3ID0gKHBbMF0gKiBtYXQudS5zLl8xNCkgKyAocFsxXSAqIG1hdC51LnMuXzI0KSArIChwWzJdICogbWF0LnUucy5fMzQpICsgKDEuMCAqIG1hdC51LnMuXzQ0KTsKCiAgICAgICAgICAgIFRSQUNFKCJ4PSVmIHk9JWYgej0lZiByaHc9JWZcbiIsIHgsIHksIHosIHJodyk7CgogICAgICAgICAgICAvKiBXQVJOSU5HOiBUaGUgZm9sbG93aW5nIHRoaW5ncyBhcmUgdGFrZW4gZnJvbSBkM2Q3IGFuZCB3ZXJlIG5vdCB5ZXQgY2hlY2tlZAogICAgICAgICAgICAgKiBhZ2FpbnN0IGQzZDggb3IgZDNkOSEKICAgICAgICAgICAgICovCgogICAgICAgICAgICAvKiBDbGlwcGluZyBjb25kaXRpb25zOiBGcm9tCiAgICAgICAgICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vYXJjaGl2ZS9kZWZhdWx0LmFzcD91cmw9L2FyY2hpdmUvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvZml4ZWRmdW5jdGlvbi92aWV3cG9ydHNjbGlwcGluZy9jbGlwcGluZ3ZvbHVtZXMuYXNwCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEEgdmVydGV4IGlzIGNsaXBwZWQgaWYgaXQgZG9lcyBub3QgbWF0Y2ggdGhlIGZvbGxvd2luZyByZXF1aXJlbWVudHMKICAgICAgICAgICAgICogLXJodyA8IHggPD0gcmh3CiAgICAgICAgICAgICAqIC1yaHcgPCB5IDw9IHJodwogICAgICAgICAgICAgKiAgICAwIDwgeiA8PSByaHcKICAgICAgICAgICAgICogICAgMCA8IHJodyAoIE5vdCBpbiBkM2Q3LCBidXQgdGVzdGVkIGluIGQzZDcpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIElmIGNsaXBwaW5nIGlzIG9uIGlzIGRldGVybWluZWQgYnkgdGhlIEQzRFZPUF9DTElQIGZsYWcgaW4gRDNENywgYW5kCiAgICAgICAgICAgICAqIGJ5IHRoZSBEM0RSU19DTElQUElORyBpbiBEM0Q5KGFjY29yZGluZyB0byB0aGUgbXNkbiwgbm90IGNoZWNrZWQpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYoICFkb0NsaXAgfHwKICAgICAgICAgICAgICAgICggKC1yaHcgLWVwcyA8IHgpICYmICgtcmh3IC1lcHMgPCB5KSAmJiAoIC1lcHMgPCB6KSAmJgogICAgICAgICAgICAgICAgICAoeCA8PSByaHcgKyBlcHMpICYmICh5IDw9IHJodyArIGVwcyApICYmICh6IDw9IHJodyArIGVwcykgJiYgCiAgICAgICAgICAgICAgICAgICggcmh3ID4gZXBzICkgKSApIHsKCiAgICAgICAgICAgICAgICAvKiAiTm9ybWFsIiB2aWV3cG9ydCB0cmFuc2Zvcm1hdGlvbiAobm90IGNsaXBwZWQpCiAgICAgICAgICAgICAgICAgKiAxKSBUaGUgdmFsdWVzIGFyZSBkaXZpZGVkIGJ5IHJodwogICAgICAgICAgICAgICAgICogMikgVGhlIHkgYXhpcyBpcyBuZWdhdGl2ZSwgc28gbXVsdGlwbHkgaXQgd2l0aCAtMQogICAgICAgICAgICAgICAgICogMykgU2NyZWVuIGNvb3JkaW5hdGVzIGdvIGZyb20gLShXaWR0aC8yKSB0byArKFdpZHRoLzIpIGFuZAogICAgICAgICAgICAgICAgICogICAgLShIZWlnaHQvMikgdG8gKyhIZWlnaHQvMikuIFRoZSB6IHJhbmdlIGlzIE1pblogdG8gTWF4WgogICAgICAgICAgICAgICAgICogNCkgTXVsdGlwbHkgeCB3aXRoIFdpZHRoLzIgYW5kIGFkZCBXaWR0aC8yCiAgICAgICAgICAgICAgICAgKiA1KSBUaGUgc2FtZSBmb3IgdGhlIGhlaWdodAogICAgICAgICAgICAgICAgICogNikgQWRkIHRoZSB2aWV3cG9pbnQgWCBhbmQgWSB0byB0aGUgMkQgY29vcmRpbmF0ZXMgYW5kCiAgICAgICAgICAgICAgICAgKiAgICBUaGUgbWluaW11bSBaIHZhbHVlIHRvIHoKICAgICAgICAgICAgICAgICAqIDcpIHJodyA9IDEgLyByaHcgUmVjaXByb2NhbCBvZiBIb21vZ2VuZW91cyBXLi4uLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFdlbGwsIGJhc2ljYWxseSBpdCdzIHNpbXBseSBhIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBpbnRvIHZpZXdwb3J0CiAgICAgICAgICAgICAgICAgKiBjb29yZGluYXRlcwogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgeCAvPSByaHc7CiAgICAgICAgICAgICAgICB5IC89IHJodzsKICAgICAgICAgICAgICAgIHogLz0gcmh3OwoKICAgICAgICAgICAgICAgIHkgKj0gLTE7CgogICAgICAgICAgICAgICAgeCAqPSB2cC5XaWR0aCAvIDI7CiAgICAgICAgICAgICAgICB5ICo9IHZwLkhlaWdodCAvIDI7CiAgICAgICAgICAgICAgICB6ICo9IHZwLk1heFogLSB2cC5NaW5aOwoKICAgICAgICAgICAgICAgIHggKz0gdnAuV2lkdGggLyAyICsgdnAuWDsKICAgICAgICAgICAgICAgIHkgKz0gdnAuSGVpZ2h0IC8gMiArIHZwLlk7CiAgICAgICAgICAgICAgICB6ICs9IHZwLk1pblo7CgogICAgICAgICAgICAgICAgcmh3ID0gMSAvIHJodzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFRoYXQgdmVydGV4IGdvdCBjbGlwcGVkCiAgICAgICAgICAgICAgICAgKiBDb250cmFyeSB0byBPcGVuR0wgaXQgaXMgbm90IGRyb3BwZWQgY29tcGxldGVseSwgaXQganVzdAogICAgICAgICAgICAgICAgICogdW5kZXJnb2VzIGEgZGlmZmVyZW50IGNhbGN1bGF0aW9uLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBUUkFDRSgiVmVydGV4IGdvdCBjbGlwcGVkXG4iKTsKICAgICAgICAgICAgICAgIHggKz0gcmh3OwogICAgICAgICAgICAgICAgeSArPSByaHc7CgogICAgICAgICAgICAgICAgeCAgLz0gMjsKICAgICAgICAgICAgICAgIHkgIC89IDI7CgogICAgICAgICAgICAgICAgLyogTXNkbiBtZW50aW9ucyB0aGF0IERpcmVjdDNEOSBrZWVwcyBhIGxpc3Qgb2YgY2xpcHBlZCB2ZXJ0aWNlcwogICAgICAgICAgICAgICAgICogb3V0c2lkZSBvZiB0aGUgbWFpbiB2ZXJ0ZXggYnVmZmVyIG1lbW9yeS4gVGhhdCBuZWVkcyBzb21lIG1vcmUKICAgICAgICAgICAgICAgICAqIGludmVzdGlnYXRpb24uLi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiV3JpdGluZyAoJWYgJWYgJWYpICVmXG4iLCB4LCB5LCB6LCByaHcpOwoKCiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVswXSA9IHg7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsxXSA9IHk7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsyXSA9IHo7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVszXSA9IHJodzsgLyogU0lDLCBzZWUgZGRyYXcgdGVzdCEgKi8KCiAgICAgICAgICAgIGRlc3RfcHRyICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgaWYoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXKSB7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGZsb2F0IHcgPSAxIC8gcmh3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVswXSA9IHggKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsxXSA9IHkgKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsyXSA9IHogKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVszXSA9IHc7CgogICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgICAgIGlmKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVykgewogICAgICAgICAgICAgICAgICAgIGRlc3RfY29udiArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChEZXN0RlZGICYgV0lORUQzREZWRl9QU0laRSkgewogICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIGRlc3RfY29udiArPSBzaXplb2YoRFdPUkQpOwogICAgICAgIH0KICAgICAgICBpZiAoRGVzdEZWRiAmIFdJTkVEM0RGVkZfTk9STUFMKSB7CiAgICAgICAgICAgIGZsb2F0ICpub3JtYWwgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChmbG9hdCAqKSBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwuZHdTdHJpZGUpOwogICAgICAgICAgICAvKiBBRkFJSyB0aGlzIHNob3VsZCBnbyBpbnRvIHRoZSBsaWdodGluZyBpbmZvcm1hdGlvbiAqLwogICAgICAgICAgICBGSVhNRSgiRGlkbid0IGV4cGVjdCB0aGUgZGVzdGluYXRpb24gdG8gaGF2ZSBhIG5vcm1hbFxuIik7CiAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIG5vcm1hbCwgMyAqIHNpemVvZihmbG9hdCkpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCBub3JtYWwsIDMgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX0RJRkZVU0UpIHsKICAgICAgICAgICAgRFdPUkQgKmNvbG9yX2QgPSAKICAgICAgICAgICAgICAoRFdPUkQgKikgKCgoY2hhciAqKSBscFN0cmlkZURhdGEtPnUucy5kaWZmdXNlLmxwRGF0YSkgKyBpICogbHBTdHJpZGVEYXRhLT51LnMuZGlmZnVzZS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9kKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBkaWZmdXNlIGNvbG9yIGluIHNvdXJjZSwgYnV0IGRlc3RpbmF0aW9uIGhhcyBvbmVcbiIpOwogICAgICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfcHRyKSA9IDB4ZmZmZmZmZmY7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwoKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpID0gMHhmZmZmZmZmZjsKICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIGNvbG9yX2QsIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSB7CiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgID0gKCpjb2xvcl9kICYgMHhmZjAwZmYwMCkgICAgICA7IC8qIEFscGhhICsgZ3JlZW4gKi8KICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSB8PSAoKmNvbG9yX2QgJiAweDAwZmYwMDAwKSA+PiAxNjsgLyogUmVkICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9kICYgMHhmZjAwMDBmZikgPDwgMTY7IC8qIEJsdWUgKi8KICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX1NQRUNVTEFSKSB7IAogICAgICAgICAgICAvKiBXaGF0J3MgdGhlIGNvbG9yIHZhbHVlIGluIHRoZSBmZWVkYmFjayBidWZmZXI/ICovCiAgICAgICAgICAgIERXT1JEICpjb2xvcl9zID0gCiAgICAgICAgICAgICAgKERXT1JEICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMuc3BlY3VsYXIubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5zcGVjdWxhci5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9zKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBzcGVjdWxhciBjb2xvciBpbiBzb3VyY2UsIGJ1dCBkZXN0aW5hdGlvbiBoYXMgb25lXG4iKTsKICAgICAgICAgICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X3B0cikgPSAweEZGMDAwMDAwOwogICAgICAgICAgICAgICAgZGVzdF9wdHIgKz0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSA9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCBjb2xvcl9zLCBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpICA9ICgqY29sb3JfcyAmIDB4ZmYwMGZmMDApICAgICAgOyAvKiBBbHBoYSArIGdyZWVuICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9zICYgMHgwMGZmMDAwMCkgPj4gMTY7IC8qIFJlZCAqLwogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpIHw9ICgqY29sb3JfcyAmIDB4ZmYwMDAwZmYpIDw8IDE2OyAvKiBCbHVlICovCiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAodGV4X2luZGV4ID0gMDsgdGV4X2luZGV4IDwgbnVtVGV4dHVyZXM7IHRleF9pbmRleCsrKSB7CiAgICAgICAgICAgIGZsb2F0ICp0ZXhfY29vcmQgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChjaGFyICopIGxwU3RyaWRlRGF0YS0+dS5zLnRleENvb3Jkc1t0ZXhfaW5kZXhdLmxwRGF0YSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKiBscFN0cmlkZURhdGEtPnUucy50ZXhDb29yZHNbdGV4X2luZGV4XS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCF0ZXhfY29vcmQpIHsKICAgICAgICAgICAgICAgIEVSUigiTm8gc291cmNlIHRleHR1cmUsIGJ1dCBkZXN0aW5hdGlvbiByZXF1ZXN0cyBvbmVcbiIpOwogICAgICAgICAgICAgICAgZGVzdF9wdHIrPUdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSBkZXN0X2NvbnYgKz0gR0VUX1RFWENPT1JEX1NJWkVfRlJPTV9GVkYoRGVzdEZWRiwgdGV4X2luZGV4KSAqIHNpemVvZihmbG9hdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBkZXN0LT52Ym8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIpIik7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZHdEZXN0SW5kZXggKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdDb3VudCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnZfYWRkcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikiKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0X2NvbnZfYWRkcik7CiAgICB9CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQojdW5kZWYgY29weV9hbmRfbmV4dAoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Qcm9jZXNzVmVydGljZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFNyY1N0YXJ0SW5kZXgsIFVJTlQgRGVzdEluZGV4LCBVSU5UIFZlcnRleENvdW50LCBJV2luZUQzRFZlcnRleEJ1ZmZlciogcERlc3RCdWZmZXIsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qIHBWZXJ0ZXhEZWNsLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgc3RyaWRlZDsKICAgIEJPT0wgdmJvID0gRkFMU0UsIHN0cmVhbVdhc1VQID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUDsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJWQsJXAsJXAsJWRcbiIsIFRoaXMsIFNyY1N0YXJ0SW5kZXgsIERlc3RJbmRleCwgVmVydGV4Q291bnQsIHBEZXN0QnVmZmVyLCBwVmVydGV4RGVjbCwgRmxhZ3MpOwoKICAgIGlmKHBWZXJ0ZXhEZWNsKSB7CiAgICAgICAgRVJSKCJPdXRwdXQgdmVydGV4IGRlY2xhcmF0aW9uIG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwogICAgfQoKICAgIC8qIE5lZWQgYW55IGNvbnRleHQgdG8gd3JpdGUgdG8gdGhlIHZiby4gSW4gYSBub24tbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudCBhIGNvbnRleHQgaXMgdGhlcmUgYW55d2F5LAogICAgICogYW5kIHRoaXMgY2FsbCBpcyBxdWl0ZSBwZXJmb3JtYW5jZSBjcml0aWNhbCwgc28gZG9uJ3QgY2FsbCBuZWVkbGVzc2x5CiAgICAgKi8KICAgIGlmKFRoaXMtPmNyZWF0ZVBhcm1zLkJlaGF2aW9yRmxhZ3MgJiBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQpIHsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CgogICAgLyogUHJvY2Vzc1ZlcnRpY2VzIHJlYWRzIGZyb20gdmVydGV4IGJ1ZmZlcnMsIHdoaWNoIGhhdmUgdG8gYmUgYXNzaWduZWQuIERyYXdQcmltaXRpdmUgYW5kIERyYXdQcmltaXRpdmVVUAogICAgICogY29udHJvbCB0aGUgc3RyZWFtSXNVUCBmbGFnLCB0aHVzIHJlc3RvcmUgaXQgYWZ0ZXJ3YXJkcy4KICAgICAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IEZBTFNFOwogICAgbWVtc2V0KCZzdHJpZGVkLCAwLCBzaXplb2Yoc3RyaWRlZCkpOwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4RGVjbCkgewogICAgICAgIHByaW1pdGl2ZURlY2xhcmF0aW9uQ29udmVydFRvU3RyaWRlZERhdGEoaWZhY2UsIEZBTFNFLCAmc3RyaWRlZCwgJnZibyk7CiAgICB9IGVsc2UgewogICAgICAgIHByaW1pdGl2ZUNvbnZlcnRUb1N0cmlkZWREYXRhKGlmYWNlLCAmc3RyaWRlZCwgJnZibyk7CiAgICB9CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gc3RyZWFtV2FzVVA7CgogICAgaWYodmJvIHx8IFNyY1N0YXJ0SW5kZXgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICAvKiBQcm9jZXNzVmVydGljZXMgY2FuJ3QgY29udmVydCBGUk9NIGEgdmJvLCBhbmQgdmVydGV4IGJ1ZmZlcnMgdXNlZCB0byBzb3VyY2UgaW50byBQcm9jZXNWZXJ0aWNzZSBhcmUKICAgICAgICAgKiB1bmxpa2VseSB0byBldmVyIGJlIHVzZWQgZm9yIGRyYXdpbmcuIFJlbGVhc2UgdmJvcyBpbiB0aG9zZSBidWZmZXJzIGFuZCBmaXggdXAgdGhlIHN0cmlkZWQgc3RydWN0dXJlCiAgICAgICAgICoKICAgICAgICAgKiBBbHNvIGdldCB0aGUgc3RhcnQgaW5kZXggaW4sIGJ1dCBvbmx5IGxvb3Agb3ZlciBhbGwgZWxlbWVudHMgaWYgdGhlcmUncyBzb21ldGhpbmcgdG8gYWRkIGF0IGFsbC4KICAgICAgICAgKi8KI2RlZmluZSBGSVhTUkModHlwZSkgXAogICAgICAgIGlmKHN0cmlkZWQudS5zLnR5cGUuVkJPKSB7IFwKICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmlkZWQudS5zLnR5cGUuc3RyZWFtTm9dOyBcCiAgICAgICAgICAgIHN0cmlkZWQudS5zLnR5cGUuVkJPID0gMDsgXAogICAgICAgICAgICBzdHJpZGVkLnUucy50eXBlLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgc3RyaWRlZC51LnMudHlwZS5scERhdGEgKyAodW5zaWduZWQgbG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7IFwKICAgICAgICAgICAgRU5URVJfR0woKTsgXAogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlQnVmZmVyc0FSQigxLCAmdmItPnZibykpOyBcCiAgICAgICAgICAgIHZiLT52Ym8gPSAwOyBcCiAgICAgICAgICAgIExFQVZFX0dMKCk7IFwKICAgICAgICB9IFwKICAgICAgICBpZihzdHJpZGVkLnUucy50eXBlLmxwRGF0YSkgeyBcCiAgICAgICAgICAgIHN0cmlkZWQudS5zLnR5cGUubHBEYXRhICs9IHN0cmlkZWQudS5zLnR5cGUuZHdTdHJpZGUgKiBTcmNTdGFydEluZGV4OyBcCiAgICAgICAgfQogICAgICAgIEZJWFNSQyhwb3NpdGlvbik7CiAgICAgICAgRklYU1JDKGJsZW5kV2VpZ2h0cyk7CiAgICAgICAgRklYU1JDKGJsZW5kTWF0cml4SW5kaWNlcyk7CiAgICAgICAgRklYU1JDKG5vcm1hbCk7CiAgICAgICAgRklYU1JDKHBTaXplKTsKICAgICAgICBGSVhTUkMoZGlmZnVzZSk7CiAgICAgICAgRklYU1JDKHNwZWN1bGFyKTsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7IGkrKykgewogICAgICAgICAgICBGSVhTUkModGV4Q29vcmRzW2ldKTsKICAgICAgICB9CiAgICAgICAgRklYU1JDKHBvc2l0aW9uMik7CiAgICAgICAgRklYU1JDKG5vcm1hbDIpOwogICAgICAgIEZJWFNSQyh0YW5nZW50KTsKICAgICAgICBGSVhTUkMoYmlub3JtYWwpOwogICAgICAgIEZJWFNSQyh0ZXNzRmFjdG9yKTsKICAgICAgICBGSVhTUkMoZm9nKTsKICAgICAgICBGSVhTUkMoZGVwdGgpOwogICAgICAgIEZJWFNSQyhzYW1wbGUpOwojdW5kZWYgRklYU1JDCiAgICB9CgogICAgcmV0dXJuIHByb2Nlc3NfdmVydGljZXNfc3RyaWRlZChUaGlzLCBEZXN0SW5kZXgsIFZlcnRleENvdW50LCAmc3RyaWRlZCwgKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBwRGVzdEJ1ZmZlciwgRmxhZ3MpOwp9CgovKioqKioKICogR2V0IC8gU2V0IFRleHR1cmUgU3RhZ2UgU3RhdGVzCiAqIFRPRE86IFZlcmlmeSBhZ2FpbnN0IGR4OSBkZWZpbml0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZVN0YWdlU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgV0lORUQzRFRFWFRVUkVTVEFHRVNUQVRFVFlQRSBUeXBlLCBEV09SRCBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgb2xkVmFsdWUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdOwoKICAgIC8qIEZJWE1FOiBIYW5kbGUgM2QgdGV4dHVyZXM/IFdoYXQgaWYgVFNTIHZhbHVlIHNldCBiZWZvcmUgc2V0IHRleHR1cmU/IE5lZWQgdG8gcmVhcHBseSBhbGwgdmFsdWVzPyAqLwoKICAgIFRSQUNFKCIoJXApIDogU3RhZ2U9JWQsIFR5cGU9JXMoJWQpLCBWYWx1ZT0lZFxuIiwgVGhpcywgU3RhZ2UsIGRlYnVnX2QzZHRleHR1cmVzdGF0ZShUeXBlKSwgVHlwZSwgVmFsdWUpOwoKICAgIGlmIChTdGFnZSA+PSBNQVhfVEVYVFVSRVMpIHsKICAgICAgICBXQVJOKCJBdHRlbXB0aW5nIHRvIHNldCBzdGFnZSAldSB3aGljaCBpcyBoaWdoZXIgdGhhbiB0aGUgbWF4IHN0YWdlICV1LCBpZ25vcmluZ1xuIiwgU3RhZ2UsIE1BWF9URVhUVVJFUyAtIDEpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSAgICAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSAgICAgICAgID0gVmFsdWU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBDaGVja2VkIGFmdGVyIHRoZSBhc3NpZ25tZW50cyB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgIGlmKG9sZFZhbHVlID09IFZhbHVlKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYoU3RhZ2UgPiBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgJiYKICAgICAgIFN0YXRlVGFibGVbU1RBVEVfVEVYVFVSRVNUQUdFKDAsIFR5cGUpXS5yZXByZXNlbnRhdGl2ZSA9PSBTVEFURV9URVhUVVJFU1RBR0UoMCwgV0lORUQzRFRTU19DT0xPUk9QKSkgewogICAgICAgIC8qIENvbG9yb3AgY2hhbmdlIGFib3ZlIGxvd2VzdCBkaXNhYmxlZCBzdGFnZT8gVGhhdCB3b24ndCBjaGFuZ2UgYW55dGhpbmcgaW4gdGhlIGdsIHNldHVwCiAgICAgICAgICogQ2hhbmdlcyBpbiBvdGhlciBzdGF0ZXMgYXJlIGltcG9ydGFudCBvbiBkaXNhYmxlZCBzdGFnZXMgdG9vCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYoVHlwZSA9PSBXSU5FRDNEVFNTX0NPTE9ST1ApIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYoVmFsdWUgPT0gV0lORUQzRFRPUF9ESVNBQkxFICYmIG9sZFZhbHVlICE9IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAvKiBQcmV2aW91c2x5IGVuYWJsZWQgc3RhZ2UgZGlzYWJsZWQgbm93LiBNYWtlIHN1cmUgdG8gZGlydGlmeSBhbGwgZW5hYmxlZCBzdGFnZXMgYWJvdmUgU3RhZ2UsCiAgICAgICAgICAgICAqIHRoZXkgaGF2ZSB0byBiZSBkaXNhYmxlZAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBUaGUgY3VycmVudCBzdGFnZSBpcyBkaXJ0aWZpZWQgYmVsb3cuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmb3IoaSA9IFN0YWdlICsgMTsgaSA8IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZTsgaSsrKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiQWRkaXRpb25hbGx5IGRpcnRpZnlpbmcgc3RhZ2UgJWRcbiIsIGkpOwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShpLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgPSBTdGFnZTsKICAgICAgICAgICAgVFJBQ0UoIk5ldyBsb3dlc3QgZGlzYWJsZWQ6ICVkXG4iLCBTdGFnZSk7CiAgICAgICAgfSBlbHNlIGlmKFZhbHVlICE9IFdJTkVEM0RUT1BfRElTQUJMRSAmJiBvbGRWYWx1ZSA9PSBXSU5FRDNEVE9QX0RJU0FCTEUpIHsKICAgICAgICAgICAgLyogUHJldmlvdXNseSBkaXNhYmxlZCBzdGFnZSBlbmFibGVkLiBTdGFnZXMgYWJvdmUgaXQgbWF5IG5lZWQgZW5hYmxpbmcKICAgICAgICAgICAgICogc3RhZ2UgbXVzdCBiZSBsb3dlc3RfZGlzYWJsZWRfc3RhZ2UgaGVyZSwgaWYgaXQncyBiaWdnZXIgc3VjY2VzcyBpcyByZXR1cm5lZCBhYm92ZSwKICAgICAgICAgICAgICogYW5kIHN0YWdlcyBiZWxvdyB0aGUgbG93ZXN0IGRpc2FibGVkIHN0YWdlIGNhbid0IGJlIGVuYWJsZWQoYmVjYXVzZSB0aGV5IGFyZSBlbmFibGVkIGFscmVhZHkpLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBBZ2FpbiBzdGFnZSBTdGFnZSBkb2Vzbid0IG5lZWQgdG8gYmUgZGlydGlmaWVkIGhlcmUsIGl0IGlzIGhhbmRsZWQgYmVsb3cuCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgZm9yKGkgPSBTdGFnZSArIDE7IGkgPCBHTF9MSU1JVFModGV4dHVyZV9zdGFnZXMpOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0NPTE9ST1BdID09IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVFJBQ0UoIkFkZGl0aW9uYWxseSBkaXJ0aWZ5aW5nIHN0YWdlICVkIGR1ZSB0byBlbmFibGVcbiIsIGkpOwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShpLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgPSBpOwogICAgICAgICAgICBUUkFDRSgiTmV3IGxvd2VzdCBkaXNhYmxlZDogJWRcbiIsIGkpOwogICAgICAgIH0KICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1JFR0lTVEVSX0NPTUJJTkVSUykgJiYgIVRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyKSB7CiAgICAgICAgICAgIC8qIFRPRE86IEJ1aWx0IGEgc3RhZ2UgLT4gdGV4dHVyZSB1bml0IG1hcHBpbmcgZm9yIHJlZ2lzdGVyIGNvbWJpbmVycyAqLwogICAgICAgIH0KICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBUeXBlKSk7CgogICAgLyogUmVidWlsZCB0aGUgc3RhZ2UgLT4gZ2wgdGV4dHVyZSB1bml0IG1hcHBpbmcgaWYgcmVnaXN0ZXIgY29tYmluZXJzIGFyZSBzdXBwb3J0ZWQKICAgICAqIElmIHRoZXJlIGlzIGEgcGl4ZWwgc2hhZGVyIHRoZXJlIHdpbGwgYmUgYSAxOjEgbWFwcGluZywgbm8gbmVlZCB0byB0b3VjaCBpdC4gU2V0UGl4ZWxTaGFkZXIKICAgICAqIHdpbGwgY2FsbCBGaW5kVGV4VW5pdE1hcCB0b28uCiAgICAgKi8KICAgIGlmKEdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSAmJiAhVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfRmluZFRleFVuaXRNYXAoVGhpcyk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlU3RhZ2VTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBXSU5FRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFR5cGUsIERXT1JEKiBwVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcmVxdWVzdGluZyBTdGFnZSAlZCwgVHlwZSAlZCBnZXR0aW5nICVkXG4iLCBUaGlzLCBTdGFnZSwgVHlwZSwgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSk7CiAgICAqcFZhbHVlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFRleHR1cmUKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSogcFRleHR1cmUpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICAgKm9sZFRleHR1cmU7CgogICAgb2xkVGV4dHVyZSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXTsKICAgIFRSQUNFKCIoJXApIDogU3RhZ2UoJWQpLCBUZXh0dXJlICglcClcbiIsIFRoaXMsIFN0YWdlLCBwVGV4dHVyZSk7CgojaWYgMCAvKiBUT0RPOiBjaGVjayBzbyB2ZXJ0ZXggdGV4dHVyZXMgKi8KICAgIGlmIChTdGFnZSA+PSBEM0RWRVJURVhURVhUVVJFU0FNUExFUiAmJiBTdGFnZSA8PSBEM0RWRVJURVhURVhUVVJFU0FNUExFUjMpewogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFRleHR1cmVzW1N0YWdlIC0gRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVJdID0gcFRleHR1cmU7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiNlbmRpZgoKICAgIGlmKHBUZXh0dXJlICE9IE5VTEwpIHsKICAgICAgICAvKiBTZXRUZXh0dXJlIGlzbid0IGFsbG93ZWQgb24gdGV4dHVyZXMgaW4gV0lORUQzRFBPT0xfU0NSQVRDSDsgCiAgICAgICAgICovCiAgICAgICAgaWYoKChJV2luZUQzRFRleHR1cmVJbXBsKilwVGV4dHVyZSktPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCkgewogICAgICAgICAgICBXQVJOKCIoJXApIEF0dGVtcHQgdG8gc2V0IHNjcmF0Y2ggdGV4dHVyZSByZWplY3RlZFxuIiwgcFRleHR1cmUpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZURpbWVuc2lvbnNbU3RhZ2VdID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhwVGV4dHVyZSk7CiAgICB9CgogICAgVFJBQ0UoIkdMX0xJTUlUUyAlZFxuIixHTF9MSU1JVFMoc2FtcGxlcl9zdGFnZXMpKTsKICAgIFRSQUNFKCIoJXApIDogb2xkdGV4dHVyZSglcClcbiIsIFRoaXMsb2xkVGV4dHVyZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnRleHR1cmVzW1N0YWdlXSAgICAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50ZXh0dXJlc1tTdGFnZV0gPSBUUlVFOwogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIG5ldyB0ZXh0dXJlIHRvICVwXG4iLCBUaGlzLCBwVGV4dHVyZSk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0gICAgICAgICA9IHBUZXh0dXJlOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKG9sZFRleHR1cmUgPT0gcFRleHR1cmUpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIHNhbWUgdGV4dHVyZSBhZ2Fpbiwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyoqIE5PVEU6IE1TRE4gc2F5cyB0aGF0IHNldFRleHR1cmUgaW5jcmVhc2VzIHRoZSByZWZlcmVuY2UgY291bnQsCiAgICAqIGFuZCB0aGUgdGhlIGFwcGxpY2F0aW9uIG51c3Qgc2V0IHRoZSB0ZXh0dXJlIGJhY2sgdG8gbnVsbCAob3IgaGF2ZSBhIGxlYWt5IGFwcGxpY2F0aW9uKSwKICAgICogVGhpcyBtZWFucyB3ZSBzaG91bGQgcGFzcyB0aGUgcmVmY291bnQgdXAgdG8gdGhlIHBhcmVudAogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBpZiAoTlVMTCAhPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0pIHsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqbmV3ID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXTsKICAgICAgICBVTE9ORyBiaW5kQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmbmV3LT5iYXNlVGV4dHVyZS5iaW5kQ291bnQpOwoKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0FkZFJlZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0pOwogICAgICAgIGlmKG9sZFRleHR1cmUgPT0gTlVMTCAmJiBTdGFnZSA8IE1BWF9URVhUVVJFUykgewogICAgICAgICAgICAvKiBUaGUgc291cmNlIGFyZ3VtZW50cyBmb3IgY29sb3IgYW5kIGFscGhhIG9wcyBoYXZlIGRpZmZlcmVudCBtZWFuaW5ncyB3aGVuIGEgTlVMTCB0ZXh0dXJlIGlzIGJvdW5kLAogICAgICAgICAgICAgKiBzbyB0aGUgQ09MT1JPUCBhbmQgQUxQSEFPUCBoYXZlIHRvIGJlIGRpcnRpZmllZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBXSU5FRDNEVFNTX0FMUEhBT1ApKTsKICAgICAgICB9CiAgICAgICAgaWYoYmluZENvdW50ID09IDEpIHsKICAgICAgICAgICAgbmV3LT5iYXNlVGV4dHVyZS5zYW1wbGVyID0gU3RhZ2U7CiAgICAgICAgfQogICAgICAgIC8qIE1vcmUgdGhhbiBvbmUgYXNzaWdubWVudD8gRG9lc24ndCBtYXR0ZXIsIHdlIG9ubHkgbmVlZCBvbmUgZ2wgdGV4dHVyZSB1bml0IHRvIHVzZSBmb3IgdXBsb2FkaW5nICovCgogICAgfQoKICAgIGlmIChOVUxMICE9IG9sZFRleHR1cmUpIHsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqb2xkID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIG9sZFRleHR1cmU7CiAgICAgICAgTE9ORyBiaW5kQ291bnQgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmb2xkLT5iYXNlVGV4dHVyZS5iaW5kQ291bnQpOwoKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2Uob2xkVGV4dHVyZSk7CiAgICAgICAgaWYocFRleHR1cmUgPT0gTlVMTCAmJiBTdGFnZSA8IE1BWF9URVhUVVJFUykgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19BTFBIQU9QKSk7CiAgICAgICAgfQoKICAgICAgICBpZihiaW5kQ291bnQgJiYgb2xkLT5iYXNlVGV4dHVyZS5zYW1wbGVyID09IFN0YWdlKSB7CiAgICAgICAgICAgIGludCBpOwogICAgICAgICAgICAvKiBIYXZlIHRvIGRvIGEgc2VhcmNoIGZvciB0aGUgb3RoZXIgc2FtcGxlcihzKSB3aGVyZSB0aGUgdGV4dHVyZSBpcyBib3VuZCB0bwogICAgICAgICAgICAgKiBTaG91bGRuJ3QgaGFwcGVuIGFzIGxvbmcgYXMgYXBwcyBiaW5kIGEgdGV4dHVyZSBvbmx5IHRvIG9uZSBzdGFnZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgVFJBQ0UoIlNlYXJjaW5nIGZvciBvdGhlciBzYW1wbGVyIC8gc3RhZ2UgaWQgd2hlcmUgdGhlIHRleHR1cmUgaXMgYm91bmQgdG9cbiIpOwogICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBHTF9MSU1JVFMoc2FtcGxlcl9zdGFnZXMpOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2ldID09IG9sZFRleHR1cmUpIHsKICAgICAgICAgICAgICAgICAgICBvbGQtPmJhc2VUZXh0dXJlLnNhbXBsZXIgPSBpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKFN0YWdlKSk7CgogICAgLyogVmVyaWZ5IHRoZSB0ZXh0dXJlIHVuaXQgbWFwcGluZyhhbmQgcmVidWlsZCBpdCBpZiBuZWVkZWQpIGlmIHdlIHVzZSBudnJjcyBhbmQgbm8KICAgICAqIHBpeGVsIHNoYWRlciBpcyB1c2VkCiAgICAgKi8KICAgIGlmKEdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSAmJiAhVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfRmluZFRleFVuaXRNYXAoVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBJV2luZUQzREJhc2VUZXh0dXJlKiogcHBUZXh0dXJlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6ICglZCAvKiBTdGFnZSAqLywlcCAvKiBwcFRleHR1cmUgKi8pXG4iLCBUaGlzLCBTdGFnZSwgcHBUZXh0dXJlKTsKCiAgICAqcHBUZXh0dXJlPVRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXTsKICAgIGlmICgqcHBUZXh0dXJlKQogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfQWRkUmVmKCpwcFRleHR1cmUpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IEJhY2sgQnVmZmVyCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRCYWNrQnVmZmVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBVSU5UIEJhY2tCdWZmZXIsIFdJTkVEM0RCQUNLQlVGRkVSX1RZUEUgVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICoqcHBCYWNrQnVmZmVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKSA6IEJhY2tCdWYgJWQgVHlwZSAlZCBTd2FwQ2hhaW4gJWQgcmV0dXJuaW5nICVwXG4iLCBUaGlzLCBCYWNrQnVmZmVyLCBUeXBlLCBpU3dhcENoYWluLCAqcHBCYWNrQnVmZmVyKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsICBpU3dhcENoYWluLCAmc3dhcENoYWluKTsKICAgIGlmIChociA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXRCYWNrQnVmZmVyKHN3YXBDaGFpbiwgQmFja0J1ZmZlciwgVHlwZSwgcHBCYWNrQnVmZmVyKTsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfSBlbHNlIHsKICAgICAgICAqcHBCYWNrQnVmZmVyID0gTlVMTDsKICAgIH0KICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXZpY2VDYXBzKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRENBUFMqIHBDYXBzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBXQVJOKCIoJXApIDogc3R1YiwgY2FsbGluZyBpZGlyZWN0M2QgZm9yIG5vd1xuIiwgVGhpcyk7CiAgICByZXR1cm4gSVdpbmVEM0RfR2V0RGV2aWNlQ2FwcyhUaGlzLT53aW5lRDNELCBUaGlzLT5hZGFwdGVyTm8sIFRoaXMtPmRldlR5cGUsIHBDYXBzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXREaXNwbGF5TW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzRERJU1BMQVlNT0RFKiBwTW9kZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CgogICAgaWYoaVN3YXBDaGFpbiA+IDApIHsKICAgICAgICBociA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsICBpU3dhcENoYWluLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBDaGFpbik7CiAgICAgICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXREaXNwbGF5TW9kZShzd2FwQ2hhaW4sIHBNb2RlKTsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIEVycm9yIGdldHRpbmcgZGlzcGxheSBtb2RlXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIERvbid0IHJlYWQgdGhlIHJlYWwgZGlzcGxheSBtb2RlLAogICAgICAgICAgIGJ1dCByZXR1cm4gdGhlIHN0b3JlZCBtb2RlIGluc3RlYWQuIFgxMSBjYW4ndCBjaGFuZ2UgdGhlIGNvbG9yCiAgICAgICAgICAgZGVwdGgsIGFuZCBzb21lIGFwcHMgYXJlIHByZXR0eSBhbmdyeSBpZiB0aGV5IFNldERpc3BsYXlNb2RlIGZyb20KICAgICAgICAgICAyNCB0byAxNiBicHAgYW5kIGZpbmQgb3V0IHRoYXQgR2V0RGlzcGxheU1vZGUgc3RpbGwgcmV0dXJucyAyNCBicHAKCiAgICAgICAgICAgQWxzbyBkb24ndCByZWxheSB0byB0aGUgc3dhcGNoYWluIGJlY2F1c2Ugd2l0aCBkZHJhdyBpdCdzIHBvc3NpYmxlCiAgICAgICAgICAgdGhhdCB0aGVyZSBpc24ndCBhIHN3YXBjaGFpbiBhdCBhbGwgKi8KICAgICAgICBwTW9kZS0+V2lkdGggPSBUaGlzLT5kZHJhd193aWR0aDsKICAgICAgICBwTW9kZS0+SGVpZ2h0ID0gVGhpcy0+ZGRyYXdfaGVpZ2h0OwogICAgICAgIHBNb2RlLT5Gb3JtYXQgPSBUaGlzLT5kZHJhd19mb3JtYXQ7CiAgICAgICAgcE1vZGUtPlJlZnJlc2hSYXRlID0gMDsKICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEhXTkQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBIV05EIGhXbmQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBoV25kKTsKCiAgICBpZihUaGlzLT5kZHJhd19mdWxsc2NyZWVuKSB7CiAgICAgICAgaWYoVGhpcy0+ZGRyYXdfd2luZG93ICYmIFRoaXMtPmRkcmF3X3dpbmRvdyAhPSBoV25kKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXN0b3JlV2luZG93KGlmYWNlLCBUaGlzLT5kZHJhd193aW5kb3cpOwogICAgICAgIH0KICAgICAgICBpZihoV25kICYmIFRoaXMtPmRkcmF3X3dpbmRvdyAhPSBoV25kKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3coaWZhY2UsIGhXbmQpOwogICAgICAgIH0KICAgIH0KCiAgICBUaGlzLT5kZHJhd193aW5kb3cgPSBoV25kOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0SFdORChJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgKmhXbmQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBoV25kKTsKCiAgICAqaFduZCA9IFRoaXMtPmRkcmF3X3dpbmRvdzsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogU3RhdGVibG9jayByZWxhdGVkIGZ1bmN0aW9ucwogKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU3RhdGVCbG9jayhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwgKm9iamVjdDsKICAgIEhSRVNVTFQgdGVtcF9yZXN1bHQ7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICAKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCkpOwogICAgaWYgKE5VTEwgPT0gb2JqZWN0ICkgewogICAgICAgIEZJWE1FKCIoJXApRXJyb3IgYWxsb2NhdGluZyBtZW1vcnkgZm9yIHN0YXRlYmxvY2tcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQogICAgVFJBQ0UoIiglcCkgY3JlYXRlZCBvYmplY3QgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICBvYmplY3QtPndpbmVEM0REZXZpY2U9IFRoaXM7CiAgICAvKiogRklYTUU6IG9iamVjdC0+cGFyZW50ICAgICAgID0gcGFyZW50OyAqKi8KICAgIG9iamVjdC0+cGFyZW50ICAgICAgID0gTlVMTDsKICAgIG9iamVjdC0+YmxvY2tUeXBlICAgID0gV0lORUQzRFNCVF9BTEw7CiAgICBvYmplY3QtPnJlZiAgICAgICAgICA9IDE7CiAgICBvYmplY3QtPmxwVnRibCAgICAgICA9ICZJV2luZUQzRFN0YXRlQmxvY2tfVnRibDsKCiAgICBmb3IoaSA9IDA7IGkgPCBMSUdIVE1BUF9TSVpFOyBpKyspIHsKICAgICAgICBsaXN0X2luaXQoJm9iamVjdC0+bGlnaHRNYXBbaV0pOwogICAgfQoKICAgIHRlbXBfcmVzdWx0ID0gYWxsb2NhdGVfc2hhZGVyX2NvbnN0YW50cyhvYmplY3QpOwogICAgaWYgKFdJTkVEM0RfT0sgIT0gdGVtcF9yZXN1bHQpCiAgICAgICAgcmV0dXJuIHRlbXBfcmVzdWx0OwoKICAgIElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jayA9IG9iamVjdDsKICAgIFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUgPSBUUlVFOwoKICAgIFRSQUNFKCIoJXApIHJlY29yZGluZyBzdGF0ZWJsb2NrICVwXG4iLFRoaXMgLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRW5kU3RhdGVCbG9jayhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3RhdGVCbG9jayoqIHBwU3RhdGVCbG9jaykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmICghVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIEZJWE1FKCIoJXApIG5vdCByZWNvcmRpbmchIHJldHVybmluZyBlcnJvclxuIiwgVGhpcyk7CiAgICAgICAgKnBwU3RhdGVCbG9jayA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgKnBwU3RhdGVCbG9jayA9IChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2s7CiAgICBUaGlzLT5pc1JlY29yZGluZ1N0YXRlID0gRkFMU0U7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrID0gVGhpcy0+c3RhdGVCbG9jazsKICAgIElXaW5lRDNEU3RhdGVCbG9ja19BZGRSZWYoKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+dXBkYXRlU3RhdGVCbG9jayk7CiAgICAvKiBJV2luZUQzRFN0YXRlQmxvY2tfQWRkUmVmKCpwcFN0YXRlQmxvY2spOyBkb24ndCBuZWVkIHRvIGRvIHRoaXMsIHNpbmNlIHdlIHNob3VsZCByZWFsbHkganVzdCByZWxlYXNlIFVwZGF0ZVN0YXRlQmxvY2sgZmlyc3QgKi8KICAgIFRSQUNFKCIoJXApIHJldHVybmluZyB0b2tlbiAocHRyIHRvIHN0YXRlYmxvY2spIG9mICVwXG4iLCBUaGlzLCAqcHBTdGF0ZUJsb2NrKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogU2NlbmUgcmVsYXRlZCBmdW5jdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU2NlbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICAvKiBBdCB0aGUgbW9tZW50IHdlIGhhdmUgbm8gbmVlZCBmb3IgYW55IGZ1bmN0aW9uYWxpdHkgYXQgdGhlIGJlZ2lubmluZwogICAgICAgb2YgYSBzY2VuZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKFRoaXMtPmluU2NlbmUpIHsKICAgICAgICBUUkFDRSgiQWxyZWFkeSBpbiBTY2VuZSwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgVGhpcy0+aW5TY2VuZSA9IFRSVUU7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTY2VuZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZighVGhpcy0+aW5TY2VuZSkgewogICAgICAgIFRSQUNFKCJOb3QgaW4gc2NlbmUsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBFTlRFUl9HTCgpOwogICAgaWYoVGhpcy0+Y3JlYXRlUGFybXMuQmVoYXZpb3JGbGFncyAmIFdJTkVEM0RDUkVBVEVfTVVMVElUSFJFQURFRCkgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgfQogICAgLyogV2Ugb25seSBoYXZlIHRvIGRvIHRoaXMgaWYgd2UgbmVlZCB0byByZWFkIHRoZSwgc3dhcGJ1ZmZlcnMgcGVyZm9ybXMgYSBmbHVzaCBmb3IgdXMgKi8KICAgIGdsRmx1c2goKTsKICAgIGNoZWNrR0xjYWxsKCJnbEZsdXNoIik7CiAgICBMRUFWRV9HTCgpOwoKICAgIFRoaXMtPmluU2NlbmUgPSBGQUxTRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1ByZXNlbnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBSRUNUKiBwU291cmNlUmVjdCwgQ09OU1QgUkVDVCogcERlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIGhEZXN0V2luZG93T3ZlcnJpZGUsIENPTlNUIFJHTkRBVEEqIHBEaXJ0eVJlZ2lvbikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbiA9IE5VTEw7CiAgICBpbnQgaTsKICAgIGludCBzd2FwY2hhaW5zID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldE51bWJlck9mU3dhcENoYWlucyhpZmFjZSk7CgogICAgVFJBQ0UoIiglcCkgUHJlc2VudGluZyB0aGUgZnJhbWVcbiIsIFRoaXMpOwoKICAgIGZvcihpID0gMCA7IGkgPCBzd2FwY2hhaW5zIDsgaSArKykgewoKICAgICAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpICwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgICAgIFRSQUNFKCJwcmVzZW50aW5uZyBjaGFpbiAlZCwgJXBcbiIsIGksIHN3YXBDaGFpbik7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUHJlc2VudChzd2FwQ2hhaW4sIHBTb3VyY2VSZWN0LCBwRGVzdFJlY3QsIGhEZXN0V2luZG93T3ZlcnJpZGUsIHBEaXJ0eVJlZ2lvbiwgMCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFyKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgQ291bnQsIENPTlNUIFdJTkVEM0RSRUNUKiBwUmVjdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywgV0lORUQzRENPTE9SIENvbG9yLCBmbG9hdCBaLCBEV09SRCBTdGVuY2lsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICp0YXJnZXQgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdOwoKICAgIEdMYml0ZmllbGQgICAgIGdsTWFzayA9IDA7CiAgICB1bnNpZ25lZCBpbnQgICBpOwogICAgQ09OU1QgV0lORUQzRFJFQ1QqIGN1clJlY3Q7CgogICAgVFJBQ0UoIiglcCkgQ291bnQgKCVkKSwgcFJlY3RzICglcCksIEZsYWdzICgleCksIFogKCVmKSwgU3RlbmNpbCAoJWQpXG4iLCBUaGlzLAogICAgICAgICAgQ291bnQsIHBSZWN0cywgRmxhZ3MsIFosIFN0ZW5jaWwpOwoKICAgIGlmKEZsYWdzICYgKFdJTkVEM0RDTEVBUl9aQlVGRkVSIHwgV0lORUQzRENMRUFSX1NURU5DSUwpICYmIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIkNsZWFyaW5nIGRlcHRoIGFuZC9vciBzdGVuY2lsIHdpdGhvdXQgYSBkZXB0aCBzdGVuY2lsIGJ1ZmZlciBhdHRhY2hlZCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIC8qIFRPRE86IFdoYXQgYWJvdXQgZGVwdGggc3RlbmNpbCBidWZmZXJzIHdpdGhvdXQgc3RlbmNpbCBiaXRzPyAqLwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CiAgICAvKiBUaGlzIGlzIGZvciBvZmZzY3JlZW4gcmVuZGVyaW5nIGFzIHdlbGwgYXMgZm9yIG11bHRpdGhyZWFkaW5nLCB0aHVzIGFjdGl2YXRlIHRoZSBzZXQgcmVuZGVyIHRhcmdldAogICAgICogYW5kIG5vdCB0aGUgbGFzdCBhY3RpdmUgb25lLgogICAgICovCgogICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8pIHsKICAgICAgICBhcHBseV9mYm9fc3RhdGUoaWZhY2UpOwogICAgfQoKICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX1NDSVNTT1JfVEVTVCIpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NDSVNTT1JSRUNUKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CgogICAgaWYgKENvdW50ID4gMCAmJiBwUmVjdHMpIHsKICAgICAgICBjdXJSZWN0ID0gcFJlY3RzOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJSZWN0ID0gTlVMTDsKICAgIH0KCiAgICAvKiBPbmx5IHNldCB0aGUgdmFsdWVzIHVwIG9uY2UsIGFzIHRoZXkgYXJlIG5vdCBjaGFuZ2luZyAqLwogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbENsZWFyU3RlbmNpbChTdGVuY2lsKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhclN0ZW5jaWwiKTsKICAgICAgICBnbE1hc2sgPSBnbE1hc2sgfCBHTF9TVEVOQ0lMX0JVRkZFUl9CSVQ7CiAgICAgICAgZ2xTdGVuY2lsTWFzaygweEZGRkZGRkZGKTsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfWkJVRkZFUikgewogICAgICAgIGdsRGVwdGhNYXNrKEdMX1RSVUUpOwogICAgICAgIGdsQ2xlYXJEZXB0aChaKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckRlcHRoIik7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfREVQVEhfQlVGRkVSX0JJVDsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aV1JJVEVFTkFCTEUpKTsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfVEFSR0VUKSB7CiAgICAgICAgVFJBQ0UoIkNsZWFyaW5nIHNjcmVlbiB3aXRoIGdsQ2xlYXIgdG8gY29sb3IgJXhcbiIsIENvbG9yKTsKICAgICAgICBnbENsZWFyQ29sb3IoRDNEQ09MT1JfUihDb2xvciksCiAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0coQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CKENvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQShDb2xvcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyQ29sb3IiKTsKCiAgICAgICAgLyogQ2xlYXIgQUxMIGNvbG9ycyEgKi8KICAgICAgICBnbENvbG9yTWFzayhHTF9UUlVFLCBHTF9UUlVFLCBHTF9UUlVFLCBHTF9UUlVFKTsKICAgICAgICBnbE1hc2sgPSBnbE1hc2sgfCBHTF9DT0xPUl9CVUZGRVJfQklUOwogICAgfQoKICAgIGlmICghY3VyUmVjdCkgewogICAgICAgIC8qIEluIGRyYXdhYmxlIGZsYWcgaXMgc2V0IGJlbG93ICovCgogICAgICAgIGdsU2Npc3NvcihUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5YLAogICAgICAgICAgICAgICAgICAoKChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pLT5jdXJyZW50RGVzYy5IZWlnaHQgLQogICAgICAgICAgICAgICAgICAoVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuWSArIFRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LkhlaWdodCkpLAogICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuV2lkdGgsCiAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5IZWlnaHQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFNjaXNzb3IiKTsKICAgICAgICBnbENsZWFyKGdsTWFzayk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYoISh0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5EUkFXQUJMRSkgJiYKICAgICAgICAgICAhKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8gJiYgVGhpcy0+cmVuZGVyX29mZnNjcmVlbiAmJiB0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5URVhUVVJFKSkgewoKICAgICAgICAgICAgaWYoY3VyUmVjdFswXS54MSA+IDAgfHwgY3VyUmVjdFswXS55MSA+IDAgfHwKICAgICAgICAgICAgICAgY3VyUmVjdFswXS54MiA8IHRhcmdldC0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgY3VyUmVjdFswXS55MiA8IHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiUGFydGlhbCBjbGVhciwgYW5kIHN1cmZhY2Ugbm90IGluIGRyYXdhYmxlLiBCbGl0dGluZyB0ZXh0dXJlIHRvIGRyYXdhYmxlXG4iKTsKICAgICAgICAgICAgICAgIGJsdF90b19kcmF3YWJsZShUaGlzLCB0YXJnZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBOb3cgcHJvY2VzcyBlYWNoIHJlY3QgaW4gdHVybiAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIC8qIE5vdGUgZ2wgdXNlcyBsb3dlciBsZWZ0LCB3aWR0aC9oZWlnaHQgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgJXAgUmVjdD0oJWQsJWQpLT4oJWQsJWQpIGdsUmVjdD0oJWQsJWQpLCBsZW49JWQsIGhlaT0lZFxuIiwgVGhpcywgY3VyUmVjdCwKICAgICAgICAgICAgICAgICAgY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MSwgY3VyUmVjdFtpXS54MiwgY3VyUmVjdFtpXS55MiwKICAgICAgICAgICAgICAgICAgY3VyUmVjdFtpXS54MSwgKHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0IC0gY3VyUmVjdFtpXS55MiksCiAgICAgICAgICAgICAgICAgIGN1clJlY3RbaV0ueDIgLSBjdXJSZWN0W2ldLngxLCBjdXJSZWN0W2ldLnkyIC0gY3VyUmVjdFtpXS55MSk7CgogICAgICAgICAgICAvKiBUZXN0cyBzaG93IHRoYXQgcmVjdGFuZ2xlcyB3aGVyZSB4MSA+IHgyIG9yIHkxID4geTIgYXJlIGlnbm9yZWQgc2lsZW50bHkuCiAgICAgICAgICAgICAqIFRoZSByZWN0YW5nbGUgaXMgbm90IGNsZWFyZWQsIG5vIGVycm9yIGlzIHJldHVybmVkLCBidXQgZnVydGhlciByZWN0YW5sZ2VzIGFyZQogICAgICAgICAgICAgKiBzdGlsbCBjbGVhcmVkIGlmIHRoZXkgYXJlIHZhbGlkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihjdXJSZWN0W2ldLngxID4gY3VyUmVjdFtpXS54MiB8fCBjdXJSZWN0W2ldLnkxID4gY3VyUmVjdFtpXS55MikgewogICAgICAgICAgICAgICAgVFJBQ0UoIlJlY3RhbmdsZSB3aXRoIG5lZ2F0aXZlIGRpbWVuc2lvbnMsIGlnbm9yaW5nXG4iKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgICAgICAgICBnbFNjaXNzb3IoY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0W2ldLngyIC0gY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MiAtIGN1clJlY3RbaV0ueTEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xTY2lzc29yKGN1clJlY3RbaV0ueDEsIHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0IC0gY3VyUmVjdFtpXS55MiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0W2ldLngyIC0gY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MiAtIGN1clJlY3RbaV0ueTEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFNjaXNzb3IiKTsKCiAgICAgICAgICAgIGdsQ2xlYXIoZ2xNYXNrKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKICAgICAgICB9CiAgICB9CgogICAgLyogUmVzdG9yZSB0aGUgb2xkIHZhbHVlcyAod2h5Li4/KSAqLwogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbFN0ZW5jaWxNYXNrKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLXSk7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfVEFSR0VUKSB7CiAgICAgICAgRFdPUkQgbWFzayA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFXTsKICAgICAgICBnbENvbG9yTWFzayhtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfUkVEID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIG1hc2sgJiBXSU5FRDNEQ09MT1JXUklURUVOQUJMRV9HUkVFTiA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfQkxVRSAgPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgbWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX0FMUEhBID8gR0xfVFJVRSA6IEdMX0ZBTFNFKTsKICAgIH0KCiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIERpcnRpZnkgdGhlIHRhcmdldCBzdXJmYWNlIGZvciBub3cuIElmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCByZWd1bGFyaWx5LCBhbmQgYW4gdXAgdG8gZGF0ZSBzeXNtZW0gY29weSBleGlzdHMsCiAgICAgKiBpdCBpcyBtb3N0IGxpa2VseSBtb3JlIGVmZmljaWVudCB0byBwZXJmb3JtIGEgY2xlYXIgb24gdGhlIHN5c21lbSBjb3B5IHRvbyBpc250ZWFkIG9mIGRvd25sb2FkaW5nIGl0CiAgICAgKi8KICAgIGlmKFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gJiYgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgICAgIHRhcmdldC0+RmxhZ3MgJj0gflNGTEFHX0lOU1lTTUVNOwogICAgfSBlbHNlIHsKICAgICAgICB0YXJnZXQtPkZsYWdzIHw9IFNGTEFHX0lORFJBV0FCTEU7CiAgICAgICAgdGFyZ2V0LT5GbGFncyAmPSB+KFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOU1lTTUVNKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogRHJhd2luZyBmdW5jdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBTdGFydD0lZCwgQ291bnQ9JWRcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhcnRWZXJ0ZXgsIFByaW1pdGl2ZUNvdW50KTsKCiAgICAvKiBUaGUgaW5kZXggYnVmZmVyIGlzIG5vdCBuZWVkZWQgaGVyZSwgYnV0IHJlc3RvcmUgaXQsIG90aGVyd2lzZSBpdCBpcyBoZWxsIHRvIGtlZXAgdHJhY2sgb2YgKi8KICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVApIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBGQUxTRTsKICAgIH0KCiAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ICE9IDApIHsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gMDsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKICAgIH0KICAgIC8qIEFjY291bnQgZm9yIHRoZSBsb2FkaW5nIG9mZnNldCBkdWUgdG8gaW5kZXggYnVmZmVycy4gSW5zdGVhZCBvZiByZWxvYWRpbmcgYWxsIHNvdXJjZXMgY29ycmVjdCBpdCB3aXRoIHRoZSBzdGFydHZlcnRleCBwYXJhbWV0ZXIgKi8KICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCBTdGFydFZlcnRleCwgMC8qIE51bVZlcnRpY2VzICovLCAtMSAvKiBpbmR4U3RhcnQgKi8sCiAgICAgICAgICAgICAgICAgIDAgLyogaW5keFNpemUgKi8sIE5VTEwgLyogaW5keERhdGEgKi8sIDAgLyogbWluSW5kZXggKi8pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRPRE86IGJhc2VWSW5kZXggbmVlZHMgdG8gYmUgcHJvdmlkZWQgZnJvbSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggd2hlbiBjYWxsZWQgZnJvbSBkM2Q4ICovCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZShJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIG1pbkluZGV4LCBVSU5UIE51bVZlcnRpY2VzLCBVSU5UIHN0YXJ0SW5kZXgsIFVJTlQgcHJpbUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgICAgICAgICAgICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICBJV2luZUQzREluZGV4QnVmZmVyICpwSUI7CiAgICBXSU5FRDNESU5ERVhCVUZGRVJfREVTQyAgSWR4QnVmRHNjOwogICAgR0x1aW50IHZibzsKCiAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gRkFMU0U7CiAgICB9CiAgICBwSUIgPSBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhOwogICAgdmJvID0gKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBwSUIpLT52Ym87CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIG1pbj0lZCwgQ291bnRWPSVkLCBzdGFydElkeD0lZCwgY291bnRQPSVkXG4iLCBUaGlzLAogICAgICAgICAgUHJpbWl0aXZlVHlwZSwgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgIG1pbkluZGV4LCBOdW1WZXJ0aWNlcywgc3RhcnRJbmRleCwgcHJpbUNvdW50KTsKCiAgICBJV2luZUQzREluZGV4QnVmZmVyX0dldERlc2MocElCLCAmSWR4QnVmRHNjKTsKICAgIGlmIChJZHhCdWZEc2MuRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgxNikgewogICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGlkeFN0cmlkZSA9IDQ7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCAhPSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXgpIHsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4OwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIHByaW1Db3VudCwgMCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsCiAgICAgICAgICAgICAgICAgICBpZHhTdHJpZGUsIHZibyA/IE5VTEwgOiAoKElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICopIHBJQiktPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWluSW5kZXgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVVUChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgcENvdW50PSVkLCBwVnR4RGF0YT0lcCwgU3RyaWRlPSVkXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIC8qIE5vdGUgaW4gdGhlIGZvbGxvd2luZywgaXQncyBub3QgdGhpcyB0eXBlLCBidXQgdGhhdCdzIHRoZSBwdXJwb3NlIG9mIHN0cmVhbUlzVVAgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKXBWZXJ0ZXhTdHJlYW1aZXJvRGF0YTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldFswXSA9IDA7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gMDsKCiAgICAvKiBUT0RPOiBPbmx5IG1hcmsgZGlydHkgaWYgZHJhd2luZyBmcm9tIGEgZGlmZmVyZW50IFVQIGFkZHJlc3MgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCAwIC8qIHN0YXJ0IHZlcnRleCAqLywgMCAgLyogTnVtVmVydGljZXMgKi8sCiAgICAgICAgICAgICAgICAgIDAgLyogaW5keFN0YXJ0Ki8sIDAgLyogaW5keFNpemUqLywgTlVMTCAvKiBpbmR4RGF0YSAqLywgMCAvKiBpbmR4TWluICovKTsKCiAgICAvKiBNU0ROIHNwZWNpZmllcyBzdHJlYW0gemVybyBzZXR0aW5ncyBtdXN0IGJlIHNldCB0byBOVUxMICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdID0gTlVMTDsKCiAgICAvKiBzdHJlYW0gemVybyBzZXR0aW5ncyBzZXQgdG8gbnVsbCBhdCBlbmQsIGFzIHBlciB0aGUgbXNkbi4gTm8gbmVlZCB0byBtYXJrIGRpcnR5IGhlcmUsIHRoZSBhcHAgaGFzIHRvIHNldAogICAgICogdGhlIG5ldyBzdHJlYW0gc291cmNlcyBvciB1c2UgVVAgZHJhd2luZyBhZ2FpbgogICAgICovCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTWluVmVydGV4SW5kZXgsIFVJTlQgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwSW5kZXhEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBJbmRleERhdGFGb3JtYXQsQ09OU1Qgdm9pZCogcFZlcnRleFN0cmVhbVplcm9EYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKSB7CiAgICBpbnQgICAgICAgICAgICAgICAgIGlkeFN0cmlkZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgTWluVnR4SWR4PSVkLCBOdW1WSWR4PSVkLCBQQ291bnQ9JWQsIHBpZHhkYXRhPSVwLCBJZHhGbXQ9JWQsIHBWdHhkYXRhPSVwLCBzdHJpZGU9JWRcbiIsCiAgICAgICAgICAgICBUaGlzLCBQcmltaXRpdmVUeXBlLCBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgTWluVmVydGV4SW5kZXgsIE51bVZlcnRpY2VzLCBQcmltaXRpdmVDb3VudCwgcEluZGV4RGF0YSwKICAgICAgICAgICAgIEluZGV4RGF0YUZvcm1hdCwgcFZlcnRleFN0cmVhbVplcm9EYXRhLCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKTsKCiAgICBpZiAoSW5kZXhEYXRhRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgxNikgewogICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGlkeFN0cmlkZSA9IDQ7CiAgICB9CgogICAgLyogTm90ZSBpbiB0aGUgZm9sbG93aW5nLCBpdCdzIG5vdCB0aGlzIHR5cGUsIGJ1dCB0aGF0J3MgdGhlIHB1cnBvc2Ugb2Ygc3RyZWFtSXNVUCAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdID0gKElXaW5lRDNEVmVydGV4QnVmZmVyICopcFZlcnRleFN0cmVhbVplcm9EYXRhOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbMF0gPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gVmVydGV4U3RyZWFtWmVyb1N0cmlkZTsKCiAgICAvKiBTZXQgdG8gMCBhcyBwZXIgbXNkbi4gRG8gaXQgbm93IGR1ZSB0byB0aGUgc3RyZWFtIHNvdXJjZSBsb2FkaW5nIGR1cmluZyBkcmF3UHJpbWl0aXZlICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCA9IDA7CiAgICAvKiBNYXJrIHRoZSBzdGF0ZSBkaXJ0eSB1bnRpbCB3ZSBoYXZlIG5pY2VyIHRyYWNraW5nIG9mIHRoZSBzdHJlYW0gc291cmNlIHBvaW50ZXJzICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKCiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgMCAvKiB2ZXJ0ZXhTdGFydCAqLywgTnVtVmVydGljZXMsIDAgLyogaW5keFN0YXJ0ICovLCBpZHhTdHJpZGUsIHBJbmRleERhdGEsIE1pblZlcnRleEluZGV4KTsKCiAgICAvKiBNU0ROIHNwZWNpZmllcyBzdHJlYW0gemVybyBzZXR0aW5ncyBhbmQgaW5kZXggYnVmZmVyIG11c3QgYmUgc2V0IHRvIE5VTEwgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IE5VTEw7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSA9IE5VTEw7CiAgICAvKiBObyBuZWVkIHRvIG1hcmsgdGhlIHN0cmVhbSBzb3VyY2Ugc3RhdGUgZGlydHkgaGVyZS4gRWl0aGVyIHRoZSBhcHAgY2FsbHMgVVAgZHJhd2luZyBhZ2Fpbiwgb3IgaXQgaGFzIHRvIGNhbGwKICAgICAqIFNldFN0cmVhbVNvdXJjZSB0byBzcGVjaWZ5IGEgdmVydGV4IGJ1ZmZlcgogICAgICovCgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVN0cmlkZWQgKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwgVUlOVCBQcmltaXRpdmVDb3VudCwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKkRyYXdQcmltU3RyaWRlRGF0YSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKCiAgICAvKiBNYXJrIHRoZSBzdGF0ZSBkaXJ0eSB1bnRpbCB3ZSBoYXZlIG5pY2VyIHRyYWNraW5nCiAgICAgKiBpdHMgZmluZSB0byBjaGFuZ2UgYmFzZVZlcnRleEluZGV4IGJlY2F1c2UgdGhhdCBjYWxsIGlzIG9ubHkgY2FsbGVkIGJ5IGRkcmF3IHdoaWNoIGRvZXMgbm90IG5lZWQKICAgICAqIHRoYXQgdmFsdWUuCiAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WREVDTCk7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwogICAgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gMDsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBEcmF3UHJpbVN0cmlkZURhdGE7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gVFJVRTsKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCAwLCAwLCAwLCAwLCBOVUxMLCAwKTsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBOVUxMOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KIC8qIFlldCBhbm90aGVyIHdheSB0byB1cGRhdGUgYSB0ZXh0dXJlLCBzb21lIGFwcHMgdXNlIHRoaXMgdG8gbG9hZCBkZWZhdWx0IHRleHR1cmVzIGluc3RlYWQgb2YgdXNpbmcgc3VyZmFjZS90ZXh0dXJlIGxvY2svdW5sb2NrICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfVXBkYXRlVGV4dHVyZSAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzREJhc2VUZXh0dXJlICpwU291cmNlVGV4dHVyZSwgIElXaW5lRDNEQmFzZVRleHR1cmUgKnBEZXN0aW5hdGlvblRleHR1cmUpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CiAgICBXSU5FRDNEUkVTT1VSQ0VUWVBFIHNvdXJjZVR5cGU7CiAgICBXSU5FRDNEUkVTT1VSQ0VUWVBFIGRlc3RpbmF0aW9uVHlwZTsKICAgIGludCBpICxsZXZlbHM7CgogICAgLyogVE9ETzogdGhpbmsgYWJvdXQgbW92aW5nIHRoZSBjb2RlIGludG8gSVdpbmVEM0RCYXNlVGV4dHVyZSAgKi8KCiAgICBUUkFDRSgiKCVwKSBTb3VyY2UgJXAgRGVzdGluYXRpb24gJXBcbiIsIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAvKiB2ZXJpZnkgdGhhdCB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiB0ZXh0dXJlcyBhcmVuJ3QgTlVMTCAqLwogICAgaWYgKE5VTEwgPT0gcFNvdXJjZVRleHR1cmUgfHwgTlVMTCA9PSBwRGVzdGluYXRpb25UZXh0dXJlKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHNvdXJjZSAoJXApIGFuZCBkZXN0aW5hdGlvbiAoJXApIHRleHR1cmVzIG11c3Qgbm90IGJlIE5VTEwsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcywgcFNvdXJjZVRleHR1cmUsIHBEZXN0aW5hdGlvblRleHR1cmUpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAocFNvdXJjZVRleHR1cmUgPT0gcERlc3RpbmF0aW9uVGV4dHVyZSkgewogICAgICAgIFdBUk4oIiglcCkgOiBzb3VyY2UgKCVwKSBhbmQgZGVzdGluYXRpb24gKCVwKSB0ZXh0dXJlcyBtdXN0IGJlIGRpZmZlcmVudCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsCiAgICAgICAgICAgICBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyogVmVyaWZ5IHRoYXQgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdGV4dHVyZXMgYXJlIHRoZSBzYW1lIHR5cGUgKi8KICAgIHNvdXJjZVR5cGUgICAgICA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0VHlwZShwU291cmNlVGV4dHVyZSk7CiAgICBkZXN0aW5hdGlvblR5cGUgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUocERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgaWYgKHNvdXJjZVR5cGUgIT0gZGVzdGluYXRpb25UeXBlKSB7CiAgICAgICAgV0FSTigiKCVwKSBTb3JjZSBhbmQgZGVzdGluYXRpb24gdHlwZXMgbXVzdCBtYXRjaCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsCiAgICAgICAgICAgICBUaGlzKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogY2hlY2sgdGhhdCBib3RoIHRleHR1cmVzIGhhdmUgdGhlIGlkZW50aWNhbCBudW1iZXJzIG9mIGxldmVscyAgKi8KICAgIGlmIChJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocERlc3RpbmF0aW9uVGV4dHVyZSkgICE9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0TGV2ZWxDb3VudChwU291cmNlVGV4dHVyZSkpIHsKICAgICAgICBXQVJOKCIoJXApIDogc291cmNlICglcCkgYW5kIGRlc3RpbmF0aW9uICglcCkgdGV4dHVyZXMgbXVzdCBoYXZlIGlkZW50aWNsZSBudW1iZXJzIG9mIGxldmVscywgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFdJTkVEM0RfT0sgPT0gaHIpIHsKCiAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUgaXMgbG9hZGVkICovCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9QcmVMb2FkKHBEZXN0aW5hdGlvblRleHR1cmUpOwoKICAgICAgICAvKiBVcGRhdGUgZXZlcnkgc3VyZmFjZSBsZXZlbCBvZiB0aGUgdGV4dHVyZSAqLwogICAgICAgIGxldmVscyA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0TGV2ZWxDb3VudChwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAgICAgc3dpdGNoIChzb3VyY2VUeXBlKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpzcmNTdXJmYWNlOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkZXN0U3VyZmFjZTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwIDsgaSA8IGxldmVscyA7ICsraSkgewogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVGV4dHVyZV9HZXRTdXJmYWNlTGV2ZWwoKElXaW5lRDNEVGV4dHVyZSAqKXBTb3VyY2VUZXh0dXJlLCAgICAgIGksICZzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfR2V0U3VyZmFjZUxldmVsKChJV2luZUQzRFRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBpLCAmZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfVXBkYXRlU3VyZmFjZShpZmFjZSwgc3JjU3VyZmFjZSwgTlVMTCwgZGVzdFN1cmZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKGRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCIoJXApIDogQ2FsbCB0byB1cGRhdGUgc3VyZmFjZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX0NVQkVURVhUVVJFOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKnNyY1N1cmZhY2U7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKmRlc3RTdXJmYWNlOwogICAgICAgICAgICAgICAgV0lORUQzRENVQkVNQVBfRkFDRVMgZmFjZVR5cGU7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAvKiBVcGRhdGUgZWFjaCBjdWJlIGZhY2UgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKGZhY2VUeXBlID0gV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YOyBmYWNlVHlwZSA8PSBXSU5FRDNEQ1VCRU1BUF9GQUNFX05FR0FUSVZFX1o7ICsrZmFjZVR5cGUpewogICAgICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNEQ3ViZVRleHR1cmVfR2V0Q3ViZU1hcFN1cmZhY2UoKElXaW5lRDNEQ3ViZVRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBmYWNlVHlwZSwgaSwgJnNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgOiBGYWlsZWQgdG8gZ2V0IHNyYyBjdWJlIHN1cmZhY2UgZmFjZXR5cGUgJWQsIGxldmVsICVkXG4iLCBUaGlzLCBmYWNlVHlwZSwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiR290IHNyY1N1cmZhY2UgJXBcbiIsIHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0RDdWJlVGV4dHVyZV9HZXRDdWJlTWFwU3VyZmFjZSgoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKXBEZXN0aW5hdGlvblRleHR1cmUsIGZhY2VUeXBlLCBpLCAmZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgOiBGYWlsZWQgdG8gZ2V0IHNyYyBjdWJlIHN1cmZhY2UgZmFjZXR5cGUgJWQsIGxldmVsICVkXG4iLCBUaGlzLCBmYWNlVHlwZSwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiR290IGRlc3JTdXJmYWNlICVwXG4iLCBkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9VcGRhdGVTdXJmYWNlKGlmYWNlLCBzcmNTdXJmYWNlLCBOVUxMLCBkZXN0U3VyZmFjZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCIoJXApIDogQ2FsbCB0byB1cGRhdGUgc3VyZmFjZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwojaWYgMCAvKiBUT0RPOiBBZGQgc3VwcG9ydCBmb3Igdm9sdW1lIHRleHR1cmVzICovCiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWUgIHNyY1ZvbHVtZSAgPSBOVUxMOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlIGRlc3RWb2x1bWUgPSBOVUxMOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgbGV2ZWxzIDsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlX0dldFZvbHVtZSgoSVdpbmVEM0RWb2x1bWVUZXh0dXJlICopcFNvdXJjZVRleHR1cmUsICAgICAgaSwgJnNyY1ZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlX0dldFZvbHVtZSgoSVdpbmVEM0RWb2x1bWVUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIGhyID0gIElXaW5lRDNERm9vX1VwZGF0ZVZvbHVtZShpZmFjZSwgc3JjVm9sdW1lLCBOVUxMLCBkZXN0Vm9sdW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZV9SZWxlYXNlKHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lX1JlbGVhc2UoZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFdBUk4oIiglcCkgOiBDYWxsIHRvIHVwZGF0ZSB2b2x1bWUgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKI2VuZGlmCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIiglcCkgOiBVbnN1cHBvcnRlZCBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHR5cGVcbiIsIFRoaXMpOwogICAgICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZyb250QnVmZmVyRGF0YShJV2luZUQzRERldmljZSAqaWZhY2UsVUlOVCBpU3dhcENoYWluLCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0U3VyZmFjZSkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CiAgICBociA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsICBpU3dhcENoYWluLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBDaGFpbik7CiAgICBpZihociA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXRGcm9udEJ1ZmZlckRhdGEoc3dhcENoYWluLCBwRGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVmFsaWRhdGVEZXZpY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCogcE51bVBhc3NlcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgLyogcmV0dXJuIGEgc2Vuc2libGUgZGVmYXVsdCAqLwogICAgKnBOdW1QYXNzZXMgPSAxOwogICAgLyogVE9ETzogSWYgdGhlIHdpbmRvdyBpcyBtaW5pbWl6ZWQgdGhlbiB2YWxpZGF0ZSBkZXZpY2Ugc2hvdWxkIHJldHVybiBzb21ldGhpbmcgb3RoZXIgdGhhbiBXSU5FRDNEX09LICovCiAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQYWxldHRlRW50cmllcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlciwgQ09OU1QgUEFMRVRURUVOVFJZKiBwRW50cmllcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGo7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKCBQYWxldHRlTnVtYmVyIDwgMCB8fCBQYWxldHRlTnVtYmVyID49IE1BWF9QQUxFVFRFUykgewogICAgICAgIFdBUk4oIiglcCkgOiAoJXUpIE91dCBvZiByYW5nZSAwLSV1LCByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyLCBNQVhfUEFMRVRURVMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZm9yIChqID0gMDsgaiA8IDI1NjsgKytqKSB7CiAgICAgICAgVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVSZWQgICA9IHBFbnRyaWVzW2pdLnBlUmVkOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlR3JlZW4gPSBwRW50cmllc1tqXS5wZUdyZWVuOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlQmx1ZSAgPSBwRW50cmllc1tqXS5wZUJsdWU7CiAgICAgICAgVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVGbGFncyA9IHBFbnRyaWVzW2pdLnBlRmxhZ3M7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZ1xuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhbGV0dGVFbnRyaWVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBQYWxldHRlTnVtYmVyLCBQQUxFVFRFRU5UUlkqIHBFbnRyaWVzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgajsKICAgIFRSQUNFKCIoJXApIDogUGFsZXR0ZU51bWJlciAldVxuIiwgVGhpcywgUGFsZXR0ZU51bWJlcik7CiAgICBpZiAoIFBhbGV0dGVOdW1iZXIgPCAwIHx8IFBhbGV0dGVOdW1iZXIgPj0gTUFYX1BBTEVUVEVTKSB7CiAgICAgICAgV0FSTigiKCVwKSA6ICgldSkgT3V0IG9mIHJhbmdlIDAtJXUsIHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIsIE1BWF9QQUxFVFRFUyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBmb3IgKGogPSAwOyBqIDwgMjU2OyArK2opIHsKICAgICAgICBwRW50cmllc1tqXS5wZVJlZCAgID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVSZWQ7CiAgICAgICAgcEVudHJpZXNbal0ucGVHcmVlbiA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlR3JlZW47CiAgICAgICAgcEVudHJpZXNbal0ucGVCbHVlICA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlQmx1ZTsKICAgICAgICBwRW50cmllc1tqXS5wZUZsYWdzID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVGbGFnczsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q3VycmVudFRleHR1cmVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBQYWxldHRlTnVtYmVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKCBQYWxldHRlTnVtYmVyIDwgMCB8fCBQYWxldHRlTnVtYmVyID49IE1BWF9QQUxFVFRFUykgewogICAgICAgIFdBUk4oIiglcCkgOiAoJXUpIE91dCBvZiByYW5nZSAwLSV1LCByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyLCBNQVhfUEFMRVRURVMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLypUT0RPOiBzdGF0ZWJsb2NrcyAqLwogICAgVGhpcy0+Y3VycmVudFBhbGV0dGUgPSBQYWxldHRlTnVtYmVyOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UKiBQYWxldHRlTnVtYmVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpZiAoUGFsZXR0ZU51bWJlciA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLypUT0RPOiBzdGF0ZWJsb2NrcyAqLwogICAgKlBhbGV0dGVOdW1iZXIgPSBUaGlzLT5jdXJyZW50UGFsZXR0ZTsKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICAldVxuIiwgVGhpcywgKlBhbGV0dGVOdW1iZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIGJTb2Z0d2FyZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd0ZpeG1lcyA9IFRSVUU7CiAgICBpZiAoc2hvd0ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICAgICAgc2hvd0ZpeG1lcyA9IEZBTFNFOwogICAgfQoKICAgIFRoaXMtPnNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZyA9IGJTb2Z0d2FyZTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKc3RhdGljIEJPT0wgICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dGaXhtZXMgPSBUUlVFOwogICAgaWYgKHNob3dGaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgICAgIHNob3dGaXhtZXMgPSBGQUxTRTsKICAgIH0KICAgIHJldHVybiBUaGlzLT5zb2Z0d2FyZVZlcnRleFByb2Nlc3Npbmc7Cn0KCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0UmFzdGVyU3RhdHVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNEUkFTVEVSX1NUQVRVUyogcFJhc3RlclN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCkgOiAgU3dhcENoYWluICVkIHJldHVybmluZyAlcFxuIiwgVGhpcywgaVN3YXBDaGFpbiwgcFJhc3RlclN0YXR1cyk7CgogICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCAgaVN3YXBDaGFpbiwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgaWYoaHIgPT0gV0lORUQzRF9PSyl7CiAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXRSYXN0ZXJTdGF0dXMoc3dhcENoYWluLCBwUmFzdGVyU3RhdHVzKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9ZWxzZXsKICAgICAgICBGSVhNRSgiKCVwKSBJV2luZUQzRFN3YXBDaGFpbl9HZXRSYXN0ZXJTdGF0dXMgcmV0dXJuZWQgaW4gZXJyb3JcbiIsIFRoaXMpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE5QYXRjaE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBmbG9hdCBuU2VnbWVudHMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dmaXhtZXMgPSBUUlVFOwogICAgaWYoblNlZ21lbnRzICE9IDAuMGYpIHsKICAgICAgICBpZiggc2hvd2ZpeG1lcykgewogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWIgblNlZ21lbnRzKCVmKVxuIiwgVGhpcywgblNlZ21lbnRzKTsKICAgICAgICAgICAgc2hvd2ZpeG1lcyA9IEZBTFNFOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgZmxvYXQgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0TlBhdGNoTW9kZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dmaXhtZXMgPSBUUlVFOwogICAgaWYoIHNob3dmaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWIgcmV0dXJuaW5nKCVmKVxuIiwgVGhpcywgMC4wZik7CiAgICAgICAgc2hvd2ZpeG1lcyA9IEZBTFNFOwogICAgfQogICAgcmV0dXJuIDAuMGY7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVTdXJmYWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpwU291cmNlU3VyZmFjZSwgQ09OU1QgUkVDVCogcFNvdXJjZVJlY3QsIElXaW5lRDNEU3VyZmFjZSAqcERlc3RpbmF0aW9uU3VyZmFjZSwgQ09OU1QgUE9JTlQqIHBEZXN0UG9pbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgICAgICAgICA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiogVE9ETzogcmVtb3ZlIGNhc3RzIHRvIElXaW5lRDNEU3VyZmFjZUltcGwKICAgICAqICAgICAgIE5PVEU6IG1vdmUgY29kZSB0byBzdXJmYWNlIHRvIGFjY29tcGxpc2ggdGhpcwogICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqcFNyY1N1cmZhY2UgID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilwU291cmNlU3VyZmFjZTsKICAgIGludCBzcmNXaWR0aCwgc3JjSGVpZ2h0OwogICAgdW5zaWduZWQgaW50ICBzcmNTdXJmYWNlV2lkdGgsIHNyY1N1cmZhY2VIZWlnaHQsIGRlc3RTdXJmYWNlV2lkdGgsIGRlc3RTdXJmYWNlSGVpZ2h0OwogICAgV0lORUQzREZPUk1BVCBkZXN0Rm9ybWF0LCBzcmNGb3JtYXQ7CiAgICBVSU5UICAgICAgICAgIGRlc3RTaXplOwogICAgaW50IHNyY0xlZnQsIGRlc3RMZWZ0LCBkZXN0VG9wOwogICAgV0lORUQzRFBPT0wgICAgICAgc3JjUG9vbCwgZGVzdFBvb2w7CiAgICBpbnQgb2Zmc2V0ICAgID0gMDsKICAgIGludCByb3dvZmZzZXQgPSAwOyAvKiBob3cgbWFueSBieXRlcyB0byBhZGQgb250byB0aGUgZW5kIG9mIGEgcm93IHRvIHdyYXBhcm91bmQgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dCAqLwogICAgZ2xEZXNjcmlwdG9yICpnbERlc2NyaXB0aW9uID0gTlVMTDsKCiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDICB3aW5lZGVzYzsKCiAgICBUUkFDRSgiKCVwKSA6IFNvdXJjZSAoJXApICBSZWN0ICglcCkgRGVzdGluYXRpb24gKCVwKSBQb2ludCglcClcbiIsIFRoaXMsIHBTb3VyY2VTdXJmYWNlLCBwU291cmNlUmVjdCwgcERlc3RpbmF0aW9uU3VyZmFjZSwgcERlc3RQb2ludCk7CiAgICBtZW1zZXQoJndpbmVkZXNjLCAwLCBzaXplb2Yod2luZWRlc2MpKTsKICAgIHdpbmVkZXNjLldpZHRoICA9ICZzcmNTdXJmYWNlV2lkdGg7CiAgICB3aW5lZGVzYy5IZWlnaHQgPSAmc3JjU3VyZmFjZUhlaWdodDsKICAgIHdpbmVkZXNjLlBvb2wgICA9ICZzcmNQb29sOwogICAgd2luZWRlc2MuRm9ybWF0ID0gJnNyY0Zvcm1hdDsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwU291cmNlU3VyZmFjZSwgJndpbmVkZXNjKTsKCiAgICB3aW5lZGVzYy5XaWR0aCAgPSAmZGVzdFN1cmZhY2VXaWR0aDsKICAgIHdpbmVkZXNjLkhlaWdodCA9ICZkZXN0U3VyZmFjZUhlaWdodDsKICAgIHdpbmVkZXNjLlBvb2wgICA9ICZkZXN0UG9vbDsKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZkZXN0Rm9ybWF0OwogICAgd2luZWRlc2MuU2l6ZSAgID0gJmRlc3RTaXplOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgaWYoc3JjUG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0gIHx8IGRlc3RQb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQpewogICAgICAgIFdBUk4oInNvdXJjZSAlcCBtdXN0IGJlIFNZU1RFTU1FTSBhbmQgZGVzdCAlcCBtdXN0IGJlIERFRkFVTFQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBwU291cmNlU3VyZmFjZSwgcERlc3RpbmF0aW9uU3VyZmFjZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKGRlc3RGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDb252ZXJ0aW5nIGRlc3RpbmF0aW9uIHN1cmZhY2UgZnJvbSBXSU5FRDNERk1UX1VOS05PV04gdG8gdGhlIHNvdXJjZSBmb3JtYXRcbiIsIFRoaXMpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRGb3JtYXQocERlc3RpbmF0aW9uU3VyZmFjZSwgc3JjRm9ybWF0KTsKCiAgICAgICAgLyogR2V0IHRoZSB1cGRhdGUgc3VyZmFjZSBkZXNjcmlwdGlvbiAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZ3aW5lZGVzYyk7CiAgICB9CgogICAgRU5URVJfR0woKTsKCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgIH0KCiAgICAvKiBNYWtlIHN1cmUgdGhlIHN1cmZhY2UgaXMgbG9hZGVkIGFuZCB1cCB0byBkYXRlICovCiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChwRGVzdGluYXRpb25TdXJmYWNlKTsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0R2xEZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZnbERlc2NyaXB0aW9uKTsKCiAgICAvKiB0aGlzIG5lZWRzIHRvIGJlIGRvbmUgaW4gbGluZXMgaWYgdGhlIHNvdXJjZVJlY3QgIT0gdGhlIHNvdXJjZVdpZHRoICovCiAgICBzcmNXaWR0aCAgID0gcFNvdXJjZVJlY3QgPyBwU291cmNlUmVjdC0+cmlnaHQgLSBwU291cmNlUmVjdC0+bGVmdCAgIDogc3JjU3VyZmFjZVdpZHRoOwogICAgc3JjSGVpZ2h0ICA9IHBTb3VyY2VSZWN0ID8gcFNvdXJjZVJlY3QtPmJvdHRvbSAtIHBTb3VyY2VSZWN0LT50b3AgICA6IHNyY1N1cmZhY2VIZWlnaHQ7CiAgICBzcmNMZWZ0ICAgID0gcFNvdXJjZVJlY3QgPyBwU291cmNlUmVjdC0+bGVmdCA6IDA7CiAgICBkZXN0TGVmdCAgID0gcERlc3RQb2ludCAgPyBwRGVzdFBvaW50LT54IDogMDsKICAgIGRlc3RUb3AgICAgPSBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnkgOiAwOwoKCiAgICAvKiBUaGlzIGZ1bmN0aW9uIGRvZXNuJ3Qgc3VwcG9ydCBjb21wcmVzc2VkIHRleHR1cmVzCiAgICB0aGUgcGl0Y2ggaXMganVzdCBieXRlc1BlclBpeGVsICogd2lkdGggKi8KICAgIGlmKHNyY1dpZHRoICE9IHNyY1N1cmZhY2VXaWR0aCAgfHwgc3JjTGVmdCApewogICAgICAgIHJvd29mZnNldCA9IHNyY1N1cmZhY2VXaWR0aCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgICAgIG9mZnNldCAgICs9IHNyY0xlZnQgKiBwU3JjU3VyZmFjZS0+Ynl0ZXNQZXJQaXhlbDsKICAgICAgICAvKiBUT0RPOiBkbyB3ZSBldmVyIGdldCAzYnBwPywgd291bGQgYSBzaGlmdCBhbmQgYW4gYWRkIGJlIHF1aWNrZXIgdGhhbiBhIG11bCAod2VsbCBtYXliZSBhIGN5Y2xlIG9yIHR3bykgKi8KICAgIH0KICAgIC8qIFRPRE8gRFhUIGZvcm1hdHMgKi8KCiAgICBpZihwU291cmNlUmVjdCAhPSBOVUxMICYmIHBTb3VyY2VSZWN0LT50b3AgIT0gMCl7CiAgICAgICBvZmZzZXQgKz0gIHBTb3VyY2VSZWN0LT50b3AgKiBzcmNTdXJmYWNlV2lkdGggKiBwU3JjU3VyZmFjZS0+Ynl0ZXNQZXJQaXhlbDsKICAgIH0KICAgIFRSQUNFKCIoJXApIGdsVGV4U3ViSW1hZ2UyRCwgTGV2ZWwgJWQsIGxlZnQgJWQsIHRvcCAlZCwgd2lkdGggJWQsIGhlaWdodCAlZCAsIGZ0bSAlZCwgdHlwZSAlZCwgbWVtb3J5ICVwXG4iCiAgICAsVGhpcwogICAgLGdsRGVzY3JpcHRpb24tPmxldmVsCiAgICAsZGVzdExlZnQKICAgICxkZXN0VG9wCiAgICAsc3JjV2lkdGgKICAgICxzcmNIZWlnaHQKICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgLGdsRGVzY3JpcHRpb24tPmdsVHlwZQogICAgLElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKQogICAgKTsKCiAgICAvKiBTYW5pdHkgY2hlY2sgKi8KICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkgPT0gTlVMTCkgewoKICAgICAgICAvKiBuZWVkIHRvIGxvY2sgdGhlIHN1cmZhY2UgdG8gZ2V0IHRoZSBkYXRhICovCiAgICAgICAgRklYTUUoIlN1cmZhY2VzIGhhcyBubyBhbGxvY2F0ZWQgbWVtb3J5LCBidXQgc2hvdWxkIGJlIGFuIGluIG1lbW9yeSBvbmx5IHN1cmZhY2VcbiIpOwogICAgfQoKICAgIC8qIFRPRE86IEN1YmUgYW5kIHZvbHVtZSBzdXBwb3J0ICovCiAgICBpZihyb3dvZmZzZXQgIT0gMCl7CiAgICAgICAgLyogbm90IGEgd2hvbGUgcm93IHNvIHdlIGhhdmUgdG8gZG8gaXQgYSBsaW5lIGF0IGEgdGltZSAqLwogICAgICAgIGludCBqOwoKICAgICAgICAvKiBob3BlZnVsbHkgdXNpbmcgcG9pbnRlciBhZGR0aW9uIHdpbGwgYmUgcXVpY2tlciB0aGFuIHVzaW5nIGEgcG9pbnQgKyBqICogcm93b2Zmc2V0ICovCiAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciogZGF0YSA9KChjb25zdCB1bnNpZ25lZCBjaGFyICopSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKSArIG9mZnNldDsKCiAgICAgICAgZm9yKGogPSBkZXN0VG9wIDsgaiA8IChzcmNIZWlnaHQgKyBkZXN0VG9wKSA7IGorKyl7CgogICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxqCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLDEKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAgICAgICAgICAgICAgICAgLGRhdGEgLyogY291bGQgYmUgcXVpY2tlciB1c2luZyAqLwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgZGF0YSArPSByb3dvZmZzZXQ7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7IC8qIEZ1bGwgd2lkdGgsIHNvIGp1c3Qgd3JpdGUgb3V0IHRoZSB3aG9sZSB0ZXh0dXJlICovCgogICAgICAgIGlmIChXSU5FRDNERk1UX0RYVDEgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDIgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDMgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDQgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDUgPT0gZGVzdEZvcm1hdCkgewogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICAgICAgaWYgKGRlc3RTdXJmYWNlSGVpZ2h0ICE9IHNyY0hlaWdodCB8fCBkZXN0U3VyZmFjZVdpZHRoICE9IHNyY1dpZHRoKSB7CiAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IFRoZSBlYXN5IHdheSB0byBkbyB0aGlzIGlzIHRvIGxvY2sgdGhlIGRlc3RpbmF0aW9uLCBhbmQgY29weSB0aGUgYml0cyBhY3Jvc3MgKi8KICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVXBkYXRpbmcgcGFydCBvZiBhIGNvbXByZXNzZWQgdGV4dHVyZSBpcyBub3Qgc3VwcG9ydGVkIGF0IHRoZSBtb21lbnRcbiIpOwogICAgICAgICAgICAgICAgfSBpZiAoZGVzdEZvcm1hdCAhPSBzcmNGb3JtYXQpIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVXBkYXRpbmcgbWl4ZWQgZm9ybWF0IGNvbXByZXNzZWQgdGV4dHVyZSBpcyBub3QgY3VycmV0bHkgc3VwcG9ydFxuIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQikoZ2xEZXNjcmlwdGlvbi0+dGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsRGVzY3JpcHRpb24tPmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJBdHRlbXB0aW5nIHRvIHVwZGF0ZSBhIERYVCBjb21wcmVzc2VkIHRleHR1cmUgd2l0aG91dCBoYXJkd2FyZSBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgfQoKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxkZXN0VG9wCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLHNyY0hlaWdodAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbFR5cGUKICAgICAgICAgICAgICAgICAgICAsSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpCiAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhTdWJJbWFnZTJEIik7CgogICAgTEVBVkVfR0woKTsKCiAgICAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilwRGVzdGluYXRpb25TdXJmYWNlKS0+RmxhZ3MgJj0gflNGTEFHX0lOU1lTTUVNOwogICAgKChJV2luZUQzRFN1cmZhY2VJbXBsICopcERlc3RpbmF0aW9uU3VyZmFjZSktPkZsYWdzIHw9IFNGTEFHX0lOVEVYVFVSRTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKDApKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogSW1wbGVtZW50YXRpb24gZGV0YWlscyBhdCBodHRwOi8vZGV2ZWxvcGVyLm52aWRpYS5jb20vYXR0YWNoLzY0OTQKYW5kCmh0dHA6Ly9vc3Muc2dpLmNvbS9wcm9qZWN0cy9vZ2wtc2FtcGxlL3JlZ2lzdHJ5L05WL2V2YWx1YXRvcnMudHh0CmhtbS4uIG5vIGxvbmdlciBzdXBwb3J0ZWQgdXNlCk9wZW5HTCBldmFsdWF0b3JzIG9yICB0ZXNzZWxsYXRlIHN1cmZhY2VzIHdpdGhpbiB5b3VyIGFwcGxpY2F0aW9uLgoqLwoKLyogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2RlZmF1bHQuYXNwP3VybD0vbGlicmFyeS9lbi11cy9kaXJlY3R4OV9jL2RpcmVjdHgvZ3JhcGhpY3MvcmVmZXJlbmNlL2QzZC9pbnRlcmZhY2VzL2lkaXJlY3QzZGRldmljZTkvRHJhd1JlY3RQYXRjaC5hc3AgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUsIENPTlNUIGZsb2F0KiBwTnVtU2VncywgQ09OU1QgV0lORUQzRFJFQ1RQQVRDSF9JTkZPKiBwUmVjdFBhdGNoSW5mbykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKSBub1NlZ3MoJXApIHJlY3RwYXRjaCglcClcbiIsIFRoaXMsIEhhbmRsZSwgcE51bVNlZ3MsIHBSZWN0UGF0Y2hJbmZvKTsKICAgIEZJWE1FKCIoJXApIDogU3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCn0KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3JlZmVyZW5jZS9kM2QvaW50ZXJmYWNlcy9pZGlyZWN0M2RkZXZpY2U5L0RyYXdUcmlQYXRjaC5hc3AgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3VHJpUGF0Y2goSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEhhbmRsZSwgQ09OU1QgZmxvYXQqIHBOdW1TZWdzLCBDT05TVCBXSU5FRDNEVFJJUEFUQ0hfSU5GTyogcFRyaVBhdGNoSW5mbykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKSBub1NlZ3MoJXApIHRyaXBhdGNoKCVwKVxuIiwgVGhpcywgSGFuZGxlLCBwTnVtU2VncywgcFRyaVBhdGNoSW5mbyk7CiAgICBGSVhNRSgiKCVwKSA6IFN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRGVsZXRlUGF0Y2goSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEhhbmRsZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKVxuIiwgVGhpcywgSGFuZGxlKTsKICAgIEZJWE1FKCIoJXApIDogU3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIElXaW5lRDNEU3dhcENoYWluICpnZXRfc3dhcGNoYWluKElXaW5lRDNEU3VyZmFjZSAqdGFyZ2V0KSB7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIodGFyZ2V0LCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVVua25vd24gKilzd2FwY2hhaW4pOwogICAgICAgIHJldHVybiBzd2FwY2hhaW47CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkIGJpbmRfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSwgR0xlbnVtIHRhcmdldCwgR0x1aW50ICpmYm8pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoISpmYm8pIHsKICAgICAgICBHTF9FWFRDQUxMKGdsR2VuRnJhbWVidWZmZXJzRVhUKDEsIGZibykpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlbkZyYW1lYnVmZmVyc0VYVCgpIik7CiAgICB9CiAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKHRhcmdldCwgKmZibykpOwogICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKfQoKc3RhdGljIHZvaWQgYXR0YWNoX3N1cmZhY2VfZmJvKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgR0xlbnVtIGZib190YXJnZXQsIERXT1JEIGlkeCwgSVdpbmVEM0RTdXJmYWNlICpzdXJmYWNlKSB7CiAgICBjb25zdCBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlX2ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXN1cmZhY2U7CiAgICBHTGVudW0gdGV4dHRhcmdldCwgdGFyZ2V0OwogICAgR0xpbnQgb2xkX2JpbmRpbmc7CgogICAgdGV4dHRhcmdldCA9IHN1cmZhY2VfaW1wbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICB0YXJnZXQgPSB0ZXh0dGFyZ2V0ID09IEdMX1RFWFRVUkVfMkQgPyBHTF9URVhUVVJFXzJEIDogR0xfVEVYVFVSRV9DVUJFX01BUF9BUkI7CiAgICBnbEdldEludGVnZXJ2KHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCA/IEdMX1RFWFRVUkVfQklORElOR18yRCA6IEdMX1RFWFRVUkVfQklORElOR19DVUJFX01BUF9BUkIsICZvbGRfYmluZGluZyk7CgogICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoc3VyZmFjZSk7CgogICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9MSU5FQVIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9MSU5FQVIpOwogICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXQsIG9sZF9iaW5kaW5nKTsKCiAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoZmJvX3RhcmdldCwgR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4LCB0ZXh0dGFyZ2V0LCBzdXJmYWNlX2ltcGwtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUsIDApKTsKCiAgICBjaGVja0dMY2FsbCgiYXR0YWNoX3N1cmZhY2VfZmJvIik7Cn0KCnN0YXRpYyB2b2lkIGNvbG9yX2ZpbGxfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpzdXJmYWNlLCBDT05TVCBXSU5FRDNEUkVDVCAqcmVjdCwgV0lORUQzRENPTE9SIGNvbG9yKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKCiAgICBzd2FwY2hhaW4gPSBnZXRfc3dhcGNoYWluKHN1cmZhY2UpOwogICAgaWYgKHN3YXBjaGFpbikgewogICAgICAgIEdMZW51bSBidWZmZXI7CgogICAgICAgIFRSQUNFKCJTdXJmYWNlICVwIGlzIG9uc2NyZWVuXG4iLCBzdXJmYWNlKTsKCiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoc3VyZmFjZSwgc3dhcGNoYWluKTsKICAgICAgICBnbERyYXdCdWZmZXIoYnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgaXMgb2Zmc2NyZWVuXG4iLCBzdXJmYWNlKTsKICAgICAgICBiaW5kX2ZibyhpZmFjZSwgR0xfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZHN0X2Zibyk7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCwgc3VyZmFjZSk7CiAgICB9CgogICAgaWYgKHJlY3QpIHsKICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHJlY3QtPngxLCByZWN0LT55MSwgcmVjdC0+eDIgLSByZWN0LT54MSwgcmVjdC0+eTIgLSByZWN0LT55MSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHJlY3QtPngxLCAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzdXJmYWNlKS0+Y3VycmVudERlc2MuSGVpZ2h0IC0gcmVjdC0+eTIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC0+eDIgLSByZWN0LT54MSwgcmVjdC0+eTIgLSByZWN0LT55MSk7CiAgICAgICAgfQogICAgICAgIGNoZWNrR0xjYWxsKCJnbFNjaXNzb3IiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1NDSVNTT1JfVEVTVCk7CiAgICB9CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRSkpOwoKICAgIGdsQ29sb3JNYXNrKEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRSkpOwoKICAgIGdsQ2xlYXJDb2xvcihEM0RDT0xPUl9SKGNvbG9yKSwgRDNEQ09MT1JfRyhjb2xvciksIEQzRENPTE9SX0IoY29sb3IpLCBEM0RDT0xPUl9BKGNvbG9yKSk7CiAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOwogICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRGcmFtZWJ1ZmZlcigpIik7CiAgICB9CgogICAgaWYgKHN3YXBjaGFpbiAmJiBzdXJmYWNlID09ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopc3dhcGNoYWluKS0+ZnJvbnRCdWZmZXIKICAgICAgICAgICAgJiYgKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilzd2FwY2hhaW4pLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NvbG9yRmlsbChJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcFN1cmZhY2UsIENPTlNUIFdJTkVEM0RSRUNUKiBwUmVjdCwgV0lORUQzRENPTE9SIGNvbG9yKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZmFjZSA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHBTdXJmYWNlOwogICAgV0lORUREQkxURlggQmx0Rng7CiAgICBUUkFDRSgiKCVwKSBDb2xvdXIgZmlsbCBTdXJmYWNlOiAlcCByZWN0OiAlcCBjb2xvcjogMHglMDh4XG4iLCBUaGlzLCBwU3VyZmFjZSwgcFJlY3QsIGNvbG9yKTsKCiAgICBpZiAoc3VyZmFjZS0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUICYmIHN1cmZhY2UtPnJlc291cmNlLnBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNKSB7CiAgICAgICAgRklYTUUoImNhbGwgdG8gY29sb3JmaWxsIHdpdGggbm9uIFdJTkVEM0RQT09MX0RFRkFVTFQgb3IgV0lORUQzRFBPT0xfU1lTVEVNTUVNIHN1cmZhY2VcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPKSB7CiAgICAgICAgY29sb3JfZmlsbF9mYm8oaWZhY2UsIHBTdXJmYWNlLCBwUmVjdCwgY29sb3IpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBKdXN0IGZvcndhcmQgdGhpcyB0byB0aGUgRGlyZWN0RHJhdyBibGl0dGluZyBlbmdpbmUgKi8KICAgICAgICBtZW1zZXQoJkJsdEZ4LCAwLCBzaXplb2YoQmx0RngpKTsKICAgICAgICBCbHRGeC5kd1NpemUgPSBzaXplb2YoQmx0RngpOwogICAgICAgIEJsdEZ4LnU1LmR3RmlsbENvbG9yID0gY29sb3I7CiAgICAgICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9CbHQocFN1cmZhY2UsIChSRUNUICopIHBSZWN0LCBOVUxMLCBOVUxMLCBXSU5FRERCTFRfQ09MT1JGSUxMLCAmQmx0RngsIFdJTkVEM0RURVhGX05PTkUpOwogICAgfQp9CgovKiByZW5kZXJ0YXJnZXQgYW5kIGRlcHR0aCBzdGVuY2lsIGZ1bmN0aW9ucyAqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlKiBpZmFjZSxEV09SRCBSZW5kZXJUYXJnZXRJbmRleCwgSVdpbmVEM0RTdXJmYWNlICoqcHBSZW5kZXJUYXJnZXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPj0gR0xfTElNSVRTKGJ1ZmZlcnMpKSB7CiAgICAgICAgRVJSKCIoJXApIDogT25seSAlZCByZW5kZXIgdGFyZ2V0cyBhcmUgc3VwcG9ydGVkLlxuIiwgVGhpcywgR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAqcHBSZW5kZXJUYXJnZXQgPSBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF07CiAgICBUUkFDRSgiKCVwKSA6IFJlbmRlclRhcmdldCAlZCBJbmRleCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCAqcHBSZW5kZXJUYXJnZXQpOwogICAgLyogTm90ZSBpbmMgcmVmIG9uIHJldHVybmVkIHN1cmZhY2UgKi8KICAgIGlmKCpwcFJlbmRlclRhcmdldCAhPSBOVUxMKQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKnBwUmVuZGVyVGFyZ2V0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKkZyb250LCBJV2luZUQzRFN1cmZhY2UgKkJhY2spIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKkZyb250SW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIEZyb250OwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqQmFja0ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBCYWNrOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpTd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBGcm9udEltcGwsIEJhY2tJbXBsKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbihpZmFjZSwgMCwgKElXaW5lRDNEU3dhcENoYWluICoqKSAmU3dhcGNoYWluKTsKICAgIGlmKGhyICE9IFdJTkVEM0RfT0spIHsKICAgICAgICBFUlIoIkNhbid0IGdldCB0aGUgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogTWFrZSBzdXJlIHRvIHJlbGVhc2UgdGhlIHN3YXBjaGFpbiAqLwogICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgU3dhcGNoYWluKTsKCiAgICBpZihGcm9udEltcGwgJiYgIShGcm9udEltcGwtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSB7CiAgICAgICAgRVJSKCJUcnlpbmcgdG8gc2V0IGEgZnJvbnQgYnVmZmVyIHdoaWNoIGRvZXNuJ3QgaGF2ZSBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHVzYWdlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGVsc2UgaWYoQmFja0ltcGwgJiYgIShCYWNrSW1wbC0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSkgewogICAgICAgIEVSUigiVHJ5aW5nIHRvIHNldCBhIGJhY2sgYnVmZmVyIHdoaWNoIGRvZXNuJ3QgaGF2ZSBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHVzYWdlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihTd2FwY2hhaW4tPmZyb250QnVmZmVyICE9IEZyb250KSB7CiAgICAgICAgVFJBQ0UoIkNoYW5naW5nIHRoZSBmcm9udCBidWZmZXIgZnJvbSAlcCB0byAlcFxuIiwgU3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgRnJvbnQpOwoKICAgICAgICBpZihTd2FwY2hhaW4tPmZyb250QnVmZmVyKQogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIE5VTEwpOwogICAgICAgIFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgPSBGcm9udDsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIChJV2luZUQzREJhc2UgKikgU3dhcGNoYWluKTsKICAgICAgICB9CiAgICB9CgogICAgaWYoQmFjayAmJiAhU3dhcGNoYWluLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgLyogV2UgbmVlZCBtZW1vcnkgZm9yIHRoZSBiYWNrIGJ1ZmZlciBhcnJheSAtIG9ubHkgb25lIGJhY2sgYnVmZmVyIHRoaXMgd2F5ICovCiAgICAgICAgU3dhcGNoYWluLT5iYWNrQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikpOwogICAgICAgIGlmKCFTd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgfQogICAgfQoKICAgIGlmKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSAhPSBCYWNrKSB7CiAgICAgICAgVFJBQ0UoIkNoYW5naW5nIHRoZSBiYWNrIGJ1ZmZlciBmcm9tICVwIHRvICVwXG4iLCBTd2FwY2hhaW4tPmJhY2tCdWZmZXIsIEJhY2spOwoKICAgICAgICAvKiBXaGF0IHRvIGRvIGFib3V0IHRoZSBjb250ZXh0IGhlcmUgaW4gdGhlIGNhc2Ugb2YgbXVsdGl0aHJlYWRpbmc/IE5vdCBzdXJlLgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IElEaXJlY3QzRDc6OkNyZWF0ZURldmljZSBzbyBpbiB0aGVvcnkgaXRzIGluaXRpYWxpemF0aW9uIGNvZGUKICAgICAgICAgKi8KICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGlmKCFTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAgICAgLyogR0wgd2FzIHRvbGQgdG8gZHJhdyB0byB0aGUgZnJvbnQgYnVmZmVyIGF0IGNyZWF0aW9uLAogICAgICAgICAgICAgKiB1bmRvIHRoYXQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgICAgICAvKiBTZXQgdGhlIGJhY2tidWZmZXIgY291bnQgdG8gMSBiZWNhdXNlIG90aGVyIGNvZGUgdXNlcyBpdCB0byBmaW5nIHRoZSBiYWNrIGJ1ZmZlcnMgKi8KICAgICAgICAgICAgU3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50ID0gMTsKICAgICAgICB9IGVsc2UgaWYgKCFCYWNrKSB7CiAgICAgICAgICAgIC8qIFRoYXQgbWFrZXMgcHJvYmxlbXMgLSBkaXNhYmxlIGZvciBub3cgKi8KICAgICAgICAgICAgLyogZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsgKi8KICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICAgICAgLyogV2UgaGF2ZSBsb3N0IG91ciBiYWNrIGJ1ZmZlciwgc2V0IHRoaXMgdG8gMCB0byBhdm9pZCBjb25mdXNpbmcgb3RoZXIgY29kZSAqLwogICAgICAgICAgICBTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQgPSAwOwogICAgICAgIH0KICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICBpZihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdLCBOVUxMKTsKICAgICAgICBTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gPSBCYWNrOwoKICAgICAgICBpZihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0sIChJV2luZUQzREJhc2UgKikgU3dhcGNoYWluKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBTd2FwY2hhaW4tPmJhY2tCdWZmZXIpOwogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXB0aFN0ZW5jaWxTdXJmYWNlKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgSVdpbmVEM0RTdXJmYWNlICoqcHBaU3RlbmNpbFN1cmZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgICpwcFpTdGVuY2lsU3VyZmFjZSA9IFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlcjsKICAgIFRSQUNFKCIoJXApIDogelN0ZW5jaWxTdXJmYWNlICByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICAqcHBaU3RlbmNpbFN1cmZhY2UpOwoKICAgIGlmKCpwcFpTdGVuY2lsU3VyZmFjZSAhPSBOVUxMKSB7CiAgICAgICAgLyogTm90ZSBpbmMgcmVmIG9uIHJldHVybmVkIHN1cmZhY2UgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCpwcFpTdGVuY2lsU3VyZmFjZSk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogSGFuZGxlIHN0ZW5jaWwgYXR0YWNobWVudHMgKi8Kc3RhdGljIHZvaWQgc2V0X2RlcHRoX3N0ZW5jaWxfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpkZXB0aF9zdGVuY2lsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpkZXB0aF9zdGVuY2lsX2ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWRlcHRoX3N0ZW5jaWw7CgogICAgVFJBQ0UoIlNldCBkZXB0aCBzdGVuY2lsIHRvICVwXG4iLCBkZXB0aF9zdGVuY2lsKTsKCiAgICBpZiAoZGVwdGhfc3RlbmNpbF9pbXBsKSB7CiAgICAgICAgaWYgKGRlcHRoX3N0ZW5jaWxfaW1wbC0+Y3VycmVudF9yZW5kZXJidWZmZXIpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyUmVuZGVyYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIEdMX1JFTkRFUkJVRkZFUl9FWFQsIGRlcHRoX3N0ZW5jaWxfaW1wbC0+Y3VycmVudF9yZW5kZXJidWZmZXItPmlkKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZyYW1lYnVmZmVyUmVuZGVyYnVmZmVyRVhUKCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBHTGVudW0gdGV4dHRhcmdldCwgdGFyZ2V0OwogICAgICAgICAgICBHTGludCBvbGRfYmluZGluZyA9IDA7CgogICAgICAgICAgICB0ZXh0dGFyZ2V0ID0gZGVwdGhfc3RlbmNpbF9pbXBsLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgICAgICAgICAgdGFyZ2V0ID0gdGV4dHRhcmdldCA9PSBHTF9URVhUVVJFXzJEID8gR0xfVEVYVFVSRV8yRCA6IEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCOwogICAgICAgICAgICBnbEdldEludGVnZXJ2KHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCA/IEdMX1RFWFRVUkVfQklORElOR18yRCA6IEdMX1RFWFRVUkVfQklORElOR19DVUJFX01BUF9BUkIsICZvbGRfYmluZGluZyk7CgogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChkZXB0aF9zdGVuY2lsKTsKCiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0YXJnZXQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0YXJnZXQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0YXJnZXQsIEdMX0RFUFRIX1RFWFRVUkVfTU9ERV9BUkIsIEdMX0xVTUlOQU5DRSk7CiAgICAgICAgICAgIGdsQmluZFRleHR1cmUodGFyZ2V0LCBvbGRfYmluZGluZyk7CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCBHTF9ERVBUSF9BVFRBQ0hNRU5UX0VYVCwgdGV4dHRhcmdldCwgZGVwdGhfc3RlbmNpbF9pbXBsLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCAwKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKCkiKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIEdMX0RFUFRIX0FUVEFDSE1FTlRfRVhULCBHTF9URVhUVVJFXzJELCAwLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzZXRfcmVuZGVyX3RhcmdldF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBpZHgsIElXaW5lRDNEU3VyZmFjZSAqcmVuZGVyX3RhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqcnRpbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilyZW5kZXJfdGFyZ2V0OwoKICAgIFRSQUNFKCJTZXQgcmVuZGVyIHRhcmdldCAldSB0byAlcFxuIiwgaWR4LCByZW5kZXJfdGFyZ2V0KTsKCiAgICBpZiAocnRpbXBsKSB7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgaWR4LCByZW5kZXJfdGFyZ2V0KTsKICAgICAgICBUaGlzLT5kcmF3X2J1ZmZlcnNbaWR4XSA9IEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCArIGlkeDsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4LCBHTF9URVhUVVJFXzJELCAwLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwoKICAgICAgICBUaGlzLT5kcmF3X2J1ZmZlcnNbaWR4XSA9IEdMX05PTkU7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGNoZWNrX2Zib19zdGF0dXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBHTGVudW0gc3RhdHVzOwoKICAgIHN0YXR1cyA9IEdMX0VYVENBTEwoZ2xDaGVja0ZyYW1lYnVmZmVyU3RhdHVzRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCkpOwogICAgaWYgKHN0YXR1cyA9PSBHTF9GUkFNRUJVRkZFUl9DT01QTEVURV9FWFQpIHsKICAgICAgICBUUkFDRSgiRkJPIGNvbXBsZXRlXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoIkZCTyBzdGF0dXMgJXMgKCUjeClcbiIsIGRlYnVnX2Zib3N0YXR1cyhzdGF0dXMpLCBzdGF0dXMpOwoKICAgICAgICAvKiBEdW1wIHRoZSBGQk8gYXR0YWNobWVudHMgKi8KICAgICAgICBpZiAoc3RhdHVzID09IEdMX0ZSQU1FQlVGRkVSX1VOU1VQUE9SVEVEX0VYVCkgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsICphdHRhY2htZW50OwogICAgICAgICAgICBpbnQgaTsKCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICAgICAgYXR0YWNobWVudCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzW2ldOwogICAgICAgICAgICAgICAgaWYgKGF0dGFjaG1lbnQpIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiXHRDb2xvciBhdHRhY2htZW50ICVkOiAoJXApICVzICV1eCV1XG4iLCBpLCBhdHRhY2htZW50LCBkZWJ1Z19kM2Rmb3JtYXQoYXR0YWNobWVudC0+cmVzb3VyY2UuZm9ybWF0KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnQtPnBvdzJXaWR0aCwgYXR0YWNobWVudC0+cG93MkhlaWdodCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXR0YWNobWVudCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+ZmJvX2RlcHRoX2F0dGFjaG1lbnQ7CiAgICAgICAgICAgIGlmIChhdHRhY2htZW50KSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiXHREZXB0aCBhdHRhY2htZW50OiAoJXApICVzICV1eCV1XG4iLCBhdHRhY2htZW50LCBkZWJ1Z19kM2Rmb3JtYXQoYXR0YWNobWVudC0+cmVzb3VyY2UuZm9ybWF0KSwKICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudC0+cG93MldpZHRoLCBhdHRhY2htZW50LT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIEJPT0wgZGVwdGhfbWlzbWF0Y2hfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqcnRfaW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF07CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpkc19pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwoKICAgIGlmICghZHNfaW1wbCkgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChkc19pbXBsLT5jdXJyZW50X3JlbmRlcmJ1ZmZlcikgewogICAgICAgIHJldHVybiAocnRfaW1wbC0+cG93MldpZHRoICE9IGRzX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyLT53aWR0aCB8fAogICAgICAgICAgICAgICAgcnRfaW1wbC0+cG93MkhlaWdodCAhPSBkc19pbXBsLT5jdXJyZW50X3JlbmRlcmJ1ZmZlci0+aGVpZ2h0KTsKICAgIH0KCiAgICByZXR1cm4gKHJ0X2ltcGwtPnBvdzJXaWR0aCAhPSBkc19pbXBsLT5wb3cyV2lkdGggfHwKICAgICAgICAgICAgcnRfaW1wbC0+cG93MkhlaWdodCAhPSBkc19pbXBsLT5wb3cySGVpZ2h0KTsKfQoKdm9pZCBhcHBseV9mYm9fc3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwoKICAgICAgICAvKiBBcHBseSByZW5kZXIgdGFyZ2V0cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKnJlbmRlcl90YXJnZXQgPSBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tpXTsKICAgICAgICAgICAgaWYgKFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSAhPSByZW5kZXJfdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBzZXRfcmVuZGVyX3RhcmdldF9mYm8oaWZhY2UsIGksIHJlbmRlcl90YXJnZXQpOwogICAgICAgICAgICAgICAgVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzW2ldID0gcmVuZGVyX3RhcmdldDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogQXBwbHkgZGVwdGggdGFyZ2V0cyAqLwogICAgICAgIGlmIChUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0IHx8IGRlcHRoX21pc21hdGNoX2ZibyhpZmFjZSkpIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHcgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPnBvdzJXaWR0aDsKICAgICAgICAgICAgdW5zaWduZWQgaW50IGggPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPnBvdzJIZWlnaHQ7CgogICAgICAgICAgICBpZiAoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgICAgICAgICAgc3VyZmFjZV9zZXRfY29tcGF0aWJsZV9yZW5kZXJidWZmZXIoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCwgdywgaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0X2RlcHRoX3N0ZW5jaWxfZmJvKGlmYWNlLCBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgICAgICAgICAgVGhpcy0+ZmJvX2RlcHRoX2F0dGFjaG1lbnQgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX0RSQVdfQlVGRkVSUykpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERyYXdCdWZmZXJzQVJCKEdMX0xJTUlUUyhidWZmZXJzKSwgVGhpcy0+ZHJhd19idWZmZXJzKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXJzKCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoVGhpcy0+ZHJhd19idWZmZXJzWzBdKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgfQoKICAgIGNoZWNrX2Zib19zdGF0dXMoaWZhY2UpOwp9Cgp2b2lkIHN0cmV0Y2hfcmVjdF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnNyY19zdXJmYWNlLCBXSU5FRDNEUkVDVCAqc3JjX3JlY3QsCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkc3Rfc3VyZmFjZSwgV0lORUQzRFJFQ1QgKmRzdF9yZWN0LCBjb25zdCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgZmlsdGVyLCBCT09MIGZsaXApIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEdMYml0ZmllbGQgbWFzayA9IEdMX0NPTE9SX0JVRkZFUl9CSVQ7IC8qIFRPRE86IFN1cHBvcnQgYmxpdHRpbmcgZGVwdGgvc3RlbmNpbCBzdXJmYWNlcyAqLwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnNyY19zd2FwY2hhaW4sICpkc3Rfc3dhcGNoYWluOwogICAgR0xlbnVtIGdsX2ZpbHRlcjsKCiAgICBUUkFDRSgiKCVwKSA6IHNyY19zdXJmYWNlICVwLCBzcmNfcmVjdCAlcCwgZHN0X3N1cmZhY2UgJXAsIGRzdF9yZWN0ICVwLCBmaWx0ZXIgJXMgKDB4JTA4eCksIGZsaXAgJXVcbiIsCiAgICAgICAgICAgIFRoaXMsIHNyY19zdXJmYWNlLCBzcmNfcmVjdCwgZHN0X3N1cmZhY2UsIGRzdF9yZWN0LCBkZWJ1Z19kM2R0ZXh0dXJlZmlsdGVydHlwZShmaWx0ZXIpLCBmaWx0ZXIsIGZsaXApOwogICAgVFJBQ0UoInNyY19yZWN0IFsldSwgJXVdLT5bJXUsICV1XVxuIiwgc3JjX3JlY3QtPngxLCBzcmNfcmVjdC0+eTEsIHNyY19yZWN0LT54Miwgc3JjX3JlY3QtPnkyKTsKICAgIFRSQUNFKCJkc3RfcmVjdCBbJXUsICV1XS0+WyV1LCAldV1cbiIsIGRzdF9yZWN0LT54MSwgZHN0X3JlY3QtPnkxLCBkc3RfcmVjdC0+eDIsIGRzdF9yZWN0LT55Mik7CgogICAgZ2xEaXNhYmxlKEdMX1NDSVNTT1JfVEVTVCk7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRSkpOwoKICAgIHN3aXRjaCAoZmlsdGVyKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9MSU5FQVI6CiAgICAgICAgICAgIGdsX2ZpbHRlciA9IEdMX0xJTkVBUjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCBmaWx0ZXIgbW9kZSAlcyAoMHglMDh4KVxuIiwgZGVidWdfZDNkdGV4dHVyZWZpbHRlcnR5cGUoZmlsdGVyKSwgZmlsdGVyKTsKICAgICAgICBjYXNlIFdJTkVEM0RURVhGX05PTkU6CiAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9QT0lOVDoKICAgICAgICAgICAgZ2xfZmlsdGVyID0gR0xfTkVBUkVTVDsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyogQXR0YWNoIHNyYyBzdXJmYWNlIHRvIHNyYyBmYm8gKi8KICAgIHNyY19zd2FwY2hhaW4gPSBnZXRfc3dhcGNoYWluKHNyY19zdXJmYWNlKTsKICAgIGlmIChzcmNfc3dhcGNoYWluKSB7CiAgICAgICAgR0xlbnVtIGJ1ZmZlcjsKCiAgICAgICAgVFJBQ0UoIlNvdXJjZSBzdXJmYWNlICVwIGlzIG9uc2NyZWVuXG4iLCBzcmNfc3VyZmFjZSk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfUkVBRF9GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoc3JjX3N1cmZhY2UsIHNyY19zd2FwY2hhaW4pOwogICAgICAgIGdsUmVhZEJ1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoKSIpOwoKICAgICAgICBzcmNfcmVjdC0+eTEgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzcmNfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyY19yZWN0LT55MTsKICAgICAgICBzcmNfcmVjdC0+eTIgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzcmNfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyY19yZWN0LT55MjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlNvdXJjZSBzdXJmYWNlICVwIGlzIG9mZnNjcmVlblxuIiwgc3JjX3N1cmZhY2UpOwogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9SRUFEX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPnNyY19mYm8pOwogICAgICAgIGF0dGFjaF9zdXJmYWNlX2ZibyhUaGlzLCBHTF9SRUFEX0ZSQU1FQlVGRkVSX0VYVCwgMCwgc3JjX3N1cmZhY2UpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9DT0xPUl9BVFRBQ0hNRU5UMF9FWFQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoKSIpOwogICAgfQoKICAgIC8qIEF0dGFjaCBkc3Qgc3VyZmFjZSB0byBkc3QgZmJvICovCiAgICBkc3Rfc3dhcGNoYWluID0gZ2V0X3N3YXBjaGFpbihkc3Rfc3VyZmFjZSk7CiAgICBpZiAoZHN0X3N3YXBjaGFpbikgewogICAgICAgIEdMZW51bSBidWZmZXI7CgogICAgICAgIFRSQUNFKCJEZXN0aW5hdGlvbiBzdXJmYWNlICVwIGlzIG9uc2NyZWVuXG4iLCBkc3Rfc3VyZmFjZSk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRFJBV19GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoZHN0X3N1cmZhY2UsIGRzdF9zd2FwY2hhaW4pOwogICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwoKICAgICAgICBkc3RfcmVjdC0+eTEgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilkc3Rfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIGRzdF9yZWN0LT55MTsKICAgICAgICBkc3RfcmVjdC0+eTIgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilkc3Rfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIGRzdF9yZWN0LT55MjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkRlc3RpbmF0aW9uIHN1cmZhY2UgJXAgaXMgb2Zmc2NyZWVuXG4iLCBkc3Rfc3VyZmFjZSk7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0RSQVdfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZHN0X2Zibyk7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX0RSQVdfRlJBTUVCVUZGRVJfRVhULCAwLCBkc3Rfc3VyZmFjZSk7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICB9CgogICAgaWYgKGZsaXApIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmxpdEZyYW1lYnVmZmVyRVhUKHNyY19yZWN0LT54MSwgc3JjX3JlY3QtPnkxLCBzcmNfcmVjdC0+eDIsIHNyY19yZWN0LT55MiwKICAgICAgICAgICAgICAgIGRzdF9yZWN0LT54MSwgZHN0X3JlY3QtPnkyLCBkc3RfcmVjdC0+eDIsIGRzdF9yZWN0LT55MSwgbWFzaywgZ2xfZmlsdGVyKSk7CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCbGl0RnJhbWVidWZmZXJFWFQoc3JjX3JlY3QtPngxLCBzcmNfcmVjdC0+eTEsIHNyY19yZWN0LT54Miwgc3JjX3JlY3QtPnkyLAogICAgICAgICAgICAgICAgZHN0X3JlY3QtPngxLCBkc3RfcmVjdC0+eTEsIGRzdF9yZWN0LT54MiwgZHN0X3JlY3QtPnkyLCBtYXNrLCBnbF9maWx0ZXIpKTsKICAgIH0KCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRGcmFtZWJ1ZmZlcigpIik7CiAgICB9CgogICAgLyogSWYgd2Ugc3dpdGNoZWQgZnJvbSBHTF9CQUNLIHRvIEdMX0ZST05UIGFib3ZlLCB3ZSBuZWVkIHRvIHN3aXRjaCBiYWNrIGhlcmUgKi8KICAgIGlmIChkc3Rfc3dhcGNoYWluICYmIGRzdF9zdXJmYWNlID09ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopZHN0X3N3YXBjaGFpbiktPmZyb250QnVmZmVyCiAgICAgICAgICAgICYmICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopZHN0X3N3YXBjaGFpbiktPmJhY2tCdWZmZXIpIHsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgUmVuZGVyVGFyZ2V0SW5kZXgsIElXaW5lRDNEU3VyZmFjZSAqcFJlbmRlclRhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRFZJRVdQT1JUIHZpZXdwb3J0OwoKICAgIFRSQUNFKCIoJXApIDogU2V0dGluZyByZW5kZXJ0YXJnZXQgJWQgdG8gJXBcbiIsIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCBwUmVuZGVyVGFyZ2V0KTsKCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPj0gR0xfTElNSVRTKGJ1ZmZlcnMpKSB7CiAgICAgICAgRVJSKCIoJXApIDogT25seSAlZCByZW5kZXIgdGFyZ2V0cyBhcmUgc3VwcG9ydGVkLlxuIiwgVGhpcywgR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBNU0ROIHNheXMgdGhhdCBudWxsIGRpc2FibGVzIHRoZSByZW5kZXIgdGFyZ2V0CiAgICBidXQgYSBkZXZpY2UgbXVzdCBhbHdheXMgYmUgYXNzb2NpYXRlZCB3aXRoIGEgcmVuZGVyIHRhcmdldAogICAgbm9wZSBNU0ROIHNheXMgdGhhdCB3ZSByZXR1cm4gaW52YWxpZCBjYWxsIHRvIGEgbnVsbCByZW5kZXJ0YXJnZXQgd2l0aCBhbiBpbmRleCBvZiAwCgogICAgc2VlIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvQWR2YW5jZWRUb3BpY3MvUGl4ZWxQaXBlL011bHRpcGxlUmVuZGVyVGFyZ2V0LmFzcAogICAgZm9yIG1vcmUgZGV0YWlscwogICAgKi8KICAgIGlmIChSZW5kZXJUYXJnZXRJbmRleCA9PSAwICYmIHBSZW5kZXJUYXJnZXQgPT0gTlVMTCkgewogICAgICAgIEZJWE1FKCJUcnlpbmcgdG8gc2V0IHJlbmRlciB0YXJnZXQgMCB0byBOVUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGlmIChwUmVuZGVyVGFyZ2V0ICYmICEoKElXaW5lRDNEU3VyZmFjZUltcGwgKilwUmVuZGVyVGFyZ2V0KS0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgRklYTUUoIiglcClUcnlpbmcgdG8gc2V0IHRoZSByZW5kZXIgdGFyZ2V0IHRvIGEgc3VyZmFjZSglcCkgdGhhdCB3YXNuJ3QgY3JlYXRlZCB3aXRoIGEgdXNhZ2Ugb2YgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVFxuIixUaGlzICxwUmVuZGVyVGFyZ2V0KTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBJZiB3ZSBhcmUgdHJ5aW5nIHRvIHNldCB3aGF0IHdlIGFscmVhZHkgaGF2ZSwgZG9uJ3QgYm90aGVyICovCiAgICBpZiAocFJlbmRlclRhcmdldCA9PSBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0pIHsKICAgICAgICBUUkFDRSgiVHJ5aW5nIHRvIGRvIGEgTk9QIFNldFJlbmRlclRhcmdldCBvcGVyYXRpb25cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQogICAgaWYocFJlbmRlclRhcmdldCkgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihwUmVuZGVyVGFyZ2V0KTsKICAgIGlmKFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSkgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdKTsKICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSA9IHBSZW5kZXJUYXJnZXQ7CgogICAgLyogUmVuZGVyIHRhcmdldCAwIGlzIHNwZWNpYWwgKi8KICAgIGlmKFJlbmRlclRhcmdldEluZGV4ID09IDApIHsKICAgICAgICAvKiBGaW5hbGx5LCByZXNldCB0aGUgdmlld3BvcnQgYXMgdGhlIE1TRE4gc3RhdGVzLiAqLwogICAgICAgIHZpZXdwb3J0LkhlaWdodCA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIHZpZXdwb3J0LldpZHRoICA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgdmlld3BvcnQuWCAgICAgID0gMDsKICAgICAgICB2aWV3cG9ydC5ZICAgICAgPSAwOwogICAgICAgIHZpZXdwb3J0Lk1heFogICA9IDEuMGY7CiAgICAgICAgdmlld3BvcnQuTWluWiAgID0gMC4wZjsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0Vmlld3BvcnQoaWZhY2UsICZ2aWV3cG9ydCk7CiAgICAgICAgLyogTWFrZSBzdXJlIHRoZSB2aWV3cG9ydCBzdGF0ZSBpcyBkaXJ0eSwgYmVjYXVzZSB0aGUgcmVuZGVyX29mZnNjcmVlbiB0aGluZyBhZmZlY3RzIGl0LgogICAgICAgICAqIFNldFZpZXdwb3J0IG1heSBjYXRjaCBOT1Agdmlld3BvcnQgY2hhbmdlcywgd2hpY2ggd291bGQgb2NjdXIgd2hlbiBzd2l0Y2hpbmcgYmV0d2VlbiBlcXVhbGx5IHNpemVkIHRhcmdldHMKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVklFV1BPUlQpOwoKICAgICAgICAvKiBBY3RpdmF0ZSB0aGUgbmV3IHJlbmRlciB0YXJnZXQgZm9yIG5vdy4gVGhpcyBzaG91bGRuJ3Qgc3RheSBoZXJlLCBidXQgaXMgbmVlZGVkIHVudGlsIGFsbCBtZXRob2RzIHVzaW5nIGdsIGFjdGl2YXRlIHRoZQogICAgICAgICAqIGN0eCBwcm9wZXJseS4KICAgICAgICAgKiBVc2UgcmVzb3VyY2Vsb2FkIHVzYWdlLCB0aGlzIHdpbGwganVzdCBzZXQgdGhlIGRyYXdhYmxlcyBhbmQgY29udGV4dCBidXQgbm90IGFwcGx5IGFueSBzdGF0ZXMuIFRoZSBzdGF0ZWJsb2NrIG1heSBiZQogICAgICAgICAqIGluY29tcGxldGUgb3IgaW5jb3JyZWN0IHdoZW4gU2V0UmVuZGVyVGFyZ2V0IGlzIGNhbGxlZC4gRHJhd1ByaW0oKSB3aWxsIGFwcGx5IHRoZSBzdGF0ZXMgd2hlbiBpdCBpcyBjYWxsZWQuCiAgICAgICAgICovCiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdLCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcE5ld1pTdGVuY2lsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBIUkVTVUxUICBociA9IFdJTkVEM0RfT0s7CiAgICBJV2luZUQzRFN1cmZhY2UgKnRtcDsKCiAgICBUUkFDRSgiKCVwKSBTd2FwcGluZyB6LWJ1ZmZlclxuIixUaGlzKTsKCiAgICBpZiAocE5ld1pTdGVuY2lsID09IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpIHsKICAgICAgICBUUkFDRSgiVHJ5aW5nIHRvIGRvIGEgTk9QIFNldFJlbmRlclRhcmdldCBvcGVyYXRpb25cbiIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiogT3BlbkdMIGRvZXNuJ3Qgc3VwcG9ydCAnc2hhcmluZycgb2YgdGhlIHN0ZW5jaWxCdWZmZXIgc28gd2UgbWF5IGluY3VyZSBhbiBleHRyYSBtZW1vcnkgb3ZlcmhlYWQKICAgICAgICAqIGRlcGVuZGluZyBvbiB0aGUgcmVudGVyIHRhcmdldCBpbXBsZW1lbnRhdGlvbiBiZWluZyB1c2VkLgogICAgICAgICogQSBzaGFyZWQgY29udGV4dCBpbXBsZW1lbnRhdGlvbiB3aWxsIHNoYXJlIGFsbCBidWZmZXJzIGJldHdlZW4gYWxsIHJlbmRlcnRhcmdldHMgKGluY2x1ZGluZyBzd2FwY2hhaW5zKSwKICAgICAgICAqIGltcGxlbWVudGF0aW9ucyB0aGF0IHVzZSBzZXBhcmF0ZSBwYnVmZmVycyBmb3IgZGlmZmVyZW50IHN3YXBjaGFpbnMgb3IgcmVuZGVydGFyZ2V0cyB3aWxsIGhhdmUgdG8gZHVwbGljYXRlIHRoZQogICAgICAgICogc3RlbmNpbCBidWZmZXIgYW5kIGluY3VyZSBhbiBleHRyYSBtZW1vcnkgb3ZlcmhlYWQKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgICAgICB0bXAgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgICAgIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPSBwTmV3WlN0ZW5jaWw7CiAgICAgICAgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9IFdJTkVEM0RfRENTX05PX0NPUFk7CiAgICAgICAgLyogc2hvdWxkIHdlIGJlIGNhbGxpbmcgdGhlIHBhcmVudCBvciB0aGUgd2luZWQzZCBzdXJmYWNlPyAqLwogICAgICAgIGlmIChOVUxMICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCk7CiAgICAgICAgaWYgKE5VTEwgIT0gdG1wKSBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSh0bXApOwogICAgICAgIGhyID0gV0lORUQzRF9PSzsKCiAgICAgICAgaWYoKCF0bXAgJiYgcE5ld1pTdGVuY2lsKSB8fCAoIXBOZXdaU3RlbmNpbCAmJiB0bXApKSB7CiAgICAgICAgICAgIC8qIFN3YXBwaW5nIE5VTEwgLyBub24gTlVMTCBkZXB0aCBzdGVuY2lsIGFmZmVjdHMgdGhlIGRlcHRoIGFuZCB0ZXN0cyAqLwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aRU5BQkxFKSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NURU5DSUxFTkFCTEUpKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1RFTkNJTFdSSVRFTUFTSykpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQcm9wZXJ0aWVzKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgVUlOVCBYSG90U3BvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFlIb3RTcG90LCBJV2luZUQzRFN1cmZhY2UgKnBDdXJzb3JCaXRtYXApIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiBUT0RPOiB0aGUgdXNlIG9mIEltcGwgaXMgZGVwcmVjYXRlZC4gKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKiBwU3VyID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcEN1cnNvckJpdG1hcDsKCiAgICBUUkFDRSgiKCVwKSA6IFNwb3QgUG9zKCV1LCV1KVxuIiwgVGhpcywgWEhvdFNwb3QsIFlIb3RTcG90KTsKCiAgICAvKiBzb21lIGJhc2ljIHZhbGlkYXRpb24gY2hlY2tzICovCiAgICBpZihUaGlzLT5jdXJzb3JUZXh0dXJlKSB7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZUaGlzLT5jdXJzb3JUZXh0dXJlKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIFRoaXMtPmN1cnNvclRleHR1cmUgPSAwOwogICAgfQoKICAgIGlmKHBDdXJzb3JCaXRtYXApIHsKICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgcmVjdDsKCiAgICAgICAgLyogTVNETjogQ3Vyc29yIG11c3QgYmUgQThSOEc4QjggKi8KICAgICAgICBpZiAoV0lORUQzREZNVF9BOFI4RzhCOCAhPSBwU3VyLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICAgICAgRVJSKCIoJXApIDogc3VyZmFjZSglcCkgaGFzIGFuIGludmFsaWQgZm9ybWF0XG4iLCBUaGlzLCBwQ3Vyc29yQml0bWFwKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICAvKiBNU0ROOiBDdXJzb3IgbXVzdCBiZSBzbWFsbGVyIHRoYW4gdGhlIGRpc3BsYXkgbW9kZSAqLwogICAgICAgIGlmKHBTdXItPmN1cnJlbnREZXNjLldpZHRoID4gVGhpcy0+ZGRyYXdfd2lkdGggfHwKICAgICAgICAgICBwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQgPiBUaGlzLT5kZHJhd19oZWlnaHQpIHsKICAgICAgICAgICAgRVJSKCIoJXApIDogU3VyZmFjZSglcCkgaXMgJWR4JWQgcGl4ZWxzLCBidXQgc2NyZWVuIHJlcyBpcyAlZHglZFxuIiwgVGhpcywgcFN1ciwgcFN1ci0+Y3VycmVudERlc2MuV2lkdGgsIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCwgVGhpcy0+ZGRyYXdfd2lkdGgsIFRoaXMtPmRkcmF3X2hlaWdodCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgLyogVE9ETzogTVNETjogQ3Vyc29yIHNpemVzIG11c3QgYmUgYSBwb3dlciBvZiAyICovCgogICAgICAgIC8qIERvIG5vdCBzdG9yZSB0aGUgc3VyZmFjZSdzIHBvaW50ZXIgYmVjYXVzZSB0aGUgYXBwbGljYXRpb24gbWF5IHJlbGVhc2UKICAgICAgICAgKiBpdCBhZnRlciBzZXR0aW5nIHRoZSBjdXJzb3IgaW1hZ2UuIFdpbmRvd3MgZG9lc24ndCBhZGRyZWYgdGhlIHNldCBzdXJmYWNlLCBzbyB3ZSBjYW4ndAogICAgICAgICAqIGRvIHRoaXMgZWl0aGVyIHdpdGhvdXQgY3JlYXRpbmcgY2lyY3VsYXIgcmVmY291bnQgZGVwZW5kZW5jaWVzLiBDb3B5IG91dCB0aGUgZ2wgdGV4dHVyZSBpbnN0ZWFkLgogICAgICAgICAqLwogICAgICAgIFRoaXMtPmN1cnNvcldpZHRoID0gcFN1ci0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+Y3Vyc29ySGVpZ2h0ID0gcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIGlmIChTVUNDRUVERUQoSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHBDdXJzb3JCaXRtYXAsICZyZWN0LCBOVUxMLCBXSU5FRDNETE9DS19SRUFET05MWSkpKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICp0YWJsZUVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFdJTkVEM0RGTVRfQThSOEc4QjgpOwogICAgICAgICAgICBjaGFyICptZW0sICpiaXRzID0gKGNoYXIgKilyZWN0LnBCaXRzOwogICAgICAgICAgICBHTGludCBpbnRmbXQgPSB0YWJsZUVudHJ5LT5nbEludGVybmFsOwogICAgICAgICAgICBHTGludCBmb3JtYXQgPSB0YWJsZUVudHJ5LT5nbEZvcm1hdDsKICAgICAgICAgICAgR0xpbnQgdHlwZSA9IHRhYmxlRW50cnktPmdsVHlwZTsKICAgICAgICAgICAgSU5UIGhlaWdodCA9IFRoaXMtPmN1cnNvckhlaWdodDsKICAgICAgICAgICAgSU5UIHdpZHRoID0gVGhpcy0+Y3Vyc29yV2lkdGg7CiAgICAgICAgICAgIElOVCBicHAgPSB0YWJsZUVudHJ5LT5icHA7CiAgICAgICAgICAgIElOVCBpOwoKICAgICAgICAgICAgLyogUmVmb3JtYXQgdGhlIHRleHR1cmUgbWVtb3J5IChwaXRjaCBhbmQgd2lkdGggY2FuIGJlIGRpZmZlcmVudCkgKi8KICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHdpZHRoICogaGVpZ2h0ICogYnBwKTsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgaGVpZ2h0OyBpKyspCiAgICAgICAgICAgICAgICBtZW1jcHkoJm1lbVt3aWR0aCAqIGJwcCAqIGldLCAmYml0c1tyZWN0LlBpdGNoICogaV0sIHdpZHRoICogYnBwKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QocEN1cnNvckJpdG1hcCk7CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0NMSUVOVF9TVE9SQUdFKSkgewogICAgICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfRkFMU0UpIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgcHJvcGVyIHRleHR1cmUgdW5pdCBpcyBzZWxlY3RlZCAqLwogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoMCkpOwogICAgICAgICAgICAvKiBDcmVhdGUgYSBuZXcgY3Vyc29yIHRleHR1cmUgKi8KICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Y3Vyc29yVGV4dHVyZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzIik7CiAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgVGhpcy0+Y3Vyc29yVGV4dHVyZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICAgICAgICAgIC8qIENvcHkgdGhlIGJpdG1hcCBtZW1vcnkgaW50byB0aGUgY3Vyc29yIHRleHR1cmUgKi8KICAgICAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIGludGZtdCwgd2lkdGgsIGhlaWdodCwgMCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0NMSUVOVF9TVE9SQUdFKSkgewogICAgICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKSIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSgiQSBjdXJzb3IgdGV4dHVyZSB3YXMgbm90IHJldHVybmVkLlxuIik7CiAgICAgICAgICAgIFRoaXMtPmN1cnNvclRleHR1cmUgPSAwOwogICAgICAgIH0KCiAgICB9CgogICAgVGhpcy0+eEhvdFNwb3QgPSBYSG90U3BvdDsKICAgIFRoaXMtPnlIb3RTcG90ID0gWUhvdFNwb3Q7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclBvc2l0aW9uKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgaW50IFhTY3JlZW5TcGFjZSwgaW50IFlTY3JlZW5TcGFjZSwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IFNldFBvcyB0byAoJXUsJXUpXG4iLCBUaGlzLCBYU2NyZWVuU3BhY2UsIFlTY3JlZW5TcGFjZSk7CgogICAgVGhpcy0+eFNjcmVlblNwYWNlID0gWFNjcmVlblNwYWNlOwogICAgVGhpcy0+eVNjcmVlblNwYWNlID0gWVNjcmVlblNwYWNlOwoKICAgIHJldHVybjsKCn0KCnN0YXRpYyBCT09MICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TaG93Q3Vyc29yKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgQk9PTCBiU2hvdykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIEJPT0wgb2xkVmlzaWJsZSA9IFRoaXMtPmJDdXJzb3JWaXNpYmxlOwogICAgUE9JTlQgcHQ7CgogICAgVFJBQ0UoIiglcCkgOiB2aXNpYmxlKCVkKVxuIiwgVGhpcywgYlNob3cpOwoKICAgIGlmKFRoaXMtPmN1cnNvclRleHR1cmUpCiAgICAgICAgVGhpcy0+YkN1cnNvclZpc2libGUgPSBiU2hvdzsKICAgIC8qCiAgICAgKiBXaGVuIFNob3dDdXJzb3IgaXMgZmlyc3QgY2FsbGVkIGl0IHNob3VsZCBtYWtlIHRoZSBjdXJzb3IgYXBwZWFyIGF0IHRoZSBPUydzIGxhc3QKICAgICAqIGtub3duIGN1cnNvciBwb3NpdGlvbi4gIEJlY2F1c2Ugb2YgdGhpcywgc29tZSBhcHBsaWNhdGlvbnMganVzdCByZXBldGl0aXZlbHkgY2FsbAogICAgICogU2hvd0N1cnNvciBpbiBvcmRlciB0byB1cGRhdGUgdGhlIGN1cnNvcidzIHBvc2l0aW9uLiAgVGhpcyBiZWhhdmlvciBpcyB1bmRvY3VtZW50ZWQuCiAgICAgKi8KICAgIEdldEN1cnNvclBvcygmcHQpOwogICAgVGhpcy0+eFNjcmVlblNwYWNlID0gcHQueDsKICAgIFRoaXMtPnlTY3JlZW5TcGFjZSA9IHB0Lnk7CgogICAgcmV0dXJuIG9sZFZpc2libGU7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbChJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHN0YXRlICgldSlcbiIsIFRoaXMsIFRoaXMtPnN0YXRlKTsKICAgIC8qIFRPRE86IEltcGxlbWVudCB3cmFwcGluZyBvZiB0aGUgV25kUHJvYyBzbyB0aGF0IG1pbWltaXplIGFuZCBtYXhhbWlzZSBjYW4gYmUgbW9uaXRvcmVkIGFuZCB0aGUgc3RhdGVzIGFkanVzdGVkLiAqLwogICAgc3dpdGNoIChUaGlzLT5zdGF0ZSkgewogICAgY2FzZSBXSU5FRDNEX09LOgogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgY2FzZSBXSU5FRDNERVJSX0RFVklDRUxPU1Q6CiAgICAgICAgewogICAgICAgICAgICBSZXNvdXJjZUxpc3QgKnJlc291cmNlTGlzdCAgPSBUaGlzLT5yZXNvdXJjZXM7CiAgICAgICAgICAgIHdoaWxlIChOVUxMICE9IHJlc291cmNlTGlzdCkgewogICAgICAgICAgICAgICAgaWYgKCgoSVdpbmVEM0RSZXNvdXJjZUltcGwgKilyZXNvdXJjZUxpc3QtPnJlc291cmNlKS0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUIC8qIFRPRE86IElXaW5lRDNEUmVzb3VyY2VfR2V0UG9vbChyZXNvdXJjZUxpc3QtPnJlc291cmNlKSovKQogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfREVWSUNFTk9UUkVTRVQ7CiAgICAgICAgICAgICAgICByZXNvdXJjZUxpc3QgPSByZXNvdXJjZUxpc3QtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfREVWSUNFTE9TVDsKICAgICAgICB9CiAgICBjYXNlIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjoKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOwogICAgfQoKICAgIC8qIFVua25vd24gc3RhdGUgKi8KICAgIHJldHVybiBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I7Cn0KCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfRXZpY3RNYW5hZ2VkUmVzb3VyY2VzKElXaW5lRDNERGV2aWNlKiBpZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIC8qKiBGSVhNRTogUmVzb3VyY2UgdHJhY2tpbmcgbmVlZHMgdG8gYmUgZG9uZSwKICAgICogVGhlIGNsb3NlcyB3ZSBjYW4gZG8gdG8gdGhpcyBpcyBzZXQgdGhlIHByaW9yaXRpZXMgb2YgYWxsIG1hbmFnZWQgdGV4dHVyZXMgbG93CiAgICAqIGFuZCB0aGVuIHJlc2V0IHRoZW0uCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIHVwZGF0ZVN1cmZhY2VEZXNjKElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmZhY2UsIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMqIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSBzdXJmYWNlLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOyAvKiBmb3IgR0xfU1VQUE9SVCAqLwoKICAgIC8qIFJlYWxsb2NhdGUgcHJvcGVyIG1lbW9yeSBmb3IgdGhlIGZyb250IGFuZCBiYWNrIGJ1ZmZlciBhbmQgYWRqdXN0IHRoZWlyIHNpemVzICovCiAgICBpZihzdXJmYWNlLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQyAqLwogICAgICAgIFNlbGVjdE9iamVjdChzdXJmYWNlLT5oREMsIHN1cmZhY2UtPmRpYi5ob2xkYml0bWFwKTsKICAgICAgICBEZWxldGVEQyhzdXJmYWNlLT5oREMpOwogICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgRGVsZXRlT2JqZWN0KHN1cmZhY2UtPmRpYi5ESUJzZWN0aW9uKTsKICAgICAgICBzdXJmYWNlLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgIHN1cmZhY2UtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgc3VyZmFjZS0+RmxhZ3MgJj0gflNGTEFHX0RJQlNFQ1RJT047CiAgICB9CiAgICBzdXJmYWNlLT5jdXJyZW50RGVzYy5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICBzdXJmYWNlLT5jdXJyZW50RGVzYy5IZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgIGlmIChHTF9TVVBQT1JUKEFSQl9URVhUVVJFX05PTl9QT1dFUl9PRl9UV08pKSB7CiAgICAgICAgc3VyZmFjZS0+cG93MldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBzdXJmYWNlLT5wb3cySGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIHN1cmZhY2UtPnBvdzJXaWR0aCA9IHN1cmZhY2UtPnBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChzdXJmYWNlLT5wb3cyV2lkdGggPCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKSBzdXJmYWNlLT5wb3cyV2lkdGggPDw9IDE7CiAgICAgICAgd2hpbGUgKHN1cmZhY2UtPnBvdzJIZWlnaHQgPCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCkgc3VyZmFjZS0+cG93MkhlaWdodCA8PD0gMTsKICAgIH0KICAgIGlmKHN1cmZhY2UtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJnN1cmZhY2UtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgc3VyZmFjZS0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9IDA7CiAgICAgICAgc3VyZmFjZS0+RmxhZ3MgJj0gflNGTEFHX0NMSUVOVDsKICAgIH0KICAgIGlmKHN1cmZhY2UtPnBvdzJXaWR0aCAhPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoIHx8CiAgICAgICBzdXJmYWNlLT5wb3cySGVpZ2h0ICE9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KSB7CiAgICAgICAgc3VyZmFjZS0+RmxhZ3MgfD0gU0ZMQUdfTk9OUE9XMjsKICAgIH0gZWxzZSAgewogICAgICAgIHN1cmZhY2UtPkZsYWdzICY9IH5TRkxBR19OT05QT1cyOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3VyZmFjZS0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgIHN1cmZhY2UtPnJlc291cmNlLnNpemUgPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKElXaW5lRDNEU3VyZmFjZSAqKSBzdXJmYWNlKSAqIHN1cmZhY2UtPnBvdzJXaWR0aDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZXNldChJV2luZUQzRERldmljZSogaWZhY2UsIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMqIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyOwogICAgQk9PTCBEaXNwbGF5TW9kZUNoYW5nZWQgPSBGQUxTRTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtb2RlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKGlmYWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopICZzd2FwY2hhaW4pOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGdldCB0aGUgZmlyc3QgaW1wbGljaXQgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogSXMgaXQgbmVjZXNzYXJ5IHRvIHJlY3JlYXRlIHRoZSBnbCBjb250ZXh0PyBBY3R1YWxseSBldmVyeSBzZXR0aW5nIGNhbiBiZSBjaGFuZ2VkCiAgICAgKiBvbiBhbiBleGlzdGluZyBnbCBjb250ZXh0LCBzbyB0aGVyZSdzIG5vIHJlYWwgbmVlZCBmb3IgcmVjcmVhdGlvbi4KICAgICAqCiAgICAgKiBUT0RPOiBGaWd1cmUgb3V0IGhvdyBSZXNldCBpbmZsdWVuY2VzIHJlc291cmNlcyBpbiBEM0RQT09MX0RFRkFVTFQsIEQzRFBPT0xfU1lTVEVNTUVNT1JZIGFuZCBEM0RQT09MX01BTkFHRUQKICAgICAqCiAgICAgKiBUT0RPOiBGaWd1cmUgb3V0IHdoYXQgaGFwcGVucyB0byBleHBsaWNpdCBzd2FwY2hhaW5zLCBvciBpZiB3ZSBoYXZlIG1vcmUgdGhhbiBvbmUgaW1wbGljaXQgc3dhcGNoYWluCiAgICAgKi8KICAgIFRSQUNFKCJOZXcgcGFyYW1zOlxuIik7CiAgICBUUkFDRSgiQmFja0J1ZmZlcldpZHRoID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpOwogICAgVFJBQ0UoIkJhY2tCdWZmZXJIZWlnaHQgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpOwogICAgVFJBQ0UoIkJhY2tCdWZmZXJGb3JtYXQgPSAlc1xuIiwgZGVidWdfZDNkZm9ybWF0KHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0KSk7CiAgICBUUkFDRSgiQmFja0J1ZmZlckNvdW50ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQpOwogICAgVFJBQ0UoIk11bHRpU2FtcGxlVHlwZSA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+TXVsdGlTYW1wbGVUeXBlKTsKICAgIFRSQUNFKCJNdWx0aVNhbXBsZVF1YWxpdHkgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPk11bHRpU2FtcGxlUXVhbGl0eSk7CiAgICBUUkFDRSgiU3dhcEVmZmVjdCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+U3dhcEVmZmVjdCk7CiAgICBUUkFDRSgiaERldmljZVdpbmRvdyA9ICVwXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdyk7CiAgICBUUkFDRSgiV2luZG93ZWQgPSAlc1xuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkID8gInRydWUiIDogImZhbHNlIik7CiAgICBUUkFDRSgiRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCA9ICVzXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RW5hYmxlQXV0b0RlcHRoU3RlbmNpbCA/ICJ0cnVlIiA6ICJmYWxzZSIpOwogICAgVFJBQ0UoIkZsYWdzID0gJTA4eFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZsYWdzKTsKICAgIFRSQUNFKCJGdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHopOwogICAgVFJBQ0UoIlByZXNlbnRhdGlvbkludGVydmFsID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5QcmVzZW50YXRpb25JbnRlcnZhbCk7CgogICAgLyogTm8gc3BlY2lhbCB0cmVhdG1lbnQgb2YgdGhlc2UgcGFyYW1ldGVycy4gSnVzdCBzdG9yZSB0aGVtICovCiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlN3YXBFZmZlY3Q7CiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5GbGFncyA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GbGFnczsKICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlByZXNlbnRhdGlvbkludGVydmFsID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlByZXNlbnRhdGlvbkludGVydmFsOwogICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuRnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHogPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CgogICAgLyogV2hhdCB0byBkbyBhYm91dCB0aGVzZT8gKi8KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQgIT0gMCAmJgogICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50KSB7CiAgICAgICAgRVJSKCJDYW5ub3QgY2hhbmdlIHRoZSBiYWNrIGJ1ZmZlciBjb3VudCB5ZXRcbiIpOwogICAgfQogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOICYmCiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCkgewogICAgICAgIEVSUigiQ2Fubm90IGNoYW5nZSB0aGUgYmFjayBidWZmZXIgZm9ybWF0IHlldFxuIik7CiAgICB9CiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdyAhPSBOVUxMICYmCiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPmhEZXZpY2VXaW5kb3cgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuaERldmljZVdpbmRvdykgewogICAgICAgIEVSUigiQ2Fubm90IGNoYW5nZSB0aGUgZGV2aWNlIHdpbmRvdyB5ZXRcbiIpOwogICAgfQogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCkgewogICAgICAgIEVSUigiV2hhdCBkbyBkbyBhYm91dCBhIGNoYW5nZWQgYXV0byBkZXB0aCBzdGVuY2lsIHBhcmFtZXRlcj9cbiIpOwogICAgfQoKICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgewogICAgICAgIG1vZGUuV2lkdGggPSBzd2FwY2hhaW4tPm9yaWdfd2lkdGg7CiAgICAgICAgbW9kZS5IZWlnaHQgPSBzd2FwY2hhaW4tPm9yaWdfaGVpZ2h0OwogICAgICAgIG1vZGUuUmVmcmVzaFJhdGUgPSAwOwogICAgICAgIG1vZGUuRm9ybWF0ID0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdDsKICAgIH0gZWxzZSB7CiAgICAgICAgbW9kZS5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgbW9kZS5IZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICBtb2RlLlJlZnJlc2hSYXRlID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6OwogICAgICAgIG1vZGUuRm9ybWF0ID0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdDsKICAgIH0KCiAgICAvKiBTaG91bGQgV2lkdGggPT0gODAwICYmIEhlaWdodCA9PSAwIHNldCA4MDB4NjAwPyAqLwogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCAhPSAwICYmIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ICE9IDAgJiYKICAgICAgIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoICE9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJXaWR0aCB8fAogICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ICE9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQpKQogICAgewogICAgICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKICAgICAgICBpbnQgaTsKCiAgICAgICAgdnAuWCA9IDA7CiAgICAgICAgdnAuWSA9IDA7CiAgICAgICAgdnAuV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIHZwLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIHZwLk1pblogPSAwOwogICAgICAgIHZwLk1heFogPSAxOwoKICAgICAgICBpZighcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgICAgIERpc3BsYXlNb2RlQ2hhbmdlZCA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJXaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwoKICAgICAgICB1cGRhdGVTdXJmYWNlRGVzYygoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzKTsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQ7IGkrKykgewogICAgICAgICAgICB1cGRhdGVTdXJmYWNlRGVzYygoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXN3YXBjaGFpbi0+YmFja0J1ZmZlcltpXSwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpOwogICAgICAgIH0KCiAgICAgICAgLyogTm93IHNldCB0aGUgbmV3IHZpZXdwb3J0ICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0Vmlld3BvcnQoaWZhY2UsICZ2cCk7CiAgICB9CgogICAgaWYoKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCAmJiAhc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQpIHx8CiAgICAgICAoc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQgJiYgIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgfHwKICAgICAgICBEaXNwbGF5TW9kZUNoYW5nZWQpIHsKCiAgICAgICAgLyogU3dpdGNoaW5nIHRvIGZ1bGxzY3JlZW4/IENoYW5nZSB0byBmdWxsc2NyZWVuIG1vZGUsIFRIRU4gY2hhbmdlIHRoZSBzY3JlZW4gcmVzICovCiAgICAgICAgaWYoIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgewogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKGlmYWNlLCBUUlVFKTsKICAgICAgICB9CgogICAgICAgIElXaW5lRDNERGV2aWNlX1NldERpc3BsYXlNb2RlKGlmYWNlLCAwLCAmbW9kZSk7CgogICAgICAgIC8qIFN3aXRjaGluZyBvdXQgb2YgZnVsbHNjcmVlbiBtb2RlPyBGaXJzdCBzZXQgdGhlIG9yaWdpbmFsIHJlcywgdGhlbiBjaGFuZ2UgdGhlIHdpbmRvdyAqLwogICAgICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgewogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKGlmYWNlLCBGQUxTRSk7CiAgICAgICAgfQogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLldpbmRvd2VkID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkOwogICAgfQoKICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXREaWFsb2dCb3hNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBiRW5hYmxlRGlhbG9ncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgLyoqIEZJWE1FOiBhbHdheXMgdHJ1ZSBhdCB0aGUgbW9tZW50ICoqLwogICAgaWYoIWJFbmFibGVEaWFsb2dzKSB7CiAgICAgICAgRklYTUUoIiglcCkgRGlhbG9ncyBjYW5ub3QgYmUgZGlzYWJsZWQgeWV0XG4iLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENyZWF0aW9uUGFyYW1ldGVycyhJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RERVZJQ0VfQ1JFQVRJT05fUEFSQU1FVEVSUyAqcFBhcmFtZXRlcnMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHBQYXJhbWV0ZXJzICVwXG4iLCBUaGlzLCBwUGFyYW1ldGVycyk7CgogICAgKnBQYXJhbWV0ZXJzID0gVGhpcy0+Y3JlYXRlUGFybXM7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRHYW1tYVJhbXAoSVdpbmVEM0REZXZpY2UgKiBpZmFjZSwgVUlOVCBpU3dhcENoYWluLCBEV09SRCBGbGFncywgQ09OU1QgV0lORUQzREdBTU1BUkFNUCogcFJhbXApIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyYyA9IFdJTkVEM0RfT0s7CgogICAgVFJBQ0UoIlJlbGF5aW5nICB0byBzd2FwY2hhaW5cbiIpOwoKICAgIGlmICgoaHJjID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaVN3YXBDaGFpbiwgJnN3YXBjaGFpbikpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9TZXRHYW1tYVJhbXAoc3dhcGNoYWluLCBGbGFncywgKFdJTkVEM0RHQU1NQVJBTVAgKilwUmFtcCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgfQogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEdhbW1hUmFtcChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzREdBTU1BUkFNUCogcFJhbXApIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyYyA9IFdJTkVEM0RfT0s7CgogICAgVFJBQ0UoIlJlbGF5aW5nICB0byBzd2FwY2hhaW5cbiIpOwoKICAgIGlmICgoaHJjID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaVN3YXBDaGFpbiwgJnN3YXBjaGFpbikpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBocmMgPUlXaW5lRDNEU3dhcENoYWluX0dldEdhbW1hUmFtcChzd2FwY2hhaW4sIHBSYW1wKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICB9CiAgICByZXR1cm47Cn0KCgovKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKiAgIE5vdGlmaWNhdGlvbiBmdW5jdGlvbnMKKiogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qKiBUaGlzIGZ1bmN0aW9uIG11c3QgYmUgY2FsbGVkIGluIHRoZSByZWxlYXNlIG9mIGEgcmVzb3VyY2Ugd2hlbiByZWYgPT0gMCwKKiB0aGUgY29udGVudHMgb2YgcmVzb3VyY2UgbXVzdCBzdGlsbCBiZSBjb3JyZWN0LAoqIGFueSBoYW5kZWxzIHRvIG90aGVyIHJlc291cmNlIGhlbGQgYnkgdGhlIGNhbGxlciBtdXN0IGJlIGNsb3NlZAoqIChlLmcuIGEgdGV4dHVyZSBzaG91bGQgcmVsZWFzZSBhbGwgaGVsZCBzdXJmYWNlcyBiZWNhdXNlIHRlbGxpbmcgdGhlIGRldmljZSB0aGF0IGl0J3MgYmVlbiByZWxlYXNlZC4pCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZXNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFJlc291cmNlTGlzdCogcmVzb3VyY2VMaXN0OwoKICAgIFRSQUNFKCIoJXApIDogcmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKICAgIC8qIGFkZCBhIG5ldyB0ZXh0dXJlIHRvIHRoZSBmcm90IG9mIHRoZSBsaW5rZWQgbGlzdCAqLwogICAgcmVzb3VyY2VMaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihSZXNvdXJjZUxpc3QpKTsKICAgIHJlc291cmNlTGlzdC0+cmVzb3VyY2UgPSByZXNvdXJjZTsKCiAgICAvKiBHZXQgdGhlIG9sZCBoZWFkICovCiAgICByZXNvdXJjZUxpc3QtPm5leHQgPSBUaGlzLT5yZXNvdXJjZXM7CgogICAgVGhpcy0+cmVzb3VyY2VzID0gcmVzb3VyY2VMaXN0OwogICAgVFJBQ0UoIkFkZGVkIHJlc291cmNlICVwIHdpdGggZWxlbWVudCAlcCBwb2ludGluZyB0byAlcFxuIiwgcmVzb3VyY2UsIHJlc291cmNlTGlzdCwgcmVzb3VyY2VMaXN0LT5uZXh0KTsKCiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVtb3ZlUmVzb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBSZXNvdXJjZUxpc3QqIHJlc291cmNlTGlzdCA9IE5VTEw7CiAgICBSZXNvdXJjZUxpc3QqIHByZXZpb3VzUmVzb3VyY2VMaXN0ID0gTlVMTDsKICAgIAogICAgVFJBQ0UoIiglcCkgOiByZXNvdXJjZSAlcFxuIiwgVGhpcywgcmVzb3VyY2UpOwoKICAgIHJlc291cmNlTGlzdCA9IFRoaXMtPnJlc291cmNlczsKCiAgICB3aGlsZSAocmVzb3VyY2VMaXN0ICE9IE5VTEwpIHsKICAgICAgICBpZihyZXNvdXJjZUxpc3QtPnJlc291cmNlID09IHJlc291cmNlKSBicmVhazsKICAgICAgICBwcmV2aW91c1Jlc291cmNlTGlzdCA9IHJlc291cmNlTGlzdDsKICAgICAgICByZXNvdXJjZUxpc3QgPSByZXNvdXJjZUxpc3QtPm5leHQ7CiAgICB9CgogICAgaWYgKHJlc291cmNlTGlzdCA9PSBOVUxMKSB7CiAgICAgICAgRklYTUUoIkF0dGVtcHRlZCB0byByZW1vdmUgcmVzb3VyY2UgJXAgdGhhdCBoYXNuJ3QgYmVlbiBzdG9yZWRcbiIsIHJlc291cmNlKTsKICAgICAgICByZXR1cm47CiAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiRm91bmQgcmVzb3VyY2UgICVwIHdpdGggZWxlbWVudCAlcCBwb2ludGluZyB0byAlcCAocHJldmlvdXMgJXApXG4iLCByZXNvdXJjZUxpc3QtPnJlc291cmNlLCByZXNvdXJjZUxpc3QsIHJlc291cmNlTGlzdC0+bmV4dCwgcHJldmlvdXNSZXNvdXJjZUxpc3QpOwogICAgfQogICAgLyogbWFrZSBzdXJlIHdlIGRvbid0IGxlYXZlIGEgaG9sZSBpbiB0aGUgbGlzdCAqLwogICAgaWYgKHByZXZpb3VzUmVzb3VyY2VMaXN0ICE9IE5VTEwpIHsKICAgICAgICBwcmV2aW91c1Jlc291cmNlTGlzdC0+bmV4dCA9IHJlc291cmNlTGlzdC0+bmV4dDsKICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2VzID0gcmVzb3VyY2VMaXN0LT5uZXh0OwogICAgfQoKICAgIHJldHVybjsKfQoKCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzb3VyY2VSZWxlYXNlZChJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBpbnQgY291bnRlcjsKCiAgICBUUkFDRSgiKCVwKSA6IHJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CiAgICBzd2l0Y2goSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKHJlc291cmNlKSl7CiAgICAgICAgLyogVE9ETzogY2hlY2sgZnJvbnQgYW5kIGJhY2sgYnVmZmVycywgcmVuZGVydGFyZ2V0cyBldGMuLiAgcG9zc2libHkgc3dhcGNoYWlucz8gKi8KICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9TVVJGQUNFOiB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwoKICAgICAgICAgICAgLyogQ2xlYW51cCBhbnkgRkJPIGF0dGFjaG1lbnRzICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICAgICAgaWYgKFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSA9PSAoSVdpbmVEM0RTdXJmYWNlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICBiaW5kX2ZibyhpZmFjZSwgR0xfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZmJvKTsKICAgICAgICAgICAgICAgICAgICBzZXRfcmVuZGVyX3RhcmdldF9mYm8oaWZhY2UsIGksIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSA9IE5VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKFRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50ID09IChJV2luZUQzRFN1cmZhY2UgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CiAgICAgICAgICAgICAgICBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oaWZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgVGhpcy0+ZmJvX2RlcHRoX2F0dGFjaG1lbnQgPSBOVUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1RFWFRVUkU6CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfQ1VCRVRFWFRVUkU6CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRToKICAgICAgICAgICAgICAgIGZvciAoY291bnRlciA9IDA7IGNvdW50ZXIgPCBHTF9MSU1JVFMoc2FtcGxlcl9zdGFnZXMpOyBjb3VudGVyKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jayAhPSBOVUxMICYmIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID09IChJV2luZUQzREJhc2VUZXh0dXJlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiVGV4dHVyZSBiZWluZyByZWxlYXNlZCBpcyBzdGlsbCBieSBhIHN0YXRlYmxvY2ssIFN0YWdlID0gJXUgVGV4dHVyZSA9ICVwXG4iLCBjb3VudGVyLCByZXNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gVGhpcy0+c3RhdGVCbG9jayApewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPT0gKElXaW5lRDNEQmFzZVRleHR1cmUgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiVGV4dHVyZSBiZWluZyByZWxlYXNlZCBpcyBzdGlsbCBieSBhIHN0YXRlYmxvY2ssIFN0YWdlID0gJXUgVGV4dHVyZSA9ICVwXG4iLCBjb3VudGVyLCByZXNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FOgogICAgICAgIC8qIFRPRE86IG5vdGhpbmcgcmVhbGx5PyAqLwogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1ZFUlRFWEJVRkZFUjoKICAgICAgICAvKiBNU0ROOiBXaGVuIGFuIGFwcGxpY2F0aW9uIG5vIGxvbmdlciBob2xkcyBhIHJlZmVyZW5jZXMgdG8gdGhpcyBpbnRlcmZhY2UsIHRoZSBpbnRlcmZhY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGZyZWVkLiAqLwogICAgICAgIHsKICAgICAgICAgICAgaW50IHN0cmVhbU51bWJlcjsKICAgICAgICAgICAgVFJBQ0UoIkNsZWFuaW5nIHVwIHN0cmVhbSBwb2ludGVyc1xuIik7CgogICAgICAgICAgICBmb3Ioc3RyZWFtTnVtYmVyID0gMDsgc3RyZWFtTnVtYmVyIDwgTUFYX1NUUkVBTVM7IHN0cmVhbU51bWJlciArKyl7CiAgICAgICAgICAgICAgICAvKiBGSU5ET1VUOiBzaG91bGQgYSB3YXJuIGJlIGdlbmVyYXRlZCBpZiB3ZXJlIHJlY29yZGluZyBhbmQgdXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlIGlzIGxvc3Q/CiAgICAgICAgICAgICAgICBGSU5ET1VUOiBzaG91bGQgY2hhbmdlcy5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSBiZSBzZXQgPwogICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qID09TlVMTCB3aGVuIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKElXaW5lRDNEUmVzb3VyY2UgKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbc3RyZWFtTnVtYmVyXSA9PSByZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVmVydGV4IGJ1ZmZlciByZWxlYXNlZCB3aGlsZSBib3VuZCB0byBhIHN0YXRlIGJsb2NrLCBzdHJlYW0gJWRcbiIsIHN0cmVhbU51bWJlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgLyogU2V0IGNoYW5nZWQgZmxhZz8gKi8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jayAhPSBOVUxMICkgeyAvKiBvbmx5IGhhcHBlbnMgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIGFwcGxpY2F0aW9uLCBvciBvbiByZXNldC9yZWxlYXNlIChiZWNhdXNlIHdlIGRvbid0IG1hbmFnZSBpbnRlcm5hbCB0cmFja2luZyBwcm9wZXJseSkgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKElXaW5lRDNEUmVzb3VyY2UgKilUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbc3RyZWFtTnVtYmVyXSA9PSByZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiVmVydGV4IGJ1ZmZlciByZWxlYXNlZCB3aGlsZSBib3VuZCB0byBhIHN0YXRlIGJsb2NrLCBzdHJlYW0gJWRcbiIsIHN0cmVhbU51bWJlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiNpZiAwICAgLyogVE9ETzogTWFuYWdlIGludGVybmFsIHRyYWNraW5nIHByb3Blcmx5IHNvIHRoYXQgJ3RoaXMgc2hvdWxkbid0IGhhcHBlbicgKi8KICAgICAgICAgICAgICAgICBlbHNlIHsgLyogVGhpcyBzaG91bGRuJ3QgaGFwcGVuICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIkNhbGxpbmcgYXBwbGljYXRpb24gaGFzIHJlbGVhc2VkIHRoZSBkZXZpY2UgYmVmb3JlIHJlbGFzaW5nIGFsbCB0aGUgcmVzb3VyY2VzIGJvdW5kIHRvIHRoZSBkZXZpY2VcbiIpOwogICAgICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfSU5ERVhCVUZGRVI6CiAgICAgICAgLyogTVNETjogV2hlbiBhbiBhcHBsaWNhdGlvbiBubyBsb25nZXIgaG9sZHMgYSByZWZlcmVuY2VzIHRvIHRoaXMgaW50ZXJmYWNlLCB0aGUgaW50ZXJmYWNlIHdpbGwgYXV0b21hdGljYWxseSBiZSBmcmVlZC4qLwogICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qID09TlVMTCB3aGVuIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBJbmRleERhdGEgPT0gKElXaW5lRDNESW5kZXhCdWZmZXIgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9ICBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qID09TlVMTCB3aGVuIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGEgPT0gKElXaW5lRDNESW5kZXhCdWZmZXIgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSA9ICBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIHVua25vd24gcmVzb3VyY2UgdHlwZSAlcCAldVxuIiwgVGhpcywgcmVzb3VyY2UsIElXaW5lRDNEUmVzb3VyY2VfR2V0VHlwZShyZXNvdXJjZSkpOwogICAgICAgIGJyZWFrOwogICAgfQoKCiAgICAvKiBSZW1vdmUgdGhlIHJlc29ydWNlIGZyb20gdGhlIHJlc291cmNlU3RvcmUgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZW1vdmVSZXNvdXJjZShpZmFjZSwgcmVzb3VyY2UpOwoKICAgIFRSQUNFKCJSZXNvdXJjZSByZWxlYXNlZFxuIik7Cgp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZSBWVGJsIGZvbGxvd3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpjb25zdCBJV2luZUQzRERldmljZVZ0YmwgSVdpbmVEM0REZXZpY2VfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gbWV0aG9kcyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UsCiAgICAvKioqIElXaW5lRDNERGV2aWNlIG1ldGhvZHMgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhcmVudCwKICAgIC8qKiogQ3JlYXRpb24gbWV0aG9kcyoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleEJ1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVJbmRleEJ1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdGF0ZUJsb2NrLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVDdWJlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVRdWVyeSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uRnJvbUZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZSwKICAgIC8qKiogT2RkIGZ1bmN0aW9ucyAqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfVW5pbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RnVsbHNjcmVlbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNdWx0aXRocmVhZGVkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRBdmFpbGFibGVUZXh0dXJlTWVtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q3JlYXRpb25QYXJhbWV0ZXJzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERldmljZUNhcHMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGlyZWN0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGlzcGxheU1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGlzcGxheU1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0SFdORCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRIV05ELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE51bWJlck9mU3dhcENoYWlucywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSYXN0ZXJTdGF0dXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpYWxvZ0JveE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUHJvcGVydGllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQb3NpdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TaG93Q3Vyc29yLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Rlc3RDb29wZXJhdGl2ZUxldmVsLAogICAgLyoqKiBHZXR0ZXJzIGFuZCBzZXR0ZXJzICoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBQbGFuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwUGxhbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEdhbW1hUmFtcCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEluZGljZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0QmFzZXZlcnRleEluZGV4LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0RW5hYmxlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0RW5hYmxlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE1hdGVyaWFsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE1hdGVyaWFsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE5QYXRjaE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TlBhdGNoTW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQYWxldHRlRW50cmllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYWxldHRlRW50cmllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJUYXJnZXQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U2FtcGxlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlRnJlcSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2VGcmVxLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Vmlld3BvcnQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Vmlld3BvcnQsCiAgICBJV2luZUQzRERldmljZUltcGxfTXVsdGlwbHlUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfVmFsaWRhdGVEZXZpY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfUHJvY2Vzc1ZlcnRpY2VzLAogICAgLyoqKiBTdGF0ZSBibG9jayAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfQmVnaW5TdGF0ZUJsb2NrLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFN0YXRlQmxvY2ssCiAgICAvKioqIFNjZW5lIG1hbmFnZW1lbnQgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU2NlbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRW5kU2NlbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfUHJlc2VudCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DbGVhciwKICAgIC8qKiogRHJhd2luZyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlVVAsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVVUCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlU3RyaWRlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdUcmlQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EZWxldGVQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9Db2xvckZpbGwsCiAgICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZyb250QnVmZmVyRGF0YSwKICAgIC8qKiogb2JqZWN0IHRyYWNraW5nICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXNvdXJjZVJlbGVhc2VkCn07CgoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19SW05VTV9TQVZFRFBJWEVMU1RBVEVTX1JdID0gewogICAgV0lORUQzRFJTX0FMUEhBQkxFTkRFTkFCTEUgICAsCiAgICBXSU5FRDNEUlNfQUxQSEFGVU5DICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTFBIQVJFRiAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0FMUEhBVEVTVEVOQUJMRSAgICAsCiAgICBXSU5FRDNEUlNfQkxFTkRPUCAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFICAgLAogICAgV0lORUQzRFJTX0RFU1RCTEVORCAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRElUSEVSRU5BQkxFICAgICAgICwKICAgIFdJTkVEM0RSU19GSUxMTU9ERSAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0RFTlNJVFkgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HRU5EICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dTVEFSVCAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0xBU1RQSVhFTCAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfU0hBREVNT0RFICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TUkNCTEVORCAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxFTkFCTEUgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTEZBSUwgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMRlVOQyAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxNQVNLICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFBBU1MgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMUkVGICAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxXUklURU1BU0sgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFpGQUlMICAgICAgICwKICAgIFdJTkVEM0RSU19URVhUVVJFRkFDVE9SICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAwICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDEgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMiAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAzICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDQgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQNSAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA2ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDcgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19aRU5BQkxFICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1pGVU5DICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfWldSSVRFRU5BQkxFCn07Cgpjb25zdCBEV09SRCBTYXZlZFBpeGVsU3RhdGVzX1RbTlVNX1NBVkVEUElYRUxTVEFURVNfVF0gPSB7CiAgICBXSU5FRDNEVFNTX0FERFJFU1NXICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMiAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBT1AgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZMT0ZGU0VUICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEUgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMCAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMSAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMCAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMSAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMiAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9ST1AgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1JFU1VMVEFSRyAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWENPT1JESU5ERVggICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUwp9OwoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19TW05VTV9TQVZFRFBJWEVMU1RBVEVTX1NdID0gewogICAgV0lORUQzRFNBTVBfQUREUkVTU1UgICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9BRERSRVNTViAgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX0FERFJFU1NXICAgICAgICAgLAogICAgV0lORUQzRFNBTVBfQk9SREVSQ09MT1IgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NQUdGSUxURVIgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX01JTkZJTFRFUiAgICAgICAgLAogICAgV0lORUQzRFNBTVBfTUlQRklMVEVSICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NSVBNQVBMT0RCSUFTICAgICwKICAgIFdJTkVEM0RTQU1QX01BWE1JUExFVkVMICAgICAgLAogICAgV0lORUQzRFNBTVBfTUFYQU5JU09UUk9QWSAgICAsCiAgICBXSU5FRDNEU0FNUF9TUkdCVEVYVFVSRSAgICAgICwKICAgIFdJTkVEM0RTQU1QX0VMRU1FTlRJTkRFWAp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfUltOVU1fU0FWRURWRVJURVhTVEFURVNfUl0gPSB7CiAgICBXSU5FRDNEUlNfQU1CSUVOVCAgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0FNQklFTlRNQVRFUklBTFNPVVJDRSAgICAgICAgICwKICAgIFdJTkVEM0RSU19DTElQUElORyAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ0xJUFBMQU5FRU5BQkxFICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NPTE9SVkVSVEVYICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19ESUZGVVNFTUFURVJJQUxTT1VSQ0UgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRU1JU1NJVkVNQVRFUklBTFNPVVJDRSAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0RFTlNJVFkgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dFTkQgICAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HU1RBUlQgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR1RBQkxFTU9ERSAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dWRVJURVhNT0RFICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfSU5ERVhFRFZFUlRFWEJMRU5ERU5BQkxFICAgICAgLAogICAgV0lORUQzRFJTX0xJR0hUSU5HICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19MT0NBTFZJRVdFUiAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTVVMVElTQU1QTEVBTlRJQUxJQVMgICAgICAgICAgLAogICAgV0lORUQzRFJTX01VTFRJU0FNUExFTUFTSyAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19OT1JNQUxJWkVOT1JNQUxTICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUEFUQ0hFREdFU1RZTEUgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVfQSAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFX0IgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9DICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVFTkFCTEUgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNJWkUgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTSVpFX01BWCAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0laRV9NSU4gICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNQUklURUVOQUJMRSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUkFOR0VGT0dFTkFCTEUgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NQRUNVTEFSTUFURVJJQUxTT1VSQ0UgICAgICAgICwKICAgIFdJTkVEM0RSU19UV0VFTkZBQ1RPUiAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfVkVSVEVYQkxFTkQKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1RbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1RdID0gewogICAgV0lORUQzRFRTU19URVhDT09SRElOREVYICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1NbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1NdID0gewogICAgV0lORUQzRFNBTVBfRE1BUE9GRlNFVAp9OwoKdm9pZCBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBEV09SRCBzdGF0ZSkgewogICAgRFdPUkQgcmVwID0gU3RhdGVUYWJsZVtzdGF0ZV0ucmVwcmVzZW50YXRpdmU7CiAgICBEV09SRCBpZHg7CiAgICBCWVRFIHNoaWZ0OwogICAgVUlOVCBpOwogICAgV2luZUQzRENvbnRleHQgKmNvbnRleHQ7CgogICAgaWYoIXJlcCkgcmV0dXJuOwogICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+bnVtQ29udGV4dHM7IGkrKykgewogICAgICAgIGNvbnRleHQgPSBUaGlzLT5jb250ZXh0c1tpXTsKICAgICAgICBpZihpc1N0YXRlRGlydHkoY29udGV4dCwgcmVwKSkgY29udGludWU7CgogICAgICAgIGNvbnRleHQtPmRpcnR5QXJyYXlbY29udGV4dC0+bnVtRGlydHlFbnRyaWVzKytdID0gcmVwOwogICAgICAgIGlkeCA9IHJlcCA+PiA1OwogICAgICAgIHNoaWZ0ID0gcmVwICYgMHgxZjsKICAgICAgICBjb250ZXh0LT5pc1N0YXRlRGlydHlbaWR4XSB8PSAoMSA8PCBzaGlmdCk7CiAgICB9Cn0K