LyoKICogQ29weXJpZ2h0IDE5OTctMjAwMCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IDIwMDAtMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICogQ29weXJpZ2h0IDIwMDggRGVudmVyIEdpbmdlcmljaAogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKCiNpbmNsdWRlICJkZHJhdy5oIgojaW5jbHVkZSAiZDNkLmgiCgojaW5jbHVkZSAiZGRyYXdfcHJpdmF0ZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZGRyYXcpOwoKc3RhdGljIEJPT0wgSURpcmVjdERyYXdJbXBsX0REU0RfTWF0Y2goY29uc3QgRERTVVJGQUNFREVTQzIqIHJlcXVlc3RlZCwgY29uc3QgRERTVVJGQUNFREVTQzIqIHByb3ZpZGVkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UoSURpcmVjdERyYXdJbXBsICpUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpwcmltYXJ5KTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywgRERTVVJGQUNFREVTQzIgKnBERFNELCBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICoqcHBTdXJmLCBVSU5UIGxldmVsKTsKCi8qIERldmljZSBpZGVudGlmaWVyLiBEb24ndCByZWxheSBpdCB0byBXaW5lRDNEICovCnN0YXRpYyBjb25zdCBERERFVklDRUlERU5USUZJRVIyIGRldmljZWlkZW50aWZpZXIgPQp7CiAgICAiZGlzcGxheSIsCiAgICAiRGlyZWN0RHJhdyBIQUwiLAogICAgeyB7IDB4MDAwMTAwMDEsIDB4MDAwMTAwMDEgfSB9LAogICAgMCwgMCwgMCwgMCwKICAgIC8qIGE4MzczYzEwLTdhYzQtNGRlYi04NDlhLTAwOTg0NGQwOGIyZCAqLwogICAgezB4YTgzNzNjMTAsMHg3YWM0LDB4NGRlYiwgezB4ODQsMHg5YSwweDAwLDB4OTgsMHg0NCwweGQwLDB4OGIsMHgyZH19LAogICAgMAp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElVbmtub3duIE1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UXVlcnlJbnRlcmZhY2UKICoKICogUXVlcmllcyBkaWZmZXJlbnQgaW50ZXJmYWNlcyBvZiB0aGUgRGlyZWN0RHJhdyBvYmplY3QuIEl0IGNhbiByZXR1cm4KICogSURpcmVjdERyYXcgaW50ZXJmYWNlcyBpbiB2ZXJzaW9uIDEsIDIsIDQgYW5kIDcsIGFuZCBJRGlyZWN0M0QgaW50ZXJmYWNlcwogKiBpbiB2ZXJzaW9uIDEsIDIsIDMgYW5kIDcuIEFuIElEaXJlY3QzRERldmljZSBjYW4gYmUgY3JlYXRlZCB3aXRoIHRoaXMKICogbWV0aG9kLgogKiBUaGUgcmV0dXJuZWQgaW50ZXJmYWNlIGlzIEFkZFJlZigpLWVkIGJlZm9yZSBpdCdzIHJldHVybmVkCiAqCiAqIFVzZWQgZm9yIHZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICByZWZpaWQ6IEludGVyZmFjZSBJRCBhc2tlZCBmb3IKICogIG9iajogVXNlZCB0byByZXR1cm4gdGhlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJldHVybnM6CiAqICBTX09LIGlmIGFuIGludGVyZmFjZSB3YXMgZm91bmQKICogIEVfTk9JTlRFUkZBQ0UgaWYgdGhlIHJlcXVlc3RlZCBpbnRlcmZhY2Ugd2Fzbid0IGZvdW5kCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9RdWVyeUludGVyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJlZmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgICAvKiBDYW4gY2hhbmdlIHN1cmZhY2UgaW1wbCB0eXBlICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIC8qIEFjY29yZGluZyB0byBDT00gZG9jcywgaWYgdGhlIFF1ZXJ5SW50ZXJmYWNlIGZhaWxzLCBvYmogc2hvdWxkIGJlIHNldCB0byBOVUxMICovCiAgICAqb2JqID0gTlVMTDsKCiAgICBpZighcmVmaWlkKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogQ2hlY2sgRGlyZWN0RHJhdyBJbnRlcmZhY2VzICovCiAgICBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lVbmtub3duLCByZWZpaWQgKSB8fAogICAgICAgICBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzcsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXc3IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXc0LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3NCBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3MywgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzMpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzMgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzIsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcyKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXcyIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXcsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQoKICAgIC8qIERpcmVjdDNECiAgICAgKiBUaGUgcmVmY291bnQgdW5pdCB0ZXN0IHJldmVhbGVkIHRoYXQgYW4gSURpcmVjdDNENyBpbnRlcmZhY2UgY2FuIG9ubHkgYmUgcXVlcmllZAogICAgICogZnJvbSBhIERpcmVjdERyYXcgb2JqZWN0IHRoYXQgd2FzIGNyZWF0ZWQgYXMgYW4gSURpcmVjdERyYXc3IGludGVyZmFjZS4gTm8gaWRlYQogICAgICogd2hvIGhhZCB0aGlzIGlkZWEgYW5kIHdoeS4gVGhlIG9sZGVyIGludGVyZmFjZXMgY2FuIHF1ZXJ5IGFuZCBJRGlyZWN0M0QgdmVyc2lvbgogICAgICogYmVjYXVzZSB0aGV5IGFyZSBhbGwgY3JlYXRlZCBhcyBJRGlyZWN0RHJhdygxKS4gVGhpcyBpc24ndCByZWFsbHkgY3J1Y2lhbCBiZWhhdmlvciwKICAgICAqIGFuZCBtZXNzeSB0byBpbXBsZW1lbnQgd2l0aCB0aGUgY29tbW9uIGNyZWF0aW9uIGZ1bmN0aW9uLCBzbyBpdCBoYXMgYmVlbiBsZWZ0IG91dCBoZXJlLgogICAgICovCiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEICAsIHJlZmlpZCApIHx8CiAgICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMiAsIHJlZmlpZCApIHx8CiAgICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMyAsIHJlZmlpZCApIHx8CiAgICAgICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNENyAsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAvKiBDaGVjayB0aGUgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgICAgIGlmKFRoaXMtPkltcGxUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIEFwcHMgbWF5IGNyZWF0ZSB0aGUgSURpcmVjdDNEIEludGVyZmFjZSBiZWZvcmUgdGhlIHByaW1hcnkgc3VyZmFjZS4KICAgICAgICAgICAgICogc2V0IHRoZSBzdXJmYWNlIGltcGxlbWVudGF0aW9uICovCiAgICAgICAgICAgIFRoaXMtPkltcGxUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIENob29zaW5nIE9wZW5HTCBzdXJmYWNlcyBiZWNhdXNlIGEgRGlyZWN0M0QgaW50ZXJmYWNlIHdhcyByZXF1ZXN0ZWRcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMICYmIERlZmF1bHRTdXJmYWNlVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICAgICAgewogICAgICAgICAgICBFUlIoIiglcCkgVGhlIEFwcCBpcyByZXF1ZXN0aW5nIGEgRDNEIGRldmljZSwgYnV0IGEgbm9uLU9wZW5HTCBzdXJmYWNlIHR5cGUgd2FzIGNob29zZW4uIFByZXBhcmUgZm9yIHRyb3VibGUhXG4iLCBUaGlzKTsKICAgICAgICAgICAgRVJSKCIgKCVwKSBZb3UgbWF5IHdhbnQgdG8gY29udGFjdCB3aW5lLWRldmVsIGZvciBoZWxwXG4iLCBUaGlzKTsKICAgICAgICAgICAgLyogU2hvdWxkIEkgYXNzZXJ0KDApIGhlcmU/Pz8gKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIlRoZSBhcHAgcmVxdWVzdHMgYSBEaXJlY3QzRCBpbnRlcmZhY2UsIGJ1dCBub24tb3BlbmdsIHN1cmZhY2VzIHdoZXJlIHNldCBpbiB3aW5lY2ZnXG4iKTsKICAgICAgICAgICAgLyogRG8gbm90IGFib3J0IGhlcmUsIG9ubHkgcmVqZWN0IDNEIERldmljZSBjcmVhdGlvbiAqLwogICAgICAgIH0KCiAgICAgICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QgICwgcmVmaWlkICkgKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDE7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRCBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDIgICwgcmVmaWlkICkgKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDI7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QyKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0QyIGludGVyZmFjZSBhdCAlcC5cbiIsICpvYmopOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMyAgLCByZWZpaWQgKSApCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5kM2R2ZXJzaW9uID0gMzsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDMpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRDMgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNENyAgLCByZWZpaWQgKSkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSA3OwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNENyk7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNENyBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICB9CgogICAgLyogVW5rbm93biBpbnRlcmZhY2UgKi8KICAgIGVsc2UKICAgIHsKICAgICAgICBFUlIoIiglcCktPiglcywgJXApOiBObyBpbnRlcmZhY2UgZm91bmRcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBFX05PSU5URVJGQUNFOwogICAgfQoKICAgIElVbmtub3duX0FkZFJlZiggKElVbmtub3duICopICpvYmogKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6QWRkUmVmCiAqCiAqIEluY3JlYXNlcyB0aGUgaW50ZXJmYWNlcyByZWZjb3VudCwgYmFzaWNhbGx5CiAqCiAqIEREcmF3IHJlZmNvdW50aW5nIGlzIGEgYml0IHRyaWNreS4gVGhlIGRpZmZlcmVudCBEaXJlY3REcmF3IGludGVyZmFjZQogKiB2ZXJzaW9ucyBoYXZlIGluZGl2aWR1YWwgcmVmY291bnRzLCBidXQgdGhlIElEaXJlY3QzRCBpbnRlcmZhY2VzIGRvIG5vdC4KICogQWxsIGludGVyZmFjZXMgYXJlIGZyb20gb25lIG9iamVjdCwgdGhhdCBtZWFucyBjYWxsaW5nIFF1ZXJ5SW50ZXJmYWNlIG9uIGFuCiAqIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgZm9yIGFuIElEaXJlY3REcmF3NCBpbnRlcmZhY2UgZG9lcyBub3QgY3JlYXRlIGEgbmV3CiAqIElEaXJlY3REcmF3SW1wbCBvYmplY3QuCiAqCiAqIFRoYXQgbWVhbnMgYWxsIEFkZFJlZiBhbmQgUmVsZWFzZSBpbXBsZW1lbnRhdGlvbnMgb2YgSURpcmVjdERyYXdYIHdvcmsKICogd2l0aCB0aGVpciBvd24gY291bnRlciwgYW5kIElEaXJlY3QzRFg6OkFkZFJlZiB0aHVuayB0byBJRGlyZWN0RHJhdyAoMSksCiAqIGV4Y2VwdCBvZiBJRGlyZWN0M0Q3IHdoaWNoIHRodW5rcyB0byBJRGlyZWN0RHJhdzcKICoKICogUmV0dXJuczogVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0FkZFJlZihJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZjcpOwoKICAgIFRSQUNFKCIoJXApIDogaW5jcmVtZW50aW5nIElEaXJlY3REcmF3NyByZWZjb3VudCBmcm9tICV1LlxuIiwgVGhpcywgcmVmIC0xKTsKCiAgICBpZihyZWYgPT0gMSkgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPm51bUlmYWNlcyk7CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9EZXN0cm95CiAqCiAqIERlc3Ryb3lzIGEgZGRyYXcgb2JqZWN0IGlmIGFsbCByZWZjb3VudHMgYXJlIDAuIFRoaXMgaXMgdG8gc2hhcmUgY29kZQogKiBiZXR3ZWVuIHRoZSBJRGlyZWN0RHJhd1g6OlJlbGVhc2UgZnVuY3Rpb25zCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERpcmVjdERyYXcgb2JqZWN0IHRvIGRlc3Ryb3kKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkCklEaXJlY3REcmF3SW1wbF9EZXN0cm95KElEaXJlY3REcmF3SW1wbCAqVGhpcykKewogICAgLyogQ2xlYXIgdGhlIGNvb3BsZXZlbCB0byByZXN0b3JlIHdpbmRvdyBhbmQgZGlzcGxheSBtb2RlICovCiAgICBJRGlyZWN0RHJhdzdfU2V0Q29vcGVyYXRpdmVMZXZlbChJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX05PUk1BTCk7CgogICAgLyogRGVzdHJveSB0aGUgZGV2aWNlIHdpbmRvdyBpZiB3ZSBjcmVhdGVkIG9uZSAqLwogICAgaWYoVGhpcy0+ZGV2aWNld2luZG93ICE9IDApCiAgICB7CiAgICAgICAgVFJBQ0UoIiAoJXApIERlc3Ryb3lpbmcgdGhlIGRldmljZSB3aW5kb3cgJXBcbiIsIFRoaXMsIFRoaXMtPmRldmljZXdpbmRvdyk7CiAgICAgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgIFRoaXMtPmRldmljZXdpbmRvdyA9IDA7CiAgICB9CgogICAgLyogVW5yZWdpc3RlciB0aGUgd2luZG93IGNsYXNzICovCiAgICBVbnJlZ2lzdGVyQ2xhc3NBKFRoaXMtPmNsYXNzbmFtZSwgMCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGxpc3RfcmVtb3ZlKCZUaGlzLT5kZHJhd19saXN0X2VudHJ5KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgLyogUmVsZWFzZSB0aGUgYXR0YWNoZWQgV2luZUQzRCBzdHVmZiAqLwogICAgSVdpbmVEM0REZXZpY2VfUmVsZWFzZShUaGlzLT53aW5lRDNERGV2aWNlKTsKICAgIElXaW5lRDNEX1JlbGVhc2UoVGhpcy0+d2luZUQzRCk7CgogICAgLyogTm93IGZyZWUgdGhlIG9iamVjdCAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlJlbGVhc2UKICoKICogRGVjcmVhc2VzIHRoZSByZWZjb3VudC4gSWYgdGhlIHJlZmNvdW50IGZhbGxzIHRvIDAsIHRoZSBvYmplY3QgaXMgZGVzdHJveWVkCiAqCiAqIFJldHVybnM6IFRoZSBuZXcgcmVmY291bnQKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZWxlYXNlKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmNyk7CgogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBJRGlyZWN0RHJhdzcgcmVmY291bnQgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiArMSk7CgogICAgaWYocmVmID09IDApCiAgICB7CiAgICAgICAgVUxPTkcgaWZhY2Vjb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5udW1JZmFjZXMpOwogICAgICAgIGlmKGlmYWNlY291bnQgPT0gMCkgSURpcmVjdERyYXdJbXBsX0Rlc3Ryb3koVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3IG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6U2V0Q29vcGVyYXRpdmVMZXZlbAogKgogKiBTZXRzIHRoZSBjb29wZXJhdGl2ZSBsZXZlbCBmb3IgdGhlIERpcmVjdERyYXcgb2JqZWN0LCBhbmQgdGhlIHdpbmRvdwogKiBhc3NpZ25lZCB0byBpdC4gVGhlIGNvb3BlcmF0aXZlIGxldmVsIGRldGVybWluZXMgdGhlIGdlbmVyYWwgYmVoYXZpb3IKICogb2YgdGhlIERpcmVjdERyYXcgYXBwbGljYXRpb24KICoKICogV2FybmluZzogVGhpcyBpcyBxdWl0ZSB0cmlja3ksIGFzIGl0J3Mgbm90IHJlYWxseSBkb2N1bWVudGVkIHdoaWNoCiAqIGNvb3BlcmF0aXZlIGxldmVscyBjYW4gYmUgY29tYmluZWQgd2l0aCBlYWNoIG90aGVyLiBJZiBhIGdhbWUgZmFpbHMKICogYWZ0ZXIgdGhpcyBmdW5jdGlvbiwgdHJ5IHRvIGNoZWNrIHRoZSBjb29wZXJhdGl2ZSBsZXZlbHMgcGFzc2VkIG9uCiAqIFdpbmRvd3MsIGFuZCBpZiBpdCByZXR1cm5zIHNvbWV0aGluZyBkaWZmZXJlbnQuCiAqCiAqIElmIHlvdSB0aGluayB0aGF0IHRoaXMgZnVuY3Rpb24gY2F1c2VkIHRoZSBmYWlsdXJlIGJlY2F1c2UgaXQgd3JpdGVzIGEKICogZml4bWUsIGJlIHN1cmUgdG8gcnVuIGFnYWluIHdpdGggYSArZGRyYXcgdHJhY2UuCiAqCiAqIFdoYXQgaXMga25vd24gYWJvdXQgY29vcGVyYXRpdmUgbGV2ZWxzIChTZWUgdGhlIGRkcmF3IG1vZGVzIHRlc3QpOgogKiBERFNDTF9FWENMVVNJVkUgYW5kIEREU0NMX0ZVTExTQ1JFRU4gbXVzdCBiZSB1c2VkIHdpdGggZWFjaCBvdGhlcgogKiBERFNDTF9OT1JNQUwgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBERFNDTF9FWENMVVNJVkUgb3IgRERTQ0xfRlVMTFNDUkVFTgogKiBERFNDTF9TRVRGT0NVU1dJTkRPVyBjYW4gYmUgcGFzc2VkIG9ubHkgaW4gRERTQ0xfTk9STUFMIG1vZGUsIGJ1dCBhZnRlciB0aGF0CiAqIEREU0NMX0ZVTExTQ1JFRU4gY2FuIGJlIGFjdGl2YXRlZAogKiBERFNDTF9TRVRGT0NVU1dJTkRPVyBtYXkgb25seSBiZSB1c2VkIHdpdGggRERTQ0xfTk9XSU5ET1dDSEFOR0VTCiAqCiAqIEhhbmRsZWQgZmxhZ3M6IEREU0NMX05PUk1BTCwgRERTQ0xfRlVMTFNDUkVFTiwgRERTQ0xfRVhDTFVTSVZFLAogKiAgICAgICAgICAgICAgICBERFNDTF9TRVRGT0NVU1dJTkRPVyAocGFydGlhbGx5KSwKICogICAgICAgICAgICAgICAgRERTQ0xfTVVMVElUSFJFQURFRCAod29yayBpbiBwcm9ncmVzcykKICoKICogVW5oYW5kbGVkIGZsYWdzLCB3aGljaCBzaG91bGQgYmUgaW1wbGVtZW50ZWQKICogIEREU0NMX1NFVERFVklDRVdJTkRPVzogU2V0cyBhIHdpbmRvdyBzcGVjaWFsbHkgdXNlZCBmb3IgcmVuZGVyaW5nIChJIGRvbid0CiAqICBleHBlY3QgYW55IGRpZmZlcmVuY2UgdG8gYSBub3JtYWwgd2luZG93IGZvciB3aW5lKQogKiAgRERTQ0xfQ1JFQVRFREVWSUNFV0lORE9XOiBUZWxscyBkZHJhdyB0byBjcmVhdGUgaXRzIG93biB3aW5kb3cgZm9yCiAqICByZW5kZXJpbmcgKFBvc3NpYmxlIHRlc3QgY2FzZTogSGFsZi1saWZlKQogKgogKiBVbnN1cmUgYWJvdXQgdGhlc2U6IEREU0NMX0ZQVVNFVFVQIEREU0NMX0ZQVVJFU0VSVkUKICoKICogVGhlc2UgZG9uJ3Qgc2VlbSB2ZXJ5IGltcG9ydGFudCBmb3Igd2luZToKICogIEREU0NMX0FMTE9XUkVCT09ULCBERFNDTF9OT1dJTkRPV0NIQU5HRVMsIEREU0NMX0FMTE9XTU9ERVgKICoKICogUmV0dXJuczoKICogIEREX09LIGlmIHRoZSBjb29wZXJhdGl2ZSBsZXZlbCB3YXMgc2V0IHN1Y2Nlc3NmdWxseQogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgcGFzc2VkIGNvb3BlcmF0aXZlIGxldmVsIGNvbWJpbmF0aW9uIGlzIGludmFsaWQKICogIERERVJSX0hXTkRBTFJFQURZU0VUIGlmIEREU0NMX1NFVEZPQ1VTV0lORE9XIGlzIHBhc3NlZCBpbiBleGNsdXNpdmUgbW9kZQogKiAgIChQcm9iYWJseSBvdGhlcnMgdG9vLCBoYXZlIHRvIGludmVzdGlnYXRlKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbChJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIGh3bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNvb3BsZXZlbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEhXTkQgd2luZG93OwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCUwOHgpXG4iLFRoaXMsaHduZCxjb29wbGV2ZWwpOwogICAgRERSQVdfZHVtcF9jb29wZXJhdGl2ZWxldmVsKGNvb3BsZXZlbCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAvKiBHZXQgdGhlIG9sZCB3aW5kb3cgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCAmd2luZG93KTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNERGV2aWNlOjpHZXRIV05EIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogVGVzdHMgc3VnZ2VzdCB0aGF0IHdlIG5lZWQgb25lIG9mIHRoZW06ICovCiAgICBpZighKGNvb3BsZXZlbCAmIChERFNDTF9TRVRGT0NVU1dJTkRPVyB8CiAgICAgICAgICAgICAgICAgICAgICBERFNDTF9OT1JNQUwgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICBERFNDTF9FWENMVVNJVkUgICAgICApKSkKICAgIHsKICAgICAgICBUUkFDRSgiSW5jb3JyZWN0IGNvb3BsZXZlbCBmbGFncywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogSGFuZGxlIHRob3NlIGxldmVscyBmaXJzdCB3aGljaCBzZXQgdmFyaW91cyBod25kcyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfU0VURk9DVVNXSU5ET1cpCiAgICB7CiAgICAgICAgLyogVGhpcyBpc24ndCBjb21wYXRpYmxlIHdpdGggYSBsb3Qgb2YgZmxhZ3MgKi8KICAgICAgICBpZihjb29wbGV2ZWwgJiAoIEREU0NMX01VTFRJVEhSRUFERUQgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9GUFVTRVRVUCAgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlBVUFJFU0VSVkUgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0FMTE9XUkVCT09UICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9BTExPV01PREVYICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfU0VUREVWSUNFV0lORE9XIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX05PUk1BTCAgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9FWENMVVNJVkUgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlVMTFNDUkVFTiAgICAgICkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIkNhbGxlZCB3aXRoIGluY29tcGF0aWJsZSBmbGFncywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRlVMTFNDUkVFTikgJiYgd2luZG93KQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgRERTQ0xfU0VURk9DVVNXSU5ET1cgd2l0aCBhbiBhbHJlYWR5IHNldCB3aW5kb3csIHJldHVybmluZyBEREVSUl9IV05EQUxSRUFEWVNFVFxuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9IV05EQUxSRUFEWVNFVDsKICAgICAgICB9CgogICAgICAgIFRoaXMtPmZvY3Vzd2luZG93ID0gaHduZDsKICAgICAgICAvKiBXb24ndCB1c2UgdGhlIGh3bmQgcGFyYW0gZm9yIGFueXRoaW5nIGVsc2UgKi8KICAgICAgICBod25kID0gTlVMTDsKCiAgICAgICAgLyogVXNlIHRoZSBmb2N1cyB3aW5kb3cgZm9yIGRyYXdpbmcgdG9vICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBUaGlzLT5mb2N1c3dpbmRvdyk7CgogICAgICAgIC8qIERlc3Ryb3kgdGhlIGRldmljZSB3aW5kb3csIGlmIHdlIGhhdmUgb25lICovCiAgICAgICAgaWYoVGhpcy0+ZGV2aWNld2luZG93KQogICAgICAgIHsKICAgICAgICAgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIC8qIEREU0NMX05PUk1BTCBvciBERFNDTF9GVUxMU0NSRUVOIHwgRERTQ0xfRVhDTFVTSVZFICovCiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9OT1JNQUwpCiAgICB7CiAgICAgICAgLyogQ2FuJ3QgY29leGlzdCB3aXRoIGZ1bGxzY3JlZW4gb3IgZXhjbHVzaXZlICovCiAgICAgICAgaWYoY29vcGxldmVsICYgKEREU0NMX0ZVTExTQ1JFRU4gfCBERFNDTF9FWENMVVNJVkUpICkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIEREU0NMX05PUk1BTCBpcyBub3QgY29tcGF0aXZlIHdpdGggRERTQ0xfRlVMTFNDUkVFTiBvciBERFNDTF9FWENMVVNJVkVcbiIsIFRoaXMpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CgogICAgICAgIC8qIFN3aXRjaGluZyBmcm9tIGZ1bGxzY3JlZW4/ICovCiAgICAgICAgaWYoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9GVUxMU0NSRUVOKQogICAgICAgIHsKICAgICAgICAgICAgLyogUmVzdG9yZSB0aGUgZGlzcGxheSBtb2RlICovCiAgICAgICAgICAgIElEaXJlY3REcmF3N19SZXN0b3JlRGlzcGxheU1vZGUoaWZhY2UpOwoKICAgICAgICAgICAgVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJj0gfkREU0NMX0ZVTExTQ1JFRU47CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9FWENMVVNJVkU7CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9BTExPV01PREVYOwogICAgICAgIH0KCiAgICAgICAgLyogRG9uJ3Qgb3ZlcnJpZGUgZm9jdXMgd2luZG93cyBvciBwcml2YXRlIGRldmljZSB3aW5kb3dzICovCiAgICAgICAgaWYoIGh3bmQgJiYKICAgICAgICAgICAgIShUaGlzLT5mb2N1c3dpbmRvdykgJiYKICAgICAgICAgICAgIShUaGlzLT5kZXZpY2V3aW5kb3cpICYmCiAgICAgICAgICAgIChod25kICE9IHdpbmRvdykgKQogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBod25kKTsKICAgICAgICB9CgogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFKTsKICAgIH0KICAgIGVsc2UgaWYoY29vcGxldmVsICYgRERTQ0xfRlVMTFNDUkVFTikKICAgIHsKICAgICAgICAvKiBOZWVkcyBERFNDTF9FWENMVVNJVkUgKi8KICAgICAgICBpZighKGNvb3BsZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfRlVMTFNDUkVFTiBuZWVkcyBERFNDTF9FWENMVVNJVkVcbiIsIFRoaXMpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgLyogTmVlZCBhIEhXTkQKICAgICAgICBpZihod25kID09IDApCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBERFNDTF9GVUxMU0NSRUVOIG5lZWRzIGEgSFdORFxuIiwgVGhpcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KICAgICAgICAqLwoKICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfTk9STUFMOwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUpOwoKICAgICAgICAvKiBEb24ndCBvdmVycmlkZSBmb2N1cyB3aW5kb3dzIG9yIHByaXZhdGUgZGV2aWNlIHdpbmRvd3MgKi8KICAgICAgICBpZiggaHduZCAmJgogICAgICAgICAgICAhKFRoaXMtPmZvY3Vzd2luZG93KSAmJgogICAgICAgICAgICAhKFRoaXMtPmRldmljZXdpbmRvdykgJiYKICAgICAgICAgICAgKGh3bmQgIT0gd2luZG93KSApCiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsIGh3bmQpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYoY29vcGxldmVsICYgRERTQ0xfRVhDTFVTSVZFKQogICAgewogICAgICAgIFRSQUNFKCIoJXApIEREU0NMX0VYQ0xVU0lWRSBuZWVkcyBERFNDTF9GVUxMU0NSRUVOXG4iLCBUaGlzKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0NSRUFURURFVklDRVdJTkRPVykKICAgIHsKICAgICAgICAvKiBEb24ndCBjcmVhdGUgYSBkZXZpY2Ugd2luZG93IGlmIGEgZm9jdXMgd2luZG93IGlzIHNldCAqLwogICAgICAgIGlmKCAhKFRoaXMtPmZvY3Vzd2luZG93KSApCiAgICAgICAgewogICAgICAgICAgICBIV05EIGRldmljZXdpbmRvdyA9IENyZWF0ZVdpbmRvd0V4QSgwLCBUaGlzLT5jbGFzc25hbWUsICJERHJhdyBkZXZpY2Ugd2luZG93IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfUE9QVVAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgR2V0TW9kdWxlSGFuZGxlQSgwKSwgTlVMTCk7CgogICAgICAgICAgICBTaG93V2luZG93KGRldmljZXdpbmRvdywgU1dfU0hPVyk7ICAgLyogSnVzdCB0byBiZSBzdXJlICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIENyZWF0ZWQgYSBERHJhdyBkZXZpY2Ugd2luZG93LiBIV05EPSVwXG4iLCBUaGlzLCBkZXZpY2V3aW5kb3cpOwoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBkZXZpY2V3aW5kb3cpOwogICAgICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSBkZXZpY2V3aW5kb3c7CiAgICAgICAgfQogICAgfQoKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX01VTFRJVEhSRUFERUQgJiYgIShUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX01VTFRJVEhSRUFERUQpKQogICAgewogICAgICAgIC8qIEVuYWJsZSB0aHJlYWQgc2FmZXR5IGluIHdpbmVkM2QgKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRNdWx0aXRocmVhZGVkKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgfQoKICAgIC8qIFVuaGFuZGxlZCBmbGFncyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dSRUJPT1QpCiAgICAgICAgV0FSTigiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9BTExPV1JFQk9PVCwgaGFybWxlc3NcbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dNT0RFWCkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0FMTE9XTU9ERVgsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZQVVNFVFVQKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfRlBVU0VUVVAsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZQVVBSRVNFUlZFKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfRlBVUFJFU0VSVkUsIGhhcm1sZXNzXG4iLCBUaGlzKTsKCiAgICAvKiBTdG9yZSB0aGUgY29vcGVyYXRpdmVfbGV2ZWwgKi8KICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsIHw9IGNvb3BsZXZlbDsKICAgIFRSQUNFKCJTZXRDb29wZXJhdGl2ZUxldmVsIHJldHVuaW5nIEREX09LXG4iKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBIZWxwZXIgZnVuY3Rpb24gZm9yIFNldERpc3BsYXlNb2RlIGFuZCBSZXN0b3JlRGlzcGxheU1vZGUKICoKICogSW1wbGVtZW50cyBEaXJlY3REcmF3J3MgU2V0RGlzcGxheU1vZGUsIGJ1dCBpZ25vcmVzIHRoZSB2YWx1ZSBvZgogKiBGb3JjZVJlZnJlc2hSYXRlLCBzaW5jZSBpdCBpcyBhbHJlYWR5IGhhbmRsZWQgYnkKICogSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlLiAgUmVzdG9yZURpc3BsYXlNb2RlIGNhbiB1c2UgdGhpcyBmdW5jdGlvbgogKiB3aXRob3V0IHdvcnJ5aW5nIHRoYXQgRm9yY2VSZWZyZXNoUmF0ZSB3aWxsIG92ZXJyaWRlIHRoZSByZWZyZXNoIHJhdGUuICBGb3IKICogYXJndW1lbnQgYW5kIHJldHVybiB2YWx1ZSBkb2N1bWVudGF0aW9uLCBzZWUKICogSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3REcmF3SW1wbF9TZXREaXNwbGF5TW9kZU5vT3ZlcnJpZGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQlBQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFJlZnJlc2hSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgV0lORUQzRERJU1BMQVlNT0RFIE1vZGU7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlZCwlZCwleDogUmVsYXkhXG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LCBCUFAsIFJlZnJlc2hSYXRlLCBGbGFncyk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKCAhV2lkdGggfHwgIUhlaWdodCApCiAgICB7CiAgICAgICAgRVJSKCJXaWR0aD0lZCwgSGVpZ2h0PSVkLCB3aGF0IHRvIGRvP1xuIiwgV2lkdGgsIEhlaWdodCk7CiAgICAgICAgLyogSXQgbG9va3MgbGlrZSBOZWVkIGZvciBTcGVlZCBQb3JzY2hlIFVubGVhc2hlZCBleHBlY3RzIEREX09LIGhlcmUgKi8KICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBERF9PSzsKICAgIH0KCiAgICAvKiBDaGVjayB0aGUgZXhjbHVzaXZlIG1vZGUKICAgIGlmKCEoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpKQogICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICAgKiBUaGlzIGlzIFdST05HLiBEb24ndCBrbm93IGlmIHRoZSBTREsgaXMgY29tcGxldGVseQogICAgICogd3JvbmcgYW5kIGlmIHRoZXJlIGFyZSBhbnkgY29uZGl0aW9ucyB3aGVuIERERVJSX05PRVhDTFVTSVZFCiAgICAgKiBpcyByZXR1cm5lZCwgYnV0IEhhbGYtTGlmZSAxLjEuMS4xIChTdGVhbSB2ZXJzaW9uKQogICAgICogZGVwZW5kcyBvbiB0aGlzCiAgICAgKi8KCiAgICBNb2RlLldpZHRoID0gV2lkdGg7CiAgICBNb2RlLkhlaWdodCA9IEhlaWdodDsKICAgIE1vZGUuUmVmcmVzaFJhdGUgPSBSZWZyZXNoUmF0ZTsKICAgIHN3aXRjaChCUFApCiAgICB7CiAgICAgICAgY2FzZSA4OiAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1A4OyAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDFSNUc1QjU7IGJyZWFrOwogICAgICAgIGNhc2UgMTY6IE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SNUc2QjU7ICAgYnJlYWs7CiAgICAgICAgY2FzZSAyNDogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I4RzhCODsgICBicmVhazsKICAgICAgICBjYXNlIDMyOiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDhSOEc4Qjg7IGJyZWFrOwogICAgfQoKICAgIC8qIFRPRE86IFRoZSBwb3NzaWJsZSByZXR1cm4gdmFsdWVzIGZyb20gbXNkbiBzdWdnZXN0IHRoYXQKICAgICAqIHRoZSBzY3JlZW4gbW9kZSBjYW4ndCBiZSBjaGFuZ2VkIGlmIGEgc3VyZmFjZSBpcyBsb2NrZWQKICAgICAqIG9yIHNvbWUgZHJhd2luZyBpcyBpbiBwcm9ncmVzcwogICAgICovCgogICAgLyogVE9ETzogTG9zZSB0aGUgcHJpbWFyeSBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIEZpcnN0IHN3YXBjaGFpbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9OT1RBVkFJTEFCTEU6ICAgICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKICAgICAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpTZXREaXNwbGF5TW9kZQogKgogKiBTZXRzIHRoZSBkaXNwbGF5IHNjcmVlbiByZXNvbHV0aW9uLCBjb2xvciBkZXB0aCBhbmQgcmVmcmVzaCBmcmVxdWVuY3kKICogd2hlbiBpbiBmdWxsc2NyZWVuIG1vZGUgKGluIHRoZW9yeSkuCiAqIFBvc3NpYmxlIHJldHVybiB2YWx1ZXMgbGlzdGVkIGluIHRoZSBTREsgc3VnZ2VzdCB0aGF0IHRoaXMgbWV0aG9kIGZhaWxzCiAqIHdoZW4gbm90IGluIGZ1bGxzY3JlZW4gbW9kZSwgYnV0IHRoaXMgaXMgd3JvbmcuIFdpbmRvd3MgMjAwMCBoYXBwaWx5IHNldHMKICogdGhlIGRpc3BsYXkgbW9kZSBpbiBERFNDTF9OT1JNQUwgbW9kZSB3aXRob3V0IGFuIGh3bmQgc3BlY2lmaWVkLgogKiBJdCBzZWVtcyB0byBiZSB2YWxpZCB0byBwYXNzIDAgZm9yIFdpdGggYW5kIEhlaWdodCwgdGhpcyBoYXMgdG8gYmUgdGVzdGVkCiAqIEl0IGNvdWxkIG1lYW4gdGhhdCB0aGUgY3VycmVudCB2aWRlbyBtb2RlIHNob3VsZCBiZSBsZWZ0IGFzLWlzLiAoQnV0IHdoeQogKiBjYWxsIGl0IHRoZW4/KQogKgogKiBQYXJhbXM6CiAqICBIZWlnaHQsIFdpZHRoOiBTY3JlZW4gZGltZW5zaW9uCiAqICBCUFA6IENvbG9yIGRlcHRoIGluIEJpdHMgcGVyIHBpeGVsCiAqICBSZWZyZXNocmF0ZTogU2NyZWVuIHJlZnJlc2ggcmF0ZQogKiAgRmxhZ3M6IE90aGVyIHN0dWZmCiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEJQUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFJlZnJlc2hSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIGlmIChmb3JjZV9yZWZyZXNoX3JhdGUgIT0gMCkKICAgIHsKICAgICAgICBUUkFDRSgiRm9yY2VSZWZyZXNoUmF0ZSBvdmVycmlkaW5nIHBhc3NlZC1pbiByZWZyZXNoIHJhdGUgKCVkIEh6KSB0byAlZCBIelxuIiwgUmVmcmVzaFJhdGUsIGZvcmNlX3JlZnJlc2hfcmF0ZSk7CiAgICAgICAgUmVmcmVzaFJhdGUgPSBmb3JjZV9yZWZyZXNoX3JhdGU7CiAgICB9CgogICAgcmV0dXJuIElEaXJlY3REcmF3SW1wbF9TZXREaXNwbGF5TW9kZU5vT3ZlcnJpZGUoaWZhY2UsIFdpZHRoLCBIZWlnaHQsIEJQUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlZnJlc2hSYXRlLCBGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlJlc3RvcmVEaXNwbGF5TW9kZQogKgogKiBSZXN0b3JlcyB0aGUgZGlzcGxheSBtb2RlIHRvIHdoYXQgaXQgd2FzIGF0IGNyZWF0aW9uIHRpbWUuIEJhc2ljYWxseS4KICoKICogQSBwcm9ibGVtIGFyaXNlcyB3aGVuIHRoZXJlIGFyZSAyIERpcmVjdERyYXcgb2JqZWN0cyB1c2luZyB0aGUgc2FtZSBod25kOgogKiAgLT4gRERfMSBmaW5kcyB0aGUgc2NyZWVuIGF0IDE0MDB4MTA1MHgzMiB3aGVuIGNyZWF0ZWQsIHNldHMgaXQgdG8gNjQweDQ4MHgxNgogKiAgLT4gRERfMiBpcyBjcmVhdGVkLCBmaW5kcyB0aGUgc2NyZWVuIGF0IDY0MHg0ODB4MTYsIHNldHMgaXQgdG8gMTAyNHg3Njh4MzIKICogIC0+IEREXzEgaXMgcmVsZWFzZWQuIFRoZSBzY3JlZW4gc2hvdWxkIGJlIGxlZnQgYXQgMTAyNHg3Njh4MzIuCiAqICAtPiBERF8yIGlzIHJlbGVhc2VkLiBUaGUgc2NyZWVuIHNob3VsZCBiZSBzZXQgdG8gMTQwMHgxMDUweDMyCiAqIFRoaXMgY2FzZSBpcyB1bmhhbmRsZWQgcmlnaHQgbm93LCBidXQgRW1waXJlIEVhcnRoIGRvZXMgaXQgdGhpcyB3YXkuCiAqIChCdXQgcGVyaGFwcyB0aGVyZSBpcyBzb21ldGhpbmcgaW4gU2V0Q29vcGVyYXRpdmVMZXZlbCB0byBwcmV2ZW50IHRoaXMpCiAqCiAqIFRoZSBtc2RuIHNheXMgdGhhdCB0aGlzIG1ldGhvZCByZXNldHMgdGhlIGRpc3BsYXkgbW9kZSB0byB3aGF0IGl0IHdhcyBiZWZvcmUKICogU2V0RGlzcGxheU1vZGUgd2FzIGNhbGxlZC4gV2hhdCBpZiBTZXREaXNwbGF5TW9kZXMgaXMgY2FsbGVkIDIgdGltZXM/PwogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9OT0VYQ0xVU0lWRSBtb2RlIGlmIHRoZSBkZXZpY2UgaXNuJ3QgaW4gZnVsbHNjcmVlbiBtb2RlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZXN0b3JlRGlzcGxheU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlTm9PdmVycmlkZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ193aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPm9yaWdfaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ19icHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldENhcHMKICoKICogUmV0dXJucyB0aGUgZHJpdmVzIGNhcGFiaWxpdGllcwogKgogKiBVc2VkIGZvciB2ZXJzaW9uIDEsIDIsIDQgYW5kIDcKICoKICogUGFyYW1zOgogKiAgRHJpdmVyQ2FwczogU3RydWN0dXJlIHRvIHdyaXRlIHRoZSBIYXJkd2FyZSBhY2NlbGVyYXRlZCBjYXBzIHRvCiAqICBIZWxDYXBzOiBTdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIGVtdWxhdGlvbiBjYXBzIHRvCiAqCiAqIFJldHVybnMKICogIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBERF9PSyBvbmx5CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRDYXBzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIEREQ0FQUyAqRHJpdmVyQ2FwcywKICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTICpIRUxDYXBzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIERyaXZlckNhcHMsIEhFTENhcHMpOwoKICAgIC8qIE9uZSBzdHJ1Y3R1cmUgbXVzdCBiZSAhPSBOVUxMICovCiAgICBpZiggKCFEcml2ZXJDYXBzKSAmJiAoIUhFTENhcHMpICkKICAgIHsKICAgICAgICBFUlIoIiglcCkgSW52YWxpZCBwYXJhbXMgdG8gSURpcmVjdERyYXdJbXBsX0dldENhcHNcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKERyaXZlckNhcHMpCiAgICB7CiAgICAgICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKERyaXZlckNhcHMsICZUaGlzLT5jYXBzKTsKICAgICAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIkRyaXZlciBDYXBzIDpcbiIpOwogICAgICAgICAgICBERFJBV19kdW1wX0REQ0FQUyhEcml2ZXJDYXBzKTsKICAgICAgICB9CgogICAgfQogICAgaWYoSEVMQ2FwcykKICAgIHsKICAgICAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoSEVMQ2FwcywgJlRoaXMtPmNhcHMpOwogICAgICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiSEVMIENhcHMgOlxuIik7CiAgICAgICAgICAgIEREUkFXX2R1bXBfRERDQVBTKEhFTENhcHMpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNvbXBhY3QKICoKICogTm8gaWRlYSB3aGF0IGl0IGRvZXMsIE1TRE4gc2F5cyBpdCdzIG5vdCBpbXBsZW1lbnRlZC4KICoKICogUmV0dXJucwogKiAgRERfT0ssIGJ1dCB0aGlzIGlzIHVuY2hlY2tlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ29tcGFjdChJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0RGlzcGxheU1vZGUKICoKICogUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudCBkaXNwbGF5IG1vZGUKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBERFNEOiBBZGRyZXNzIG9mIGEgc3VyZmFjZSBkZXNjcmlwdGlvbiBzdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIGluZm8gdG8KICoKICogUmV0dXJucwogKiAgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldERpc3BsYXlNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKICAgIERXT1JEIFNpemU7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsIFRoaXMsIEREU0QpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAvKiBUaGlzIHNlZW1zIHNhbmUgKi8KICAgIGlmKCFERFNEKSAKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFRoZSBuZWNlc3NhcnkgbWVtYmVycyBvZiBMUEREU1VSRkFDRURFU0MgYW5kIExQRERTVVJGQUNFREVTQzIgYXJlIGVxdWFsLAogICAgICogc28gb25lIG1ldGhvZCBjYW4gYmUgdXNlZCBmb3IgYWxsIHZlcnNpb25zIChIb3BlZnVsbHkpCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0RGlzcGxheU1vZGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIHN3YXBjaGFpbiAwICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNb2RlKTsKICAgIGlmKCBociAhPSBEM0RfT0sgKQogICAgewogICAgICAgIEVSUigiICglcCkgSVdpbmVEM0REZXZpY2U6OkdldERpc3BsYXlNb2RlIHJldHVybmVkICUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBTaXplID0gRERTRC0+ZHdTaXplOwogICAgbWVtc2V0KEREU0QsIDAsIFNpemUpOwoKICAgIEREU0QtPmR3U2l6ZSA9IFNpemU7CiAgICBERFNELT5kd0ZsYWdzIHw9IEREU0RfSEVJR0hUIHwgRERTRF9XSURUSCB8IEREU0RfUElYRUxGT1JNQVQgfCBERFNEX1BJVENIIHwgRERTRF9SRUZSRVNIUkFURTsKICAgIEREU0QtPmR3V2lkdGggPSBNb2RlLldpZHRoOwogICAgRERTRC0+ZHdIZWlnaHQgPSBNb2RlLkhlaWdodDsgCiAgICBERFNELT51Mi5kd1JlZnJlc2hSYXRlID0gNjA7CiAgICBERFNELT5kZHNDYXBzLmR3Q2FwcyA9IDA7CiAgICBERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdCk7CiAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0LCBNb2RlLkZvcm1hdCk7CiAgICBERFNELT51MS5sUGl0Y2ggPSBNb2RlLldpZHRoICogRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQgLyA4OwoKICAgIGlmKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiUmV0dXJuaW5nIHN1cmZhY2UgZGVzYyA6XG4iKTsKICAgICAgICBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhERFNEKTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRGb3VyQ0NDb2RlcwogKgogKiBSZXR1cm5zIGFuIGFycmF5IG9mIHN1cHBvcnRlZCBGb3VyQ0MgY29kZXMuCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIsIDQgYW5kIDcKICoKICogUGFyYW1zOgogKiAgTnVtQ29kZXM6IENvbnRhaW5zIHRoZSBudW1iZXIgb2YgQ29kZXMgdGhhdCBDb2RlcyBjYW4gY2FycnkuIFJldHVybnMgdGhlIG51bWJlcgogKiAgICAgICAgICAgIG9mIGVudW1lcmF0ZWQgY29kZXMKICogIENvZGVzOiBQb2ludGVyIHRvIGFuIGFycmF5IG9mIERXT1JEcyB3aGVyZSB0aGUgc3VwcG9ydGVkIGNvZGVzIGFyZSB3cml0dGVuCiAqICAgICAgICAgdG8KICoKICogUmV0dXJucwogKiAgQWx3YXlzIHJldHVybnMgRERfT0ssIGFzIGl0J3MgYSBzdHViIGZvciBub3cKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldEZvdXJDQ0NvZGVzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqTnVtQ29kZXMsIERXT1JEICpDb2RlcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsICVwKTogU3R1YiFcbiIsIFRoaXMsIE51bUNvZGVzLCBDb2Rlcyk7CgogICAgaWYoTnVtQ29kZXMpICpOdW1Db2RlcyA9IDA7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRNb25pdG9yRnJlcXVlbmN5CiAqCiAqIFJldHVybnMgdGhlIG1vbml0b3IncyBmcmVxdWVuY3kKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBGcmVxOiBQb2ludGVyIHRvIGEgRFdPUkQgdG8gd3JpdGUgdGhlIGZyZXF1ZW5jeSB0bwogKgogKiBSZXR1cm5zCiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0TW9uaXRvckZyZXF1ZW5jeShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqRnJlcSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBGcmVxKTsKCiAgICAvKiBJZGVhbGx5IHRoaXMgc2hvdWxkIGJlIGluIFdpbmVEM0QsIGFzIGl0IGNvbmNlcm5zIHRoZSBzY3JlZW4gc2V0dXAsCiAgICAgKiBidXQgZm9yIG5vdyB0aGlzIHNob3VsZCBtYWtlIHRoZSBnYW1lcyBoYXBweQogICAgICovCiAgICAqRnJlcSA9IDYwOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRWZXJ0aWNhbEJsYW5rU3RhdHVzCiAqCiAqIFJldHVybnMgdGhlIFZlcnRpY2FsIGJsYW5rIHN0YXR1cyBvZiB0aGUgbW9uaXRvci4gVGhpcyBzaG91bGQgYmUgaW4gV2luZUQzRAogKiB0b28gYmFzaWNhbGx5LCBidXQgYXMgaXQncyBhIHNlbWkgc3R1YiwgSSBkaWRuJ3QgY3JlYXRlIGEgZnVuY3Rpb24gdGhlcmUKICoKICogUGFyYW1zOgogKiAgc3RhdHVzOiBQb2ludGVyIHRvIGEgQk9PTCB0byBiZSBmaWxsZWQgd2l0aCB0aGUgdmVydGljYWwgYmxhbmsgc3RhdHVzCiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgc3RhdHVzIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldFZlcnRpY2FsQmxhbmtTdGF0dXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCAqc3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHN0YXR1cyk7CgogICAgLyogVGhpcyBsb29rcyBzYW5lLCB0aGUgTVNETiBzdWdnZXN0cyBpdCB0b28gKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZighc3RhdHVzKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgKnN0YXR1cyA9IFRoaXMtPmZha2VfdmJsYW5rOwogICAgVGhpcy0+ZmFrZV92YmxhbmsgPSAhVGhpcy0+ZmFrZV92Ymxhbms7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRBdmFpbGFibGVWaWRNZW0KICoKICogUmV0dXJucyB0aGUgdG90YWwgYW5kIGZyZWUgdmlkZW8gbWVtb3J5CiAqCiAqIFBhcmFtczoKICogIENhcHM6IFNwZWNpZmllcyB0aGUgbWVtb3J5IHR5cGUgYXNrZWQgZm9yCiAqICB0b3RhbDogUG9pbnRlciB0byBhIERXT1JEIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSB0b3RhbCBtZW1vcnkKICogIGZyZWU6IFBvaW50ZXIgdG8gYSBEV09SRCB0byBiZSBmaWxsZWQgd2l0aCB0aGUgZnJlZSBtZW1vcnkKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBvZiBmcmVlIGFuZCB0b3RhbCBhcmUgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0QXZhaWxhYmxlVmlkTWVtKElEaXJlY3REcmF3NyAqaWZhY2UsIEREU0NBUFMyICpDYXBzLCBEV09SRCAqdG90YWwsIERXT1JEICpmcmVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwgJXAsICVwKVxuIiwgVGhpcywgQ2FwcywgdG90YWwsIGZyZWUpOwoKICAgIGlmKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKSBBc2tlZCBmb3IgbWVtb3J5IHdpdGggZGVzY3JpcHRpb246ICIsIFRoaXMpOwogICAgICAgIEREUkFXX2R1bXBfRERTQ0FQUzIoQ2Fwcyk7CiAgICB9CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIC8qIFRvZG86IFN5c3RlbSBtZW1vcnkgdnMgbG9jYWwgdmlkZW8gbWVtb3J5IHZzIG5vbi1sb2NhbCB2aWRlbyBtZW1vcnkKICAgICAqIFRoZSBNU0ROIGFsc28gbWVudGlvbnMgZGlmZmVyZW5jZXMgYmV0d2VlbiB0ZXh0dXJlIG1lbW9yeSBhbmQgb3RoZXIKICAgICAqIHJlc291cmNlcywgYnV0IHRoYXQncyBub3QgaW1wb3J0YW50CiAgICAgKi8KCiAgICBpZiggKCF0b3RhbCkgJiYgKCFmcmVlKSApCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZih0b3RhbCkgKnRvdGFsID0gVGhpcy0+dG90YWxfdmlkbWVtOwogICAgaWYoZnJlZSkgKmZyZWUgPSBJV2luZUQzRERldmljZV9HZXRBdmFpbGFibGVUZXh0dXJlTWVtKFRoaXMtPndpbmVEM0REZXZpY2UpOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkluaXRpYWxpemUKICoKICogSW5pdGlhbGl6ZXMgYSBEaXJlY3REcmF3IGludGVyZmFjZS4KICoKICogUGFyYW1zOgogKiAgR1VJRDogSW50ZXJmYWNlIGlkZW50aWZpZXIuIFdlbGwsIGRvbid0IGtub3cgd2hhdCB0aGlzIGlzIHJlYWxseSBnb29kCiAqICAgZm9yCiAqCiAqIFJldHVybnMKICogIFJldHVybnMgRERfT0sgb24gdGhlIGZpcnN0IGNhbGwsCiAqICBEREVSUl9BTFJFQURZSU5JVElBTElaRUQgb24gcmVwZWF0ZWQgY2FsbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0luaXRpYWxpemUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgR1VJRCAqR3VpZCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXMpOiBOby1vcFxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChHdWlkKSk7CgogICAgaWYoVGhpcy0+aW5pdGlhbGl6ZWQpCiAgICB7CiAgICAgICAgcmV0dXJuIERERVJSX0FMUkVBRFlJTklUSUFMSVpFRDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gRERfT0s7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkZsaXBUb0dESVN1cmZhY2UKICoKICogIk1ha2VzIHRoZSBzdXJmYWNlIHRoYXQgdGhlIEdESSB3cml0ZXMgdG8gdGhlIHByaW1hcnkgc3VyZmFjZSIKICogTG9va3MgbGlrZSBzb21lIHdpbmRvd3Mgc3BlY2lmaWMgdGhpbmcgd2UgZG9uJ3QgaGF2ZSB0byBjYXJlIGFib3V0LgogKiBBY2NvcmRpbmcgdG8gTVNETiBpdCBwZXJtaXRzIEdESSBkaWFsb2cgYm94ZXMgaW4gRlVMTFNDUkVFTiBtb2RlLiBHb29kIHRvCiAqIHNob3cgZXJyb3IgYm94ZXMgOykKICogV2VsbCwganVzdCByZXR1cm4gRERfT0suCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRmxpcFRvR0RJU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6V2FpdEZvclZlcnRpY2FsQmxhbmsKICoKICogVGhpcyBtZXRob2QgYWxsb3dzIGFwcGxpY2F0aW9ucyB0byBnZXQgaW4gc3luYyB3aXRoIHRoZSB2ZXJ0aWNhbCBibGFuawogKiBpbnRlcnZhbC4KICogVGhlIHdvcm1ob2xlIGRlbW8gaW4gdGhlIERpcmVjdFggNyBzZGsgdXNlcyB0aGlzIGNhbGwsIGFuZCBpdCBkb2Vzbid0CiAqIHJlZHJhdyB0aGUgc2NyZWVuLCBtb3N0IGxpa2VseSBiZWNhdXNlIG9mIHRoaXMgc3R1YgogKgogKiBQYXJhbWV0ZXJzOgogKiAgRmxhZ3M6IG9uZSBvZiBERFdBSVRWQl9CTE9DS0JFR0lOLCBERFdBSVRWQl9CTE9DS0JFR0lORVZFTlQKICogICAgICAgICBvciBERFdBSVRWQl9CTE9DS0VORAogKiAgaDogTm90IHVzZWQsIGFjY29yZGluZyB0byBNU0ROCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1dhaXRGb3JWZXJ0aWNhbEJsYW5rKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPigleCwlcCk6IFN0dWJcbiIsIFRoaXMsIEZsYWdzLCBoKTsKCiAgICAvKiBNU0ROIHNheXMgRERXQUlUVkJfQkxPQ0tCRUdJTkVWRU5UIGlzIG5vdCBzdXBwb3J0ZWQgKi8KICAgIGlmKEZsYWdzICYgRERXQUlUVkJfQkxPQ0tCRUdJTkVWRU5UKQogICAgICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsgLyogdW5jaGVja2VkICovCgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRTY2FuTGluZQogKgogKiBSZXR1cm5zIHRoZSBzY2FuIGxpbmUgdGhhdCBpcyBiZWluZyBkcmF3biBvbiB0aGUgbW9uaXRvcgogKgogKiBQYXJhbWV0ZXJzOgogKiAgU2NhbmxpbmU6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHNjYW4gbGluZSB2YWx1ZSB0bwogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3SW1wbF9HZXRTY2FuTGluZShJRGlyZWN0RHJhdzcgKmlmYWNlLCBEV09SRCAqU2NhbmxpbmUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBzdGF0aWMgQk9PTCBoaWRlID0gRkFMU0U7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKCiAgICAvKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBvZnRlbiwgc28gcHJpbnQgdGhlIGZpeG1lIG9ubHkgb25jZSAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKCFoaWRlKQogICAgewogICAgICAgIEZJWE1FKCIoJXApLT4oJXApOiBTZW1pLVN0dWJcbiIsIFRoaXMsIFNjYW5saW5lKTsKICAgICAgICBoaWRlID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZV9HZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNb2RlKTsKCiAgICAvKiBGYWtlIHRoZSBsaW5lIHN3ZWVwaW5nIG9mIHRoZSBtb25pdG9yICovCiAgICAvKiBGSVhNRTogV2Ugc2hvdWxkIHN5bmNocm9uaXplIHdpdGggYSBzb3VyY2UgdG8ga2VlcCB0aGUgcmVmcmVzaCByYXRlICovIAogICAgKlNjYW5saW5lID0gVGhpcy0+Y3VyX3NjYW5saW5lKys7CiAgICAvKiBBc3N1bWUgMjAgc2NhbiBsaW5lcyBpbiB0aGUgdmVydGljYWwgYmxhbmsgKi8KICAgIGlmIChUaGlzLT5jdXJfc2NhbmxpbmUgPj0gTW9kZS5IZWlnaHQgKyAyMCkKICAgICAgICBUaGlzLT5jdXJfc2NhbmxpbmUgPSAwOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlRlc3RDb29wZXJhdGl2ZUxldmVsCiAqCiAqIEluZm9ybXMgdGhlIGFwcGxpY2F0aW9uIGFib3V0IHRoZSBzdGF0ZSBvZiB0aGUgdmlkZW8gYWRhcHRlciwgZGVwZW5kaW5nCiAqIG9uIHRoZSBjb29wZXJhdGl2ZSBsZXZlbAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIGRldmljZSBpcyBpbiBhIHNhbmUgc3RhdGUKICogIERERVJSX05PRVhDTFVTSVZFTU9ERSBvciBEREVSUl9FWENMVVNJVkVNT0RFQUxSRUFEWVNFVAogKiAgaWYgdGhlIHN0YXRlIGlzIG5vdCBjb3JyZWN0KFNlZSBiZWxvdykKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbChJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgLyogRGVzY3JpcHRpb24gZnJvbSBNU0ROOgogICAgICogRm9yIGZ1bGxzY3JlZW4gYXBwcyByZXR1cm4gRERFUlJfTk9FWENMVVNJVkVNT0RFIGlmIHRoZSB1c2VyIHN3aXRjaGVkCiAgICAgKiBhd2F5IGZyb20gdGhlIGFwcCB3aXRoIGUuZy4gYWx0LXRhYi4gV2luZG93ZWQgYXBwcyByZWNlaXZlIAogICAgICogRERFUlJfRVhDTFVTSVZFTU9ERUFMUkVBRFlTRVQgaWYgYW5vdGhlciBhcHBsaWNhdGlvbiBjcmVhdGVkIGEgCiAgICAgKiBEaXJlY3REcmF3IG9iamVjdCBpbiBleGNsdXNpdmUgbW9kZS4gRERFUlJfV1JPTkdNT0RFIGlzIHJldHVybmVkLAogICAgICogd2hlbiB0aGUgdmlkZW8gbW9kZSBoYXMgY2hhbmdlZAogICAgICovCgogICAgaHIgPSAgSVdpbmVEM0REZXZpY2VfVGVzdENvb3BlcmF0aXZlTGV2ZWwoVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgLyogRml4IHRoZSByZXN1bHQgdmFsdWUuIFRoZXNlIHZhbHVlcyBhcmUgbWFwcGVkIGZyb20gdGhlaXIKICAgICAqIGQzZDkgY291bnRlcnBhcnQuCiAgICAgKi8KICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTE9TVDoKICAgICAgICAgICAgaWYoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRERFUlJfTk9FWENMVVNJVkVNT0RFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9FWENMVVNJVkVNT0RFQUxSRUFEWVNFVDsKICAgICAgICAgICAgfQoKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTk9UUkVTRVQ6CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKCiAgICAgICAgY2FzZSBXSU5FRDNEX09LOgogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERfT0s7CgogICAgICAgIGNhc2UgV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiKCVwKSBVbmV4cGVjdGVkIHJldHVybiB2YWx1ZSAlMDh4IGZyb20gd2luZUQzRCwgIgogICAgICAgICAgICAgICAgIiByZXR1cm5pbmcgRERfT0tcbiIsIFRoaXMsIGhyKTsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRHRElTdXJmYWNlCiAqCiAqIFJldHVybnMgdGhlIHN1cmZhY2UgdGhhdCBHREkgaXMgdHJlYXRpbmcgYXMgdGhlIHByaW1hcnkgc3VyZmFjZS4KICogRm9yIFdpbmUgdGhpcyBpcyB0aGUgZnJvbnQgYnVmZmVyCiAqCiAqIFBhcmFtczoKICogIEdESVN1cmZhY2U6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIHN1cmZhY2Ugd2FzIGZvdW5kCiAqICBEREVSUl9OT1RGT1VORCBpZiB0aGUgR0RJIHN1cmZhY2Ugd2Fzbid0IGZvdW5kCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0R0RJU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqR0RJU3VyZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElXaW5lRDNEU3VyZmFjZSAqU3VyZjsKICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRkc3VyZjsKICAgIEhSRVNVTFQgaHI7CiAgICBERFNDQVBTMiBkZHNDYXBzOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIEdESVN1cmZhY2UpOwoKICAgIC8qIEdldCB0aGUgYmFjayBidWZmZXIgZnJvbSB0aGUgd2luZUQzRERldmljZSBhbmQgc2VhcmNoIGl0cwogICAgICogYXR0YWNoZWQgc3VyZmFjZXMgZm9yIHRoZSBmcm9udCBidWZmZXIKICAgICAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0QmFja0J1ZmZlcihUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIFN3YXBDaGFpbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIGZpcnN0IGJhY2sgYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEQkFDS0JVRkZFUl9UWVBFX01PTk8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN1cmYpOwoKICAgIGlmKCAoaHIgIT0gRDNEX09LKSB8fAogICAgICAgICghU3VyZikgKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0REZXZpY2U6OkdldEJhY2tCdWZmZXIgZmFpbGVkXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RGT1VORDsKICAgIH0KCiAgICAvKiBHZXRCYWNrQnVmZmVyIEFkZFJlZigpZWQgdGhlIHN1cmZhY2UsIHJlbGVhc2UgaXQgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKFN1cmYpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQoU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICoqKSAmZGRzdXJmKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShkZHN1cmYpOyAgLyogRm9yIHRoZSBHZXRQYXJlbnQgKi8KCiAgICAvKiBGaW5kIHRoZSBmcm9udCBidWZmZXIgKi8KICAgIGRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19GUk9OVEJVRkZFUjsKICAgIGhyID0gSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoZGRzdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGRzQ2FwcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0RJU3VyZmFjZSk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICBFUlIoIklEaXJlY3REcmF3U3VyZmFjZTc6OkdldEF0dGFjaGVkU3VyZmFjZSBmYWlsZWQsIGhyID0gJXhcbiIsIGhyKTsKICAgIH0KCiAgICAvKiBUaGUgQWRkUmVmIGlzIE9LIHRoaXMgdGltZSAqLwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RW51bURpc3BsYXlNb2RlcwogKgogKiBFbnVtZXJhdGVzIHRoZSBzdXBwb3J0ZWQgRGlzcGxheSBtb2Rlcy4gVGhlIG1vZGVzIGNhbiBiZSBmaWx0ZXJlZCB3aXRoCiAqIHRoZSBERFNEIHBhcmFtZXRlci4KICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IGNhbiBiZSBEREVETV9SRUZSRVNIUkFURVMgYW5kIERERURNX1NUQU5EQVJEVkdBTU9ERVMKICogIEREU0Q6IFN1cmZhY2UgZGVzY3JpcHRpb24gdG8gZmlsdGVyIHRoZSBtb2RlcwogKiAgQ29udGV4dDogUG9pbnRlciBwYXNzZWQgYmFjayB0byB0aGUgY2FsbGJhY2sgZnVuY3Rpb24KICogIGNiOiBBcHBsaWNhdGlvbi1wcm92aWRlZCBjYWxsYmFjayBmdW5jdGlvbgogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgY2FsbGJhY2sgd2Fzbid0IHNldAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0VudW1EaXNwbGF5TW9kZXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERERU5VTU1PREVTQ0FMTEJBQ0syIGNiKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgdW5zaWduZWQgaW50IG1vZGVudW0sIGZtdDsKICAgIFdJTkVEM0RGT1JNQVQgcGl4ZWxmb3JtYXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICBXSU5FRDNERElTUExBWU1PREUgbW9kZTsKICAgIEREU1VSRkFDRURFU0MyIGNhbGxiYWNrX3NkOwogICAgV0lORUQzRERJU1BMQVlNT0RFICplbnVtX21vZGVzID0gTlVMTDsKICAgIHVuc2lnbmVkIGVudW1fbW9kZV9jb3VudCA9IDAsIGVudW1fbW9kZV9hcnJheV9zaXplID0gMDsKCiAgICBXSU5FRDNERk9STUFUIGNoZWNrRm9ybWF0TGlzdFtdID0KICAgIHsKICAgICAgICBXSU5FRDNERk1UX1I4RzhCOCwKICAgICAgICBXSU5FRDNERk1UX0E4UjhHOEI4LAogICAgICAgIFdJTkVEM0RGTVRfWDhSOEc4QjgsCiAgICAgICAgV0lORUQzREZNVF9SNUc2QjUsCiAgICAgICAgV0lORUQzREZNVF9YMVI1RzVCNSwKICAgICAgICBXSU5FRDNERk1UX0ExUjVHNUI1LAogICAgICAgIFdJTkVEM0RGTVRfQTRSNEc0QjQsCiAgICAgICAgV0lORUQzREZNVF9SM0czQjIsCiAgICAgICAgV0lORUQzREZNVF9BOFIzRzNCMiwKICAgICAgICBXSU5FRDNERk1UX1g0UjRHNEI0LAogICAgICAgIFdJTkVEM0RGTVRfQTJCMTBHMTBSMTAsCiAgICAgICAgV0lORUQzREZNVF9BOEI4RzhSOCwKICAgICAgICBXSU5FRDNERk1UX1g4QjhHOFI4LAogICAgICAgIFdJTkVEM0RGTVRfQTJSMTBHMTBCMTAsCiAgICAgICAgV0lORUQzREZNVF9BOFA4LAogICAgICAgIFdJTkVEM0RGTVRfUDgKICAgIH07CgogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBERFNELCBDb250ZXh0LCBjYik7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSAqLwogICAgaWYoIWNiKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoRERTRCkKICAgIHsKICAgICAgICBpZiAoKEREU0QtPmR3RmxhZ3MgJiBERFNEX1BJWEVMRk9STUFUKSAmJiAoRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0LmR3RmxhZ3MgJiBERFBGX1JHQikgKQogICAgICAgICAgICBwaXhlbGZvcm1hdCA9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJkREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdCk7CiAgICB9CgogICAgaWYoIShGbGFncyAmIERERURNX1JFRlJFU0hSQVRFUykpCiAgICB7CiAgICAgICAgZW51bV9tb2RlX2FycmF5X3NpemUgPSAxNjsKICAgICAgICBlbnVtX21vZGVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihXSU5FRDNERElTUExBWU1PREUpICogZW51bV9tb2RlX2FycmF5X3NpemUpOwogICAgICAgIGlmICghZW51bV9tb2RlcykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICB9CgogICAgZm9yKGZtdCA9IDA7IGZtdCA8IChzaXplb2YoY2hlY2tGb3JtYXRMaXN0KSAvIHNpemVvZihjaGVja0Zvcm1hdExpc3RbMF0pKTsgZm10KyspCiAgICB7CiAgICAgICAgaWYocGl4ZWxmb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOICYmIGNoZWNrRm9ybWF0TGlzdFtmbXRdICE9IHBpeGVsZm9ybWF0KQogICAgICAgIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBtb2RlbnVtID0gMDsKICAgICAgICB3aGlsZShJV2luZUQzRF9FbnVtQWRhcHRlck1vZGVzKFRoaXMtPndpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEQURBUFRFUl9ERUZBVUxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tGb3JtYXRMaXN0W2ZtdF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbnVtKyssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbW9kZSkgPT0gV0lORUQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIGlmKEREU0QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmKEREU0QtPmR3RmxhZ3MgJiBERFNEX1dJRFRIICYmIG1vZGUuV2lkdGggIT0gRERTRC0+ZHdXaWR0aCkgY29udGludWU7CiAgICAgICAgICAgICAgICBpZihERFNELT5kd0ZsYWdzICYgRERTRF9IRUlHSFQgJiYgbW9kZS5IZWlnaHQgIT0gRERTRC0+ZHdIZWlnaHQpIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZighKEZsYWdzICYgRERFRE1fUkVGUkVTSFJBVEVTKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogRFggZG9jcyBzdGF0ZSBFbnVtRGlzcGxheU1vZGUgc2hvdWxkIHJldHVybiBvbmx5IHVuaXF1ZSBtb2Rlcy4gSWYgRERFRE1fUkVGUkVTSFJBVEVTIGlzIG5vdCBzZXQsIHJlZnJlc2gKICAgICAgICAgICAgICAgICAqIHJhdGUgZG9lc24ndCBtYXR0ZXIgd2hlbiBkZXRlcm1pbmluZyBpZiB0aGUgbW9kZSBpcyB1bmlxdWUuIFNvIG1vZGVzIG9ubHkgZGlmZmVyaW5nIGluIHJlZnJlc2ggcmF0ZSBoYXZlCiAgICAgICAgICAgICAgICAgKiB0byBiZSByZWR1Y2VkIHRvIGEgc2luZ2xlIHVuaXF1ZSByZXN1bHQgaW4gc3VjaCBjYXNlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBCT09MIGZvdW5kID0gRkFMU0U7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBlbnVtX21vZGVfY291bnQ7IGkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZihlbnVtX21vZGVzW2ldLldpZHRoID09IG1vZGUuV2lkdGggJiYgZW51bV9tb2Rlc1tpXS5IZWlnaHQgPT0gbW9kZS5IZWlnaHQgJiYKICAgICAgICAgICAgICAgICAgICAgICBlbnVtX21vZGVzW2ldLkZvcm1hdCA9PSBtb2RlLkZvcm1hdCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKGZvdW5kKSBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbWVtc2V0KCZjYWxsYmFja19zZCwgMCwgc2l6ZW9mKGNhbGxiYWNrX3NkKSk7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLmR3U2l6ZSA9IHNpemVvZihjYWxsYmFja19zZCk7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERQSVhFTEZPUk1BVCk7CgogICAgICAgICAgICBjYWxsYmFja19zZC5kd0ZsYWdzID0gRERTRF9IRUlHSFR8RERTRF9XSURUSHxERFNEX1BJWEVMRk9STUFUfEREU0RfUElUQ0g7CiAgICAgICAgICAgIGlmKEZsYWdzICYgRERFRE1fUkVGUkVTSFJBVEVTKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYWxsYmFja19zZC5kd0ZsYWdzIHw9IEREU0RfUkVGUkVTSFJBVEU7CiAgICAgICAgICAgICAgICBjYWxsYmFja19zZC51Mi5kd1JlZnJlc2hSYXRlID0gbW9kZS5SZWZyZXNoUmF0ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY2FsbGJhY2tfc2QuZHdXaWR0aCA9IG1vZGUuV2lkdGg7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLmR3SGVpZ2h0ID0gbW9kZS5IZWlnaHQ7CgogICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmY2FsbGJhY2tfc2QudTQuZGRwZlBpeGVsRm9ybWF0LCBtb2RlLkZvcm1hdCk7CgogICAgICAgICAgICAvKiBDYWxjIHBpdGNoIGFuZCBEV09SRCBhbGlnbiBsaWtlIE1TRE4gc2F5cyAqLwogICAgICAgICAgICBjYWxsYmFja19zZC51MS5sUGl0Y2ggPSAoY2FsbGJhY2tfc2QudTQuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQgLyA4KSAqIG1vZGUuV2lkdGg7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLnUxLmxQaXRjaCA9IChjYWxsYmFja19zZC51MS5sUGl0Y2ggKyAzKSAmIH4zOwoKICAgICAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW5nICVkeCVkeCVkIEAlZFxuIiwgY2FsbGJhY2tfc2QuZHdXaWR0aCwgY2FsbGJhY2tfc2QuZHdIZWlnaHQsIGNhbGxiYWNrX3NkLnU0LmRkcGZQaXhlbEZvcm1hdC51MS5kd1JHQkJpdENvdW50LAogICAgICAgICAgICAgIGNhbGxiYWNrX3NkLnUyLmR3UmVmcmVzaFJhdGUpOwoKICAgICAgICAgICAgaWYoY2IoJmNhbGxiYWNrX3NkLCBDb250ZXh0KSA9PSBEREVOVU1SRVRfQ0FOQ0VMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gYXNrZWQgdG8gdGVybWluYXRlIHRoZSBlbnVtZXJhdGlvblxuIik7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnVtX21vZGVzKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKCEoRmxhZ3MgJiBEREVETV9SRUZSRVNIUkFURVMpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZW51bV9tb2RlX2NvdW50ID09IGVudW1fbW9kZV9hcnJheV9zaXplKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdJTkVEM0RESVNQTEFZTU9ERSAqbmV3X2VudW1fbW9kZXM7CgogICAgICAgICAgICAgICAgICAgIGVudW1fbW9kZV9hcnJheV9zaXplICo9IDI7CiAgICAgICAgICAgICAgICAgICAgbmV3X2VudW1fbW9kZXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnVtX21vZGVzLCBzaXplb2YoV0lORUQzRERJU1BMQVlNT0RFKSAqIGVudW1fbW9kZV9hcnJheV9zaXplKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCFuZXdfZW51bV9tb2RlcykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGVudW1fbW9kZXMpOwogICAgICAgICAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBlbnVtX21vZGVzID0gbmV3X2VudW1fbW9kZXM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZW51bV9tb2Rlc1tlbnVtX21vZGVfY291bnQrK10gPSBtb2RlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCJFbmQgb2YgZW51bWVyYXRpb25cbiIpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZW51bV9tb2Rlcyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFdmFsdWF0ZU1vZGUKICoKICogVXNlZCB3aXRoIElEaXJlY3REcmF3Nzo6U3RhcnRNb2RlVGVzdCB0byB0ZXN0IHZpZGVvIG1vZGVzLgogKiBFdmFsdWF0ZU1vZGUgaXMgdXNlZCB0byBwYXNzIG9yIGZhaWwgYSBtb2RlLCBhbmQgY29udGludWUgd2l0aCB0aGUgbmV4dAogKiBtb2RlCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBEREVNX01PREVQQVNTRUQgb3IgRERFTV9NT0RFRkFJTEVECiAqICBUaW1lb3V0OiBSZXR1cm5zIHRoZSBhbW91bnQgb2Ygc2Vjb25kcyBsZWZ0IGJlZm9yZSB0aGUgbW9kZSB3b3VsZCBoYXZlCiAqICAgICAgICAgICBiZWVuIGZhaWxlZCBhdXRvbWF0aWNhbGx5CiAqCiAqIFJldHVybnM6CiAqICBUaGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyBERF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRXZhbHVhdGVNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlRpbWVvdXQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVkLCVwKTogU3R1YiFcbiIsIFRoaXMsIEZsYWdzLCBUaW1lb3V0KTsKCiAgICAvKiBXaGVuIGltcGxlbWVudGluZyB0aGlzLCBpbXBsZW1lbnQgaXQgaW4gV2luZUQzRCAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0RGV2aWNlSWRlbnRpZmllcgogKgogKiBSZXR1cm5zIHRoZSBkZXZpY2UgaWRlbnRpZmllciwgd2hpY2ggZ2l2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRyaXZlcgogKiBPdXIgZGV2aWNlIGlkZW50aWZpZXIgaXMgZGVmaW5lZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgZmlsZS4KICoKICogUGFyYW1zOgogKiAgRERESTogQWRkcmVzcyBmb3IgdGhlIHJldHVybmVkIHN0cnVjdHVyZQogKiAgRmxhZ3M6IENhbiBiZSBEREdESV9HRVRIT1NUSURFTlRJRklFUgogKgogKiBSZXR1cm5zOgogKiAgT24gc3VjY2VzcyBpdCByZXR1cm5zIEREX09LCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREREkgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0RGV2aWNlSWRlbnRpZmllcihJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERERFVklDRUlERU5USUZJRVIyICpERERJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJTA4eClcbiIsIFRoaXMsIEREREksIEZsYWdzKTsKCiAgICBpZighRERESSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBUaGUgRERHRElfR0VUSE9TVElERU5USUZJRVIgcmV0dXJucyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIDJECiAgICAgKiBob3N0IGFkYXB0ZXIsIGlmIHRoZXJlJ3MgYSBzZWNvbmRhcnkgM0QgYWRhcHRlci4gVGhpcyBkb2Vzbid0IGFwcGx5CiAgICAgKiB0byBhbnkgbW9kZXJuIGhhcmR3YXJlLCBub3IgaXMgaXQgaW50ZXJlc3RpbmcgZm9yIFdpbmUsIHNvIGlnbm9yZSBpdAogICAgICovCgogICAgKkREREkgPSBkZXZpY2VpZGVudGlmaWVyOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRTdXJmYWNlRnJvbURDCiAqCiAqIFJldHVybnMgdGhlIFN1cmZhY2UgZm9yIGEgR0RJIGRldmljZSBjb250ZXh0IGhhbmRsZS4KICogSXMgdGhpcyByZWxhdGVkIHRvIElEaXJlY3REcmF3U3VyZmFjZTo6R2V0REMgPz8/CiAqCiAqIFBhcmFtczoKICogIGhkYzogaGRjIHRvIHJldHVybiB0aGUgc3VyZmFjZSBmb3IKICogIFN1cmZhY2U6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0U3VyZmFjZUZyb21EQyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIREMgaGRjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqU3VyZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsJXApOiBTdHViIVxuIiwgVGhpcywgaGRjLCBTdXJmYWNlKTsKCiAgICAvKiBJbXBsZW1lbnRhdGlvbiBpZGVhIGlmIG5lZWRlZDogTG9vcCB0aHJvdWdoIGFsbCBzdXJmYWNlcyBhbmQgY29tcGFyZQogICAgICogdGhlaXIgaGRjIHdpdGggaGRjLiBJbXBsZW1lbnQgaXQgaW4gV2luZUQzRCEgKi8KICAgIHJldHVybiBEREVSUl9OT1RGT1VORDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVzdG9yZUFsbFN1cmZhY2VzCiAqCiAqIENhbGxzIHRoZSByZXN0b3JlIG1ldGhvZCBvZiBhbGwgc3VyZmFjZXMKICoKICogUGFyYW1zOgogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZUFsbFN1cmZhY2VzKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKTogU3R1YlxuIiwgVGhpcyk7CgogICAgLyogVGhpcyBpc24ndCBoYXJkIHRvIGltcGxlbWVudDogRW51bWVyYXRlIGFsbCBXaW5lRDNEIHN1cmZhY2VzLAogICAgICogZ2V0IHRoZWlyIHBhcmVudCBhbmQgY2FsbCB0aGVpciByZXN0b3JlIG1ldGhvZC4gRG8gbm90IGltcGxlbWVudAogICAgICogaXQgaW4gV2luZUQzRCwgYXMgcmVzdG9yaW5nIGEgc3VyZmFjZSBtZWFucyByZS1jcmVhdGluZyB0aGUKICAgICAqIFdpbmVEM0REU3VyZmFjZQogICAgICovCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlN0YXJ0TW9kZVRlc3QKICoKICogVGVzdHMgdGhlIHNwZWNpZmllZCB2aWRlbyBtb2RlcyB0byB1cGRhdGUgdGhlIHN5c3RlbSByZWdpc3RyeSB3aXRoCiAqIHJlZnJlc2ggcmF0ZSBpbmZvcm1hdGlvbi4gU3RhcnRNb2RlVGVzdCBzdGFydHMgdGhlIG1vZGUgdGVzdCwKICogRXZhbHVhdGVNb2RlIGlzIHVzZWQgdG8gZmFpbCBvciBwYXNzIGEgbW9kZS4gSWYgRXZhbHVhdGVNb2RlCiAqIGlzbid0IGNhbGxlZCB3aXRoaW4gMTUgc2Vjb25kcywgdGhlIG1vZGUgaXMgZmFpbGVkIGF1dG9tYXRpY2FsbHkKICoKICogQXMgcmVmcmVzaCByYXRlcyBhcmUgaGFuZGxlZCBieSB0aGUgWCBzZXJ2ZXIsIEkgZG9uJ3QgdGhpbmsgdGhpcwogKiBNZXRob2QgaXMgaW1wb3J0YW50CiAqCiAqIFBhcmFtczoKICogIE1vZGVzOiBBbiBhcnJheSBvZiBtb2RlIHNwZWNpZmljYXRpb25zCiAqICBOdW1Nb2RlczogVGhlIG51bWJlciBvZiBtb2RlcyBpbiBNb2RlcwogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MuLi4KICoKICogUmV0dXJuczoKICogIFJldHVybnMgRERFUlJfVEVTVEZJTklTSEVEIGlmIGZsYWdzIGNvbnRhaW5zIEREU01UX0lTVEVTVFJFUVVJUkVELAogKiAgaWYgbm8gbW9kZXMgYXJlIHBhc3NlZCwgRERFUlJfSU5WQUxJRFBBUkFNUyBpcyByZXR1cm5lZCwKICogIG90aGVyd2lzZSBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU3RhcnRNb2RlVGVzdChJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSVpFICpNb2RlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTnVtTW9kZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgV0FSTigiKCVwKS0+KCVwLCAlZCwgJXgpOiBTZW1pLVN0dWIsIG1vc3QgbGlrZWx5IGhhcm1sZXNzXG4iLCBUaGlzLCBNb2RlcywgTnVtTW9kZXMsIEZsYWdzKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUgKi8KICAgIGlmKCAoIU1vZGVzKSB8fCAoTnVtTW9kZXMgPT0gMCkgKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBERFNNVF9JU1RFU1RSRVFVSVJFRCBhc2tzIGlmIGEgbW9kZSB0ZXN0IGlzIG5lY2Vzc2FyeS4KICAgICAqIEFzIGl0IGlzIG5vdCwgRERFUlJfVEVTVEZJTklTSEVEIGlzIHJldHVybmVkCiAgICAgKiAoaG9wZWZ1bGx5IHRoYXQncyBjb3JyZWN0CiAgICAgKgogICAgaWYoRmxhZ3MgJiBERFNNVF9JU1RFU1RSRVFVSVJFRCkgcmV0dXJuIERERVJSX1RFU1RGSU5JU0hFRDsKICAgICAqIHdlbGwsIHRoYXQgdmFsdWUgZG9lc24ndCAoeWV0KSBleGlzdCBpbiB0aGUgd2luZSBoZWFkZXJzLCBzbyBpZ25vcmUgaXQKICAgICAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2sKICoKICogRW51bWVyYXRpb24gY2FsbGJhY2sgZm9yIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzLgogKiBJdCByZS1yZWNyZWF0ZXMgdGhlIFdpbmVEM0RTdXJmYWNlLiBJdCdzIHByZXR0eSBzdHJhaWdodGZvcndhcmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVTdXJmYWNlc0NhbGxiYWNrKElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZkltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJmKTsKICAgIElEaXJlY3REcmF3SW1wbCAqVGhpcyA9IHN1cmZJbXBsLT5kZHJhdzsKICAgIElVbmtub3duICpQYXJlbnQ7CiAgICBJUGFyZW50SW1wbCAqcGFySW1wbCA9IE5VTEw7CiAgICBJV2luZUQzRFN1cmZhY2UgKndpbmVEM0RTdXJmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIHZvaWQgKnRtcDsKICAgIElXaW5lRDNEQ2xpcHBlciAqY2xpcHBlciA9IE5VTEw7CgogICAgV0lORUQzRFNVUkZBQ0VfREVTQyAgICAgRGVzYzsKICAgIFdJTkVEM0RGT1JNQVQgICAgICAgICAgIEZvcm1hdDsKICAgIFdJTkVEM0RSRVNPVVJDRVRZUEUgICAgIFR5cGU7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICBVc2FnZTsKICAgIFdJTkVEM0RQT09MICAgICAgICAgICAgIFBvb2w7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICBTaXplOwoKICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlVHlwZTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIE11bHRpU2FtcGxlUXVhbGl0eTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgIFdpZHRoOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgSGVpZ2h0OwoKICAgIFRSQUNFKCIoJXApOiBFbnVtZXJhdGVkIFN1cmZhY2UgJXBcbiIsIFRoaXMsIHN1cmZJbXBsKTsKCiAgICAvKiBGb3IgdGhlIGVudW1lcmF0aW9uICovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7CgogICAgaWYoc3VyZkltcGwtPkltcGxUeXBlID09IFRoaXMtPkltcGxUeXBlKSByZXR1cm4gRERFTlVNUkVUX09LOyAvKiBDb250aW51ZSAqLwoKICAgIC8qIEdldCB0aGUgb2JqZWN0cyAqLwogICAgd2luZUQzRFN1cmZhY2UgPSBzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KHdpbmVEM0RTdXJmYWNlLCAmUGFyZW50KTsKICAgIElVbmtub3duX1JlbGVhc2UoUGFyZW50KTsgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KCiAgICAvKiBJcyB0aGUgcGFyZW50IGFuIElQYXJlbnQgaW50ZXJmYWNlPyAqLwogICAgaWYoSVVua25vd25fUXVlcnlJbnRlcmZhY2UoUGFyZW50LCAmSUlEX0lQYXJlbnQsICZ0bXApID09IFNfT0spCiAgICB7CiAgICAgICAgLyogSXQgaXMgYSBJUGFyZW50IGludGVyZmFjZSEgKi8KICAgICAgICBJVW5rbm93bl9SZWxlYXNlKFBhcmVudCk7IC8qIEZvciB0aGUgUXVlcnlJbnRlcmZhY2UgKi8KICAgICAgICBwYXJJbXBsID0gSUNPTV9PQkpFQ1QoSVBhcmVudEltcGwsIElQYXJlbnQsIFBhcmVudCk7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgcmVmZXJlbmNlIHRoZSBwYXJlbnQgaW50ZXJmYWNlIGlzIGhvbGRpbmcgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSh3aW5lRDNEU3VyZmFjZSk7CiAgICB9CgogICAgLyogZ2V0IHRoZSBjbGlwcGVyICovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q2xpcHBlcih3aW5lRDNEU3VyZmFjZSwgJmNsaXBwZXIpOwoKICAgIC8qIEdldCB0aGUgc3VyZmFjZSBwcm9wZXJ0aWVzICovCiAgICBEZXNjLkZvcm1hdCA9ICZGb3JtYXQ7CiAgICBEZXNjLlR5cGUgPSAmVHlwZTsKICAgIERlc2MuVXNhZ2UgPSAmVXNhZ2U7CiAgICBEZXNjLlBvb2wgPSAmUG9vbDsKICAgIERlc2MuU2l6ZSA9ICZTaXplOwogICAgRGVzYy5NdWx0aVNhbXBsZVR5cGUgPSAmTXVsdGlTYW1wbGVUeXBlOwogICAgRGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSAmTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgRGVzYy5XaWR0aCA9ICZXaWR0aDsKICAgIERlc2MuSGVpZ2h0ID0gJkhlaWdodDsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHdpbmVEM0RTdXJmYWNlLCAmRGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spIHJldHVybiBocjsKCiAgICAvKiBDcmVhdGUgdGhlIG5ldyBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaWR0aCwgSGVpZ2h0LCBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBEaXNjYXJkICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cmZJbXBsLT5taXBtYXBfbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpU2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFNoYXJlZEhhbmRsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJlbnQpOwoKICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICByZXR1cm4gaHI7CgogICAgSVdpbmVEM0RTdXJmYWNlX1NldENsaXBwZXIoc3VyZkltcGwtPldpbmVEM0RTdXJmYWNlLCBjbGlwcGVyKTsKCiAgICAvKiBVcGRhdGUgdGhlIElQYXJlbnQgaWYgaXQgZXhpc3RzICovCiAgICBpZihwYXJJbXBsKQogICAgewogICAgICAgIHBhckltcGwtPmNoaWxkID0gKElVbmtub3duICopIHN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZTsKICAgICAgICAvKiBBZGQgYSByZWZlcmVuY2UgZm9yIHRoZSBJUGFyZW50ICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2UpOwogICAgfQogICAgLyogVE9ETzogQ29weSB0aGUgc3VyZmFjZSBjb250ZW50LCBleGNlcHQgZm9yIHJlbmRlciB0YXJnZXRzICovCgogICAgaWYoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uod2luZUQzRFN1cmZhY2UpID09IDApCiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgcmVsZWFzZWQgc3VjY2Vzc2Z1bCwgbmV4dCBzdXJmYWNlXG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoIlNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIG9sZCBXaW5lRDNEU3VyZmFjZVxuIik7CgogICAgc3VyZkltcGwtPkltcGxUeXBlID0gVGhpcy0+SW1wbFR5cGU7CgogICAgaWYoY2xpcHBlcikKICAgIHsKICAgICAgICBJV2luZUQzRENsaXBwZXJfUmVsZWFzZShjbGlwcGVyKTsKICAgIH0KICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcwogKgogKiBBIGZ1bmN0aW9uLCB0aGF0IGNvbnZlcnRzIGFsbCB3aW5lRDNEU3VyZmFjZXMgdG8gdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiB0eXBlCiAqIEl0IGVudW1lcmF0ZXMgYWxsIHN1cmZhY2VzIHdpdGggSVdpbmVEM0REZXZpY2U6OkVudW1TdXJmYWNlcywgY3JlYXRlcyBhCiAqIG5ldyBXaW5lRDNEU3VyZmFjZSwgY29waWVzIHRoZSBjb250ZW50IGFuZCByZWxlYXNlcyB0aGUgb2xkIHN1cmZhY2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcyhJRGlyZWN0RHJhd0ltcGwgKlRoaXMpCnsKICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICBUUkFDRSgiKCVwKTogU3dpdGNoIHRvIGltcGxlbWVudGF0aW9uICVkXG4iLCBUaGlzLCBUaGlzLT5JbXBsVHlwZSk7CgogICAgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wgJiYgVGhpcy0+ZDNkX2luaXRpYWxpemVkKQogICAgewogICAgICAgIC8qIFNob3VsZCBoYXBwZW4gYWxtb3N0IG5ldmVyICovCiAgICAgICAgRklYTUUoIiglcCkgU3dpdGNoaW5nIHRvIG5vbi1vcGVuZ2wgc3VyZmFjZXMgd2l0aCBkM2Qgc3RhcnRlZC4gSXMgdGhpcyBhIGJ1Zz9cbiIsIFRoaXMpOwogICAgICAgIC8qIFNodXRkb3duIGQzZCAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX1VuaW5pdDNEKFRoaXMtPndpbmVEM0REZXZpY2UsIEQzRDdDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZSwgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4pOwogICAgfQogICAgLyogQ29udHJhcnk6IEQzRCBzdGFydGluZyBpcyBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIsIGJlY2F1c2UgaXQga25vd3MgdGhlIHJlbmRlciB0YXJnZXQgKi8KCiAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICBkZXNjLmR3U2l6ZSA9IHNpemVvZihkZXNjKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXc3X0VudW1TdXJmYWNlcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2spOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZVN1cmZhY2UKICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIElEaXJlY3QzRERldmljZV9DcmVhdGVUZXh0dXJlLiBJdCBzZWFyY2hlcyBmb3IgdGhlCiAqIGNvcnJlY3QgbWlwbWFwIHN1YmxldmVsLCBhbmQgcmV0dXJucyBpdCB0byBXaW5lRDNELgogKiBUaGUgc3VyZmFjZXMgYXJlIGNyZWF0ZWQgYWxyZWFkeSBieSBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgV2l0aCwgSGVpZ2h0OiBXaXRoIGFuZCBoZWlnaHQgb2YgdGhlIHN1cmZhY2UKICogIEZvcm1hdDogVGhlIHJlcXVlc3RlZCBmb3JtYXQKICogIFVzYWdlLCBQb29sOiBEM0RVU0FHRSBhbmQgRDNEUE9PTCBvZiB0aGUgc3VyZmFjZQogKiAgbGV2ZWw6IFRoZSBtaXBtYXAgbGV2ZWwKICogIEZhY2U6IFRoZSBjdWJlIG1hcCBmYWNlIHR5cGUKICogIFN1cmZhY2U6IFBvaW50ZXIgdG8gcGFzcyB0aGUgY3JlYXRlZCBzdXJmYWNlIGJhY2sgYXQKICogIFNoYXJlZEhhbmRsZTogTlVMTAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVTdXJmYWNlKElVbmtub3duICpkZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwU3VwZXJpb3IsCiAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RQT09MIFBvb2wsIFVJTlQgbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RDVUJFTUFQX0ZBQ0VTIEZhY2UsCiAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqKlN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSAqU2hhcmVkSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYgPSBOVUxMOwogICAgaW50IGkgPSAwOwogICAgRERTQ0FQUzIgc2VhcmNoY2FwcyA9IFRoaXMtPnRleF9yb290LT5zdXJmYWNlX2Rlc2MuZGRzQ2FwczsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFjay4gc3VyZj0lcC4gRmFjZSAlZCBsZXZlbCAlZFxuIiwgZGV2aWNlLCBUaGlzLT50ZXhfcm9vdCwgRmFjZSwgbGV2ZWwpOwoKICAgIHNlYXJjaGNhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKICAgIHN3aXRjaChGYWNlKQogICAgewogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIHBvc2l0aXZlIHhcbiIpOwogICAgICAgICAgICBpZihzZWFyY2hjYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKSB7CiAgICAgICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VyZiA9IFRoaXMtPnRleF9yb290OyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWDoKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBuZWdhdGl2ZSB4XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVYOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWToKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBwb3NpdGl2ZSB5XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVZOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWToKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBuZWdhdGl2ZSB5XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVZOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWjoKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBwb3NpdGl2ZSB6XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVaOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWjoKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBuZWdhdGl2ZSB6XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVaOyBicmVhazsKICAgICAgICBkZWZhdWx0OiB7RVJSKCJVbmV4cGVjdGVkIGN1YmUgZmFjZVxuIik7fSAvKiBTdHVwaWQgY29tcGlsZXIgKi8KICAgIH0KCiAgICBpZighc3VyZikKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICphdHRhY2hlZDsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRShUaGlzLT50ZXhfcm9vdCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlYXJjaGNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dGFjaGVkKTsKICAgICAgICBzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgYXR0YWNoZWQpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShhdHRhY2hlZCk7CiAgICB9CiAgICBpZighc3VyZikgRVJSKCJyb290IHNlYXJjaCBzdXJmYWNlIG5vdCBmb3VuZFxuIik7CgogICAgLyogRmluZCB0aGUgd2FudGVkIG1pcG1hcC4gVGhlcmUgYXJlIGVub3VnaCBtaXBtYXBzIGluIHRoZSBjaGFpbiAqLwogICAgd2hpbGUoaSA8IGxldmVsKQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmF0dGFjaGVkOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWFyY2hjYXBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdHRhY2hlZCk7CiAgICAgICAgaWYoIWF0dGFjaGVkKSBFUlIoIlN1cmZhY2Ugbm90IGZvdW5kXG4iKTsKICAgICAgICBzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgYXR0YWNoZWQpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShhdHRhY2hlZCk7CiAgICAgICAgaSsrOwogICAgfQoKICAgIC8qIFJldHVybiB0aGUgc3VyZmFjZSAqLwogICAgKlN1cmZhY2UgPSBzdXJmLT5XaW5lRDNEU3VyZmFjZTsKCiAgICBUUkFDRSgiUmV0dXJuaW5nIHdpbmVEM0RTdXJmYWNlICVwLCBpdCBiZWxvbmdzIHRvIHN1cmZhY2UgJXBcbiIsICpTdXJmYWNlLCBzdXJmKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KClVMT05HIFdJTkFQSSBEM0Q3Q0JfRGVzdHJveVN3YXBDaGFpbihJV2luZUQzRFN3YXBDaGFpbiAqcFN3YXBDaGFpbikgewogICAgSVVua25vd24qIHN3YXBDaGFpblBhcmVudDsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgcFN3YXBDaGFpbik7CgogICAgSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UGFyZW50KHBTd2FwQ2hhaW4sICZzd2FwQ2hhaW5QYXJlbnQpOwogICAgSVVua25vd25fUmVsZWFzZShzd2FwQ2hhaW5QYXJlbnQpOwogICAgcmV0dXJuIElVbmtub3duX1JlbGVhc2Uoc3dhcENoYWluUGFyZW50KTsKfQoKVUxPTkcgV0lOQVBJIEQzRDdDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZShJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlKSB7CiAgICBJVW5rbm93biogc3VyZmFjZVBhcmVudDsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgcFN1cmZhY2UpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQocFN1cmZhY2UsICZzdXJmYWNlUGFyZW50KTsKICAgIElVbmtub3duX1JlbGVhc2Uoc3VyZmFjZVBhcmVudCk7CiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZShzdXJmYWNlUGFyZW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlCiAqCiAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UuIEl0IGNyZWF0ZXMgYSBuZXcgc3VyZmFjZQogKiB3aXRoIHRoZSBwYXNzZWQgcGFyYW1ldGVycy4KICoKICogUGFyYW1zOgogKiAgRERTRDogRGVzY3JpcHRpb24gb2YgdGhlIHN1cmZhY2UgdG8gY3JlYXRlCiAqICBTdXJmOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBhdAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpwRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnBwU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBsZXZlbCkKewogICAgSFJFU1VMVCBocjsKICAgIFVJTlQgV2lkdGggPSAwLCBIZWlnaHQgPSAwOwogICAgV0lORUQzREZPUk1BVCBGb3JtYXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICBXSU5FRDNEUkVTT1VSQ0VUWVBFIFJlc1R5cGUgPSBXSU5FRDNEUlRZUEVfU1VSRkFDRTsKICAgIERXT1JEIFVzYWdlID0gMDsKICAgIFdJTkVEM0RTVVJGVFlQRSBJbXBsVHlwZSA9IFRoaXMtPkltcGxUeXBlOwogICAgV0lORUQzRFNVUkZBQ0VfREVTQyBEZXNjOwogICAgSVVua25vd24gKlBhcmVudDsKICAgIElQYXJlbnRJbXBsICpwYXJJbXBsID0gTlVMTDsKICAgIFdJTkVEM0RQT09MIFBvb2wgPSBXSU5FRDNEUE9PTF9ERUZBVUxUOwoKICAgIC8qIER1bW1pZXMgZm9yIEdldERlc2MgKi8KICAgIFdJTkVEM0RQT09MIGR1bW15X2QzZHBvb2w7CiAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBkdW1teV9tc3Q7CiAgICBVSU5UIGR1bW15X3VpbnQ7CiAgICBEV09SRCBkdW1teV9kd29yZDsKCiAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCIgKCVwKSBSZXF1ZXN0aW5nIHN1cmZhY2UgZGVzYyA6XG4iLCBUaGlzKTsKICAgICAgICBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhwRERTRCk7CiAgICB9CgogICAgLyogU2VsZWN0IHRoZSBzdXJmYWNlIHR5cGUsIGlmIGl0IHdhc24ndCBjaG9vc2VuIHlldCAqLwogICAgaWYoSW1wbFR5cGUgPT0gU1VSRkFDRV9VTktOT1dOKQogICAgewogICAgICAgIC8qIFVzZSBHTCBTdXJmYWNlcyBpZiBhIEQzRERFVklDRSBTdXJmYWNlIGlzIHJlcXVlc3RlZCAqLwogICAgICAgIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfM0RERVZJQ0UpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBDaG9vc2luZyBHTCBzdXJmYWNlcyBiZWNhdXNlIGEgM0RERVZJQ0UgU3VyZmFjZSB3YXMgcmVxdWVzdGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgSW1wbFR5cGUgPSBTVVJGQUNFX09QRU5HTDsKICAgICAgICB9CgogICAgICAgIC8qIE90aGVyd2lzZSB1c2UgR0RJIHN1cmZhY2VzIGZvciBub3cgKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBDaG9vc2luZyBHREkgc3VyZmFjZXMgZm9yIDJEIHJlbmRlcmluZ1xuIiwgVGhpcyk7CiAgICAgICAgICAgIEltcGxUeXBlID0gU1VSRkFDRV9HREk7CiAgICAgICAgfQoKICAgICAgICAvKiBQb2xpY3kgaWYgYWxsIHN1cmZhY2UgaW1wbGVtZW50YXRpb25zIGFyZSBhdmFpbGFibGU6CiAgICAgICAgICogRmlyc3QsIGNoZWNrIGlmIGEgZGVmYXVsdCB0eXBlIHdhcyBzZXQgd2l0aCB3aW5lY2ZnLiBJZiBub3QsCiAgICAgICAgICogdHJ5IFhyZW5kZXIgc3VyZmFjZXMsIGFuZCB1c2UgdGhlbSBpZiB0aGV5IHdvcmsuIE5leHQsIGNoZWNrIGlmCiAgICAgICAgICogYWNjZWxlcmF0ZWQgT3BlbkdMIGlzIGF2YWlsYWJsZSwgYW5kIHVzZSBHTCBzdXJmYWNlcyBpbiB0aGlzCiAgICAgICAgICogY2FzZS4gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBHREkgc3VyZmFjZXMuIElmIGEgM0RERVZJQ0Ugc3VyZmFjZQogICAgICAgICAqIHdhcyBjcmVhdGVkLCBhbHdheXMgdXNlIE9wZW5HTCBzdXJmYWNlcy4KICAgICAgICAgKgogICAgICAgICAqIChOb3RlOiBYcmVuZGVyIHN1cmZhY2VzIGFyZSBub3QgaW1wbGVtZW50ZWQgZm9yIG5vdywgdGhlCiAgICAgICAgICogdW5hY2NlbGVyYXRlZCBpbXBsZW1lbnRhdGlvbiB1c2VzIEdESSB0byByZW5kZXIgaW4gU29mdHdhcmUpCiAgICAgICAgICovCgogICAgICAgIC8qIFN0b3JlIHRoZSB0eXBlLiBJZiBpdCBuZWVkcyB0byBiZSBjaGFuZ2VkLCBhbGwgV2luZUQzRFN1cmZhY2VzIGhhdmUgdG8KICAgICAgICAgKiBiZSByZS1jcmVhdGVkLiBUaGlzIGNvdWxkIGJlIGRvbmUgd2l0aCBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZXN0b3JlCiAgICAgICAgICovCiAgICAgICAgVGhpcy0+SW1wbFR5cGUgPSBJbXBsVHlwZTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAgaWYoKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfM0RERVZJQ0UgKSAmJiAKICAgICAgICAgICAgKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMICkgJiYgRGVmYXVsdFN1cmZhY2VUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIFdlIGhhdmUgdG8gY2hhbmdlIHRvIE9wZW5HTCwKICAgICAgICAgICAgICogYW5kIHJlLWNyZWF0ZSBhbGwgV2luZUQzRFN1cmZhY2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJbXBsVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSA9IEltcGxUeXBlOwogICAgICAgICAgICBUUkFDRSgiKCVwKSBSZS1jcmVhdGluZyBhbGwgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcyhUaGlzKTsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRG9uZSByZWNyZWF0aW5nIGFsbCBzdXJmYWNlc1xuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wgJiYgcEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU18zRERFVklDRSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIlRoZSBhcHBsaWNhdGlvbiByZXF1ZXN0cyBhIDNEIGNhcGFibGUgc3VyZmFjZSwgYnV0IGEgbm9uLW9wZW5nbCBzdXJmYWNlIHdhcyBzZXQgaW4gdGhlIHJlZ2lzdHJ5XG4iKTsKICAgICAgICAgICAgLyogRG8gbm90IGZhaWwgc3VyZmFjZSBjcmVhdGlvbiwgb25seSBmYWlsIDNEIGRldmljZSBjcmVhdGlvbiAqLwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHZXQgdGhlIGNvcnJlY3Qgd2luZWQzZCB1c2FnZSAqLwogICAgaWYgKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19CQUNLQlVGRkVSICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfM0RERVZJQ0UgICAgICAgKSApCiAgICB7CiAgICAgICAgVXNhZ2UgfD0gV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVDsKCiAgICAgICAgcEREU0QtPmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfVklERU9NRU1PUlkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX1ZJU0lCTEU7CiAgICB9CiAgICBpZiAocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVXNhZ2UgfD0gV0lORUQzRFVTQUdFX09WRVJMQVk7CiAgICB9CiAgICBpZihUaGlzLT5kZXB0aHN0ZW5jaWwgfHwgKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfWkJVRkZFUikgKQogICAgewogICAgICAgIC8qIFRoZSBkZXB0aCBzdGVuY2lsIGNyZWF0aW9uIGNhbGxiYWNrIHNldHMgdGhpcyBmbGFnLgogICAgICAgICAqIFNldCB0aGUgV2luZUQzRCB1c2FnZSB0byBsZXQgaXQga25vdyB0aGF0IGl0J3MgYSBkZXB0aAogICAgICAgICAqIFN0ZW5jaWwgc3VyZmFjZS4KICAgICAgICAgKi8KICAgICAgICBVc2FnZSB8PSBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMOwogICAgfQogICAgaWYocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19TWVNURU1NRU1PUlkpCiAgICB7CiAgICAgICAgUG9vbCA9IFdJTkVEM0RQT09MX1NZU1RFTU1FTTsKICAgIH0KICAgIGVsc2UgaWYocEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX1RFWFRVUkVNQU5BR0UpCiAgICB7CiAgICAgICAgUG9vbCA9IFdJTkVEM0RQT09MX01BTkFHRUQ7CiAgICAgICAgLyogTWFuYWdlZCB0ZXh0dXJlcyBoYXZlIHRoZSBzeXN0ZW0gbWVtb3J5IGZsYWcgc2V0ICovCiAgICAgICAgcEREU0QtPmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfU1lTVEVNTUVNT1JZOwogICAgfQogICAgZWxzZSBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1ZJREVPTUVNT1JZKQogICAgewogICAgICAgIC8qIFZpZGVvbWVtb3J5IGFkZHMgbG9jYWx2aWRtZW0sIHRoaXMgaXMgbXV0dWFsbHkgZXhjbHVzaXZlIHdpdGggc3lzdGVtbWVtb3J5CiAgICAgICAgICogYW5kIHRleHR1cmVtYW5hZ2UKICAgICAgICAgKi8KICAgICAgICBwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19MT0NBTFZJRE1FTTsKICAgIH0KCiAgICBGb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZwRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pCiAgICB7CiAgICAgICAgRVJSKCJVbnN1cHBvcnRlZCAvIFVua25vd24gcGl4ZWxmb3JtYXRcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUElYRUxGT1JNQVQ7CiAgICB9CgogICAgLyogQ3JlYXRlIHRoZSBTdXJmYWNlIG9iamVjdCAqLwogICAgKnBwU3VyZiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSURpcmVjdERyYXdTdXJmYWNlSW1wbCkpOwogICAgaWYoISpwcFN1cmYpCiAgICB7CiAgICAgICAgRVJSKCIoJXApIEVycm9yIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9PVVRPRlZJREVPTUVNT1JZOwogICAgfQogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBJRGlyZWN0RHJhd1N1cmZhY2U3X1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2UzLCBJRGlyZWN0RHJhd1N1cmZhY2UzX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCwgSURpcmVjdERyYXdHYW1tYUNvbnRyb2xfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3QzRFRleHR1cmUyLCBJRGlyZWN0M0RUZXh0dXJlMl9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdDNEVGV4dHVyZSwgSURpcmVjdDNEVGV4dHVyZTFfVnRibCk7CiAgICAoKnBwU3VyZiktPnJlZiA9IDE7CiAgICAoKnBwU3VyZiktPnZlcnNpb24gPSA3OwogICAgKCpwcFN1cmYpLT5kZHJhdyA9IFRoaXM7CiAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy5kd1NpemUgPSBzaXplb2YoRERTVVJGQUNFREVTQzIpOwogICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihERFBJWEVMRk9STUFUKTsKICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRSgmKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MsIHBERFNEKTsKCiAgICAvKiBTdXJmYWNlIGF0dGFjaG1lbnRzICovCiAgICAoKnBwU3VyZiktPm5leHRfYXR0YWNoZWQgPSBOVUxMOwogICAgKCpwcFN1cmYpLT5maXJzdF9hdHRhY2hlZCA9ICpwcFN1cmY7CgogICAgLyogTmVlZGVkIHRvIHJlLWNyZWF0ZSB0aGUgc3VyZmFjZSBvbiBhbiBpbXBsZW1lbnRhdGlvbiBjaGFuZ2UgKi8KICAgICgqcHBTdXJmKS0+SW1wbFR5cGUgPSBJbXBsVHlwZTsKCiAgICAvKiBGb3IgRDNERGV2aWNlIGNyZWF0aW9uICovCiAgICAoKnBwU3VyZiktPmlzUmVuZGVyVGFyZ2V0ID0gRkFMU0U7CgogICAgLyogQSB0cmFjZSBtZXNzYWdlIGZvciBkZWJ1Z2dpbmcgKi8KICAgIFRSQUNFKCIoJXApIENyZWF0ZWQgSURpcmVjdERyYXdTdXJmYWNlIGltcGxlbWVudGF0aW9uIHN0cnVjdHVyZSBhdCAlcFxuIiwgVGhpcywgKnBwU3VyZik7CgogICAgaWYocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgKCBERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU19URVhUVVJFIHwgRERTQ0FQU18zRERFVklDRSkgKQogICAgewogICAgICAgIC8qIFJlbmRlciB0YXJnZXRzIGFuZCB0ZXh0dXJlcyBuZWVkIGEgSVBhcmVudCBpbnRlcmZhY2UsCiAgICAgICAgICogYmVjYXVzZSBXaW5lRDNEIHdpbGwgZGVzdHJveSB0aGVtIHdoZW4gdGhlIHN3YXBjaGFpbgogICAgICAgICAqIGlzIHJlbGVhc2VkCiAgICAgICAgICovCiAgICAgICAgcGFySW1wbCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoSVBhcmVudEltcGwpKTsKICAgICAgICBpZighcGFySW1wbCkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIElQYXJlbnQgaW1wbGVtZW50YXRpb25cbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZNRU1PUlk7CiAgICAgICAgfQogICAgICAgIHBhckltcGwtPnJlZiA9IDE7CiAgICAgICAgSUNPTV9JTklUX0lOVEVSRkFDRShwYXJJbXBsLCBJUGFyZW50LCBJUGFyZW50X1Z0YmwpOwogICAgICAgIFBhcmVudCA9IChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRShwYXJJbXBsLCBJUGFyZW50KTsKICAgICAgICBUUkFDRSgiVXNpbmcgSVBhcmVudCBpbnRlcmZhY2UgJXAgYXMgcGFyZW50XG4iLCBwYXJJbXBsKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBVc2UgdGhlIHN1cmZhY2UgYXMgcGFyZW50ICovCiAgICAgICAgUGFyZW50ID0gKElVbmtub3duICopIElDT01fSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpOwogICAgICAgIFRSQUNFKCJVc2luZyBTdXJmYWNlIGludGVyZmFjZSAlcCBhcyBwYXJlbnRcbiIsICpwcFN1cmYpOwogICAgfQoKICAgIC8qIE5vdyBjcmVhdGUgdGhlIFdpbmVEM0QgU3VyZmFjZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVTdXJmYWNlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEREU0QtPmR3V2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcEREU0QtPmR3SGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIExvY2thYmxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFIC8qIERpc2NhcmQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJigqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzVHlwZSwgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETVVMVElTQU1QTEVfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIE11bHRpU2FtcGxlUXVhbGl0eSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFNoYXJlZEhhbmRsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbXBsVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJlbnQpOwoKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNERGV2aWNlOjpDcmVhdGVTdXJmYWNlIGZhaWxlZC4gaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIFNldCB0aGUgY2hpbGQgb2YgdGhlIHBhcmVudCBpbXBsZW1lbnRhdGlvbiBpZiBpdCBleGlzdHMgKi8KICAgIGlmKHBhckltcGwpCiAgICB7CiAgICAgICAgcGFySW1wbC0+Y2hpbGQgPSAoSVVua25vd24gKikgKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZTsKICAgICAgICAvKiBUaGUgSVBhcmVudCByZWxlYXNlcyB0aGUgV2luZUQzRFN1cmZhY2UsIGFuZAogICAgICAgICAqIHRoZSBkZHJhdyBzdXJmYWNlIGRvZXMgdGhhdCB0b28uIEhvbGQgYSByZWZlcmVuY2UKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UpOwogICAgfQoKICAgIC8qIEluY3JlYXNlIHRoZSBzdXJmYWNlIGNvdW50ZXIsIGFuZCBhdHRhY2ggdGhlIHN1cmZhY2UgKi8KICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5zdXJmYWNlcyk7CiAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5zdXJmYWNlX2xpc3QsICYoKnBwU3VyZiktPnN1cmZhY2VfbGlzdF9lbnRyeSk7CgogICAgLyogSGVyZSB3ZSBjb3VsZCBzdG9yZSBhbGwgY3JlYXRlZCBzdXJmYWNlcyBpbiB0aGUgRGlyZWN0RHJhd0ltcGwgc3RydWN0dXJlLAogICAgICogQnV0IHRoaXMgY291bGQgYWxzbyBiZSBkZWxlZ2F0ZWQgdG8gV2luZUREcmF3LCBhcyBpdCBrZWVwcyB0cmFjayBvZiBhbGwgaXRzCiAgICAgKiByZXNvdXJjZXMuIE5vdCBpbXBsZW1lbnRlZCBmb3Igbm93LCBhcyB0aGVyZSBhcmUgbW9yZSBpbXBvcnRhbnQgdGhpbmdzIDspCiAgICAgKi8KCiAgICAvKiBHZXQgdGhlIHBpeGVsIGZvcm1hdCBvZiB0aGUgV2luZUQzRFN1cmZhY2UgYW5kIHN0b3JlIGl0LgogICAgICogRG9uJ3QgdXNlIHRoZSBGb3JtYXQgY2hvb3NlbiBhYm92ZSwgV2luZUQzRCBtaWdodCBoYXZlCiAgICAgKiBjaGFuZ2VkIGl0CiAgICAgKi8KICAgIERlc2MuRm9ybWF0ID0gJkZvcm1hdDsKICAgIERlc2MuVHlwZSA9ICZSZXNUeXBlOwogICAgRGVzYy5Vc2FnZSA9ICZVc2FnZTsKICAgIERlc2MuUG9vbCA9ICZkdW1teV9kM2Rwb29sOwogICAgRGVzYy5TaXplID0gJmR1bW15X3VpbnQ7CiAgICBEZXNjLk11bHRpU2FtcGxlVHlwZSA9ICZkdW1teV9tc3Q7CiAgICBEZXNjLk11bHRpU2FtcGxlUXVhbGl0eSA9ICZkdW1teV9kd29yZDsKICAgIERlc2MuV2lkdGggPSAmV2lkdGg7CiAgICBEZXNjLkhlaWdodCA9ICZIZWlnaHQ7CgogICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX1BJWEVMRk9STUFUOwogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYygoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLCAmRGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRFN1cmZhY2U6OkdldERlc2MgZmFpbGVkXG4iKTsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoIChJRGlyZWN0RHJhd1N1cmZhY2U3ICopICpwcFN1cmYpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBpZihGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKQogICAgewogICAgICAgIEZJWE1FKCJJV2luZUQzRFN1cmZhY2U6OkdldERlc2MgcmV0dXJuZWQgV0lORUQzREZNVF9VTktOT1dOXG4iKTsKICAgIH0KICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCAmKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0LCBGb3JtYXQpOwoKICAgIC8qIEFubm8gMTYwMiBzdG9yZXMgdGhlIHBpdGNoIHJpZ2h0IGFmdGVyIHN1cmZhY2UgY3JlYXRpb24sIHNvIG1ha2Ugc3VyZSBpdCdzIHRoZXJlLgogICAgICogSSBjYW4ndCBMb2NrUmVjdCgpIHRoZSBzdXJmYWNlIGhlcmUgYmVjYXVzZSBpZiBPcGVuR0wgc3VyZmFjZXMgYXJlIGluIHVzZSwgdGhlCiAgICAgKiBXaW5lRDNERGV2aWNlIG1pZ2h0IG5vdCBiZSB1c2FibGUgZm9yIDNEIHlldCwgc28gYW4gZXh0cmEgbWV0aG9kIHdhcyBjcmVhdGVkLgogICAgICogVE9ETzogVGVzdCBvdGhlciBmb3VyY2MgZm9ybWF0cwogICAgICovCiAgICBpZihGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KQogICAgewogICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9MSU5FQVJTSVpFOwogICAgICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51MS5kd0xpbmVhclNpemUgPSBtYXgoNCwgV2lkdGgpICogbWF4KDQsIEhlaWdodCkgLyAyOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51MS5kd0xpbmVhclNpemUgPSBtYXgoNCwgV2lkdGgpICogbWF4KDQsIEhlaWdodCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9QSVRDSDsKICAgICAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51MS5sUGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSk7CiAgICB9CgogICAgLyogQXBwbGljYXRpb24gcGFzc2VkIGEgY29sb3Iga2V5PyBTZXQgaXQhICovCiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tERVNUT1ZFUkxBWSkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX0RFU1RPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJnBERFNELT51My5kZGNrQ0tEZXN0T3ZlcmxheSk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tERVNUQkxUKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVEJMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZwRERTRC0+ZGRja0NLRGVzdEJsdCk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tTUkNPVkVSTEFZKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfU1JDT1ZFUkxBWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZwRERTRC0+ZGRja0NLU3JjT3ZlcmxheSk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tTUkNCTFQpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNCTFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERDT0xPUktFWSAqKSAmcEREU0QtPmRkY2tDS1NyY0JsdCk7CiAgICB9CiAgICBpZiAoIHBERFNELT5kd0ZsYWdzICYgRERTRF9MUFNVUkZBQ0UpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsIHBERFNELT5scFN1cmZhY2UpOwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBuZWVkIGZvciBhIHRyYWNlIGhlcmUsIHdpbmVkM2QgZG9lcyB0aGF0IGZvciB1cyAqLwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoKCpwcFN1cmYpLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMKICoKICogQ3JlYXRlcyBhIG5ldyBtaXBtYXAgY2hhaW4uCiAqCiAqIFBhcmFtczoKICogIHJvb3Q6IFJvb3Qgc3VyZmFjZSB0byBhdHRhY2ggdGhlIG5ld2x5IGNyZWF0ZWQgY2hhaW4gdG8KICogIGNvdW50OiBudW1iZXIgb2Ygc3VyZmFjZXMgdG8gY3JlYXRlCiAqICBERFNEOiBEZXNjcmlwdGlvbiBvZiB0aGUgc3VyZmFjZS4gSW50ZW50aW9uYWxseSBub3QgYSBwb2ludGVyIHRvIGF2b2lkIHNpZGUKICogICAgICAgIGVmZmVjdHMgb24gdGhlIGNhbGxlcgogKiAgQ3ViZUZhY2VSb290OiBXaGV0aGVyIHRoZSBuZXcgc3VyZmFjZSBpcyBhIHJvb3Qgb2YgYSBjdWJlIG1hcCBmYWNlLiBUaGlzCiAqICAgICAgICAgICAgICAgIGNyZWF0ZXMgYW4gYWRkaXRpb25hbCBzdXJmYWNlIHdpdGhvdXQgdGhlIG1pcG1hcHBpbmcgZmxhZ3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcm9vdCwKICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiBERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBDdWJlRmFjZVJvb3QpCnsKICAgIFVJTlQgaSwgaiwgbGV2ZWwgPSAwOwogICAgSFJFU1VMVCBocjsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmxhc3QgPSByb290OwoKICAgIGZvcihpID0gMDsgaSA8IGNvdW50OyBpKyspCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqb2JqZWN0MiA9IE5VTEw7CgogICAgICAgIC8qIGluY3JlYXNlIHRoZSBtaXBtYXAgbGV2ZWwsIGJ1dCBvbmx5IGlmIGEgbWlwbWFwIGlzIGNyZWF0ZWQKICAgICAgICAgKiBJbiB0aGlzIGNhc2UsIGFsc28gaGFsdmUgdGhlIHNpemUKICAgICAgICAgKi8KICAgICAgICBpZihERFNELmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVAgJiYgIUN1YmVGYWNlUm9vdCkKICAgICAgICB7CiAgICAgICAgICAgIGxldmVsKys7CiAgICAgICAgICAgIGlmKEREU0QuZHdXaWR0aCA+IDEpIEREU0QuZHdXaWR0aCAvPSAyOwogICAgICAgICAgICBpZihERFNELmR3SGVpZ2h0ID4gMSkgRERTRC5kd0hlaWdodCAvPSAyOwogICAgICAgICAgICAvKiBTZXQgdGhlIG1pcG1hcCBzdWJsZXZlbCBmbGFnIGFjY29yZGluZyB0byBtc2RuICovCiAgICAgICAgICAgIEREU0QuZGRzQ2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBERFNELmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfTUlQTUFQU1VCTEVWRUw7CiAgICAgICAgfQogICAgICAgIEN1YmVGYWNlUm9vdCA9IEZBTFNFOwoKICAgICAgICBociA9IElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlKFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvYmplY3QyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwpOwogICAgICAgIGlmKGhyICE9IEREX09LKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgLyogQWRkIHRoZSBuZXcgc3VyZmFjZSB0byB0aGUgY29tcGxleCBhdHRhY2htZW50IGFycmF5ICovCiAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX0NPTVBMRVhfQVRUQUNIRUQ7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKGxhc3QtPmNvbXBsZXhfYXJyYXlbal0pIGNvbnRpbnVlOwogICAgICAgICAgICBsYXN0LT5jb21wbGV4X2FycmF5W2pdID0gb2JqZWN0MjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxhc3QgPSBvYmplY3QyOwoKICAgICAgICAvKiBSZW1vdmUgdGhlIChwb3NzaWJsZSkgYmFjayBidWZmZXIgY2FwIGZyb20gdGhlIG5ldyBzdXJmYWNlIGRlc2NyaXB0aW9uLAogICAgICAgICAqIGJlY2F1c2Ugb25seSBvbmUgc3VyZmFjZSBpbiB0aGUgZmxpcHBpbmcgY2hhaW4gaXMgYSBiYWNrIGJ1ZmZlciwgb25lCiAgICAgICAgICogaXMgYSBmcm9udCBidWZmZXIsIHRoZSBvdGhlcnMgYXJlIGp1c3QgcHJpbWFyeSBzdXJmYWNlcy4KICAgICAgICAgKi8KICAgICAgICBERFNELmRkc0NhcHMuZHdDYXBzICY9IH5ERFNDQVBTX0JBQ0tCVUZGRVI7CiAgICB9CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICoKICogQ3JlYXRlcyBhIG5ldyBJRGlyZWN0RHJhd1N1cmZhY2Ugb2JqZWN0IGFuZCByZXR1cm5zIGl0cyBpbnRlcmZhY2UuCiAqCiAqIFRoZSBzdXJmYWNlIGNvbm5lY3Rpb25zIHdpdGggd2luZWQzZCBhcmUgYSBiaXQgdHJpY2t5LiBCYXNpY2FsbHkgaXQgd29ya3MKICogbGlrZSB0aGlzOgogKgogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwKICogfCBERHJhdyBzdXJmYWNlICAgICAgICAgIHwgICAgICAgICAgICAgICB8IFdpbmVEM0RTdXJmYWNlICB8CiAqIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfAogKiB8ICAgICAgICBXaW5lRDNEU3VyZmFjZSAgfC0tLS0tLS0tLS0tLS0tPnwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgQ2hpbGQgICAgICAgICAgIHw8LS0tLS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8CiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfAogKgogKiBUaGUgRERyYXcgc3VyZmFjZSBpcyB0aGUgcGFyZW50IG9mIHRoZSB3aW5lZDNkIHN1cmZhY2UsIGFuZCBpdCByZWxlYXNlcwogKiB0aGUgV2luZUQzRFN1cmZhY2Ugd2hlbiB0aGUgZGRyYXcgc3VyZmFjZSBpcyBkZXN0cm95ZWQuCiAqCiAqIEhvd2V2ZXIsIGZvciBhbGwgc3VyZmFjZXMgd2hpY2ggY2FuIGJlIGluIGEgY29udGFpbmVyIGluIFdpbmVEM0QsCiAqIHdlIGhhdmUgdG8gZG8gdGhpcy4gVGhlc2Ugc3VyZmFjZXMgYXJlIHVzdWFsbHkgY29tcGxleCBzdXJmYWNlcywKICogc28gdGhpcyBjb25jZXJucyBwcmltYXJ5IHN1cmZhY2VzIHdpdGggYSBmcm9udCBhbmQgYSBiYWNrIGJ1ZmZlciwKICogYW5kIHRleHR1cmVzLgogKgogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwKICogfCBERHJhdyBzdXJmYWNlICAgICAgICAgIHwgICAgICAgICAgICAgICB8IENvbnRhaW5lciAgICAgICB8CiAqIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfAogKiB8ICAgICAgICAgICAgICAgICAgQ2hpbGQgfDwtLS0tLS0tLS0tLS0tPnwgUGFyZW50ICAgICAgICAgIHwKICogfCAgICAgICAgICAgICAgICBUZXh0dXJlIHw8LS0tLS0tLS0tLS0tLT58ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgICBXaW5lRDNEU3VyZmFjZSB8PC0tLS18ICAgICAgICAgfCAgICAgICAgICBMZXZlbHMgfDwtLXwKICogfCBDb21wbGV4IGNvbm5lY3Rpb24gICAgIHwgICAgIHwgICAgICAgICB8ICAgICAgICAgICAgICAgICB8ICAgfAogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgfCAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICBeICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgfCBJUGFyZW50ICAgICAgICAgIHwgICAgIHwtLS0tLS0tLT58IFdpbmVEM0RTdXJmYWNlICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICBDaGlsZCB8PC0tLS0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8ICAgICAgIENvbnRhaW5lciB8PC0tfAogKiAgfCAgICB8LS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwgRERyYXcgc3VyZmFjZSAyICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHw8LT58IENvbXBsZXggcm9vdCAgIENoaWxkIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwgICAgICAgICAgICAgIFRleHR1cmUgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCAgICAgICBXaW5lRDNEU3VyZmFjZSB8PC0tLS18ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgfCBJUGFyZW50ICAgICAgICAgICAgIHwgICAgIHwtLS0tLT58IFdpbmVEM0RTdXJmYWNlICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICBDaGlsZCB8PC0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfCAgIHwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICB8ICAgICAgIENvbnRhaW5lciB8PC0tfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgICAgICAgICAgLS0tTW9yZSBzdXJmYWNlcyBjYW4gZm9sbG93LS0tICAgICAgICAgICAgICAgICAgfAogKgogKiBUaGUgcmVhc29uIGlzIHRoYXQgdGhlIElXaW5lRDNEU3dhcGNoYWluKHJlbmRlciB0YXJnZXQgY29udGFpbmVyKQogKiBhbmQgdGhlIElXaW5lRDNEVGV4dXJlKFRleHR1cmUgY29udGFpbmVyKSByZWxlYXNlIHRoZSBwYXJlbnRzCiAqIG9mIHRoZWlyIHN1cmZhY2UncyBjaGlsZHJlbiwgYnV0IGJ5IHJlbGVhc2luZyB0aGUgY29tcGxleCByb290CiAqIHRoZSBzdXJmYWNlcyB3aGljaCBhcmUgY29tcGxleGx5IGF0dGFjaGVkIHRvIGl0IGFyZSBkZXN0cm95ZWQKICogdG9vLiBTZWUgSURpcmVjdERyYXdTdXJmYWNlOjpSZWxlYXNlIGZvciBhIG1vcmUgZGV0YWlsZWQKICogZXhwbGFuYXRpb24uCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IERlc2NyaXB0aW9uIG9mIHRoZSBzdXJmYWNlIHRvIGNyZWF0ZQogKiAgU3VyZjogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICogIFVua091dGVyOiBCYXNpY2FsbHkgZm9yIGFnZ3JlZ2F0aW9uIHN1cHBvcnQsIGJ1dCBkZHJhdyBkb2Vzbid0IHN1cHBvcnQKICogICAgICAgICAgICBhZ2dyZWdhdGlvbiwgc28gaXQgaGFzIHRvIGJlIE5VTEwKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIENMQVNTX0VfTk9BR0dSRUdBVElPTiBpZiBVbmtPdXRlciAhPSBOVUxMCiAqICBEREVSUl8qIGlmIGFuIGVycm9yIG9jY3VycwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqKlN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKm9iamVjdCA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgTE9ORyBleHRyYV9zdXJmYWNlcyA9IDA7CiAgICBERFNVUkZBQ0VERVNDMiBkZXNjMjsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXApXG4iLCBUaGlzLCBERFNELCBTdXJmLCBVbmtPdXRlcik7CgogICAgLyogU29tZSBjaGVja3MgYmVmb3JlIHdlIHN0YXJ0ICovCiAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCIgKCVwKSBSZXF1ZXN0aW5nIHN1cmZhY2UgZGVzYyA6XG4iLCBUaGlzKTsKICAgICAgICBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhERFNEKTsKICAgIH0KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgaWYgKFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgOiBvdXRlciAhPSBOVUxMP1xuIiwgVGhpcyk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOyAvKiB1bmNoZWNrZWQgKi8KICAgIH0KCiAgICBpZiAoU3VyZiA9PSBOVUxMKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIFlvdSB3YW50IHRvIGdldCBiYWNrIGEgc3VyZmFjZT8gRG9uJ3QgZ2l2ZSBOVUxMIHB0cnMhXG4iLCBUaGlzKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBFX1BPSU5URVI7IC8qIHVuY2hlY2tlZCAqLwogICAgfQoKICAgIGlmICghKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NBUFMpKQogICAgewogICAgICAgIC8qIERWSURFTy5ETEwgZG9lcyBmb3JnZXQgdGhlIEREU0RfQ0FQUyBmbGFnIC4uLiAqc2lnaCogKi8KICAgICAgICBERFNELT5kd0ZsYWdzIHw9IEREU0RfQ0FQUzsKICAgIH0KICAgIGlmIChERFNELT5kZHNDYXBzLmR3Q2FwcyA9PSAwKQogICAgewogICAgICAgIC8qIFRoaXMgaGFzIGJlZW4gY2hlY2tlZCBvbiByZWFsIFdpbmRvd3MgKi8KICAgICAgICBERFNELT5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfTE9DQUxWSURNRU0gfCBERFNDQVBTX1ZJREVPTUVNT1JZOwogICAgfQoKICAgIGlmIChERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfQUxMT0NPTkxPQUQpCiAgICB7CiAgICAgICAgLyogSWYgdGhlIHN1cmZhY2UgaXMgb2YgdGhlICdhbGxvY29ubG9hZCcgdHlwZSwgaWdub3JlIHRoZSBMUFNVUkZBQ0UgZmllbGQgKi8KICAgICAgICBERFNELT5kd0ZsYWdzICY9IH5ERFNEX0xQU1VSRkFDRTsKICAgIH0KCiAgICBpZiAoKEREU0QtPmR3RmxhZ3MgJiBERFNEX0xQU1VSRkFDRSkgJiYgKEREU0QtPmxwU3VyZmFjZSA9PSBOVUxMKSkKICAgIHsKICAgICAgICAvKiBGcmFuayBIZXJiZXJ0J3MgRHVuZSBzcGVjaWZpZXMgYSBudWxsIHBvaW50ZXIgZm9yIHRoZSBzdXJmYWNlLCBpZ25vcmUgdGhlIExQU1VSRkFDRSBmaWVsZCAqLwogICAgICAgIFdBUk4oIiglcCkgTnVsbCBzdXJmYWNlIHBvaW50ZXIgc3BlY2lmaWVkLCBpZ25vcmUgaXQhXG4iLCBUaGlzKTsKICAgICAgICBERFNELT5kd0ZsYWdzICY9IH5ERFNEX0xQU1VSRkFDRTsKICAgIH0KCiAgICBpZigoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19GTElQIHwgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkpID09IChERFNDQVBTX0ZMSVAgfCBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSAmJgogICAgICAgIShUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IEF0dGVtcHQgdG8gY3JlYXRlIGEgZmxpcGFibGUgcHJpbWFyeSBzdXJmYWNlIHdpdGhvdXQgRERTQ0xfRVhDTFVTSVZFIHNldFxuIiwgVGhpcyk7CiAgICAgICAgKlN1cmYgPSBOVUxMOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX05PRVhDTFVTSVZFTU9ERTsKICAgIH0KCiAgICBpZihERFNELT5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX0ZST05UQlVGRkVSIHwgRERTQ0FQU19CQUNLQlVGRkVSKSkgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIHRyaWVkIHRvIGNyZWF0ZSBhbiBleHBsaWNpdCBmcm9udCBvciBiYWNrIGJ1ZmZlclxuIik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRENBUFM7CiAgICB9CiAgICAvKiBDaGVjayBjdWJlIG1hcHMgYnV0IG9ubHkgaWYgdGhlIHNpemUgaW5jbHVkZXMgdGhlbSAqLwogICAgaWYgKEREU0QtPmR3U2l6ZSA+PSBzaXplb2YoRERTVVJGQUNFREVTQzIpKQogICAgewogICAgICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVBfQUxMRkFDRVMgJiYKICAgICAgICAgICAhKEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVApKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQ3ViZSBtYXAgZmFjZXMgcmVxdWVzdGVkIHdpdGhvdXQgY3ViZSBtYXAgZmxhZ1xuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEQ0FQUzsKICAgICAgICB9CiAgICAgICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCAmJgogICAgICAgICAgIChERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQX0FMTEZBQ0VTKSA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQ3ViZSBtYXAgd2l0aG91dCBmYWNlcyByZXF1ZXN0ZWRcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CgogICAgICAgIC8qIFF1aWNrIHRlc3RzIGNvbmZpcm0gdGhvc2UgY2FuIGJlIGNyZWF0ZWQsIGJ1dCB3ZSBkb24ndCBkbyB0aGF0IHlldCAqLwogICAgICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVAgJiYKICAgICAgICAgICAoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUykgIT0gRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUykKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FKCJQYXJ0aWFsIGN1YmUgbWFwcyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEFjY29yZGluZyB0byB0aGUgbXNkbiB0aGlzIGZsYWcgaXMgaWdub3JlZCBieSBDcmVhdGVTdXJmYWNlICovCiAgICBpZiAoRERTRC0+ZHdTaXplID49IHNpemVvZihERFNVUkZBQ0VERVNDMikpCiAgICAgICAgRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9NSVBNQVBTVUJMRVZFTDsKCiAgICAvKiBNb2RpZnkgc29tZSBmbGFncyAqLwogICAgbWVtc2V0KCZkZXNjMiwgMCwgc2l6ZW9mKGRlc2MyKSk7CiAgICBkZXNjMi5kd1NpemUgPSBzaXplb2YoZGVzYzIpOyAgIC8qIEZvciB0aGUgc3RydWN0IGNvcHkgKi8KICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRSgmZGVzYzIsIEREU0QpOwogICAgZGVzYzIuZHdTaXplID0gc2l6ZW9mKGRlc2MyKTsgICAvKiBUbyBvdmVycmlkZSBhIHBvc3NpYmx5IHNtYWxsZXIgc2l6ZSAqLwogICAgZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZT1zaXplb2YoRERQSVhFTEZPUk1BVCk7IC8qIEp1c3QgdG8gYmUgc3VyZSAqLwoKICAgIC8qIEdldCB0aGUgdmlkZW8gbW9kZSBmcm9tIFdpbmVEM0QgLSB3ZSB3aWxsIG5lZWQgaXQgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0RGlzcGxheU1vZGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU3dhcGNoYWluIDAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byByZWFkIGRpc3BsYXkgbW9kZSBmcm9tIHdpbmVkM2RcbiIpOwogICAgICAgIHN3aXRjaChUaGlzLT5vcmlnX2JwcCkKICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9QODsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9YMVI1RzVCNTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SNUc2QjU7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUjhHOEI4OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDMyOgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1g4UjhHOEI4OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIE1vZGUuV2lkdGggPSBUaGlzLT5vcmlnX3dpZHRoOwogICAgICAgIE1vZGUuSGVpZ2h0ID0gVGhpcy0+b3JpZ19oZWlnaHQ7CiAgICB9CgogICAgLyogTm8gcGl4ZWxmb3JtYXQgZ2l2ZW4/IFVzZSB0aGUgY3VycmVudCBzY3JlZW4gZm9ybWF0ICovCiAgICBpZighKGRlc2MyLmR3RmxhZ3MgJiBERFNEX1BJWEVMRk9STUFUKSkKICAgIHsKICAgICAgICBkZXNjMi5kd0ZsYWdzIHw9IEREU0RfUElYRUxGT1JNQVQ7CiAgICAgICAgZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZT1zaXplb2YoRERQSVhFTEZPUk1BVCk7CgogICAgICAgIC8qIFdhaXQ6IEl0IGNvdWxkIGJlIGEgWiBidWZmZXIgKi8KICAgICAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfWkJVRkZFUikKICAgICAgICB7CiAgICAgICAgICAgIHN3aXRjaChkZXNjMi51Mi5kd01pcE1hcENvdW50KSAvKiBXaG8gaGFkIHRoaXMgZ2xvcmlvdXMgaWRlYT8gKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSAxNToKICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBXSU5FRDNERk1UX0QxNVMxKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMTY6CiAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgV0lORUQzREZNVF9EMTYpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBXSU5FRDNERk1UX0QyNFg4KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgV0lORUQzREZNVF9EMzIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBFUlIoIlVua25vd24gWiBidWZmZXIgYml0IGRlcHRoXG4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBNb2RlLkZvcm1hdCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIE5vIFdpZHRoIG9yIG5vIEhlaWdodD8gVXNlIHRoZSBvcmlnaW5hbCBzY3JlZW4gc2l6ZQogICAgICovCiAgICBpZighKGRlc2MyLmR3RmxhZ3MgJiBERFNEX1dJRFRIKSB8fAogICAgICAgIShkZXNjMi5kd0ZsYWdzICYgRERTRF9IRUlHSFQpICkKICAgIHsKICAgICAgICAvKiBJbnZhbGlkIGZvciBub24tcmVuZGVyIHRhcmdldHMgKi8KICAgICAgICBpZighKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJDcmVhdGluZyBhIG5vbi1QcmltYXJ5IHN1cmZhY2Ugd2l0aG91dCBXaWR0aCBvciBIZWlnaHQgaW5mbywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgICAgICAqU3VyZiA9IE5VTEw7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgZGVzYzIuZHdGbGFncyB8PSBERFNEX1dJRFRIIHwgRERTRF9IRUlHSFQ7CiAgICAgICAgZGVzYzIuZHdXaWR0aCA9IE1vZGUuV2lkdGg7CiAgICAgICAgZGVzYzIuZHdIZWlnaHQgPSBNb2RlLkhlaWdodDsKICAgIH0KCiAgICAvKiBNaXBtYXAgY291bnQgZml4ZXMgKi8KICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVApCiAgICB7CiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0NPTVBMRVgpCiAgICAgICAgewogICAgICAgICAgICBpZihkZXNjMi5kd0ZsYWdzICYgRERTRF9NSVBNQVBDT1VOVCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTWlwbWFwIGNvdW50IGlzIGdpdmVuLCBzaG91bGQgbm90IGJlIDAgKi8KICAgICAgICAgICAgICAgIGlmKCBkZXNjMi51Mi5kd01pcE1hcENvdW50ID09IDAgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBVbmRvY3VtZW50ZWQgZmVhdHVyZTogQ3JlYXRlIHN1YmxldmVscyB1bnRpbAogICAgICAgICAgICAgICAgICogZWl0aGVyIHRoZSB3aWR0aCBvciB0aGUgaGVpZ2h0IGlzIDEKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgRFdPUkQgbWluID0gZGVzYzIuZHdXaWR0aCA8IGRlc2MyLmR3SGVpZ2h0ID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MyLmR3V2lkdGggOiBkZXNjMi5kd0hlaWdodDsKICAgICAgICAgICAgICAgIGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgPSAwOwogICAgICAgICAgICAgICAgd2hpbGUoIG1pbiApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVzYzIudTIuZHdNaXBNYXBDb3VudCArPSAxOwogICAgICAgICAgICAgICAgICAgIG1pbiA+Pj0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBOb3QtY29tcGxleCBtaXBtYXAgLT4gTWlwbWFwY291bnQgPSAxICovCiAgICAgICAgICAgIGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgPSAxOwogICAgICAgIH0KICAgICAgICBleHRyYV9zdXJmYWNlcyA9IGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgLSAxOwoKICAgICAgICAvKiBUaGVyZSdzIGEgbWlwbWFwIGNvdW50IGluIHRoZSBjcmVhdGVkIHN1cmZhY2UgaW4gYW55IGNhc2UgKi8KICAgICAgICBkZXNjMi5kd0ZsYWdzIHw9IEREU0RfTUlQTUFQQ09VTlQ7CiAgICB9CiAgICAvKiBJZiBubyBtaXBtYXAgaXMgZ2l2ZW4sIHRoZSB0ZXh0dXJlIGhhcyBvbmx5IG9uZSBsZXZlbCAqLwoKICAgIC8qIFRoZSBmaXJzdCBzdXJmYWNlIGlzIGEgZnJvbnQgYnVmZmVyLCB0aGUgYmFjayBidWZmZXIgaXMgY3JlYXRlZCBhZnRlcndhcmRzICovCiAgICBpZiggKGRlc2MyLmR3RmxhZ3MgJiBERFNEX0NBUFMpICYmIChkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpICkKICAgIHsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX0ZST05UQlVGRkVSOwogICAgfQoKICAgIC8qIFRoZSByb290IHN1cmZhY2UgaW4gYSBjdWJlIG1hcCBpcyBwb3NpdGl2ZSB4ICovCiAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKQogICAgewogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVYOwogICAgfQoKICAgIC8qIENyZWF0ZSB0aGUgZmlyc3Qgc3VyZmFjZSAqLwogICAgaHIgPSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShUaGlzLCAmZGVzYzIsICZvYmplY3QsIDApOwogICAgaWYoIGhyICE9IEREX09LKQogICAgewogICAgICAgIEVSUigiSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UgZmFpbGVkIHdpdGggJTA4eFxuIiwgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgb2JqZWN0LT5pc19jb21wbGV4X3Jvb3QgPSBUUlVFOwoKICAgICpTdXJmID0gSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKCiAgICAvKiBDcmVhdGUgQWRkaXRpb25hbCBzdXJmYWNlcyBpZiBuZWNlc3NhcnkKICAgICAqIFRoaXMgYXBwbGllcyB0byBQcmltYXJ5IHN1cmZhY2VzIHdoaWNoIGhhdmUgYSBiYWNrIGJ1ZmZlciBjb3VudAogICAgICogc2V0LCBidXQgbm90IHRvIG1pcG1hcCB0ZXh0dXJlcy4gSW4gY2FzZSBvZiBNaXBtYXAgdGV4dHVyZXMsCiAgICAgKiB3aW5lRDNEIHRha2VzIGNhcmUgb2YgdGhlIGNyZWF0aW9uIG9mIGFkZGl0aW9uYWwgc3VyZmFjZXMKICAgICAqLwogICAgaWYoRERTRC0+ZHdGbGFncyAmIEREU0RfQkFDS0JVRkZFUkNPVU5UKQogICAgewogICAgICAgIGV4dHJhX3N1cmZhY2VzID0gRERTRC0+ZHdCYWNrQnVmZmVyQ291bnQ7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJj0gfkREU0NBUFNfRlJPTlRCVUZGRVI7IC8qIEl0J3Mgbm90IGEgZnJvbnQgYnVmZmVyICovCiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19CQUNLQlVGRkVSOwogICAgfQoKICAgIGhyID0gRERfT0s7CiAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKQogICAgewogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVaOwogICAgICAgIGhyIHw9IENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcyhUaGlzLCBvYmplY3QsIGV4dHJhX3N1cmZhY2VzICsgMSwgZGVzYzIsIFRSVUUpOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVo7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWjsKICAgICAgICBociB8PSBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoVGhpcywgb2JqZWN0LCBleHRyYV9zdXJmYWNlcyArIDEsIGRlc2MyLCBUUlVFKTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVaOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVk7CiAgICAgICAgaHIgfD0gQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKFRoaXMsIG9iamVjdCwgZXh0cmFfc3VyZmFjZXMgKyAxLCBkZXNjMiwgVFJVRSk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVZOwogICAgICAgIGhyIHw9IENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcyhUaGlzLCBvYmplY3QsIGV4dHJhX3N1cmZhY2VzICsgMSwgZGVzYzIsIFRSVUUpOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWDsKICAgICAgICBociB8PSBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoVGhpcywgb2JqZWN0LCBleHRyYV9zdXJmYWNlcyArIDEsIGRlc2MyLCBUUlVFKTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVYOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVg7CiAgICB9CgogICAgaHIgfD0gQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKFRoaXMsIG9iamVjdCwgZXh0cmFfc3VyZmFjZXMsIGRlc2MyLCBGQUxTRSk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICAvKiBUaGlzIGRlc3Ryb3lzIGFuZCBwb3NzaWJseSBjcmVhdGVkIHN1cmZhY2VzIHRvbyAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9SZWxlYXNlKCBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3U3VyZmFjZTcpICk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogSWYgdGhlIGltcGxlbWVudGF0aW9uIGlzIE9wZW5HTCBhbmQgdGhlcmUncyBubyBkM2RkZXZpY2UsIGF0dGFjaCBhIGQzZGRldmljZQogICAgICogQnV0IGF0dGFjaCB0aGUgZDNkZGV2aWNlIG9ubHkgaWYgdGhlIGN1cnJlbnRseSBjcmVhdGVkIHN1cmZhY2Ugd2FzCiAgICAgKiBhIHByaW1hcnkgc3VyZmFjZSAoMkQgYXBwIGluIDNEIG1vZGUpIG9yIGEgM0RERVZJQ0Ugc3VyZmFjZSAoM0QgYXBwKQogICAgICogVGhlIG9ubHkgY2FzZSBJIGNhbiB0aGluayBvZiB3aGVyZSB0aGlzIGRvZXNuJ3QgYXBwbHkgaXMgd2hlbiBhCiAgICAgKiAyRCBhcHAgd2FzIGNvbmZpZ3VyZWQgYnkgdGhlIHVzZXIgdG8gcnVuIHdpdGggT3BlbkdMIGFuZCBpdCBkaWRuJ3QgY3JlYXRlCiAgICAgKiB0aGUgcmVuZGVyIHRhcmdldCBhcyBmaXJzdCBzdXJmYWNlLiBJbiB0aGlzIGNhc2UgdGhlIHJlbmRlciB0YXJnZXQgY3JlYXRpb24KICAgICAqIHdpbGwgY2F1c2UgdGhlIDNEIGluaXQuCiAgICAgKi8KICAgIGlmKCAoVGhpcy0+SW1wbFR5cGUgPT0gU1VSRkFDRV9PUEVOR0wpICYmICEoVGhpcy0+ZDNkX2luaXRpYWxpemVkKSAmJgogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTXzNEREVWSUNFKSApCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqdGFyZ2V0ID0gb2JqZWN0LCAqc3VyZmFjZTsKICAgICAgICBzdHJ1Y3QgbGlzdCAqZW50cnk7CgogICAgICAgIC8qIFNlYXJjaCBmb3IgdGhlIHByaW1hcnkgdG8gdXNlIGFzIHJlbmRlciB0YXJnZXQgKi8KICAgICAgICBMSVNUX0ZPUl9FQUNIKGVudHJ5LCAmVGhpcy0+c3VyZmFjZV9saXN0KQogICAgICAgIHsKICAgICAgICAgICAgc3VyZmFjZSA9IExJU1RfRU5UUlkoZW50cnksIElEaXJlY3REcmF3U3VyZmFjZUltcGwsIHN1cmZhY2VfbGlzdF9lbnRyeSk7CiAgICAgICAgICAgIGlmKChzdXJmYWNlLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfRlJPTlRCVUZGRVIpKSA9PQogICAgICAgICAgICAgICAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfRlJPTlRCVUZGRVIpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBmb3VuZCAqLwogICAgICAgICAgICAgICAgdGFyZ2V0ID0gc3VyZmFjZTsKICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBwcmltYXJ5ICVwIGFzIHJlbmRlciB0YXJnZXRcbiIsIHRhcmdldCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIiglcCkgQXR0YWNoaW5nIGEgRDNERGV2aWNlLCByZW5kZXJ0YXJnZXQgPSAlcFxuIiwgVGhpcywgdGFyZ2V0KTsKICAgICAgICBociA9IElEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UoVGhpcywgdGFyZ2V0KTsKICAgICAgICBpZihociAhPSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpyZWxlYXNlX3N1cmY7CiAgICAgICAgICAgIEVSUigiSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZSBmYWlsZWQsIGhyID0gJXhcbiIsIGhyKTsKICAgICAgICAgICAgKlN1cmYgPSBOVUxMOwoKICAgICAgICAgICAgLyogVGhlIGJlZm9yZSBjcmVhdGVkIHN1cmZhY2Ugc3RydWN0dXJlcyBhcmUgaW4gYW4gaW5jb21wbGV0ZSBzdGF0ZSBoZXJlLgogICAgICAgICAgICAgKiBXaW5lRDNEIGhvbGRzIHRoZSByZWZlcmVuY2Ugb24gdGhlIElQYXJlbnRzLCBhbmQgaXQgcmVsZWFzZWQgdGhlbSBvbiB0aGUgZmFpbHVyZQogICAgICAgICAgICAgKiBhbHJlYWR5LiBTbyB0aGUgcmVndWxhciByZWxlYXNlIG1ldGhvZCBpbXBsZW1lbnRhdGlvbiB3b3VsZCBmYWlsIG9uIHRoZSBhdHRlbXB0CiAgICAgICAgICAgICAqIHRvIGRlc3Ryb3kgZWl0aGVyIHRoZSBJUGFyZW50cyBvciB0aGUgc3dhcGNoYWluLiBTbyBmcmVlIHRoZSBzdXJmYWNlIGhlcmUuCiAgICAgICAgICAgICAqIFRoZSBzdXJmYWNlIHN0cnVjdHVyZSBoZXJlIGlzIGEgbGlzdCwgbm90IGEgdHJlZSwgYmVjYXVzZSBvbnNjcmVlbiB0YXJnZXRzCiAgICAgICAgICAgICAqIGNhbm5vdCBiZSBjdWJlIHRleHR1cmVzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB3aGlsZShvYmplY3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlbGVhc2Vfc3VyZiA9IG9iamVjdDsKICAgICAgICAgICAgICAgIG9iamVjdCA9IG9iamVjdC0+Y29tcGxleF9hcnJheVswXTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGxfRGVzdHJveShyZWxlYXNlX3N1cmYpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgLyogQWRkcmVmIHRoZSBkZHJhdyBpbnRlcmZhY2UgdG8ga2VlcCBhbiByZWZlcmVuY2UgZm9yIGVhY2ggc3VyZmFjZSAqLwogICAgSURpcmVjdERyYXc3X0FkZFJlZihpZmFjZSk7CiAgICBvYmplY3QtPmlmYWNlVG9SZWxlYXNlID0gKElVbmtub3duICopIGlmYWNlOwoKICAgIC8qIENyZWF0ZSBhIFdpbmVEM0RUZXh0dXJlIGlmIGEgdGV4dHVyZSB3YXMgcmVxdWVzdGVkICovCiAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfVEVYVFVSRSkKICAgIHsKICAgICAgICBVSU5UIGxldmVsczsKICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdDsKICAgICAgICBXSU5FRDNEUE9PTCBQb29sID0gV0lORUQzRFBPT0xfREVGQVVMVDsKCiAgICAgICAgVGhpcy0+dGV4X3Jvb3QgPSBvYmplY3Q7CgogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVApCiAgICAgICAgewogICAgICAgICAgICAvKiBhIG1pcG1hcCBpcyBjcmVhdGVkLCBjcmVhdGUgZW5vdWdoIGxldmVscyAqLwogICAgICAgICAgICBsZXZlbHMgPSBkZXNjMi51Mi5kd01pcE1hcENvdW50OwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBtaXBtYXAgaXMgY3JlYXRlZCwgY3JlYXRlIG9uZSBsZXZlbCAqLwogICAgICAgICAgICBsZXZlbHMgPSAxOwogICAgICAgIH0KCiAgICAgICAgLyogRERTQ0FQU19TWVNURU1NRU1PUlkgdGV4dHVyZXMgYXJlIGluIFdJTkVEM0RQT09MX1NZU1RFTU1FTSAqLwogICAgICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19TWVNURU1NRU1PUlkpCiAgICAgICAgewogICAgICAgICAgICBQb29sID0gV0lORUQzRFBPT0xfU1lTVEVNTUVNOwogICAgICAgIH0KICAgICAgICAvKiBTaG91bGQgSSBmb3J3YXJkIHRoZSBNQU5BR0VEIGNhcCB0byB0aGUgbWFuYWdlZCBwb29sID8gKi8KCiAgICAgICAgLyogR2V0IHRoZSBmb3JtYXQuIEl0J3Mgc2V0IGFscmVhZHkgYnkgQ3JlYXRlTmV3U3VyZmFjZSAqLwogICAgICAgIEZvcm1hdCA9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJm9iamVjdC0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdCk7CgogICAgICAgIC8qIFRoZSBzdXJmYWNlcyBhcmUgYWxyZWFkeSBjcmVhdGVkLCB0aGUgY2FsbGJhY2sgb25seQogICAgICAgICAqIHBhc3NlcyB0aGUgSVdpbmVEM0RTdXJmYWNlIHRvIFdpbmVEM0QKICAgICAgICAgKi8KICAgICAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKQogICAgICAgIHsKICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVDdWJlVGV4dHVyZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0QtPmR3V2lkdGgsIC8qIEVkZ2VsZW5ndGggKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogdXNhZ2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKikgJm9iamVjdC0+d2luZUQzRFRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU2hhcmVkSGFuZGxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZVN1cmZhY2UpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVRleHR1cmUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0QtPmR3V2lkdGgsIEREU0QtPmR3SGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzLCAvKiBNaXBNYXBDb3VudCA9IExldmVscyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogdXNhZ2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RUZXh0dXJlICoqKSAmb2JqZWN0LT53aW5lRDNEVGV4dHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIFNoYXJlZEhhbmRsZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlU3VyZmFjZSApOwogICAgICAgIH0KICAgICAgICBUaGlzLT50ZXhfcm9vdCA9IE5VTEw7CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKI2RlZmluZSBEREVOVU1TVVJGQUNFU19TRUFSQ0hUWVBFIChEREVOVU1TVVJGQUNFU19DQU5CRUNSRUFURUR8RERFTlVNU1VSRkFDRVNfRE9FU0VYSVNUKQojZGVmaW5lIERERU5VTVNVUkZBQ0VTX01BVENIVFlQRSAoRERFTlVNU1VSRkFDRVNfQUxMfERERU5VTVNVUkZBQ0VTX01BVENIfERERU5VTVNVUkZBQ0VTX05PTUFUQ0gpCgpzdGF0aWMgQk9PTApNYWluX0RpcmVjdERyYXdfRERQSVhFTEZPUk1BVF9NYXRjaChjb25zdCBERFBJWEVMRk9STUFUICpyZXF1ZXN0ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEREUElYRUxGT1JNQVQgKnByb3ZpZGVkKQp7CiAgICAvKiBTb21lIGZsYWdzIG11c3QgYmUgcHJlc2VudCBpbiBib3RoIG9yIG5laXRoZXIgZm9yIGEgbWF0Y2guICovCiAgICBzdGF0aWMgY29uc3QgRFdPUkQgbXVzdF9tYXRjaCA9IEREUEZfUEFMRVRURUlOREVYRUQxIHwgRERQRl9QQUxFVFRFSU5ERVhFRDIKICAgICAgICB8IEREUEZfUEFMRVRURUlOREVYRUQ0IHwgRERQRl9QQUxFVFRFSU5ERVhFRDggfCBERFBGX0ZPVVJDQwogICAgICAgIHwgRERQRl9aQlVGRkVSIHwgRERQRl9TVEVOQ0lMQlVGRkVSOwoKICAgIGlmICgocmVxdWVzdGVkLT5kd0ZsYWdzICYgcHJvdmlkZWQtPmR3RmxhZ3MpICE9IHJlcXVlc3RlZC0+ZHdGbGFncykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBtdXN0X21hdGNoKSAhPSAocHJvdmlkZWQtPmR3RmxhZ3MgJiBtdXN0X21hdGNoKSkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIEREUEZfRk9VUkNDKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPmR3Rm91ckNDICE9IHByb3ZpZGVkLT5kd0ZvdXJDQykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9SR0J8RERQRl9ZVVZ8RERQRl9aQlVGRkVSfEREUEZfQUxQSEEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfEREUEZfTFVNSU5BTkNFfEREUEZfQlVNUERVRFYpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnUxLmR3UkdCQml0Q291bnQgIT0gcHJvdmlkZWQtPnUxLmR3UkdCQml0Q291bnQpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfU1RFTkNJTEJVRkZFUgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8RERQRl9MVU1JTkFOQ0V8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTIuZHdSQml0TWFzayAhPSBwcm92aWRlZC0+dTIuZHdSQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9SR0J8RERQRl9ZVVZ8RERQRl9aQlVGRkVSfEREUEZfQlVNUERVRFYpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnUzLmR3R0JpdE1hc2sgIT0gcHJvdmlkZWQtPnUzLmR3R0JpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAvKiBJIGNvdWxkIGJlIHdyb25nIGFib3V0IHRoZSBidW1wbWFwcGluZy4gTVNETiBkb2NzIGFyZSB2YWd1ZS4gKi8KICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9SR0J8RERQRl9ZVVZ8RERQRl9TVEVOQ0lMQlVGRkVSCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51NC5kd0JCaXRNYXNrICE9IHByb3ZpZGVkLT51NC5kd0JCaXRNYXNrKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX0FMUEhBUElYRUxTfEREUEZfWlBJWEVMUykpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTUuZHdSR0JBbHBoYUJpdE1hc2sgIT0gcHJvdmlkZWQtPnU1LmR3UkdCQWxwaGFCaXRNYXNrKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MCklEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKGNvbnN0IEREU1VSRkFDRURFU0MyKiByZXF1ZXN0ZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEREU1VSRkFDRURFU0MyKiBwcm92aWRlZCkKewogICAgc3RydWN0IGNvbXBhcmVfaW5mbwogICAgewogICAgICAgIERXT1JEIGZsYWc7CiAgICAgICAgcHRyZGlmZl90IG9mZnNldDsKICAgICAgICBzaXplX3Qgc2l6ZTsKICAgIH07CgojZGVmaW5lIENNUChGTEFHLCBGSUVMRCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICAgICB7IEREU0RfIyNGTEFHLCBvZmZzZXRvZihERFNVUkZBQ0VERVNDMiwgRklFTEQpLCBcCiAgICAgICAgICBzaXplb2YoKChERFNVUkZBQ0VERVNDMiAqKShOVUxMKSktPkZJRUxEKSB9CgogICAgc3RhdGljIGNvbnN0IHN0cnVjdCBjb21wYXJlX2luZm8gY29tcGFyZVtdID0KICAgIHsKICAgICAgICBDTVAoQUxQSEFCSVRERVBUSCwgZHdBbHBoYUJpdERlcHRoKSwKICAgICAgICBDTVAoQkFDS0JVRkZFUkNPVU5ULCBkd0JhY2tCdWZmZXJDb3VudCksCiAgICAgICAgQ01QKENBUFMsIGRkc0NhcHMpLAogICAgICAgIENNUChDS0RFU1RCTFQsIGRkY2tDS0Rlc3RCbHQpLAogICAgICAgIENNUChDS0RFU1RPVkVSTEFZLCB1MyAvKiBkZGNrQ0tEZXN0T3ZlcmxheSAqLyksCiAgICAgICAgQ01QKENLU1JDQkxULCBkZGNrQ0tTcmNCbHQpLAogICAgICAgIENNUChDS1NSQ09WRVJMQVksIGRkY2tDS1NyY092ZXJsYXkpLAogICAgICAgIENNUChIRUlHSFQsIGR3SGVpZ2h0KSwKICAgICAgICBDTVAoTElORUFSU0laRSwgdTEgLyogZHdMaW5lYXJTaXplICovKSwKICAgICAgICBDTVAoTFBTVVJGQUNFLCBscFN1cmZhY2UpLAogICAgICAgIENNUChNSVBNQVBDT1VOVCwgdTIgLyogZHdNaXBNYXBDb3VudCAqLyksCiAgICAgICAgQ01QKFBJVENILCB1MSAvKiBsUGl0Y2ggKi8pLAogICAgICAgIC8qIFBJWEVMRk9STUFUOiBtYW51YWwgKi8KICAgICAgICBDTVAoUkVGUkVTSFJBVEUsIHUyIC8qIGR3UmVmcmVzaFJhdGUgKi8pLAogICAgICAgIENNUChURVhUVVJFU1RBR0UsIGR3VGV4dHVyZVN0YWdlKSwKICAgICAgICBDTVAoV0lEVEgsIGR3V2lkdGgpLAogICAgICAgIC8qIFpCVUZGRVJCSVRERVBUSDogIm9ic29sZXRlIiAqLwogICAgfTsKCiN1bmRlZiBDTVAKCiAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICBpZiAoKHJlcXVlc3RlZC0+ZHdGbGFncyAmIHByb3ZpZGVkLT5kd0ZsYWdzKSAhPSByZXF1ZXN0ZWQtPmR3RmxhZ3MpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGZvciAoaT0wOyBpIDwgc2l6ZW9mKGNvbXBhcmUpL3NpemVvZihjb21wYXJlWzBdKTsgaSsrKQogICAgewogICAgICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBjb21wYXJlW2ldLmZsYWcKICAgICAgICAgICAgJiYgbWVtY21wKChjb25zdCBjaGFyICopcHJvdmlkZWQgKyBjb21wYXJlW2ldLm9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopcmVxdWVzdGVkICsgY29tcGFyZVtpXS5vZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICBjb21wYXJlW2ldLnNpemUpICE9IDApCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkKICAgIHsKICAgICAgICBpZiAoIU1haW5fRGlyZWN0RHJhd19ERFBJWEVMRk9STUFUX01hdGNoKCZyZXF1ZXN0ZWQtPnU0LmRkcGZQaXhlbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnByb3ZpZGVkLT51NC5kZHBmUGl4ZWxGb3JtYXQpKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCiN1bmRlZiBEREVOVU1TVVJGQUNFU19TRUFSQ0hUWVBFCiN1bmRlZiBEREVOVU1TVVJGQUNFU19NQVRDSFRZUEUKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkVudW1TdXJmYWNlcwogKgogKiBMb29wcyB0aHJvdWdoIGFsbCBzdXJmYWNlcyBhdHRhY2hlZCB0byB0aGlzIGRldmljZSBhbmQgY2FsbHMgdGhlCiAqIGFwcGxpY2F0aW9uIGNhbGxiYWNrLiBUaGlzIGNhbid0IGJlIHJlbGF5ZWQgdG8gV2luZUQzRERldmljZSwKICogYmVjYXVzZSBzb21lIFdpbmVEM0RTdXJmYWNlcycgcGFyZW50cyBhcmUgSVBhcmVudCBvYmplY3RzCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBTb21lIGZpbHRlcmluZyBmbGFncy4gU2VlIElEaXJlY3REcmF3SW1wbF9FbnVtU3VyZmFjZXNDYWxsYmFjawogKiAgRERTRDogRGVzY3JpcHRpb24gdG8gZmlsdGVyIGZvcgogKiAgQ29udGV4dDogQXBwbGljYXRpb24tcHJvdmlkZWQgcG9pbnRlciwgaXQncyBwYXNzZWQgdW5tb2RpZmllZCB0byB0aGUKICogICAgICAgICAgIENhbGxiYWNrIGZ1bmN0aW9uCiAqICBDYWxsYmFjazogQWRkcmVzcyB0byBjYWxsIGZvciBlYWNoIHN1cmZhY2UKICoKICogUmV0dXJuczoKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIGNhbGxiYWNrIGlzIE5VTEwKICogIEREX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0VudW1TdXJmYWNlcyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBEREVOVU1TVVJGQUNFU0NBTExCQUNLNyBDYWxsYmFjaykKewogICAgLyogVGhlIHN1cmZhY2UgZW51bWVyYXRpb24gaXMgaGFuZGxlZCBieSBXaW5lRERyYXcsCiAgICAgKiBiZWNhdXNlIGl0IGtlZXBzIHRyYWNrIG9mIGFsbCBzdXJmYWNlcyBhdHRhY2hlZCB0bwogICAgICogaXQuIFRoZSBmaWx0ZXJpbmcgaXMgZG9uZSBieSBvdXIgY2FsbGJhY2sgZnVuY3Rpb24sCiAgICAgKiBiZWNhdXNlIFdpbmVERHJhdyBkb2Vzbid0IGhhbmRsZSBkZHJhdy1saWtlIHN1cmZhY2UKICAgICAqIGNhcHMgc3RydWN0dXJlcwogICAgICovCiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZjsKICAgIEJPT0wgYWxsLCBub21hdGNoOwogICAgRERTVVJGQUNFREVTQzIgZGVzYzsKICAgIHN0cnVjdCBsaXN0ICplbnRyeSwgKmVudHJ5MjsKCiAgICBhbGwgPSBGbGFncyAmIERERU5VTVNVUkZBQ0VTX0FMTDsKICAgIG5vbWF0Y2ggPSBGbGFncyAmIERERU5VTVNVUkZBQ0VTX05PTUFUQ0g7CgogICAgVFJBQ0UoIiglcCktPigleCwlcCwlcCwlcClcbiIsIFRoaXMsIEZsYWdzLCBERFNELCBDb250ZXh0LCBDYWxsYmFjayk7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIGlmKCFDYWxsYmFjaykKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFVzZSB0aGUgX1NBRkUgZW51bWVyYXRpb24sIHRoZSBhcHAgbWF5IGRlc3Ryb3kgZW51bWVyYXRlZCBzdXJmYWNlcyAqLwogICAgTElTVF9GT1JfRUFDSF9TQUZFKGVudHJ5LCBlbnRyeTIsICZUaGlzLT5zdXJmYWNlX2xpc3QpCiAgICB7CiAgICAgICAgc3VyZiA9IExJU1RfRU5UUlkoZW50cnksIElEaXJlY3REcmF3U3VyZmFjZUltcGwsIHN1cmZhY2VfbGlzdF9lbnRyeSk7CiAgICAgICAgaWYgKGFsbCB8fCAobm9tYXRjaCAhPSBJRGlyZWN0RHJhd0ltcGxfRERTRF9NYXRjaChERFNELCAmc3VyZi0+c3VyZmFjZV9kZXNjKSkpCiAgICAgICAgewogICAgICAgICAgICBkZXNjID0gc3VyZi0+c3VyZmFjZV9kZXNjOwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICAgICAgICAgIGlmKENhbGxiYWNrKCBJQ09NX0lOVEVSRkFDRShzdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwgJmRlc2MsIENvbnRleHQpICE9IERERU5VTVJFVF9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBERF9PSzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpmaW5kUmVuZGVyVGFyZ2V0KElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmZhY2UsCiAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICAgdm9pZCAqY3R4KQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgc3VyZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICoqdGFyZ2V0ID0gKElEaXJlY3REcmF3U3VyZmFjZUltcGwgKiopIGN0eDsKCiAgICBpZighc3VyZi0+aXNSZW5kZXJUYXJnZXQpIHsKICAgICAgICAqdGFyZ2V0ID0gc3VyZjsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZmFjZSk7CiAgICAgICAgcmV0dXJuIERERU5VTVJFVF9DQU5DRUw7CiAgICB9CgogICAgLyogUmVjdXJzZSBpbnRvIHRoZSBzdXJmYWNlIHRyZWUgKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZTdfRW51bUF0dGFjaGVkU3VyZmFjZXMoc3VyZmFjZSwgY3R4LCBmaW5kUmVuZGVyVGFyZ2V0KTsKCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZmFjZSk7CiAgICBpZigqdGFyZ2V0KSByZXR1cm4gRERFTlVNUkVUX0NBTkNFTDsKICAgIGVsc2UgcmV0dXJuIERERU5VTVJFVF9PSzsgLyogQ29udGludWUgd2l0aCB0aGUgbmV4dCBuZWlnaGJvciBzdXJmYWNlICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEM0Q3Q0JfQ3JlYXRlUmVuZGVyVGFyZ2V0CiAqCiAqIENhbGxiYWNrIGNhbGxlZCBieSBXaW5lRDNEIHRvIGNyZWF0ZSBTdXJmYWNlcyBmb3IgcmVuZGVyIHRhcmdldCB1c2FnZQogKiBUaGlzIGZ1bmN0aW9uIHRha2VzIHRoZSBEM0QgdGFyZ2V0IGZyb20gdGhlIElEaXJlY3REcmF3SW1wbCBzdHJ1Y3R1cmUsCiAqIGFuZCByZXR1cm5zIHRoZSBXaW5lRDNEU3VyZmFjZS4gVG8gYXZvaWQgZG91YmxlIHVzYWdlLCB0aGUgc3VyZmFjZQogKiBpcyBtYXJrZWQgYXMgcmVuZGVyIHRhcmdldCBhZnRlcndhcmRzCiAqCiAqIFBhcmFtcwogKiAgZGV2aWNlOiBUaGUgV2luZUQzRERldmljZSdzIHBhcmVudAogKiAgV2lkdGgsIEhlaWdodCwgRm9ybWF0OiBEaW1lbnNpb25zIGFuZCBwaXhlbGZvcm1hdCBvZiB0aGUgcmVuZGVyIHRhcmdldAogKiAgICAgICAgICAgICAgICAgICAgICAgICBJZ25vcmVkLCBiZWNhdXNlIHRoZSBzdXJmYWNlIGFscmVhZHkgZXhpc3RzCiAqICBNdWx0aVNhbXBsZSwgTXVsdGlzYW1wbGVRdWFsaXR5LCBMb2NrYWJsZTogSWdub3JlZCBmb3IgdGhlIHNhbWUgcmVhc29uCiAqICBMb2NrYWJsZTogaWdub3JlZAogKiAgcHBTdXJmYWNlOiBBZGRyZXNzIHRvIHBhc3MgdGhlIHN1cmZhY2UgcG9pbnRlciBiYWNrIGF0CiAqICBwU2hhcmVkSGFuZGxlOiBJZ25vcmVkCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBEM0RfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZVJlbmRlclRhcmdldChJVW5rbm93biAqZGV2aWNlLCBJVW5rbm93biAqcFN1cGVyaW9yLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE11bHRpc2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIExvY2thYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSoqIHBwU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUqIHBTaGFyZWRIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqZDNkU3VyZmFjZSA9IFRoaXMtPmQzZF90YXJnZXQsICp0YXJnZXQgPSBOVUxMOwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBkZXZpY2UpOwoKICAgIGlmKGQzZFN1cmZhY2UtPmlzUmVuZGVyVGFyZ2V0KQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfRW51bUF0dGFjaGVkU3VyZmFjZXMoSUNPTV9JTlRFUkZBQ0UoZDNkU3VyZmFjZSwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGFyZ2V0LCBmaW5kUmVuZGVyVGFyZ2V0KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICB0YXJnZXQgPSBkM2RTdXJmYWNlOwogICAgfQoKICAgIGlmKCF0YXJnZXQpCiAgICB7CiAgICAgICAgdGFyZ2V0ID0gVGhpcy0+ZDNkX3RhcmdldDsKICAgICAgICBFUlIoIiAoJXApIDogTm8gRGlyZWN0RHJhd1N1cmZhY2UgZm91bmQgdG8gY3JlYXRlIHRoZSBiYWNrIGJ1ZmZlci4gVXNpbmcgdGhlIGZyb250IGJ1ZmZlciBhcyBiYWNrIGJ1ZmZlci4gVW5jZXJ0YWluIGNvbnNlcXVlbmNlc1xuIiwgVGhpcyk7CiAgICB9CgogICAgLyogVE9ETzogUmV0dXJuIGZhaWx1cmUgaWYgdGhlIGRpbWVuc2lvbnMgZG8gbm90IG1hdGNoLCBidXQgdGhpcyBzaG91bGRuJ3QgaGFwcGVuICovCgogICAgKnBwU3VyZmFjZSA9IHRhcmdldC0+V2luZUQzRFN1cmZhY2U7CiAgICB0YXJnZXQtPmlzUmVuZGVyVGFyZ2V0ID0gVFJVRTsKICAgIFRSQUNFKCJSZXR1cm5pbmcgd2luZUQzRFN1cmZhY2UgJXAsIGl0IGJlbG9uZ3MgdG8gc3VyZmFjZSAlcFxuIiwgKnBwU3VyZmFjZSwgZDNkU3VyZmFjZSk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UoSVVua25vd24gKmRldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKnBTdXBlcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTXVsdGlzYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIERpc2NhcmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSoqIHBwU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFKiBwU2hhcmVkSGFuZGxlKQp7CiAgICAvKiBDcmVhdGUgYSBEZXB0aCBTdGVuY2lsIHN1cmZhY2UgdG8gbWFrZSBXaW5lRDNEIGhhcHB5ICovCiAgICBIUkVTVUxUIGhyID0gRDNEX09LOwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGRldmljZSk7CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwoKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgZGV2aWNlKTsKCiAgICAqcHBTdXJmYWNlID0gTlVMTDsKCiAgICAvKiBDcmVhdGUgYSBEaXJlY3REcmF3IHN1cmZhY2UgKi8KICAgIG1lbXNldCgmZGRzZCwgMCwgc2l6ZW9mKGRkc2QpKTsKICAgIGRkc2QuZHdTaXplID0gc2l6ZW9mKGRkc2QpOwogICAgZGRzZC51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREUElYRUxGT1JNQVQpOwogICAgZGRzZC5kd0ZsYWdzID0gRERTRF9QSVhFTEZPUk1BVCB8IEREU0RfV0lEVEggfCBERFNEX0hFSUdIVCB8IEREU0RfQ0FQUzsKICAgIGRkc2QuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX09GRlNDUkVFTlBMQUlOOwogICAgZGRzZC5kd0hlaWdodCA9IEhlaWdodDsKICAgIGRkc2QuZHdXaWR0aCA9IFdpZHRoOwogICAgaWYoRm9ybWF0ICE9IDApCiAgICB7CiAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZHNkLnU0LmRkcGZQaXhlbEZvcm1hdCwgRm9ybWF0KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgZGRzZC5kd0ZsYWdzIF49IEREU0RfUElYRUxGT1JNQVQ7CiAgICB9CgogICAgVGhpcy0+ZGVwdGhzdGVuY2lsID0gVFJVRTsKICAgIGhyID0gSURpcmVjdERyYXc3X0NyZWF0ZVN1cmZhY2UoKElEaXJlY3REcmF3NyAqKSBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGRzZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElEaXJlY3REcmF3U3VyZmFjZTcgKiopICZUaGlzLT5EZXB0aFN0ZW5jaWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgVGhpcy0+ZGVwdGhzdGVuY2lsID0gRkFMU0U7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiICglcCkgQ3JlYXRpbmcgYSBEZXB0aFN0ZW5jaWwgU3VyZmFjZSBmYWlsZWQsIHJlc3VsdCA9ICV4XG4iLCBUaGlzLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgKnBwU3VyZmFjZSA9IFRoaXMtPkRlcHRoU3RlbmNpbEJ1ZmZlci0+V2luZUQzRFN1cmZhY2U7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4KICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIFdpbmVEM0Qgd2hpY2ggY3JlYXRlcyBhIG5ldyBXaW5lRDNEU3dhcGNoYWluCiAqIGludGVyZmFjZS4gSXQgYWxzbyBjcmVhdGVzIGFuIElQYXJlbnQgaW50ZXJmYWNlIHRvIHN0b3JlIHRoYXQgcG9pbnRlciwKICogc28gdGhlIFdpbmVEM0RTd2FwY2hhaW4gaGFzIGEgcGFyZW50IGFuZCBjYW4gYmUgcmVsZWFzZWQgd2hlbiB0aGUgRDNECiAqIGRldmljZSBpcyBkZXN0cm95ZWQKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVVua25vd24gKmRldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluICoqIHBwU3dhcENoYWluKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElQYXJlbnRJbXBsICpvYmplY3QgPSBOVUxMOwogICAgSFJFU1VMVCByZXMgPSBEM0RfT0s7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBkZXZpY2UpOwoKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElQYXJlbnRJbXBsKSk7CiAgICBpZiAoTlVMTCA9PSBvYmplY3QpCiAgICB7CiAgICAgICAgRklYTUUoIkFsbG9jYXRpb24gb2YgbWVtb3J5IGZhaWxlZFxuIik7CiAgICAgICAgKnBwU3dhcENoYWluID0gTlVMTDsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZWSURFT01FTU9SWTsKICAgIH0KCiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKG9iamVjdCwgSVBhcmVudCwgSVBhcmVudF9WdGJsKTsKICAgIG9iamVjdC0+cmVmID0gMTsKCiAgICByZXMgPSBJV2luZUQzRERldmljZV9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN3YXBjaGFpbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSVBhcmVudCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlKTsKICAgIGlmIChyZXMgIT0gRDNEX09LKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIGNhbGwgdG8gSVdpbmVEM0REZXZpY2VfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbiBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAgLCBvYmplY3QpOwogICAgICAgICpwcFN3YXBDaGFpbiA9IE5VTEw7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgKnBwU3dhcENoYWluID0gc3dhcGNoYWluOwogICAgICAgIG9iamVjdC0+Y2hpbGQgPSAoSVVua25vd24gKikgc3dhcGNoYWluOwogICAgfQoKICAgIHJldHVybiByZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlCiAqCiAqIEluaXRpYWxpemVzIHRoZSBEM0QgY2FwYWJpbGl0aWVzIG9mIFdpbmVEM0QKICoKICogUGFyYW1zOgogKiAgcHJpbWFyeTogVGhlIHByaW1hcnkgc3VyZmFjZSBmb3IgRDNECiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MsCiAqICBEREVSUl8qIG90aGVyd2lzZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpwcmltYXJ5KQp7CiAgICBIUkVTVUxUIGhyOwogICAgSFdORCAgICAgICAgICAgICAgICAgIHdpbmRvdzsKCiAgICBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTIGxvY2FsUGFyYW1ldGVyczsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgcHJpbWFyeSk7CgogICAgLyogR2V0IHRoZSB3aW5kb3cgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ3aW5kb3cpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0REZXZpY2U6OkdldEhXTkQgZmFpbGVkXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogSWYgdGhlcmUncyBubyB3aW5kb3csIGNyZWF0ZSBhIGhpZGRlbiB3aW5kb3cuIFdpbmVEM0QgbmVlZHMgaXQgKi8KICAgIGlmKHdpbmRvdyA9PSAwKQogICAgewogICAgICAgIHdpbmRvdyA9IENyZWF0ZVdpbmRvd0V4QSgwLCBUaGlzLT5jbGFzc25hbWUsICJIaWRkZW4gRDNEIFdpbmRvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdTX0RJU0FCTEVELCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwsIEdldE1vZHVsZUhhbmRsZUEoMCksIE5VTEwpOwoKICAgICAgICBTaG93V2luZG93KHdpbmRvdywgU1dfSElERSk7ICAgLyogSnVzdCB0byBiZSBzdXJlICovCiAgICAgICAgV0FSTigiKCVwKSBObyB3aW5kb3cgZm9yIHRoZSBEaXJlY3QzRERldmljZSwgY3JlYXRlZCBhIGhpZGRlbiB3aW5kb3cuIEhXTkQ9JXBcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICAgICAgVGhpcy0+ZDNkX3dpbmRvdyA9IHdpbmRvdzsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKSBVc2luZyBleGlzdGluZyB3aW5kb3cgJXAgZm9yIERpcmVjdDNEIHJlbmRlcmluZ1xuIiwgVGhpcywgd2luZG93KTsKICAgIH0KCiAgICAvKiBTdG9yZSB0aGUgZnV0dXJlIFJlbmRlciBUYXJnZXQgc3VyZmFjZSAqLwogICAgVGhpcy0+ZDNkX3RhcmdldCA9IHByaW1hcnk7CgogICAgLyogVXNlIHRoZSBzdXJmYWNlIGRlc2NyaXB0aW9uIGZvciB0aGUgZGV2aWNlIHBhcmFtZXRlcnMsIG5vdCB0aGUKICAgICAqIERldmljZSBzZXR0aW5ncy4gVGhlIGFwcCBtaWdodCByZW5kZXIgdG8gYW4gb2Zmc2NyZWVuIHN1cmZhY2UKICAgICAqLwogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJXaWR0aCAgICAgICAgICAgICAgICAgPSBwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdXaWR0aDsKICAgIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVySGVpZ2h0ICAgICAgICAgICAgICAgID0gcHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3SGVpZ2h0OwogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJGb3JtYXQgICAgICAgICAgICAgICAgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZwcmltYXJ5LT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVyQ291bnQgICAgICAgICAgICAgICAgID0gKHByaW1hcnktPnN1cmZhY2VfZGVzYy5kd0ZsYWdzICYgRERTRF9CQUNLQlVGRkVSQ09VTlQpID8gcHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3QmFja0J1ZmZlckNvdW50IDogMDsKICAgIGxvY2FsUGFyYW1ldGVycy5NdWx0aVNhbXBsZVR5cGUgICAgICAgICAgICAgICAgID0gV0lORUQzRE1VTFRJU0FNUExFX05PTkU7CiAgICBsb2NhbFBhcmFtZXRlcnMuTXVsdGlTYW1wbGVRdWFsaXR5ICAgICAgICAgICAgICA9IDA7CiAgICBsb2NhbFBhcmFtZXRlcnMuU3dhcEVmZmVjdCAgICAgICAgICAgICAgICAgICAgICA9IFdJTkVEM0RTV0FQRUZGRUNUX0NPUFk7CiAgICBsb2NhbFBhcmFtZXRlcnMuaERldmljZVdpbmRvdyAgICAgICAgICAgICAgICAgICA9IHdpbmRvdzsKICAgIGxvY2FsUGFyYW1ldGVycy5XaW5kb3dlZCAgICAgICAgICAgICAgICAgICAgICAgID0gIShUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0ZVTExTQ1JFRU4pOwogICAgbG9jYWxQYXJhbWV0ZXJzLkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgICAgICAgICAgPSBUUlVFOwogICAgbG9jYWxQYXJhbWV0ZXJzLkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgICAgICAgICAgPSBXSU5FRDNERk1UX0QxNjsKICAgIGxvY2FsUGFyYW1ldGVycy5GbGFncyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMDsKICAgIGxvY2FsUGFyYW1ldGVycy5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiAgICAgID0gV0lORUQzRFBSRVNFTlRfUkFURV9ERUZBVUxUOyAvKiBEZWZhdWx0IHJhdGU6IEl0J3MgYWxyZWFkeSBzZXQgKi8KICAgIGxvY2FsUGFyYW1ldGVycy5QcmVzZW50YXRpb25JbnRlcnZhbCAgICAgICAgICAgID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfREVGQVVMVDsKCiAgICBUUkFDRSgiUGFzc2luZyBtb2RlICVkXG4iLCBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckZvcm1hdCk7CgogICAgLyogU2V0IHRoaXMgTk9XLCBvdGhlcndpc2UgY3JlYXRpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZSB3aWxsIGNhdXNlIGEKICAgICAqIHJlY3Vyc2l2ZSBsb29wIHVudGlsIHJhbSBvciBlbXVsYXRlZCB2aWRlbyBtZW1vcnkgaXMgZnVsbAogICAgICovCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBUUlVFOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfSW5pdDNEKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbG9jYWxQYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4pOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBUaGlzLT5kM2RfdGFyZ2V0ID0gTlVMTDsKICAgICAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBGQUxTRTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSA9IDI7CiAgICBUaGlzLT5kZWNscyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqVGhpcy0+ZGVjbHMpICogVGhpcy0+ZGVjbEFycmF5U2l6ZSk7CiAgICBpZighVGhpcy0+ZGVjbHMpCiAgICB7CiAgICAgICAgRVJSKCJFcnJvciBhbGxvY2F0aW5nIGFuIGFycmF5IGZvciB0aGUgY29udmVydGVkIHZlcnRleCBkZWNsc1xuIik7CiAgICAgICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSA9IDA7CiAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9VbmluaXQzRChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4pOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIC8qIENyZWF0ZSBhbiBJbmRleCBCdWZmZXIgcGFyZW50ICovCiAgICBUUkFDRSgiKCVwKSBTdWNjZXNzZnVsbHkgaW5pdGlhbGl6ZWQgM0RcbiIsIFRoaXMpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIgKEREUkFXLkApCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURpcmVjdERyYXdDbGlwcGVyIG9iamVjdC4KICoKICogUGFyYW1zOgogKiAgQ2xpcHBlcjogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgd2hpY2ggZGRyYXcgZG9lc24ndCBoYXZlLiBIYXMgdG8gYmUKICogICAgICAgICAgICBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBhbGxvY2F0aW5nIHRoZSBvYmplY3QgZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIoRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIExQRElSRUNURFJBV0NMSVBQRVIgKkNsaXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSURpcmVjdERyYXdDbGlwcGVySW1wbCogb2JqZWN0OwogICAgVFJBQ0UoIiglMDh4LCVwLCVwKVxuIiwgRmxhZ3MsIENsaXBwZXIsIFVua091dGVyKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYgKFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwogICAgfQoKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoSURpcmVjdERyYXdDbGlwcGVySW1wbCkpOwogICAgaWYgKG9iamVjdCA9PSBOVUxMKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3Q2xpcHBlciwgSURpcmVjdERyYXdDbGlwcGVyX1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT53aW5lRDNEQ2xpcHBlciA9IHBXaW5lRGlyZWN0M0RDcmVhdGVDbGlwcGVyKChJVW5rbm93biAqKSBvYmplY3QpOwogICAgaWYoIW9iamVjdC0+d2luZUQzRENsaXBwZXIpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgICpDbGlwcGVyID0gKElEaXJlY3REcmF3Q2xpcHBlciAqKSBvYmplY3Q7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDcmVhdGVDbGlwcGVyCiAqCiAqIENyZWF0ZXMgYSBERHJhdyBjbGlwcGVyLiBTZWUgRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIgZm9yIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZUNsaXBwZXIoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Q2xpcHBlciAqKkNsaXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgQ2xpcHBlciwgVW5rT3V0ZXIpOwogICAgcmV0dXJuIERpcmVjdERyYXdDcmVhdGVDbGlwcGVyKEZsYWdzLCBDbGlwcGVyLCBVbmtPdXRlcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNyZWF0ZVBhbGV0dGUKICoKICogQ3JlYXRlcyBhIG5ldyBJRGlyZWN0RHJhd1BhbGV0dGUgb2JqZWN0CiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBUaGUgZmxhZ3MgZm9yIHRoZSBuZXcgY2xpcHBlcgogKiAgQ29sb3JUYWJsZTogQ29sb3IgdGFibGUgdG8gYXNzaWduIHRvIHRoZSBuZXcgY2xpcHBlcgogKiAgUGFsZXR0ZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgd2hpY2ggZGRyYXcgZG9lc24ndCBoYXZlLiBIYXMgdG8gYmUKICogICAgICAgICAgICBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBhbGxvY2F0aW5nIHRoZSBvYmplY3QgZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVQYWxldHRlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUxFVFRFRU5UUlkgKkNvbG9yVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqKlBhbGV0dGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwVW5rT3V0ZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsICpvYmplY3Q7CiAgICBIUkVTVUxUIGhyID0gRERFUlJfR0VORVJJQzsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgQ29sb3JUYWJsZSwgUGFsZXR0ZSwgcFVua091dGVyKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYocFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgV0FSTigicFVua091dGVyIGlzICVwLCByZXR1cm5pbmcgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OXG4iLCBwVW5rT3V0ZXIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKICAgIH0KCiAgICAvKiBUaGUgcmVmY291bnQgdGVzdCBzaG93cyB0aGF0IGEgY29vcGxldmVsIGlzIHJlcXVpcmVkIGZvciB0aGlzICovCiAgICBpZighVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwpCiAgICB7CiAgICAgICAgV0FSTigiTm8gY29vcGVyYXRpdmUgbGV2ZWwgc2V0LCByZXR1cm5pbmcgRERFUlJfTk9DT09QRVJBVElWRUxFVkVMU0VUXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9OT0NPT1BFUkFUSVZFTEVWRUxTRVQ7CiAgICB9CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJRGlyZWN0RHJhd1BhbGV0dGVJbXBsKSk7CiAgICBpZighb2JqZWN0KQogICAgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIHBhbGV0dGUgaW1wbGVtZW50YXRpb25cbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3UGFsZXR0ZSwgSURpcmVjdERyYXdQYWxldHRlX1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT5kZHJhd19vd25lciA9IFRoaXM7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVQYWxldHRlKFRoaXMtPndpbmVEM0REZXZpY2UsIEZsYWdzLCBDb2xvclRhYmxlLCAmb2JqZWN0LT53aW5lRDNEUGFsZXR0ZSwgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlKSApOwogICAgaWYoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBJRGlyZWN0RHJhdzdfQWRkUmVmKGlmYWNlKTsKICAgIG9iamVjdC0+aWZhY2VUb1JlbGVhc2UgPSAoSVVua25vd24gKikgaWZhY2U7CiAgICAqUGFsZXR0ZSA9IElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkR1cGxpY2F0ZVN1cmZhY2UKICoKICogRHVwbGljYXRlcyBhIHN1cmZhY2UuIFRoZSBzdXJmYWNlIG1lbW9yeSBwb2ludHMgdG8gdGhlIHNhbWUgbWVtb3J5IGFzCiAqIHRoZSBvcmlnaW5hbCBzdXJmYWNlLCBhbmQgaXQncyByZWxlYXNlZCB3aGVuIHRoZSBsYXN0IHN1cmZhY2UgcmVmZXJlbmNpbmcKICogaXQgaXMgcmVsZWFzZWQuIEkgZ3Vlc3MgdGhhdCdzIGJleW9uZCBXaW5lJ3Mgc3VyZmFjZSBtYW5hZ2VtZW50IHJpZ2h0IG5vdwogKiAoSWRlYTogY3JlYXRlIGEgbmV3IEREcmF3IHN1cmZhY2Ugd2l0aCB0aGUgc2FtZSBXaW5lRDNEU3VyZmFjZS4gSSBuZWVkIGEKICogdGVzdCBhcHBsaWNhdGlvbiB0byBpbXBsZW1lbnQgdGhpcykKICoKICogUGFyYW1zOgogKiAgU3JjOiBBZGRyZXNzIG9mIHRoZSBzb3VyY2Ugc3VyZmFjZQogKiAgRGVzdDogQWRkcmVzcyB0byB3cml0ZSB0aGUgbmV3IHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgU2VlIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRHVwbGljYXRlU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipEZXN0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqU3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyYyk7CgogICAgRklYTUUoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIFN1cmYsIERlc3QpOwoKICAgIC8qIEZvciBub3csIHNpbXBseSBjcmVhdGUgYSBuZXcsIGluZGVwZW5kZW50IHN1cmZhY2UgKi8KICAgIHJldHVybiBJRGlyZWN0RHJhdzdfQ3JlYXRlU3VyZmFjZShpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3VyZi0+c3VyZmFjZV9kZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzcgVlRhYmxlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KY29uc3QgSURpcmVjdERyYXc3VnRibCBJRGlyZWN0RHJhdzdfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gKioqLwogICAgSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3SW1wbF9SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0RHJhdyAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfQ29tcGFjdCwKICAgIElEaXJlY3REcmF3SW1wbF9DcmVhdGVDbGlwcGVyLAogICAgSURpcmVjdERyYXdJbXBsX0NyZWF0ZVBhbGV0dGUsCiAgICBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlU3VyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9EdXBsaWNhdGVTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0VudW1EaXNwbGF5TW9kZXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzLAogICAgSURpcmVjdERyYXdJbXBsX0ZsaXBUb0dESVN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0Q2FwcywKICAgIElEaXJlY3REcmF3SW1wbF9HZXREaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRGb3VyQ0NDb2RlcywKICAgIElEaXJlY3REcmF3SW1wbF9HZXRHRElTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0dldE1vbml0b3JGcmVxdWVuY3ksCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0U2NhbkxpbmUsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0VmVydGljYWxCbGFua1N0YXR1cywKICAgIElEaXJlY3REcmF3SW1wbF9Jbml0aWFsaXplLAogICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVEaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsLAogICAgSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlLAogICAgSURpcmVjdERyYXdJbXBsX1dhaXRGb3JWZXJ0aWNhbEJsYW5rLAogICAgLyoqKiBJRGlyZWN0RHJhdzIgKioqLwogICAgSURpcmVjdERyYXdJbXBsX0dldEF2YWlsYWJsZVZpZE1lbSwKICAgIC8qKiogSURpcmVjdERyYXc3ICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9HZXRTdXJmYWNlRnJvbURDLAogICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVBbGxTdXJmYWNlcywKICAgIElEaXJlY3REcmF3SW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbCwKICAgIElEaXJlY3REcmF3SW1wbF9HZXREZXZpY2VJZGVudGlmaWVyLAogICAgLyoqKiBJRGlyZWN0RHJhdzcgKioqLwogICAgSURpcmVjdERyYXdJbXBsX1N0YXJ0TW9kZVRlc3QsCiAgICBJRGlyZWN0RHJhd0ltcGxfRXZhbHVhdGVNb2RlCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX0ZpbmREZWNsCiAqCiAqIEZpbmRzIHRoZSBXaW5lRDNEIHZlcnRleCBkZWNsYXJhdGlvbiBmb3IgYSBzcGVjaWZpYyBmdmYsIGFuZCBjcmVhdGVzIG9uZQogKiBpZiBub25lIHdhcyBmb3VuZC4KICoKICogVGhpcyBmdW5jdGlvbiBpcyBpbiBkZHJhdy5jIGFuZCB0aGUgRERyYXcgb2JqZWN0IHNwYWNlIGJlY2F1c2UgRDNENwogKiB2ZXJ0ZXggYnVmZmVycyBhcmUgY3JlYXRlZCB1c2luZyB0aGUgSURpcmVjdDNEIGludGVyZmFjZSB0byB0aGUgZGRyYXcKICogb2JqZWN0LCBzbyB0aGV5IGNhbiBiZSB2YWxpZCBhY3Jvc3MgRDNEIGRldmljZXModGhlb3JldGljYWxseS4gVGhlIGRkcmF3CiAqIG9iamVjdCBhbHNvIG93bnMgdGhlIHdpbmVkM2QgZGV2aWNlCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBUaGlzOiBEZXZpY2UKICogIGZ2ZjogRnZmIHRvIGZpbmQgdGhlIGRlY2wgZm9yCiAqCiAqIFJldHVybnM6CiAqICBOVUxMIGluIGNhc2Ugb2YgYW4gZXJyb3IsIHRoZSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uIGludGVyZmFjZSBmb3IgdGhlCiAqICBmdmYgb3RoZXJ3aXNlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCklXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKgpJRGlyZWN0RHJhd0ltcGxfRmluZERlY2woSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZnZmKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiogcERlY2wgPSBOVUxMOwogICAgaW50IHAsIGxvdywgaGlnaDsgLyogZGVsaWJlcmF0ZWx5IHNpZ25lZCAqLwogICAgc3RydWN0IEZ2ZlRvRGVjbCAqY29udmVydGVkRGVjbHMgPSBUaGlzLT5kZWNsczsKCiAgICBUUkFDRSgiU2VhcmNoaW5nIGZvciBkZWNsYXJhdGlvbiBmb3IgZnZmICUwOHguLi4gIiwgZnZmKTsKCiAgICBsb3cgPSAwOwogICAgaGlnaCA9IFRoaXMtPm51bUNvbnZlcnRlZERlY2xzIC0gMTsKICAgIHdoaWxlKGxvdyA8PSBoaWdoKSB7CiAgICAgICAgcCA9IChsb3cgKyBoaWdoKSA+PiAxOwogICAgICAgIFRSQUNFKCIlZCAiLCBwKTsKICAgICAgICBpZihjb252ZXJ0ZWREZWNsc1twXS5mdmYgPT0gZnZmKSB7CiAgICAgICAgICAgIFRSQUNFKCJmb3VuZCAlcFxuIiwgY29udmVydGVkRGVjbHNbcF0uZGVjbCk7CiAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZWREZWNsc1twXS5kZWNsOwogICAgICAgIH0gZWxzZSBpZihjb252ZXJ0ZWREZWNsc1twXS5mdmYgPCBmdmYpIHsKICAgICAgICAgICAgbG93ID0gcCArIDE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaGlnaCA9IHAgLSAxOwogICAgICAgIH0KICAgIH0KICAgIFRSQUNFKCJub3QgZm91bmQuIENyZWF0aW5nIGFuZCBpbnNlcnRpbmcgYXQgcG9zaXRpb24gJWQuXG4iLCBsb3cpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb25Gcm9tRlZGKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcERlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ2Zik7CiAgICBpZiAoaHIgIT0gU19PSykgcmV0dXJuIE5VTEw7CgogICAgaWYoVGhpcy0+ZGVjbEFycmF5U2l6ZSA9PSBUaGlzLT5udW1Db252ZXJ0ZWREZWNscykgewogICAgICAgIGludCBncm93ID0gbWF4KFRoaXMtPmRlY2xBcnJheVNpemUgLyAyLCA4KTsKICAgICAgICBjb252ZXJ0ZWREZWNscyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvbnZlcnRlZERlY2xzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGNvbnZlcnRlZERlY2xzWzBdKSAqIChUaGlzLT5udW1Db252ZXJ0ZWREZWNscyArIGdyb3cpKTsKICAgICAgICBpZighY29udmVydGVkRGVjbHMpIHsKICAgICAgICAgICAgLyogVGhpcyB3aWxsIGRlc3Ryb3kgaXQgKi8KICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9SZWxlYXNlKHBEZWNsKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmRlY2xzID0gY29udmVydGVkRGVjbHM7CiAgICAgICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSArPSBncm93OwogICAgfQoKICAgIG1lbW1vdmUoY29udmVydGVkRGVjbHMgKyBsb3cgKyAxLCBjb252ZXJ0ZWREZWNscyArIGxvdywgc2l6ZW9mKGNvbnZlcnRlZERlY2xzWzBdKSAqIChUaGlzLT5udW1Db252ZXJ0ZWREZWNscyAtIGxvdykpOwogICAgY29udmVydGVkRGVjbHNbbG93XS5kZWNsID0gcERlY2w7CiAgICBjb252ZXJ0ZWREZWNsc1tsb3ddLmZ2ZiA9IGZ2ZjsKICAgIFRoaXMtPm51bUNvbnZlcnRlZERlY2xzKys7CgogICAgVFJBQ0UoIlJldHVybmluZyAlcC4gJWQgZGVjbHMgaW4gYXJyYXlcbiIsIHBEZWNsLCBUaGlzLT5udW1Db252ZXJ0ZWREZWNscyk7CiAgICByZXR1cm4gcERlY2w7Cn0K