LyoKICogQ29weXJpZ2h0IDE5OTctMjAwMCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IDIwMDAtMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCnN0YXRpYyBCT09MIElEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKGNvbnN0IEREU1VSRkFDRURFU0MyKiByZXF1ZXN0ZWQsIGNvbnN0IEREU1VSRkFDRURFU0MyKiBwcm92aWRlZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcHJpbWFyeSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsIEREU1VSRkFDRURFU0MyICpwRERTRCwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnBwU3VyZiwgVUlOVCBsZXZlbCk7CgovKiBEZXZpY2UgaWRlbnRpZmllci4gRG9uJ3QgcmVsYXkgaXQgdG8gV2luZUQzRCAqLwpzdGF0aWMgY29uc3QgRERERVZJQ0VJREVOVElGSUVSMiBkZXZpY2VpZGVudGlmaWVyID0KewogICAgImRpc3BsYXkiLAogICAgIkRpcmVjdERyYXcgSEFMIiwKICAgIHsgeyAweDAwMDEwMDAxLCAweDAwMDEwMDAxIH0gfSwKICAgIDAsIDAsIDAsIDAsCiAgICAvKiBhODM3M2MxMC03YWM0LTRkZWItODQ5YS0wMDk4NDRkMDhiMmQgKi8KICAgIHsweGE4MzczYzEwLDB4N2FjNCwweDRkZWIsIHsweDg0LDB4OWEsMHgwMCwweDk4LDB4NDQsMHhkMCwweDhiLDB4MmR9fSwKICAgIDAKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBNZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJpZXMgZGlmZmVyZW50IGludGVyZmFjZXMgb2YgdGhlIERpcmVjdERyYXcgb2JqZWN0LiBJdCBjYW4gcmV0dXJuCiAqIElEaXJlY3REcmF3IGludGVyZmFjZXMgaW4gdmVyc2lvbiAxLCAyLCA0IGFuZCA3LCBhbmQgSURpcmVjdDNEIGludGVyZmFjZXMKICogaW4gdmVyc2lvbiAxLCAyLCAzIGFuZCA3LiBBbiBJRGlyZWN0M0REZXZpY2UgY2FuIGJlIGNyZWF0ZWQgd2l0aCB0aGlzCiAqIG1ldGhvZC4KICogVGhlIHJldHVybmVkIGludGVyZmFjZSBpcyBBZGRSZWYoKS1lZCBiZWZvcmUgaXQncyByZXR1cm5lZAogKgogKiBSdWxlcyBmb3IgUXVlcnlJbnRlcmZhY2U6CiAqICBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/IFwKICogICAgdXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG1sLzZkYjE3ZWQ4LTA2ZTQtNGJhZS1iYzI2LTExMzE3NmNjN2UwZS5hc3AKICoKICogVXNlZCBmb3IgdmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIHJlZmlpZDogSW50ZXJmYWNlIElEIGFza2VkIGZvcgogKiAgb2JqOiBVc2VkIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIFNfT0sgaWYgYW4gaW50ZXJmYWNlIHdhcyBmb3VuZAogKiAgRV9OT0lOVEVSRkFDRSBpZiB0aGUgcmVxdWVzdGVkIGludGVyZmFjZSB3YXNuJ3QgZm91bmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmVmaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICAgIC8qIEFjY29yZGluZyB0byBDT00gZG9jcywgaWYgdGhlIFF1ZXJ5SW50ZXJmYWNlIGZhaWxzLCBvYmogc2hvdWxkIGJlIHNldCB0byBOVUxMICovCiAgICAqb2JqID0gTlVMTDsKCiAgICBpZighcmVmaWlkKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIENoZWNrIERpcmVjdERyYXcgSW50ZXJmYWNlcyAqLwogICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JVW5rbm93biwgcmVmaWlkICkgfHwKICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXc3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3Nyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3NCwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzQpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzQgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzMsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXczKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXczIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXcyLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3Mik7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3MiBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3KTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KCiAgICAvKiBEaXJlY3QzRAogICAgICogVGhlIHJlZmNvdW50IHVuaXQgdGVzdCByZXZlYWxlZCB0aGF0IGFuIElEaXJlY3QzRDcgaW50ZXJmYWNlIGNhbiBvbmx5IGJlIHF1ZXJpZWQKICAgICAqIGZyb20gYSBEaXJlY3REcmF3IG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIGFzIGFuIElEaXJlY3REcmF3NyBpbnRlcmZhY2UuIE5vIGlkZWEKICAgICAqIHdobyBoYWQgdGhpcyBpZGVhIGFuZCB3aHkuIFRoZSBvbGRlciBpbnRlcmZhY2VzIGNhbiBxdWVyeSBhbmQgSURpcmVjdDNEIHZlcnNpb24KICAgICAqIGJlY2F1c2UgdGhleSBhcmUgYWxsIGNyZWF0ZWQgYXMgSURpcmVjdERyYXcoMSkuIFRoaXMgaXNuJ3QgcmVhbGx5IGNydWNpYWwgYmVoYXZpb3IsCiAgICAgKiBhbmQgbWVzc3kgdG8gaW1wbGVtZW50IHdpdGggdGhlIGNvbW1vbiBjcmVhdGlvbiBmdW5jdGlvbiwgc28gaXQgaGFzIGJlZW4gbGVmdCBvdXQgaGVyZS4KICAgICAqLwogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRCAgLCByZWZpaWQgKSB8fAogICAgICAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDIgLCByZWZpaWQgKSB8fAogICAgICAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDMgLCByZWZpaWQgKSB8fAogICAgICAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDcgLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgLyogQ2hlY2sgdGhlIHN1cmZhY2UgaW1wbGVtZW50YXRpb24gKi8KICAgICAgICBpZihUaGlzLT5JbXBsVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICAgICAgewogICAgICAgICAgICAvKiBBcHBzIG1heSBjcmVhdGUgdGhlIElEaXJlY3QzRCBJbnRlcmZhY2UgYmVmb3JlIHRoZSBwcmltYXJ5IHN1cmZhY2UuCiAgICAgICAgICAgICAqIHNldCB0aGUgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICBUUkFDRSgiKCVwKSBDaG9vc2luZyBPcGVuR0wgc3VyZmFjZXMgYmVjYXVzZSBhIERpcmVjdDNEIGludGVyZmFjZSB3YXMgcmVxdWVzdGVkXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCAmJiBEZWZhdWx0U3VyZmFjZVR5cGUgPT0gU1VSRkFDRV9VTktOT1dOKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCIoJXApIFRoZSBBcHAgaXMgcmVxdWVzdGluZyBhIEQzRCBkZXZpY2UsIGJ1dCBhIG5vbi1PcGVuR0wgc3VyZmFjZSB0eXBlIHdhcyBjaG9vc2VuLiBQcmVwYXJlIGZvciB0cm91YmxlIVxuIiwgVGhpcyk7CiAgICAgICAgICAgIEVSUigiICglcCkgWW91IG1heSB3YW50IHRvIGNvbnRhY3Qgd2luZS1kZXZlbCBmb3IgaGVscFxuIiwgVGhpcyk7CiAgICAgICAgICAgIC8qIFNob3VsZCBJIGFzc2VydCgwKSBoZXJlPz8/ICovCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJUaGUgYXBwIHJlcXVlc3RzIGEgRGlyZWN0M0QgaW50ZXJmYWNlLCBidXQgbm9uLW9wZW5nbCBzdXJmYWNlcyB3aGVyZSBzZXQgaW4gd2luZWNmZ1xuIik7CiAgICAgICAgICAgIC8qIERvIG5vdCBhYm9ydCBoZXJlLCBvbmx5IHJlamVjdCAzRCBEZXZpY2UgY3JlYXRpb24gKi8KICAgICAgICB9CgogICAgICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEICAsIHJlZmlpZCApICkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSAxOwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0QgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QyICAsIHJlZmlpZCApICkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSAyOwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEMik7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEMiBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDMgICwgcmVmaWlkICkgKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDM7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QzKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0QzIGludGVyZmFjZSBhdCAlcC5cbiIsICpvYmopOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDcgICwgcmVmaWlkICkpCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5kM2R2ZXJzaW9uID0gNzsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDcpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRDcgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFVua25vd24gaW50ZXJmYWNlICovCiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCIoJXApLT4oJXMsICVwKTogTm8gaW50ZXJmYWNlIGZvdW5kXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CiAgICAgICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CgogICAgSVVua25vd25fQWRkUmVmKCAoSVVua25vd24gKikgKm9iaiApOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkFkZFJlZgogKgogKiBJbmNyZWFzZXMgdGhlIGludGVyZmFjZXMgcmVmY291bnQsIGJhc2ljYWxseQogKgogKiBERHJhdyByZWZjb3VudGluZyBpcyBhIGJpdCB0cmlja3kuIFRoZSBkaWZmZXJlbnQgRGlyZWN0RHJhdyBpbnRlcmZhY2UKICogdmVyc2lvbnMgaGF2ZSBpbmRpdmlkdWFsIHJlZmNvdW50cywgYnV0IHRoZSBJRGlyZWN0M0QgaW50ZXJmYWNlcyBkbyBub3QuCiAqIEFsbCBpbnRlcmZhY2VzIGFyZSBmcm9tIG9uZSBvYmplY3QsIHRoYXQgbWVhbnMgY2FsbGluZyBRdWVyeUludGVyZmFjZSBvbiBhbgogKiBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlIGZvciBhbiBJRGlyZWN0RHJhdzQgaW50ZXJmYWNlIGRvZXMgbm90IGNyZWF0ZSBhIG5ldwogKiBJRGlyZWN0RHJhd0ltcGwgb2JqZWN0LgogKgogKiBUaGF0IG1lYW5zIGFsbCBBZGRSZWYgYW5kIFJlbGVhc2UgaW1wbGVtZW50YXRpb25zIG9mIElEaXJlY3REcmF3WCB3b3JrCiAqIHdpdGggdGhlaXIgb3duIGNvdW50ZXIsIGFuZCBJRGlyZWN0M0RYOjpBZGRSZWYgdGh1bmsgdG8gSURpcmVjdERyYXcgKDEpLAogKiBleGNlcHQgb2YgSURpcmVjdDNENyB3aGljaCB0aHVua3MgdG8gSURpcmVjdERyYXc3CiAqCiAqIFJldHVybnM6IFRoZSBuZXcgcmVmY291bnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9BZGRSZWYoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWY3KTsKCiAgICBUUkFDRSgiKCVwKSA6IGluY3JlbWVudGluZyBJRGlyZWN0RHJhdzcgcmVmY291bnQgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiAtMSk7CgogICAgaWYocmVmID09IDEpIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5udW1JZmFjZXMpOwoKICAgIHJldHVybiByZWY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfRGVzdHJveQogKgogKiBEZXN0cm95cyBhIGRkcmF3IG9iamVjdCBpZiBhbGwgcmVmY291bnRzIGFyZSAwLiBUaGlzIGlzIHRvIHNoYXJlIGNvZGUKICogYmV0d2VlbiB0aGUgSURpcmVjdERyYXdYOjpSZWxlYXNlIGZ1bmN0aW9ucwogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEaXJlY3REcmF3IG9iamVjdCB0byBkZXN0cm95CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZApJRGlyZWN0RHJhd0ltcGxfRGVzdHJveShJRGlyZWN0RHJhd0ltcGwgKlRoaXMpCnsKICAgIGludCBpOwoKICAgIGZvcihpID0gMDsgaSA8IFRoaXMtPm51bUNvbnZlcnRlZERlY2xzOyBpKyspCiAgICB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9SZWxlYXNlKFRoaXMtPmRlY2xzW2ldLmRlY2wpOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZGVjbHMpOwoKICAgIC8qIENsZWFyIHRoZSBjb29wbGV2ZWwgdG8gcmVzdG9yZSB3aW5kb3cgYW5kIGRpc3BsYXkgbW9kZSAqLwogICAgSURpcmVjdERyYXc3X1NldENvb3BlcmF0aXZlTGV2ZWwoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9OT1JNQUwpOwoKICAgIC8qIERlc3Ryb3kgdGhlIGRldmljZSB3aW5kb3cgaWYgd2UgY3JlYXRlZCBvbmUgKi8KICAgIGlmKFRoaXMtPmRldmljZXdpbmRvdyAhPSAwKQogICAgewogICAgICAgIFRSQUNFKCIgKCVwKSBEZXN0cm95aW5nIHRoZSBkZXZpY2Ugd2luZG93ICVwXG4iLCBUaGlzLCBUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgIERlc3Ryb3lXaW5kb3coVGhpcy0+ZGV2aWNld2luZG93KTsKICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSAwOwogICAgfQoKICAgIC8qIFVucmVnaXN0ZXIgdGhlIHdpbmRvdyBjbGFzcyAqLwogICAgVW5yZWdpc3RlckNsYXNzQShUaGlzLT5jbGFzc25hbWUsIDApOwoKICAgIHJlbW92ZV9kZHJhd19vYmplY3QoVGhpcyk7CgogICAgLyogUmVsZWFzZSB0aGUgYXR0YWNoZWQgV2luZUQzRCBzdHVmZiAqLwogICAgSVdpbmVEM0REZXZpY2VfUmVsZWFzZShUaGlzLT53aW5lRDNERGV2aWNlKTsKICAgIElXaW5lRDNEX1JlbGVhc2UoVGhpcy0+d2luZUQzRCk7CgogICAgLyogTm93IGZyZWUgdGhlIG9iamVjdCAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlJlbGVhc2UKICoKICogRGVjcmVhc2VzIHRoZSByZWZjb3VudC4gSWYgdGhlIHJlZmNvdW50IGZhbGxzIHRvIDAsIHRoZSBvYmplY3QgaXMgZGVzdHJveWVkCiAqCiAqIFJldHVybnM6IFRoZSBuZXcgcmVmY291bnQKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZWxlYXNlKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmNyk7CgogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBJRGlyZWN0RHJhdzcgcmVmY291bnQgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiArMSk7CgogICAgaWYocmVmID09IDApCiAgICB7CiAgICAgICAgVUxPTkcgaWZhY2Vjb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5udW1JZmFjZXMpOwogICAgICAgIGlmKGlmYWNlY291bnQgPT0gMCkgSURpcmVjdERyYXdJbXBsX0Rlc3Ryb3koVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3IG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6U2V0Q29vcGVyYXRpdmVMZXZlbAogKgogKiBTZXRzIHRoZSBjb29wZXJhdGl2ZSBsZXZlbCBmb3IgdGhlIERpcmVjdERyYXcgb2JqZWN0LCBhbmQgdGhlIHdpbmRvdwogKiBhc3NpZ25lZCB0byBpdC4gVGhlIGNvb3BlcmF0aXZlIGxldmVsIGRldGVybWluZXMgdGhlIGdlbmVyYWwgYmVoYXZpb3IKICogb2YgdGhlIERpcmVjdERyYXcgYXBwbGljYXRpb24KICoKICogV2FybmluZzogVGhpcyBpcyBxdWl0ZSB0cmlja3ksIGFzIGl0J3Mgbm90IHJlYWxseSBkb2N1bWVudGVkIHdoaWNoCiAqIGNvb3BlcmF0aXZlIGxldmVscyBjYW4gYmUgY29tYmluZWQgd2l0aCBlYWNoIG90aGVyLiBJZiBhIGdhbWUgZmFpbHMKICogYWZ0ZXIgdGhpcyBmdW5jdGlvbiwgdHJ5IHRvIGNoZWNrIHRoZSBjb29wZXJhdGl2ZSBsZXZlbHMgcGFzc2VkIG9uCiAqIFdpbmRvd3MsIGFuZCBpZiBpdCByZXR1cm5zIHNvbWV0aGluZyBkaWZmZXJlbnQuCiAqCiAqIElmIHlvdSB0aGluayB0aGF0IHRoaXMgZnVuY3Rpb24gY2F1c2VkIHRoZSBmYWlsdXJlIGJlY2F1c2UgaXQgd3JpdGVzIGEKICogZml4bWUsIGJlIHN1cmUgdG8gcnVuIGFnYWluIHdpdGggYSArZGRyYXcgdHJhY2UuCiAqCiAqIFdoYXQgaXMga25vd24gYWJvdXQgY29vcGVyYXRpdmUgbGV2ZWxzIChTZWUgdGhlIGRkcmF3IG1vZGVzIHRlc3QpOgogKiBERFNDTF9FWENMVVNJVkUgYW5kIEREU0NMX0ZVTExTQ1JFRU4gbXVzdCBiZSB1c2VkIHdpdGggZWFjaCBvdGhlcgogKiBERFNDTF9OT1JNQUwgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBERFNDTF9FWENMVVNJVkUgb3IgRERTQ0xfRlVMTFNDUkVFTgogKiBERFNDTF9TRVRGT0NVU1dJTkRPVyBjYW4gYmUgcGFzc2VkIG9ubHkgaW4gRERTQ0xfTk9STUFMIG1vZGUsIGJ1dCBhZnRlciB0aGF0CiAqIEREU0NMX0ZVTExTQ1JFRU4gY2FuIGJlIGFjdGl2YXRlZAogKiBERFNDTF9TRVRGT0NVU1dJTkRPVyBtYXkgb25seSBiZSB1c2VkIHdpdGggRERTQ0xfTk9XSU5ET1dDSEFOR0VTCiAqCiAqIEhhbmRsZWQgZmxhZ3M6IEREU0NMX05PUk1BTCwgRERTQ0xfRlVMTFNDUkVFTiwgRERTQ0xfRVhDTFVTSVZFLAogKiAgICAgICAgICAgICAgICBERFNDTF9TRVRGT0NVU1dJTkRPVyAocGFydGlhbGx5KSwKICogICAgICAgICAgICAgICAgRERTQ0xfTVVMVElUSFJFQURFRCAod29yayBpbiBwcm9ncmVzcykKICoKICogVW5oYW5kbGVkIGZsYWdzLCB3aGljaCBzaG91bGQgYmUgaW1wbGVtZW50ZWQKICogIEREU0NMX1NFVERFVklDRVdJTkRPVzogU2V0cyBhIHdpbmRvdyBzcGVjaWFsbHkgdXNlZCBmb3IgcmVuZGVyaW5nIChJIGRvbid0CiAqICBleHBlY3QgYW55IGRpZmZlcmVuY2UgdG8gYSBub3JtYWwgd2luZG93IGZvciB3aW5lKQogKiAgRERTQ0xfQ1JFQVRFREVWSUNFV0lORE9XOiBUZWxscyBkZHJhdyB0byBjcmVhdGUgaXRzIG93biB3aW5kb3cgZm9yCiAqICByZW5kZXJpbmcgKFBvc3NpYmxlIHRlc3QgY2FzZTogSGFsZi1saWZlKQogKgogKiBVbnN1cmUgYWJvdXQgdGhlc2U6IEREU0NMX0ZQVVNFVFVQIEREU0NMX0ZQVVJFU0VSVkUKICoKICogVGhlc2Ugc2VlbSBub3QgcmVhbGx5IGltcG9yYW50IGZvciB3aW5lCiAqICBERFNDTF9BTExPV1JFQk9PVCwgRERTQ0xfTk9XSU5ET1dDSEFOR0VTLCBERFNDTF9BTExPV01PREVYCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgY29vcGVyYXRpdmUgbGV2ZWwgd2FzIHNldCBzdWNjZXNzZnVsbHkKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgdGhlIHBhc3NlZCBjb29wZXJhdGl2ZSBsZXZlbCBjb21iaW5hdGlvbiBpcyBpbnZhbGlkCiAqICBEREVSUl9IV05EQUxSRUFEWVNFVCBpZiBERFNDTF9TRVRGT0NVU1dJTkRPVyBpcyBwYXNzZWQgaW4gZXhjbHVzaXZlIG1vZGUKICogICAoUHJvYmFibHkgb3RoZXJzIHRvbywgaGF2ZSB0byBpbnZlc3RpZ2F0ZSkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1NldENvb3BlcmF0aXZlTGV2ZWwoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSFdORCBod25kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBjb29wbGV2ZWwpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBIV05EIHdpbmRvdzsKICAgIEhSRVNVTFQgaHI7CgogICAgRklYTUUoIiglcCktPiglcCwlMDh4KVxuIixUaGlzLGh3bmQsY29vcGxldmVsKTsKICAgIEREUkFXX2R1bXBfY29vcGVyYXRpdmVsZXZlbChjb29wbGV2ZWwpOwoKICAgIC8qIEdldCB0aGUgb2xkIHdpbmRvdyAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsICZ3aW5kb3cpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0REZXZpY2U6OkdldEhXTkQgZmFpbGVkLCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogVGVzdHMgc3VnZ2VzdCB0aGF0IHdlIG5lZWQgb25lIG9mIHRoZW06ICovCiAgICBpZighKGNvb3BsZXZlbCAmIChERFNDTF9TRVRGT0NVU1dJTkRPVyB8CiAgICAgICAgICAgICAgICAgICAgICBERFNDTF9OT1JNQUwgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICBERFNDTF9FWENMVVNJVkUgICAgICApKSkKICAgIHsKICAgICAgICBUUkFDRSgiSW5jb3JyZWN0IGNvb3BsZXZlbCBmbGFncywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIEhhbmRsZSB0aG9zZSBsZXZlbHMgZmlyc3Qgd2hpY2ggc2V0IHZhcmlvdXMgaHduZHMgKi8KICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX1NFVEZPQ1VTV0lORE9XKQogICAgewogICAgICAgIC8qIFRoaXMgaXNuJ3QgY29tcGF0aWJsZSB3aXRoIGEgbG90IG9mIGZsYWdzICovCiAgICAgICAgaWYoY29vcGxldmVsICYgKCBERFNDTF9NVUxUSVRIUkVBREVEICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlBVU0VUVVAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0ZQVVBSRVNFUlZFICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9BTExPV1JFQk9PVCAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfQUxMT1dNT0RFWCAgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX1NFVERFVklDRVdJTkRPVyB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9OT1JNQUwgICAgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRVhDTFVTSVZFICAgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0ZVTExTQ1JFRU4gICAgICApICkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJDYWxsZWQgd2l0aCBpbmNvbXBhdGlibGUgZmxhZ3MsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIChUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0ZVTExTQ1JFRU4pICYmIHdpbmRvdykKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJTZXR0aW5nIEREU0NMX1NFVEZPQ1VTV0lORE9XIHdpdGggYW4gYWxyZWFkeSBzZXQgd2luZG93LCByZXR1cm5pbmcgRERFUlJfSFdOREFMUkVBRFlTRVRcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSFdOREFMUkVBRFlTRVQ7CiAgICAgICAgfQoKICAgICAgICBUaGlzLT5mb2N1c3dpbmRvdyA9IGh3bmQ7CiAgICAgICAgLyogV29uJ3QgdXNlIHRoZSBod25kIHBhcmFtIGZvciBhbnl0aGluZyBlbHNlICovCiAgICAgICAgaHduZCA9IE5VTEw7CgogICAgICAgIC8qIFVzZSB0aGUgZm9jdXMgd2luZG93IGZvciBkcmF3aW5nIHRvbyAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwgVGhpcy0+Zm9jdXN3aW5kb3cpOwoKICAgICAgICAvKiBEZXN0cm95IHRoZSBkZXZpY2Ugd2luZG93LCBpZiB3ZSBoYXZlIG9uZSAqLwogICAgICAgIGlmKFRoaXMtPmRldmljZXdpbmRvdykKICAgICAgICB7CiAgICAgICAgICAgIERlc3Ryb3lXaW5kb3coVGhpcy0+ZGV2aWNld2luZG93KTsKICAgICAgICAgICAgVGhpcy0+ZGV2aWNld2luZG93ID0gTlVMTDsKICAgICAgICB9CiAgICB9CiAgICAvKiBERFNDTF9OT1JNQUwgb3IgRERTQ0xfRlVMTFNDUkVFTiB8IEREU0NMX0VYQ0xVU0lWRSAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfTk9STUFMKQogICAgewogICAgICAgIC8qIENhbid0IGNvZXhpc3Qgd2l0aCBmdWxsc2NyZWVuIG9yIGV4Y2x1c2l2ZSAqLwogICAgICAgIGlmKGNvb3BsZXZlbCAmIChERFNDTF9GVUxMU0NSRUVOIHwgRERTQ0xfRVhDTFVTSVZFKSApCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBERFNDTF9OT1JNQUwgaXMgbm90IGNvbXBhdGl2ZSB3aXRoIEREU0NMX0ZVTExTQ1JFRU4gb3IgRERTQ0xfRVhDTFVTSVZFXG4iLCBUaGlzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQoKICAgICAgICAvKiBTd2l0Y2hpbmcgZnJvbSBmdWxsc2NyZWVuPyAqLwogICAgICAgIGlmKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRlVMTFNDUkVFTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIGRpc3BsYXkgbW9kZSAqLwogICAgICAgICAgICBJRGlyZWN0RHJhdzdfUmVzdG9yZURpc3BsYXlNb2RlKGlmYWNlKTsKCiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9GVUxMU0NSRUVOOwogICAgICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfRVhDTFVTSVZFOwogICAgICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfQUxMT1dNT0RFWDsKICAgICAgICB9CgogICAgICAgIC8qIERvbid0IG92ZXJyaWRlIGZvY3VzIHdpbmRvd3Mgb3IgcHJpdmF0ZSBkZXZpY2Ugd2luZG93cyAqLwogICAgICAgIGlmKCBod25kICYmCiAgICAgICAgICAgICEoVGhpcy0+Zm9jdXN3aW5kb3cpICYmCiAgICAgICAgICAgICEoVGhpcy0+ZGV2aWNld2luZG93KSAmJgogICAgICAgICAgICAoaHduZCAhPSB3aW5kb3cpICkKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwgaHduZCk7CiAgICAgICAgfQoKICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSk7CiAgICB9CiAgICBlbHNlIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZVTExTQ1JFRU4pCiAgICB7CiAgICAgICAgLyogTmVlZHMgRERTQ0xfRVhDTFVTSVZFICovCiAgICAgICAgaWYoIShjb29wbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpICkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIEREU0NMX0ZVTExTQ1JFRU4gbmVlZHMgRERTQ0xfRVhDTFVTSVZFXG4iLCBUaGlzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgICAgIC8qIE5lZWQgYSBIV05ECiAgICAgICAgaWYoaHduZCA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfRlVMTFNDUkVFTiBuZWVkcyBhIEhXTkRcbiIsIFRoaXMpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgKi8KCiAgICAgICAgVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJj0gfkREU0NMX05PUk1BTDsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFKTsKCiAgICAgICAgLyogRG9uJ3Qgb3ZlcnJpZGUgZm9jdXMgd2luZG93cyBvciBwcml2YXRlIGRldmljZSB3aW5kb3dzICovCiAgICAgICAgaWYoIGh3bmQgJiYKICAgICAgICAgICAgIShUaGlzLT5mb2N1c3dpbmRvdykgJiYKICAgICAgICAgICAgIShUaGlzLT5kZXZpY2V3aW5kb3cpICYmCiAgICAgICAgICAgIChod25kICE9IHdpbmRvdykgKQogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBod25kKTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIGlmKGNvb3BsZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKSBERFNDTF9FWENMVVNJVkUgbmVlZHMgRERTQ0xfRlVMTFNDUkVFTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQ1JFQVRFREVWSUNFV0lORE9XKQogICAgewogICAgICAgIC8qIERvbid0IGNyZWF0ZSBhIGRldmljZSB3aW5kb3cgaWYgYSBmb2N1cyB3aW5kb3cgaXMgc2V0ICovCiAgICAgICAgaWYoICEoVGhpcy0+Zm9jdXN3aW5kb3cpICkKICAgICAgICB7CiAgICAgICAgICAgIEhXTkQgZGV2aWNld2luZG93ID0gQ3JlYXRlV2luZG93RXhBKDAsIFRoaXMtPmNsYXNzbmFtZSwgIkREcmF3IGRldmljZSB3aW5kb3ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXU19QT1BVUCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCBHZXRNb2R1bGVIYW5kbGVBKDApLCBOVUxMKTsKCiAgICAgICAgICAgIFNob3dXaW5kb3coZGV2aWNld2luZG93LCBTV19TSE9XKTsgICAvKiBKdXN0IHRvIGJlIHN1cmUgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ3JlYXRlZCBhIEREcmF3IGRldmljZSB3aW5kb3cuIEhXTkQ9JXBcbiIsIFRoaXMsIGRldmljZXdpbmRvdyk7CgogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsIGRldmljZXdpbmRvdyk7CiAgICAgICAgICAgIFRoaXMtPmRldmljZXdpbmRvdyA9IGRldmljZXdpbmRvdzsKICAgICAgICB9CiAgICB9CgogICAgaWYoY29vcGxldmVsICYgRERTQ0xfTVVMVElUSFJFQURFRCAmJiAhKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfTVVMVElUSFJFQURFRCkpCiAgICB7CiAgICAgICAgRklYTUUoIkRpcmVjdERyYXcgaXMgbm90IHRocmVhZCBzYWZlIHlldFxuIik7CgogICAgICAgIC8qIEVuYWJsZSB0aHJlYWQgc2FmZXR5IGluIHdpbmVkM2QgKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRNdWx0aXRocmVhZGVkKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgfQoKICAgIC8qIFVuaGFuZGxlZCBmbGFncyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dSRUJPT1QpCiAgICAgICAgV0FSTigiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9BTExPV1JFQk9PVCwgaGFybWxlc3NcbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dNT0RFWCkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0FMTE9XTU9ERVgsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZQVVNFVFVQKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfRlBVU0VUVVAsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZQVVBSRVNFUlZFKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfRlBVUFJFU0VSVkUsIGhhcm1sZXNzXG4iLCBUaGlzKTsKCiAgICAvKiBTdG9yZSB0aGUgY29vcGVyYXRpdmVfbGV2ZWwgKi8KICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsIHw9IGNvb3BsZXZlbDsKICAgIFRSQUNFKCJTZXRDb29wZXJhdGl2ZUxldmVsIHJldHVuaW5nIEREX09LXG4iKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6U2V0RGlzcGxheU1vZGUKICoKICogU2V0cyB0aGUgZGlzcGxheSBzY3JlZW4gcmVzb2x1dGlvbiwgY29sb3IgZGVwdGggYW5kIHJlZnJlc2ggZnJlcXVlbmN5CiAqIHdoZW4gaW4gZnVsbHNjcmVlbiBtb2RlIChpbiB0aGVvcnkpLgogKiBQb3NzaWJsZSByZXR1cm4gdmFsdWVzIGxpc3RlZCBpbiB0aGUgU0RLIHN1Z2dlc3QgdGhhdCB0aGlzIG1ldGhvZCBmYWlscwogKiB3aGVuIG5vdCBpbiBmdWxsc2NyZWVuIG1vZGUsIGJ1dCB0aGlzIGlzIHdyb25nLiBXaW5kb3dzIDIwMDAgaGFwcGlseSBzZXRzCiAqIHRoZSBkaXNwbGF5IG1vZGUgaW4gRERTQ0xfTk9STUFMIG1vZGUgd2l0aG91dCBhbiBod25kIHNwZWNpZmllZC4KICogSXQgc2VlbXMgdG8gYmUgdmFsaWQgdG8gcGFzcyAwIGZvciBXaXRoIGFuZCBIZWlnaHQsIHRoaXMgaGFzIHRvIGJlIHRlc3RlZAogKiBJdCBjb3VsZCBtZWFuIHRoYXQgdGhlIGN1cnJlbnQgdmlkZW8gbW9kZSBzaG91bGQgYmUgbGVmdCBhcy1pcy4gKEJ1dCB3aHkKICogY2FsbCBpdCB0aGVuPykKICoKICogUGFyYW1zOgogKiAgSGVpZ2h0LCBXaWR0aDogU2NyZWVuIGRpbWVuc2lvbgogKiAgQlBQOiBDb2xvciBkZXB0aCBpbiBCaXRzIHBlciBwaXhlbAogKiAgUmVmcmVzaHJhdGU6IFNjcmVlbiByZWZyZXNoIHJhdGUKICogIEZsYWdzOiBPdGhlciBzdHVmZgogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9TZXREaXNwbGF5TW9kZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBCUFAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBSZWZyZXNoUmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgV0lORUQzRERJU1BMQVlNT0RFIE1vZGU7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlZCwlZCwleDogUmVsYXkhXG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LCBCUFAsIFJlZnJlc2hSYXRlLCBGbGFncyk7CgogICAgaWYoICFXaWR0aCB8fCAhSGVpZ2h0ICkKICAgIHsKICAgICAgICBFUlIoIldpZHRoPSVkLCBIZWlnaHQ9JWQsIHdoYXQgdG8gZG8/XG4iLCBXaWR0aCwgSGVpZ2h0KTsKICAgICAgICAvKiBJdCBsb29rcyBsaWtlIE5lZWQgZm9yIFNwZWVkIFBvcnNjaGUgVW5sZWFzaGVkIGV4cGVjdHMgRERfT0sgaGVyZSAqLwogICAgICAgIHJldHVybiBERF9PSzsKICAgIH0KCiAgICAvKiBDaGVjayB0aGUgZXhjbHVzaXZlIG1vZGUKICAgIGlmKCEoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpKQogICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICAgKiBUaGlzIGlzIFdST05HLiBEb24ndCBrbm93IGlmIHRoZSBTREsgaXMgY29tcGxldGVseQogICAgICogd3JvbmcgYW5kIGlmIHRoZXJlIGFyZSBhbnkgY29uZGl0aW9ucyB3aGVuIERERVJSX05PRVhDTFVTSVZFCiAgICAgKiBpcyByZXR1cm5lZCwgYnV0IEhhbGYtTGlmZSAxLjEuMS4xIChTdGVhbSB2ZXJzaW9uKQogICAgICogZGVwZW5kcyBvbiB0aGlzCiAgICAgKi8KCiAgICBNb2RlLldpZHRoID0gV2lkdGg7CiAgICBNb2RlLkhlaWdodCA9IEhlaWdodDsKICAgIE1vZGUuUmVmcmVzaFJhdGUgPSBSZWZyZXNoUmF0ZTsKICAgIHN3aXRjaChCUFApCiAgICB7CiAgICAgICAgY2FzZSA4OiAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1A4OyAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE1OiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDFSNUc1QjU7IGJyZWFrOwogICAgICAgIGNhc2UgMTY6IE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SNUc2QjU7ICAgYnJlYWs7CiAgICAgICAgY2FzZSAyNDogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I4RzhCODsgICBicmVhazsKICAgICAgICBjYXNlIDMyOiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfQThSOEc4Qjg7IGJyZWFrOwogICAgfQoKICAgIC8qIFRPRE86IFRoZSBwb3NzaWJsZSByZXR1cm4gdmFsdWVzIGZyb20gbXNkbiBzdWdnZXN0IHRoYXQKICAgICAqIHRoZSBzY3JlZW4gbW9kZSBjYW4ndCBiZSBjaGFuZ2VkIGlmIGEgc3VyZmFjZSBpcyBsb2NrZWQKICAgICAqIG9yIHNvbWUgZHJhd2luZyBpcyBpbiBwcm9ncmVzcwogICAgICovCgogICAgLyogVE9ETzogTG9zZSB0aGUgcHJpbWFyeSBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX1NldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIEZpcnN0IHN3YXBjaGFpbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7CiAgICBzd2l0Y2goaHIpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTogICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURNT0RFOwogICAgICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgIH07Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlJlc3RvcmVEaXNwbGF5TW9kZQogKgogKiBSZXN0b3JlcyB0aGUgZGlzcGxheSBtb2RlIHRvIHdoYXQgaXQgd2FzIGF0IGNyZWF0aW9uIHRpbWUuIEJhc2ljYWxseS4KICoKICogQSBwcm9ibGVtIGFyaXNlcyB3aGVuIHRoZXJlIGFyZSAyIERpcmVjdERyYXcgb2JqZWN0cyB1c2luZyB0aGUgc2FtZSBod25kOgogKiAgLT4gRERfMSBmaW5kcyB0aGUgc2NyZWVuIGF0IDE0MDB4MTA1MHgzMiB3aGVuIGNyZWF0ZWQsIHNldHMgaXQgdG8gNjQweDQ4MHgxNgogKiAgLT4gRERfMiBpcyBjcmVhdGVkLCBmaW5kcyB0aGUgc2NyZWVuIGF0IDY0MHg0ODB4MTYsIHNldHMgaXQgdG8gMTAyNHg3Njh4MzIKICogIC0+IEREXzEgaXMgcmVsZWFzZWQuIFRoZSBzY3JlZW4gc2hvdWxkIGJlIGxlZnQgYXQgMTAyNHg3Njh4MzIuCiAqICAtPiBERF8yIGlzIHJlbGVhc2VkLiBUaGUgc2NyZWVuIHNob3VsZCBiZSBzZXQgdG8gMTQwMHgxMDUweDMyCiAqIFRoaXMgY2FzZSBpcyB1bmhhbmRsZWQgcmlnaHQgbm93LCBidXQgRW1waXJlIEVhcnRoIGRvZXMgaXQgdGhpcyB3YXkuCiAqIChCdXQgcGVyaGFwcyB0aGVyZSBpcyBzb21ldGhpbmcgaW4gU2V0Q29vcGVyYXRpdmVMZXZlbCB0byBwcmV2ZW50IHRoaXMpCiAqCiAqIFRoZSBtc2RuIHNheXMgdGhhdCB0aGlzIG1ldGhvZCByZXNldHMgdGhlIGRpc3BsYXkgbW9kZSB0byB3aGF0IGl0IHdhcyBiZWZvcmUKICogU2V0RGlzcGxheU1vZGUgd2FzIGNhbGxlZC4gV2hhdCBpZiBTZXREaXNwbGF5TW9kZXMgaXMgY2FsbGVkIDIgdGltZXM/PwogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9OT0VYQ0xVU0lWRSBtb2RlIGlmIHRoZSBkZXZpY2UgaXNuJ3QgaW4gZnVsbHNjcmVlbiBtb2RlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZXN0b3JlRGlzcGxheU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXc3X1NldERpc3BsYXlNb2RlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPm9yaWdfd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPm9yaWdfaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5vcmlnX2JwcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldENhcHMKICoKICogUmV0dXJucyB0aGUgZHJpdmVzIGNhcGFiaWxpdGllcwogKgogKiBVc2VkIGZvciB2ZXJzaW9uIDEsIDIsIDQgYW5kIDcKICoKICogUGFyYW1zOgogKiAgRHJpdmVyQ2FwczogU3RydWN0dXJlIHRvIHdyaXRlIHRoZSBIYXJkd2FyZSBhY2NlbGVyYXRlZCBjYXBzIHRvCiAqICBIZWxDYXBzOiBTdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIGVtdWxhdGlvbiBjYXBzIHRvCiAqCiAqIFJldHVybnMKICogIFRoaXMgaW1wbGVtZW50YXRpb24gcmV0dXJucyBERF9PSyBvbmx5CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRDYXBzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgIEREQ0FQUyAqRHJpdmVyQ2FwcywKICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTICpIRUxDYXBzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIERyaXZlckNhcHMsIEhFTENhcHMpOwoKICAgIC8qIE9uZSBzdHJ1Y3R1cmUgbXVzdCBiZSAhPSBOVUxMICovCiAgICBpZiggKCFEcml2ZXJDYXBzKSAmJiAoIUhFTENhcHMpICkKICAgIHsKICAgICAgICBFUlIoIiglcCkgSW52YWxpZCBwYXJhbXMgdG8gSURpcmVjdERyYXdJbXBsX0dldENhcHNcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKERyaXZlckNhcHMpCiAgICB7CiAgICAgICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKERyaXZlckNhcHMsICZUaGlzLT5jYXBzKTsKICAgICAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIkRyaXZlciBDYXBzIDpcbiIpOwogICAgICAgICAgICBERFJBV19kdW1wX0REQ0FQUyhEcml2ZXJDYXBzKTsKICAgICAgICB9CgogICAgfQogICAgaWYoSEVMQ2FwcykKICAgIHsKICAgICAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoSEVMQ2FwcywgJlRoaXMtPmNhcHMpOwogICAgICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiSEVMIENhcHMgOlxuIik7CiAgICAgICAgICAgIEREUkFXX2R1bXBfRERDQVBTKEhFTENhcHMpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNvbXBhY3QKICoKICogTm8gaWRlYSB3aGF0IGl0IGRvZXMsIE1TRE4gc2F5cyBpdCdzIG5vdCBpbXBsZW1lbnRlZC4KICoKICogUmV0dXJucwogKiAgRERfT0ssIGJ1dCB0aGlzIGlzIHVuY2hlY2tlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ29tcGFjdChJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0RGlzcGxheU1vZGUKICoKICogUmV0dXJucyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY3VycmVudCBkaXNwbGF5IG1vZGUKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBERFNEOiBBZGRyZXNzIG9mIGEgc3VyZmFjZSBkZXNjcmlwdGlvbiBzdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIGluZm8gdG8KICoKICogUmV0dXJucwogKiAgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldERpc3BsYXlNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKICAgIERXT1JEIFNpemU7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsIFRoaXMsIEREU0QpOwoKICAgIC8qIFRoaXMgc2VlbXMgc2FuZSAqLwogICAgaWYoIUREU0QpIAogICAgewogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIC8qIFRoZSBuZWNlc3NhcnkgbWVtYmVycyBvZiBMUEREU1VSRkFDRURFU0MgYW5kIExQRERTVVJGQUNFREVTQzIgYXJlIGVxdWFsLAogICAgICogc28gb25lIG1ldGhvZCBjYW4gYmUgdXNlZCBmb3IgYWxsIHZlcnNpb25zIChIb3BlZnVsbHkpCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0RGlzcGxheU1vZGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIHN3YXBjaGFpbiAwICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNb2RlKTsKICAgIGlmKCBociAhPSBEM0RfT0sgKQogICAgewogICAgICAgIEVSUigiICglcCkgSVdpbmVEM0REZXZpY2U6OkdldERpc3BsYXlNb2RlIHJldHVybmVkICUwOHhcbiIsIFRoaXMsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgU2l6ZSA9IEREU0QtPmR3U2l6ZTsKICAgIG1lbXNldChERFNELCAwLCBTaXplKTsKCiAgICBERFNELT5kd1NpemUgPSBTaXplOwogICAgRERTRC0+ZHdGbGFncyB8PSBERFNEX0hFSUdIVCB8IEREU0RfV0lEVEggfCBERFNEX1BJWEVMRk9STUFUIHwgRERTRF9QSVRDSCB8IEREU0RfUkVGUkVTSFJBVEU7CiAgICBERFNELT5kd1dpZHRoID0gTW9kZS5XaWR0aDsKICAgIEREU0QtPmR3SGVpZ2h0ID0gTW9kZS5IZWlnaHQ7IAogICAgRERTRC0+dTIuZHdSZWZyZXNoUmF0ZSA9IDYwOwogICAgRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgPSAwOwogICAgRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJkREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdCwgTW9kZS5Gb3JtYXQpOwogICAgRERTRC0+dTEubFBpdGNoID0gTW9kZS5XaWR0aCAqIEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdC51MS5kd1JHQkJpdENvdW50IC8gODsKCiAgICBpZihUUkFDRV9PTihkZHJhdykpCiAgICB7CiAgICAgICAgVFJBQ0UoIlJldHVybmluZyBzdXJmYWNlIGRlc2MgOlxuIik7CiAgICAgICAgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MoRERTRCk7CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRGb3VyQ0NDb2RlcwogKgogKiBSZXR1cm5zIGFuIGFycmF5IG9mIHN1cHBvcnRlZCBGb3VyQ0MgY29kZXMuCiAqCiAqIEV4aXN0cyBpbiBWZXJzaW9uIDEsIDIsIDQgYW5kIDcKICoKICogUGFyYW1zOgogKiAgTnVtQ29kZXM6IENvbnRhaW5zIHRoZSBudW1iZXIgb2YgQ29kZXMgdGhhdCBDb2RlcyBjYW4gY2FycnkuIFJldHVybnMgdGhlIG51bWJlcgogKiAgICAgICAgICAgIG9mIGVudW1lcmF0ZWQgY29kZXMKICogIENvZGVzOiBQb2ludGVyIHRvIGFuIGFycmF5IG9mIERXT1JEcyB3aGVyZSB0aGUgc3VwcG9ydGVkIGNvZGVzIGFyZSB3cml0dGVuCiAqICAgICAgICAgdG8KICoKICogUmV0dXJucwogKiAgQWx3YXlzIHJldHVybnMgRERfT0ssIGFzIGl0J3MgYSBzdHViIGZvciBub3cKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldEZvdXJDQ0NvZGVzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqTnVtQ29kZXMsIERXT1JEICpDb2RlcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsICVwKTogU3R1YiFcbiIsIFRoaXMsIE51bUNvZGVzLCBDb2Rlcyk7CgogICAgaWYoTnVtQ29kZXMpICpOdW1Db2RlcyA9IDA7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRNb25pdG9yRnJlcXVlbmN5CiAqCiAqIFJldHVybnMgdGhlIG1vbml0b3IncyBmcmVxdWVuY3kKICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBGcmVxOiBQb2ludGVyIHRvIGEgRFdPUkQgdG8gd3JpdGUgdGhlIGZyZXF1ZW5jeSB0bwogKgogKiBSZXR1cm5zCiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0TW9uaXRvckZyZXF1ZW5jeShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqRnJlcSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBGcmVxKTsKCiAgICAvKiBJZGVhbGx5IHRoaXMgc2hvdWxkIGJlIGluIFdpbmVEM0QsIGFzIGl0IGNvbmNlcm5zIHRoZSBzY3JlZW4gc2V0dXAsCiAgICAgKiBidXQgZm9yIG5vdyB0aGlzIHNob3VsZCBtYWtlIHRoZSBnYW1lcyBoYXBweQogICAgICovCiAgICAqRnJlcSA9IDYwOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRWZXJ0aWNhbEJsYW5rU3RhdHVzCiAqCiAqIFJldHVybnMgdGhlIFZlcnRpY2FsIGJsYW5rIHN0YXR1cyBvZiB0aGUgbW9uaXRvci4gVGhpcyBzaG91bGQgYmUgaW4gV2luZUQzRAogKiB0b28gYmFzaWNhbGx5LCBidXQgYXMgaXQncyBhIHNlbWkgc3R1YiwgSSBkaWRuJ3QgY3JlYXRlIGEgZnVuY3Rpb24gdGhlcmUKICoKICogUGFyYW1zOgogKiAgc3RhdHVzOiBQb2ludGVyIHRvIGEgQk9PTCB0byBiZSBmaWxsZWQgd2l0aCB0aGUgdmVydGljYWwgYmxhbmsgc3RhdHVzCiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgc3RhdHVzIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldFZlcnRpY2FsQmxhbmtTdGF0dXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCAqc3RhdHVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHN0YXR1cyk7CgogICAgLyogVGhpcyBsb29rcyBzYW5lLCB0aGUgTVNETiBzdWdnZXN0cyBpdCB0b28gKi8KICAgIGlmKCFzdGF0dXMpIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgICpzdGF0dXMgPSBUaGlzLT5mYWtlX3ZibGFuazsKICAgIFRoaXMtPmZha2VfdmJsYW5rID0gIVRoaXMtPmZha2VfdmJsYW5rOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRBdmFpbGFibGVWaWRNZW0KICoKICogUmV0dXJucyB0aGUgdG90YWwgYW5kIGZyZWUgdmlkZW8gbWVtb3J5CiAqCiAqIFBhcmFtczoKICogIENhcHM6IFNwZWNpZmllcyB0aGUgbWVtb3J5IHR5cGUgYXNrZWQgZm9yCiAqICB0b3RhbDogUG9pbnRlciB0byBhIERXT1JEIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSB0b3RhbCBtZW1vcnkKICogIGZyZWU6IFBvaW50ZXIgdG8gYSBEV09SRCB0byBiZSBmaWxsZWQgd2l0aCB0aGUgZnJlZSBtZW1vcnkKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBvZiBmcmVlIGFuZCB0b3RhbCBhcmUgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0QXZhaWxhYmxlVmlkTWVtKElEaXJlY3REcmF3NyAqaWZhY2UsIEREU0NBUFMyICpDYXBzLCBEV09SRCAqdG90YWwsIERXT1JEICpmcmVlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwgJXAsICVwKVxuIiwgVGhpcywgQ2FwcywgdG90YWwsIGZyZWUpOwoKICAgIGlmKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKSBBc2tlZCBmb3IgbWVtb3J5IHdpdGggZGVzY3JpcHRpb246ICIsIFRoaXMpOwogICAgICAgIEREUkFXX2R1bXBfRERTQ0FQUzIoQ2Fwcyk7CiAgICAgICAgVFJBQ0UoIlxuIik7CiAgICB9CgogICAgLyogVG9kbzogU3lzdGVtIG1lbW9yeSB2cyBsb2NhbCB2aWRlbyBtZW1vcnkgdnMgbm9uLWxvY2FsIHZpZGVvIG1lbW9yeQogICAgICogVGhlIE1TRE4gYWxzbyBtZW50aW9ucyBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRleHR1cmUgbWVtb3J5IGFuZCBvdGhlcgogICAgICogcmVzb3VyY2VzLCBidXQgdGhhdCdzIG5vdCBpbXBvcnRhbnQKICAgICAqLwoKICAgIGlmKCAoIXRvdGFsKSAmJiAoIWZyZWUpICkgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgaWYodG90YWwpICp0b3RhbCA9IFRoaXMtPnRvdGFsX3ZpZG1lbTsKICAgIGlmKGZyZWUpICpmcmVlID0gSVdpbmVEM0REZXZpY2VfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbShUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkluaXRpYWxpemUKICoKICogSW5pdGlhbGl6ZXMgYSBEaXJlY3REcmF3IGludGVyZmFjZS4KICoKICogUGFyYW1zOgogKiAgR1VJRDogSW50ZXJmYWNlIGlkZW50aWZpZXIuIFdlbGwsIGRvbid0IGtub3cgd2hhdCB0aGlzIGlzIHJlYWxseSBnb29kCiAqICAgZm9yCiAqCiAqIFJldHVybnMKICogIFJldHVybnMgRERfT0sgb24gdGhlIGZpcnN0IGNhbGwsCiAqICBEREVSUl9BTFJFQURZSU5JVElBTElaRUQgb24gcmVwZWF0ZWQgY2FsbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0luaXRpYWxpemUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgR1VJRCAqR3VpZCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXMpOiBOby1vcFxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChHdWlkKSk7CgogICAgaWYoVGhpcy0+aW5pdGlhbGl6ZWQpCiAgICB7CiAgICAgICAgcmV0dXJuIERERVJSX0FMUkVBRFlJTklUSUFMSVpFRDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gRERfT0s7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkZsaXBUb0dESVN1cmZhY2UKICoKICogIk1ha2VzIHRoZSBzdXJmYWNlIHRoYXQgdGhlIEdESSB3cml0ZXMgdG8gdGhlIHByaW1hcnkgc3VyZmFjZSIKICogTG9va3MgbGlrZSBzb21lIHdpbmRvd3Mgc3BlY2lmaWMgdGhpbmcgd2UgZG9uJ3QgaGF2ZSB0byBjYXJlIGFib3V0LgogKiBBY2NvcmRpbmcgdG8gTVNETiBpdCBwZXJtaXRzIEdESSBkaWFsb2cgYm94ZXMgaW4gRlVMTFNDUkVFTiBtb2RlLiBHb29kIHRvCiAqIHNob3cgZXJyb3IgYm94ZXMgOykKICogV2VsbCwganVzdCByZXR1cm4gRERfT0suCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRmxpcFRvR0RJU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6V2FpdEZvclZlcnRpY2FsQmxhbmsKICoKICogVGhpcyBtZXRob2QgYWxsb3dzIGFwcGxpY2F0aW9ucyB0byBnZXQgaW4gc3luYyB3aXRoIHRoZSB2ZXJ0aWNhbCBibGFuawogKiBpbnRlcnZhbC4KICogVGhlIHdvcm1ob2xlIGRlbW8gaW4gdGhlIERpcmVjdFggNyBzZGsgdXNlcyB0aGlzIGNhbGwsIGFuZCBpdCBkb2Vzbid0CiAqIHJlZHJhdyB0aGUgc2NyZWVuLCBtb3N0IGxpa2VseSBiZWNhdXNlIG9mIHRoaXMgc3R1YgogKgogKiBQYXJhbWV0ZXJzOgogKiAgRmxhZ3M6IG9uZSBvZiBERFdBSVRWQl9CTE9DS0JFR0lOLCBERFdBSVRWQl9CTE9DS0JFR0lORVZFTlQKICogICAgICAgICBvciBERFdBSVRWQl9CTE9DS0VORAogKiAgaDogTm90IHVzZWQsIGFjY29yZGluZyB0byBNU0ROCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1dhaXRGb3JWZXJ0aWNhbEJsYW5rKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPigleCwlcCk6IFN0dWJcbiIsIFRoaXMsIEZsYWdzLCBoKTsKCiAgICAvKiBNU0ROIHNheXMgRERXQUlUVkJfQkxPQ0tCRUdJTkVWRU5UIGlzIG5vdCBzdXBwb3J0ZWQgKi8KICAgIGlmKEZsYWdzICYgRERXQUlUVkJfQkxPQ0tCRUdJTkVWRU5UKQogICAgICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsgLyogdW5jaGVja2VkICovCgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRTY2FuTGluZQogKgogKiBSZXR1cm5zIHRoZSBzY2FuIGxpbmUgdGhhdCBpcyBiZWluZyBkcmF3biBvbiB0aGUgbW9uaXRvcgogKgogKiBQYXJhbWV0ZXJzOgogKiAgU2NhbmxpbmU6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHNjYW4gbGluZSB2YWx1ZSB0bwogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElEaXJlY3REcmF3SW1wbF9HZXRTY2FuTGluZShJRGlyZWN0RHJhdzcgKmlmYWNlLCBEV09SRCAqU2NhbmxpbmUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBzdGF0aWMgQk9PTCBoaWRlID0gRkFMU0U7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKCiAgICAvKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBvZnRlbiwgc28gcHJpbnQgdGhlIGZpeG1lIG9ubHkgb25jZSAqLwogICAgaWYoIWhpZGUpCiAgICB7CiAgICAgICAgRklYTUUoIiglcCktPiglcCk6IFNlbWktU3R1YlxuIiwgVGhpcywgU2NhbmxpbmUpOwogICAgICAgIGhpZGUgPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlX0dldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwoKICAgIC8qIEZha2UgdGhlIGxpbmUgc3dlZXBpbmcgb2YgdGhlIG1vbml0b3IgKi8KICAgIC8qIEZJWE1FOiBXZSBzaG91bGQgc3luY2hyb25pemUgd2l0aCBhIHNvdXJjZSB0byBrZWVwIHRoZSByZWZyZXNoIHJhdGUgKi8gCiAgICAqU2NhbmxpbmUgPSBUaGlzLT5jdXJfc2NhbmxpbmUrKzsKICAgIC8qIEFzc3VtZSAyMCBzY2FuIGxpbmVzIGluIHRoZSB2ZXJ0aWNhbCBibGFuayAqLwogICAgaWYgKFRoaXMtPmN1cl9zY2FubGluZSA+PSBNb2RlLkhlaWdodCArIDIwKQogICAgICAgIFRoaXMtPmN1cl9zY2FubGluZSA9IDA7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpUZXN0Q29vcGVyYXRpdmVMZXZlbAogKgogKiBJbmZvcm1zIHRoZSBhcHBsaWNhdGlvbiBhYm91dCB0aGUgc3RhdGUgb2YgdGhlIHZpZGVvIGFkYXB0ZXIsIGRlcGVuZGluZwogKiBvbiB0aGUgY29vcGVyYXRpdmUgbGV2ZWwKICoKICogUmV0dXJuczoKICogIEREX09LIGlmIHRoZSBkZXZpY2UgaXMgaW4gYSBzYW5lIHN0YXRlCiAqICBEREVSUl9OT0VYQ0xVU0lWRU1PREUgb3IgRERFUlJfRVhDTFVTSVZFTU9ERUFMUkVBRFlTRVQKICogIGlmIHRoZSBzdGF0ZSBpcyBub3QgY29ycmVjdChTZWUgYmVsb3cpCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfVGVzdENvb3BlcmF0aXZlTGV2ZWwoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogRGVzY3JpcHRpb24gZnJvbSBNU0ROOgogICAgICogRm9yIGZ1bGxzY3JlZW4gYXBwcyByZXR1cm4gRERFUlJfTk9FWENMVVNJVkVNT0RFIGlmIHRoZSB1c2VyIHN3aXRjaGVkCiAgICAgKiBhd2F5IGZyb20gdGhlIGFwcCB3aXRoIGUuZy4gYWx0LXRhYi4gV2luZG93ZWQgYXBwcyByZWNlaXZlIAogICAgICogRERFUlJfRVhDTFVTSVZFTU9ERUFMUkVBRFlTRVQgaWYgYW5vdGhlciBhcHBsaWNhdGlvbiBjcmVhdGVkIGEgCiAgICAgKiBEaXJlY3REcmF3IG9iamVjdCBpbiBleGNsdXNpdmUgbW9kZS4gRERFUlJfV1JPTkdNT0RFIGlzIHJldHVybmVkLAogICAgICogd2hlbiB0aGUgdmlkZW8gbW9kZSBoYXMgY2hhbmdlZAogICAgICovCgogICAgaHIgPSAgSVdpbmVEM0REZXZpY2VfVGVzdENvb3BlcmF0aXZlTGV2ZWwoVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgLyogRml4IHRoZSByZXN1bHQgdmFsdWUuIFRoZXNlIHZhbHVlcyBhcmUgbWFwcGVkIGZyb20gdGhlaXIKICAgICAqIGQzZDkgY291bnRlcnBhcnQuCiAgICAgKi8KICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTE9TVDoKICAgICAgICAgICAgaWYoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICByZXR1cm4gRERFUlJfRVhDTFVTSVZFTU9ERUFMUkVBRFlTRVQ7CiAgICAgICAgICAgIH0KCiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0RFVklDRU5PVFJFU0VUOgogICAgICAgICAgICByZXR1cm4gRERfT0s7CgogICAgICAgIGNhc2UgV0lORUQzRF9PSzoKICAgICAgICAgICAgcmV0dXJuIEREX09LOwoKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIiglcCkgVW5leHBlY3RlZCByZXR1cm4gdmFsdWUgJTA4eCBmcm9tIHdpbmVEM0QsICIKICAgICAgICAgICAgICAgICIgcmV0dXJuaW5nIEREX09LXG4iLCBUaGlzLCBocik7CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRHRElTdXJmYWNlCiAqCiAqIFJldHVybnMgdGhlIHN1cmZhY2UgdGhhdCBHREkgaXMgdHJlYXRpbmcgYXMgdGhlIHByaW1hcnkgc3VyZmFjZS4KICogRm9yIFdpbmUgdGhpcyBpcyB0aGUgZnJvbnQgYnVmZmVyCiAqCiAqIFBhcmFtczoKICogIEdESVN1cmZhY2U6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIHN1cmZhY2Ugd2FzIGZvdW5kCiAqICBEREVSUl9OT1RGT1VORCBpZiB0aGUgR0RJIHN1cmZhY2Ugd2Fzbid0IGZvdW5kCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0R0RJU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqR0RJU3VyZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElXaW5lRDNEU3VyZmFjZSAqU3VyZjsKICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmRkc3VyZjsKICAgIEhSRVNVTFQgaHI7CiAgICBERFNDQVBTMiBkZHNDYXBzOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIEdESVN1cmZhY2UpOwoKICAgIC8qIEdldCB0aGUgYmFjayBidWZmZXIgZnJvbSB0aGUgd2luZUQzRERldmljZSBhbmQgc2VhcmNoIGl0cwogICAgICogYXR0YWNoZWQgc3VyZmFjZXMgZm9yIHRoZSBmcm9udCBidWZmZXIKICAgICAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRCYWNrQnVmZmVyKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU3dhcENoYWluICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogZmlyc3QgYmFjayBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RCQUNLQlVGRkVSX1RZUEVfTU9OTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3VyZik7CgogICAgaWYoIChociAhPSBEM0RfT0spIHx8CiAgICAgICAgKCFTdXJmKSApCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6R2V0QmFja0J1ZmZlciBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9OT1RGT1VORDsKICAgIH0KCiAgICAvKiBHZXRCYWNrQnVmZmVyIEFkZFJlZigpZWQgdGhlIHN1cmZhY2UsIHJlbGVhc2UgaXQgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKFN1cmYpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQoU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICoqKSAmZGRzdXJmKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShkZHN1cmYpOyAgLyogRm9yIHRoZSBHZXRQYXJlbnQgKi8KCiAgICAvKiBGaW5kIHRoZSBmcm9udCBidWZmZXIgKi8KICAgIGRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19GUk9OVEJVRkZFUjsKICAgIGhyID0gSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoZGRzdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGRzQ2FwcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR0RJU3VyZmFjZSk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICBFUlIoIklEaXJlY3REcmF3U3VyZmFjZTc6OkdldEF0dGFjaGVkU3VyZmFjZSBmYWlsZWQsIGhyID0gJXhcbiIsIGhyKTsKICAgIH0KCiAgICAvKiBUaGUgQWRkUmVmIGlzIE9LIHRoaXMgdGltZSAqLwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFbnVtRGlzcGxheU1vZGVzCiAqCiAqIEVudW1lcmF0ZXMgdGhlIHN1cHBvcnRlZCBEaXNwbGF5IG1vZGVzLiBUaGUgbW9kZXMgY2FuIGJlIGZpbHRlcmVkIHdpdGgKICogdGhlIEREU0QgcGFyYW1ldGVyLgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogY2FuIGJlIERERURNX1JFRlJFU0hSQVRFUyBhbmQgRERFRE1fU1RBTkRBUkRWR0FNT0RFUwogKiAgRERTRDogU3VyZmFjZSBkZXNjcmlwdGlvbiB0byBmaWx0ZXIgdGhlIG1vZGVzCiAqICBDb250ZXh0OiBQb2ludGVyIHBhc3NlZCBiYWNrIHRvIHRoZSBjYWxsYmFjayBmdW5jdGlvbgogKiAgY2I6IEFwcGxpY2F0aW9uLXByb3ZpZGVkIGNhbGxiYWNrIGZ1bmN0aW9uCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBjYWxsYmFjayB3YXNuJ3Qgc2V0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRW51bURpc3BsYXlNb2RlcyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNTU9ERVNDQUxMQkFDSzIgY2IpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICB1bnNpZ25lZCBpbnQgbW9kZW51bSwgZm10OwogICAgV0lORUQzREZPUk1BVCBwaXhlbGZvcm1hdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtb2RlOwogICAgRERTVVJGQUNFREVTQzIgY2FsbGJhY2tfc2Q7CgogICAgV0lORUQzREZPUk1BVCBjaGVja0Zvcm1hdExpc3RbXSA9CiAgICB7CiAgICAgICAgV0lORUQzREZNVF9SOEc4QjgsCiAgICAgICAgV0lORUQzREZNVF9BOFI4RzhCOCwKICAgICAgICBXSU5FRDNERk1UX1g4UjhHOEI4LAogICAgICAgIFdJTkVEM0RGTVRfUjVHNkI1LAogICAgICAgIFdJTkVEM0RGTVRfWDFSNUc1QjUsCiAgICAgICAgV0lORUQzREZNVF9BMVI1RzVCNSwKICAgICAgICBXSU5FRDNERk1UX0E0UjRHNEI0LAogICAgICAgIFdJTkVEM0RGTVRfUjNHM0IyLAogICAgICAgIFdJTkVEM0RGTVRfQThSM0czQjIsCiAgICAgICAgV0lORUQzREZNVF9YNFI0RzRCNCwKICAgICAgICBXSU5FRDNERk1UX0EyQjEwRzEwUjEwLAogICAgICAgIFdJTkVEM0RGTVRfQThCOEc4UjgsCiAgICAgICAgV0lORUQzREZNVF9YOEI4RzhSOCwKICAgICAgICBXSU5FRDNERk1UX0EyUjEwRzEwQjEwLAogICAgICAgIFdJTkVEM0RGTVRfQThQOCwKICAgICAgICBXSU5FRDNERk1UX1A4CiAgICB9OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXApOiBSZWxheVxuIiwgVGhpcywgRERTRCwgQ29udGV4dCwgY2IpOwoKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSAqLwogICAgaWYoIWNiKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBpZihERFNEKQogICAgewogICAgICAgIGlmICgoRERTRC0+ZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpICYmIChERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQuZHdGbGFncyAmIEREUEZfUkdCKSApCiAgICAgICAgICAgIHBpeGVsZm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIH0KCiAgICBmb3IoZm10ID0gMDsgZm10IDwgKHNpemVvZihjaGVja0Zvcm1hdExpc3QpIC8gc2l6ZW9mKGNoZWNrRm9ybWF0TGlzdFswXSkpOyBmbXQrKykKICAgIHsKICAgICAgICBpZihwaXhlbGZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04gJiYgY2hlY2tGb3JtYXRMaXN0W2ZtdF0gIT0gcGl4ZWxmb3JtYXQpCiAgICAgICAgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIG1vZGVudW0gPSAwOwogICAgICAgIHdoaWxlKElXaW5lRDNEX0VudW1BZGFwdGVyTW9kZXMoVGhpcy0+d2luZUQzRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RBREFQVEVSX0RFRkFVTFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0Zvcm1hdExpc3RbZm10XSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGVudW0rKywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtb2RlKSA9PSBXSU5FRDNEX09LKQogICAgICAgIHsKICAgICAgICAgICAgaWYoRERTRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoRERTRC0+ZHdGbGFncyAmIEREU0RfV0lEVEggJiYgbW9kZS5XaWR0aCAhPSBERFNELT5kd1dpZHRoKSBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmKEREU0QtPmR3RmxhZ3MgJiBERFNEX0hFSUdIVCAmJiBtb2RlLkhlaWdodCAhPSBERFNELT5kd0hlaWdodCkgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG1lbXNldCgmY2FsbGJhY2tfc2QsIDAsIHNpemVvZihjYWxsYmFja19zZCkpOwogICAgICAgICAgICBjYWxsYmFja19zZC5kd1NpemUgPSBzaXplb2YoY2FsbGJhY2tfc2QpOwogICAgICAgICAgICBjYWxsYmFja19zZC51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREUElYRUxGT1JNQVQpOwoKICAgICAgICAgICAgY2FsbGJhY2tfc2QuZHdGbGFncyA9IEREU0RfSEVJR0hUfEREU0RfV0lEVEh8RERTRF9QSVhFTEZPUk1BVHxERFNEX1BJVENIOwogICAgICAgICAgICBpZihGbGFncyAmIERERURNX1JFRlJFU0hSQVRFUykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FsbGJhY2tfc2QuZHdGbGFncyB8PSBERFNEX1JFRlJFU0hSQVRFOwogICAgICAgICAgICAgICAgY2FsbGJhY2tfc2QudTIuZHdSZWZyZXNoUmF0ZSA9IG1vZGUuUmVmcmVzaFJhdGU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNhbGxiYWNrX3NkLmR3V2lkdGggPSBtb2RlLldpZHRoOwogICAgICAgICAgICBjYWxsYmFja19zZC5kd0hlaWdodCA9IG1vZGUuSGVpZ2h0OwoKICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmNhbGxiYWNrX3NkLnU0LmRkcGZQaXhlbEZvcm1hdCwgbW9kZS5Gb3JtYXQpOwoKICAgICAgICAgICAgVFJBQ0UoIkVudW1lcmF0aW5nICVkeCVkQCVkXG4iLCBjYWxsYmFja19zZC5kd1dpZHRoLCBjYWxsYmFja19zZC5kd0hlaWdodCwgY2FsbGJhY2tfc2QudTQuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQpOwoKICAgICAgICAgICAgaWYoY2IoJmNhbGxiYWNrX3NkLCBDb250ZXh0KSA9PSBEREVOVU1SRVRfQ0FOQ0VMKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gYXNrZWQgdG8gdGVybWluYXRlIHRoZSBlbnVtZXJhdGlvblxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIkVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkV2YWx1YXRlTW9kZQogKgogKiBVc2VkIHdpdGggSURpcmVjdERyYXc3OjpTdGFydE1vZGVUZXN0IHRvIHRlc3QgdmlkZW8gbW9kZXMuCiAqIEV2YWx1YXRlTW9kZSBpcyB1c2VkIHRvIHBhc3Mgb3IgZmFpbCBhIG1vZGUsIGFuZCBjb250aW51ZSB3aXRoIHRoZSBuZXh0CiAqIG1vZGUKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IERERU1fTU9ERVBBU1NFRCBvciBEREVNX01PREVGQUlMRUQKICogIFRpbWVvdXQ6IFJldHVybnMgdGhlIGFtb3VudCBvZiBzZWNvbmRzIGxlZnQgYmVmb3JlIHRoZSBtb2RlIHdvdWxkIGhhdmUKICogICAgICAgICAgIGJlZW4gZmFpbGVkIGF1dG9tYXRpY2FsbHkKICoKICogUmV0dXJuczoKICogIFRoaXMgaW1wbGVtZW50YXRpb24gYWx3YXlzIEREX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9FdmFsdWF0ZU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqVGltZW91dCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJWQsJXApOiBTdHViIVxuIiwgVGhpcywgRmxhZ3MsIFRpbWVvdXQpOwoKICAgIC8qIFdoZW4gaW1wbGVtZW50aW5nIHRoaXMsIGltcGxlbWVudCBpdCBpbiBXaW5lRDNEICovCgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXREZXZpY2VJZGVudGlmaWVyCiAqCiAqIFJldHVybnMgdGhlIGRldmljZSBpZGVudGlmaWVyLCB3aGljaCBnaXZlcyBpbmZvcm1hdGlvbiBhYm91dCB0aGUgZHJpdmVyCiAqIE91ciBkZXZpY2UgaWRlbnRpZmllciBpcyBkZWZpbmVkIGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhpcyBmaWxlLgogKgogKiBQYXJhbXM6CiAqICBERERJOiBBZGRyZXNzIGZvciB0aGUgcmV0dXJuZWQgc3RydWN0dXJlCiAqICBGbGFnczogQ2FuIGJlIERER0RJX0dFVEhPU1RJREVOVElGSUVSCiAqCiAqIFJldHVybnM6CiAqICBPbiBzdWNjZXNzIGl0IHJldHVybnMgRERfT0sKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgRERESSBpcyBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXREZXZpY2VJZGVudGlmaWVyKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREREVWSUNFSURFTlRJRklFUjIgKkREREksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcCwlMDh4KVxuIiwgVGhpcywgRERESSwgRmxhZ3MpOwoKICAgIGlmKCFERERJKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIFRoZSBEREdESV9HRVRIT1NUSURFTlRJRklFUiByZXR1cm5zIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgMkQKICAgICAqIGhvc3QgYWRhcHRlciwgaWYgdGhlcmUncyBhIHNlY29uZGFyeSAzRCBhZGFwdGVyLiBUaGlzIGRvZXNuJ3QgYXBwbHkKICAgICAqIHRvIGFueSBtb2Rlcm4gaGFyZHdhcmUsIG5vciBpcyBpdCBpbnRlcmVzdGluZyBmb3IgV2luZSwgc28gaWdub3JlIGl0CiAgICAgKi8KCiAgICAqRERESSA9IGRldmljZWlkZW50aWZpZXI7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldFN1cmZhY2VGcm9tREMKICoKICogUmV0dXJucyB0aGUgU3VyZmFjZSBmb3IgYSBHREkgZGV2aWNlIGNvbnRleHQgaGFuZGxlLgogKiBJcyB0aGlzIHJlbGF0ZWQgdG8gSURpcmVjdERyYXdTdXJmYWNlOjpHZXREQyA/Pz8KICoKICogUGFyYW1zOgogKiAgaGRjOiBoZGMgdG8gcmV0dXJuIHRoZSBzdXJmYWNlIGZvcgogKiAgU3VyZmFjZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgc3VyZmFjZSBwb2ludGVyIHRvCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRTdXJmYWNlRnJvbURDKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhEQyBoZGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipTdXJmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCwlcCk6IFN0dWIhXG4iLCBUaGlzLCBoZGMsIFN1cmZhY2UpOwoKICAgIC8qIEltcGxlbWVudGF0aW9uIGlkZWEgaWYgbmVlZGVkOiBMb29wIHRocm91Z2ggYWxsIHN1cmZhY2VzIGFuZCBjb21wYXJlCiAgICAgKiB0aGVpciBoZGMgd2l0aCBoZGMuIEltcGxlbWVudCBpdCBpbiBXaW5lRDNEISAqLwogICAgcmV0dXJuIERERVJSX05PVEZPVU5EOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpSZXN0b3JlQWxsU3VyZmFjZXMKICoKICogQ2FsbHMgdGhlIHJlc3RvcmUgbWV0aG9kIG9mIGFsbCBzdXJmYWNlcwogKgogKiBQYXJhbXM6CiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSyBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZXN0b3JlQWxsU3VyZmFjZXMoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApOiBTdHViXG4iLCBUaGlzKTsKCiAgICAvKiBUaGlzIGlzbid0IGhhcmQgdG8gaW1wbGVtZW50OiBFbnVtZXJhdGUgYWxsIFdpbmVEM0Qgc3VyZmFjZXMsCiAgICAgKiBnZXQgdGhlaXIgcGFyZW50IGFuZCBjYWxsIHRoZWlyIHJlc3RvcmUgbWV0aG9kLiBEbyBub3QgaW1wbGVtZW50CiAgICAgKiBpdCBpbiBXaW5lRDNELCBhcyByZXN0b3JpbmcgYSBzdXJmYWNlIG1lYW5zIHJlLWNyZWF0aW5nIHRoZQogICAgICogV2luZUQzRERTdXJmYWNlCiAgICAgKi8KICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6U3RhcnRNb2RlVGVzdAogKgogKiBUZXN0cyB0aGUgc3BlY2lmaWVkIHZpZGVvIG1vZGVzIHRvIHVwZGF0ZSB0aGUgc3lzdGVtIHJlZ2lzdHJ5IHdpdGgKICogcmVmcmVzaCByYXRlIGluZm9ybWF0aW9uLiBTdGFydE1vZGVUZXN0IHN0YXJ0cyB0aGUgbW9kZSB0ZXN0LAogKiBFdmFsdWF0ZU1vZGUgaXMgdXNlZCB0byBmYWlsIG9yIHBhc3MgYSBtb2RlLiBJZiBFdmFsdWF0ZU1vZGUKICogaXNuJ3QgY2FsbGVkIHdpdGhpbiAxNSBzZWNvbmRzLCB0aGUgbW9kZSBpcyBmYWlsZWQgYXV0b21hdGljYWxseQogKgogKiBBcyByZWZyZXNoIHJhdGVzIGFyZSBoYW5kbGVkIGJ5IHRoZSBYIHNlcnZlciwgSSBkb24ndCB0aGluayB0aGlzCiAqIE1ldGhvZCBpcyBpbXBvcnRhbnQKICoKICogUGFyYW1zOgogKiAgTW9kZXM6IEFuIGFycmF5IG9mIG1vZGUgc3BlY2lmaWNhdGlvbnMKICogIE51bU1vZGVzOiBUaGUgbnVtYmVyIG9mIG1vZGVzIGluIE1vZGVzCiAqICBGbGFnczogU29tZSBmbGFncy4uLgogKgogKiBSZXR1cm5zOgogKiAgUmV0dXJucyBEREVSUl9URVNURklOSVNIRUQgaWYgZmxhZ3MgY29udGFpbnMgRERTTVRfSVNURVNUUkVRVUlSRUQsCiAqICBpZiBubyBtb2RlcyBhcmUgcGFzc2VkLCBEREVSUl9JTlZBTElEUEFSQU1TIGlzIHJldHVybmVkLAogKiAgb3RoZXJ3aXNlIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9TdGFydE1vZGVUZXN0KElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJWkUgKk1vZGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBOdW1Nb2RlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBXQVJOKCIoJXApLT4oJXAsICVkLCAleCk6IFNlbWktU3R1YiwgbW9zdCBsaWtlbHkgaGFybWxlc3NcbiIsIFRoaXMsIE1vZGVzLCBOdW1Nb2RlcywgRmxhZ3MpOwoKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSAqLwogICAgaWYoICghTW9kZXMpIHx8IChOdW1Nb2RlcyA9PSAwKSApIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIEREU01UX0lTVEVTVFJFUVVJUkVEIGFza3MgaWYgYSBtb2RlIHRlc3QgaXMgbmVjZXNzYXJ5LgogICAgICogQXMgaXQgaXMgbm90LCBEREVSUl9URVNURklOSVNIRUQgaXMgcmV0dXJuZWQKICAgICAqIChob3BlZnVsbHkgdGhhdCdzIGNvcnJlY3QKICAgICAqCiAgICBpZihGbGFncyAmIEREU01UX0lTVEVTVFJFUVVJUkVEKSByZXR1cm4gRERFUlJfVEVTVEZJTklTSEVEOwogICAgICogd2VsbCwgdGhhdCB2YWx1ZSBkb2Vzbid0ICh5ZXQpIGV4aXN0IGluIHRoZSB3aW5lIGhlYWRlcnMsIHNvIGlnbm9yZSBpdAogICAgICovCgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlU3VyZmFjZXNDYWxsYmFjawogKgogKiBFbnVtZXJhdGlvbiBjYWxsYmFjayBmb3IgSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlQWxsU3VyZmFjZXMuCiAqIEl0IHJlLXJlY3JlYXRlcyB0aGUgV2luZUQzRFN1cmZhY2UuIEl0J3MgcHJldHR5IHN0cmFpZ2h0Zm9yd2FyZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2soSURpcmVjdERyYXdTdXJmYWNlNyAqc3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqZGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0KQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmSW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cmYpOwogICAgSURpcmVjdERyYXdJbXBsICpUaGlzID0gc3VyZkltcGwtPmRkcmF3OwogICAgSVVua25vd24gKlBhcmVudDsKICAgIElQYXJlbnRJbXBsICpwYXJJbXBsID0gTlVMTDsKICAgIElXaW5lRDNEU3VyZmFjZSAqd2luZUQzRFN1cmZhY2U7CiAgICBIUkVTVUxUIGhyOwogICAgdm9pZCAqdG1wOwogICAgSVdpbmVEM0RDbGlwcGVyICpjbGlwcGVyID0gTlVMTDsKCiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDICAgICBEZXNjOwogICAgV0lORUQzREZPUk1BVCAgICAgICAgICAgRm9ybWF0OwogICAgV0lORUQzRFJFU09VUkNFVFlQRSAgICAgVHlwZTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIFVzYWdlOwogICAgV0lORUQzRFBPT0wgICAgICAgICAgICAgUG9vbDsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgIFNpemU7CgogICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGVUeXBlOwogICAgRFdPUkQgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgV2lkdGg7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICBIZWlnaHQ7CgogICAgVFJBQ0UoIiglcCk6IEVudW1lcmF0ZWQgU3VyZmFjZSAlcFxuIiwgVGhpcywgc3VyZkltcGwpOwoKICAgIC8qIEZvciB0aGUgZW51bWVyYXRpb24gKi8KICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmKTsKCiAgICBpZihzdXJmSW1wbC0+SW1wbFR5cGUgPT0gVGhpcy0+SW1wbFR5cGUpIHJldHVybiBEREVOVU1SRVRfT0s7IC8qIENvbnRpbnVlICovCgogICAgLyogR2V0IHRoZSBvYmplY3RzICovCiAgICB3aW5lRDNEU3VyZmFjZSA9IHN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQod2luZUQzRFN1cmZhY2UsICZQYXJlbnQpOwogICAgSVVua25vd25fUmVsZWFzZShQYXJlbnQpOyAvKiBGb3IgdGhlIGdldFBhcmVudCAqLwoKICAgIC8qIElzIHRoZSBwYXJlbnQgYW4gSVBhcmVudCBpbnRlcmZhY2U/ICovCiAgICBpZihJVW5rbm93bl9RdWVyeUludGVyZmFjZShQYXJlbnQsICZJSURfSVBhcmVudCwgJnRtcCkgPT0gU19PSykKICAgIHsKICAgICAgICAvKiBJdCBpcyBhIElQYXJlbnQgaW50ZXJmYWNlISAqLwogICAgICAgIElVbmtub3duX1JlbGVhc2UoUGFyZW50KTsgLyogRm9yIHRoZSBRdWVyeUludGVyZmFjZSAqLwogICAgICAgIHBhckltcGwgPSBJQ09NX09CSkVDVChJUGFyZW50SW1wbCwgSVBhcmVudCwgUGFyZW50KTsKICAgICAgICAvKiBSZWxlYXNlIHRoZSByZWZlcmVuY2UgdGhlIHBhcmVudCBpbnRlcmZhY2UgaXMgaG9sZGluZyAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHdpbmVEM0RTdXJmYWNlKTsKICAgIH0KCiAgICAvKiBnZXQgdGhlIGNsaXBwZXIgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDbGlwcGVyKHdpbmVEM0RTdXJmYWNlLCAmY2xpcHBlcik7CgogICAgLyogR2V0IHRoZSBzdXJmYWNlIHByb3BlcnRpZXMgKi8KICAgIERlc2MuRm9ybWF0ID0gJkZvcm1hdDsKICAgIERlc2MuVHlwZSA9ICZUeXBlOwogICAgRGVzYy5Vc2FnZSA9ICZVc2FnZTsKICAgIERlc2MuUG9vbCA9ICZQb29sOwogICAgRGVzYy5TaXplID0gJlNpemU7CiAgICBEZXNjLk11bHRpU2FtcGxlVHlwZSA9ICZNdWx0aVNhbXBsZVR5cGU7CiAgICBEZXNjLk11bHRpU2FtcGxlUXVhbGl0eSA9ICZNdWx0aVNhbXBsZVF1YWxpdHk7CiAgICBEZXNjLldpZHRoID0gJldpZHRoOwogICAgRGVzYy5IZWlnaHQgPSAmSGVpZ2h0OwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERlc2Mod2luZUQzRFN1cmZhY2UsICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykgcmV0dXJuIGhyOwoKICAgIC8qIENyZWF0ZSB0aGUgbmV3IHN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlU3VyZmFjZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdpZHRoLCBIZWlnaHQsIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIExvY2thYmxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFIC8qIERpc2NhcmQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyZkltcGwtPm1pcG1hcF9sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3VyZkltcGwtPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU2hhcmVkSGFuZGxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPkltcGxUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmVudCk7CgogICAgaWYoaHIgIT0gRDNEX09LKQogICAgICAgIHJldHVybiBocjsKCiAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q2xpcHBlcihzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2UsIGNsaXBwZXIpOwoKICAgIC8qIFVwZGF0ZSB0aGUgSVBhcmVudCBpZiBpdCBleGlzdHMgKi8KICAgIGlmKHBhckltcGwpCiAgICB7CiAgICAgICAgcGFySW1wbC0+Y2hpbGQgPSAoSVVua25vd24gKikgc3VyZkltcGwtPldpbmVEM0RTdXJmYWNlOwogICAgICAgIC8qIEFkZCBhIHJlZmVyZW5jZSBmb3IgdGhlIElQYXJlbnQgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKHN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZSk7CiAgICB9CiAgICAvKiBUT0RPOiBDb3B5IHRoZSBzdXJmYWNlIGNvbnRlbnQsIGV4Y2VwdCBmb3IgcmVuZGVyIHRhcmdldHMgKi8KCiAgICBpZihJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSh3aW5lRDNEU3VyZmFjZSkgPT0gMCkKICAgICAgICBUUkFDRSgiU3VyZmFjZSByZWxlYXNlZCBzdWNjZXNzZnVsLCBuZXh0IHN1cmZhY2VcbiIpOwogICAgZWxzZQogICAgICAgIEVSUigiU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgb2xkIFdpbmVEM0RTdXJmYWNlXG4iKTsKCiAgICBzdXJmSW1wbC0+SW1wbFR5cGUgPSBUaGlzLT5JbXBsVHlwZTsKCiAgICBpZihjbGlwcGVyKQogICAgewogICAgICAgIElXaW5lRDNEQ2xpcHBlcl9SZWxlYXNlKGNsaXBwZXIpOwogICAgfQogICAgcmV0dXJuIERERU5VTVJFVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzCiAqCiAqIEEgZnVuY3Rpb24sIHRoYXQgY29udmVydHMgYWxsIHdpbmVEM0RTdXJmYWNlcyB0byB0aGUgbmV3IGltcGxlbWVudGF0aW9uIHR5cGUKICogSXQgZW51bWVyYXRlcyBhbGwgc3VyZmFjZXMgd2l0aCBJV2luZUQzRERldmljZTo6RW51bVN1cmZhY2VzLCBjcmVhdGVzIGEKICogbmV3IFdpbmVEM0RTdXJmYWNlLCBjb3BpZXMgdGhlIGNvbnRlbnQgYW5kIHJlbGVhc2VzIHRoZSBvbGQgc3VyZmFjZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCklEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzKElEaXJlY3REcmF3SW1wbCAqVGhpcykKewogICAgRERTVVJGQUNFREVTQzIgZGVzYzsKICAgIFRSQUNFKCIoJXApOiBTd2l0Y2ggdG8gaW1wbGVtZW50YXRpb24gJWRcbiIsIFRoaXMsIFRoaXMtPkltcGxUeXBlKTsKCiAgICBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCAmJiBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpCiAgICB7CiAgICAgICAgLyogU2hvdWxkIGhhcHBlbiBhbG1vc3QgbmV2ZXIgKi8KICAgICAgICBGSVhNRSgiKCVwKSBTd2l0Y2hpbmcgdG8gbm9uLW9wZW5nbCBzdXJmYWNlcyB3aXRoIGQzZCBzdGFydGVkLiBJcyB0aGlzIGEgYnVnP1xuIiwgVGhpcyk7CiAgICAgICAgLyogU2h1dGRvd24gZDNkICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfVW5pbml0M0QoVGhpcy0+d2luZUQzRERldmljZSwgRDNEN0NCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlLCBEM0Q3Q0JfRGVzdHJveVN3YXBDaGFpbik7CiAgICB9CiAgICAvKiBDb250cmFyeTogRDNEIHN0YXJ0aW5nIGlzIGhhbmRsZWQgYnkgdGhlIGNhbGxlciwgYmVjYXVzZSBpdCBrbm93cyB0aGUgcmVuZGVyIHRhcmdldCAqLwoKICAgIG1lbXNldCgmZGVzYywgMCwgc2l6ZW9mKGRlc2MpKTsKICAgIGRlc2MuZHdTaXplID0gc2l6ZW9mKGRlc2MpOwoKICAgIHJldHVybiBJRGlyZWN0RHJhdzdfRW51bVN1cmZhY2VzKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlU3VyZmFjZXNDYWxsYmFjayk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEM0Q3Q0JfQ3JlYXRlU3VyZmFjZQogKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgSURpcmVjdDNERGV2aWNlX0NyZWF0ZVRleHR1cmUuIEl0IHNlYXJjaGVzIGZvciB0aGUKICogY29ycmVjdCBtaXBtYXAgc3VibGV2ZWwsIGFuZCByZXR1cm5zIGl0IHRvIFdpbmVEM0QuCiAqIFRoZSBzdXJmYWNlcyBhcmUgY3JlYXRlZCBhbHJlYWR5IGJ5IElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBXaXRoLCBIZWlnaHQ6IFdpdGggYW5kIGhlaWdodCBvZiB0aGUgc3VyZmFjZQogKiAgRm9ybWF0OiBUaGUgcmVxdWVzdGVkIGZvcm1hdAogKiAgVXNhZ2UsIFBvb2w6IEQzRFVTQUdFIGFuZCBEM0RQT09MIG9mIHRoZSBzdXJmYWNlCiAqICBsZXZlbDogVGhlIG1pcG1hcCBsZXZlbAogKiAgRmFjZTogVGhlIGN1YmUgbWFwIGZhY2UgdHlwZQogKiAgU3VyZmFjZTogUG9pbnRlciB0byBwYXNzIHRoZSBjcmVhdGVkIHN1cmZhY2UgYmFjayBhdAogKiAgU2hhcmVkSGFuZGxlOiBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZVN1cmZhY2UoSVVua25vd24gKmRldmljZSwKICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKnBTdXBlcmlvciwKICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICBEV09SRCBVc2FnZSwgV0lORUQzRFBPT0wgUG9vbCwgVUlOVCBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgV0lORUQzRENVQkVNQVBfRkFDRVMgRmFjZSwKICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICoqU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgSEFORExFICpTaGFyZWRIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IE5VTEw7CiAgICBpbnQgaSA9IDA7CiAgICBERFNDQVBTMiBzZWFyY2hjYXBzID0gVGhpcy0+dGV4X3Jvb3QtPnN1cmZhY2VfZGVzYy5kZHNDYXBzOwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrLiBzdXJmPSVwLiBGYWNlICVkIGxldmVsICVkXG4iLCBkZXZpY2UsIFRoaXMtPnRleF9yb290LCBGYWNlLCBsZXZlbCk7CgogICAgc2VhcmNoY2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9DVUJFTUFQX0FMTEZBQ0VTOwogICAgc3dpdGNoKEZhY2UpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNEQ1VCRU1BUF9GQUNFX1BPU0lUSVZFX1g6CiAgICAgICAgICAgIFRSQUNFKCJBc2tlZCBmb3IgcG9zaXRpdmUgeFxuIik7CiAgICAgICAgICAgIGlmKHNlYXJjaGNhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVApIHsKICAgICAgICAgICAgICAgIHNlYXJjaGNhcHMuZHdDYXBzMiB8PSBERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWDsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdXJmID0gVGhpcy0+dGV4X3Jvb3Q7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9ORUdBVElWRV9YOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIG5lZ2F0aXZlIHhcbiIpOwogICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVg7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9ZOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIHBvc2l0aXZlIHlcbiIpOwogICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVk7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9ORUdBVElWRV9ZOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIG5lZ2F0aXZlIHlcbiIpOwogICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVk7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9aOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIHBvc2l0aXZlIHpcbiIpOwogICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVo7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9ORUdBVElWRV9aOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIG5lZ2F0aXZlIHpcbiIpOwogICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVo7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IHtFUlIoIlVuZXhwZWN0ZWQgY3ViZSBmYWNlXG4iKTt9IC8qIFN0dXBpZCBjb21waWxlciAqLwogICAgfQoKICAgIGlmKCFzdXJmKQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmF0dGFjaGVkOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKFRoaXMtPnRleF9yb290LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VhcmNoY2FwcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYXR0YWNoZWQpOwogICAgICAgIHN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBhdHRhY2hlZCk7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGF0dGFjaGVkKTsKICAgIH0KICAgIGlmKCFzdXJmKSBFUlIoInJvb3Qgc2VhcmNoIHN1cmZhY2Ugbm90IGZvdW5kXG4iKTsKCiAgICAvKiBGaW5kIHRoZSB3YW50ZWQgbWlwbWFwLiBUaGVyZSBhcmUgZW5vdWdoIG1pcG1hcHMgaW4gdGhlIGNoYWluICovCiAgICB3aGlsZShpIDwgbGV2ZWwpCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqYXR0YWNoZWQ7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19HZXRBdHRhY2hlZFN1cmZhY2UoSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlYXJjaGNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dGFjaGVkKTsKICAgICAgICBpZighYXR0YWNoZWQpIEVSUigiU3VyZmFjZSBub3QgZm91bmRcbiIpOwogICAgICAgIHN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBhdHRhY2hlZCk7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGF0dGFjaGVkKTsKICAgICAgICBpKys7CiAgICB9CgogICAgLyogUmV0dXJuIHRoZSBzdXJmYWNlICovCiAgICAqU3VyZmFjZSA9IHN1cmYtPldpbmVEM0RTdXJmYWNlOwoKICAgIFRSQUNFKCJSZXR1cm5pbmcgd2luZUQzRFN1cmZhY2UgJXAsIGl0IGJlbG9uZ3MgdG8gc3VyZmFjZSAlcFxuIiwgKlN1cmZhY2UsIHN1cmYpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKVUxPTkcgV0lOQVBJIEQzRDdDQl9EZXN0cm95U3dhcENoYWluKElXaW5lRDNEU3dhcENoYWluICpwU3dhcENoYWluKSB7CiAgICBJVW5rbm93biogc3dhcENoYWluUGFyZW50OwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBwU3dhcENoYWluKTsKCiAgICBJV2luZUQzRFN3YXBDaGFpbl9HZXRQYXJlbnQocFN3YXBDaGFpbiwgJnN3YXBDaGFpblBhcmVudCk7CiAgICBJVW5rbm93bl9SZWxlYXNlKHN3YXBDaGFpblBhcmVudCk7CiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZShzd2FwQ2hhaW5QYXJlbnQpOwp9CgpVTE9ORyBXSU5BUEkgRDNEN0NCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlKElXaW5lRDNEU3VyZmFjZSAqcFN1cmZhY2UpIHsKICAgIElVbmtub3duKiBzdXJmYWNlUGFyZW50OwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBwU3VyZmFjZSk7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChwU3VyZmFjZSwgKElVbmtub3duICoqKSAmc3VyZmFjZVBhcmVudCk7CiAgICBJVW5rbm93bl9SZWxlYXNlKHN1cmZhY2VQYXJlbnQpOwogICAgcmV0dXJuIElVbmtub3duX1JlbGVhc2Uoc3VyZmFjZVBhcmVudCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZQogKgogKiBBIGhlbHBlciBmdW5jdGlvbiBmb3IgSURpcmVjdERyYXc3OjpDcmVhdGVTdXJmYWNlLiBJdCBjcmVhdGVzIGEgbmV3IHN1cmZhY2UKICogd2l0aCB0aGUgcGFzc2VkIHBhcmFtZXRlcnMuCiAqCiAqIFBhcmFtczoKICogIEREU0Q6IERlc2NyaXB0aW9uIG9mIHRoZSBzdXJmYWNlIHRvIGNyZWF0ZQogKiAgU3VyZjogQWRkcmVzcyB0byBzdG9yZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UoSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqcEREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKipwcFN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbGV2ZWwpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBVSU5UIFdpZHRoID0gMCwgSGVpZ2h0ID0gMDsKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0ID0gV0lORUQzREZNVF9VTktOT1dOOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBSZXNUeXBlID0gV0lORUQzRFJUWVBFX1NVUkZBQ0U7CiAgICBEV09SRCBVc2FnZSA9IDA7CiAgICBXSU5FRDNEU1VSRlRZUEUgSW1wbFR5cGUgPSBUaGlzLT5JbXBsVHlwZTsKICAgIFdJTkVEM0RTVVJGQUNFX0RFU0MgRGVzYzsKICAgIElVbmtub3duICpQYXJlbnQ7CiAgICBJUGFyZW50SW1wbCAqcGFySW1wbCA9IE5VTEw7CiAgICBXSU5FRDNEUE9PTCBQb29sID0gV0lORUQzRFBPT0xfREVGQVVMVDsKCiAgICAvKiBEdW1taWVzIGZvciBHZXREZXNjICovCiAgICBXSU5FRDNEUE9PTCBkdW1teV9kM2Rwb29sOwogICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgZHVtbXlfbXN0OwogICAgVUlOVCBkdW1teV91aW50OwogICAgRFdPUkQgZHVtbXlfZHdvcmQ7CgogICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiICglcCkgUmVxdWVzdGluZyBzdXJmYWNlIGRlc2MgOlxuIiwgVGhpcyk7CiAgICAgICAgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MocEREU0QpOwogICAgfQoKICAgIC8qIFNlbGVjdCB0aGUgc3VyZmFjZSB0eXBlLCBpZiBpdCB3YXNuJ3QgY2hvb3NlbiB5ZXQgKi8KICAgIGlmKEltcGxUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgIHsKICAgICAgICAvKiBVc2UgR0wgU3VyZmFjZXMgaWYgYSBEM0RERVZJQ0UgU3VyZmFjZSBpcyByZXF1ZXN0ZWQgKi8KICAgICAgICBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTXzNEREVWSUNFKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2hvb3NpbmcgR0wgc3VyZmFjZXMgYmVjYXVzZSBhIDNEREVWSUNFIFN1cmZhY2Ugd2FzIHJlcXVlc3RlZFxuIiwgVGhpcyk7CiAgICAgICAgICAgIEltcGxUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgfQoKICAgICAgICAvKiBPdGhlcndpc2UgdXNlIEdESSBzdXJmYWNlcyBmb3Igbm93ICovCiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2hvb3NpbmcgR0RJIHN1cmZhY2VzIGZvciAyRCByZW5kZXJpbmdcbiIsIFRoaXMpOwogICAgICAgICAgICBJbXBsVHlwZSA9IFNVUkZBQ0VfR0RJOwogICAgICAgIH0KCiAgICAgICAgLyogUG9saWN5IGlmIGFsbCBzdXJmYWNlIGltcGxlbWVudGF0aW9ucyBhcmUgYXZhaWxhYmxlOgogICAgICAgICAqIEZpcnN0LCBjaGVjayBpZiBhIGRlZmF1bHQgdHlwZSB3YXMgc2V0IHdpdGggd2luZWNmZy4gSWYgbm90LAogICAgICAgICAqIHRyeSBYcmVuZGVyIHN1cmZhY2VzLCBhbmQgdXNlIHRoZW0gaWYgdGhleSB3b3JrLiBOZXh0LCBjaGVjayBpZgogICAgICAgICAqIGFjY2VsZXJhdGVkIE9wZW5HTCBpcyBhdmFpbGFibGUsIGFuZCB1c2UgR0wgc3VyZmFjZXMgaW4gdGhpcwogICAgICAgICAqIGNhc2UuIElmIGFsbCBlbHNlIGZhaWxzLCB1c2UgR0RJIHN1cmZhY2VzLiBJZiBhIDNEREVWSUNFIHN1cmZhY2UKICAgICAgICAgKiB3YXMgY3JlYXRlZCwgYWx3YXlzIHVzZSBPcGVuR0wgc3VyZmFjZXMuCiAgICAgICAgICoKICAgICAgICAgKiAoTm90ZTogWHJlbmRlciBzdXJmYWNlcyBhcmUgbm90IGltcGxlbWVudGVkIGZvciBub3csIHRoZQogICAgICAgICAqIHVuYWNjZWxlcmF0ZWQgaW1wbGVtZW50YXRpb24gdXNlcyBHREkgdG8gcmVuZGVyIGluIFNvZnR3YXJlKQogICAgICAgICAqLwoKICAgICAgICAvKiBTdG9yZSB0aGUgdHlwZS4gSWYgaXQgbmVlZHMgdG8gYmUgY2hhbmdlZCwgYWxsIFdpbmVEM0RTdXJmYWNlcyBoYXZlIHRvCiAgICAgICAgICogYmUgcmUtY3JlYXRlZC4gVGhpcyBjb3VsZCBiZSBkb25lIHdpdGggSURpcmVjdERyYXdTdXJmYWNlNzo6UmVzdG9yZQogICAgICAgICAqLwogICAgICAgIFRoaXMtPkltcGxUeXBlID0gSW1wbFR5cGU7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgIGlmKChwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTXzNEREVWSUNFICkgJiYgCiAgICAgICAgICAgIChUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCApICYmIERlZmF1bHRTdXJmYWNlVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICAgICAgewogICAgICAgICAgICAvKiBXZSBoYXZlIHRvIGNoYW5nZSB0byBPcGVuR0wsCiAgICAgICAgICAgICAqIGFuZCByZS1jcmVhdGUgYWxsIFdpbmVEM0RTdXJmYWNlcwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSW1wbFR5cGUgPSBTVVJGQUNFX09QRU5HTDsKICAgICAgICAgICAgVGhpcy0+SW1wbFR5cGUgPSBJbXBsVHlwZTsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgUmUtY3JlYXRpbmcgYWxsIHN1cmZhY2VzXG4iLCBUaGlzKTsKICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlQWxsU3VyZmFjZXMoVGhpcyk7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIERvbmUgcmVjcmVhdGluZyBhbGwgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMICYmIHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfM0RERVZJQ0UpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJUaGUgYXBwbGljYXRpb24gcmVxdWVzdHMgYSAzRCBjYXBhYmxlIHN1cmZhY2UsIGJ1dCBhIG5vbi1vcGVuZ2wgc3VyZmFjZSB3YXMgc2V0IGluIHRoZSByZWdpc3RyeVxuIik7CiAgICAgICAgICAgIC8qIERvIG5vdCBmYWlsIHN1cmZhY2UgY3JlYXRpb24sIG9ubHkgZmFpbCAzRCBkZXZpY2UgY3JlYXRpb24gKi8KICAgICAgICB9CiAgICB9CgogICAgLyogR2V0IHRoZSBjb3JyZWN0IHdpbmVkM2QgdXNhZ2UgKi8KICAgIGlmIChwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfQkFDS0JVRkZFUiAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTXzNEREVWSUNFICAgICAgICkgKQogICAgewogICAgICAgIFVzYWdlIHw9IFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQ7CgogICAgICAgIHBERFNELT5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX1ZJREVPTUVNT1JZIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19WSVNJQkxFOwogICAgfQogICAgaWYgKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX09WRVJMQVkpKQogICAgewogICAgICAgIFVzYWdlIHw9IFdJTkVEM0RVU0FHRV9PVkVSTEFZOwogICAgfQogICAgaWYoVGhpcy0+ZGVwdGhzdGVuY2lsIHx8IChwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1pCVUZGRVIpICkKICAgIHsKICAgICAgICAvKiBUaGUgZGVwdGggc3RlbmNpbCBjcmVhdGlvbiBjYWxsYmFjayBzZXRzIHRoaXMgZmxhZy4KICAgICAgICAgKiBTZXQgdGhlIFdpbmVEM0QgdXNhZ2UgdG8gbGV0IGl0IGtub3cgdGhhdCBpdCdzIGEgZGVwdGgKICAgICAgICAgKiBTdGVuY2lsIHN1cmZhY2UuCiAgICAgICAgICovCiAgICAgICAgVXNhZ2UgfD0gV0lORUQzRFVTQUdFX0RFUFRIU1RFTkNJTDsKICAgIH0KICAgIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfU1lTVEVNTUVNT1JZKQogICAgewogICAgICAgIFBvb2wgPSBXSU5FRDNEUE9PTF9TWVNURU1NRU07CiAgICB9CiAgICBlbHNlIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9URVhUVVJFTUFOQUdFKQogICAgewogICAgICAgIFBvb2wgPSBXSU5FRDNEUE9PTF9NQU5BR0VEOwogICAgICAgIC8qIE1hbmFnZWQgdGV4dHVyZXMgaGF2ZSB0aGUgc3lzdGVtIG1lbW9yeSBmbGFnIHNldCAqLwogICAgICAgIHBERFNELT5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX1NZU1RFTU1FTU9SWTsKICAgIH0KICAgIGVsc2UgaWYocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19WSURFT01FTU9SWSkKICAgIHsKICAgICAgICAvKiBWaWRlb21lbW9yeSBhZGRzIGxvY2FsdmlkbWVtLCB0aGlzIGlzIG11dHVhbGx5IGV4Y2x1c2l2ZSB3aXRoIHN5c3RlbW1lbW9yeQogICAgICAgICAqIGFuZCB0ZXh0dXJlbWFuYWdlCiAgICAgICAgICovCiAgICAgICAgcEREU0QtPmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfTE9DQUxWSURNRU07CiAgICB9CgogICAgRm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmcEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdCk7CiAgICBpZihGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKQogICAgewogICAgICAgIEVSUigiVW5zdXBwb3J0ZWQgLyBVbmtub3duIHBpeGVsZm9ybWF0XG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBJWEVMRk9STUFUOwogICAgfQoKICAgIC8qIENyZWF0ZSB0aGUgU3VyZmFjZSBvYmplY3QgKi8KICAgICpwcFN1cmYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElEaXJlY3REcmF3U3VyZmFjZUltcGwpKTsKICAgIGlmKCEqcHBTdXJmKQogICAgewogICAgICAgIEVSUigiKCVwKSBFcnJvciBhbGxvY2F0aW5nIG1lbW9yeSBmb3IgYSBzdXJmYWNlXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZWSURFT01FTU9SWTsKICAgIH0KICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNywgSURpcmVjdERyYXdTdXJmYWNlN19WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdERyYXdTdXJmYWNlMywgSURpcmVjdERyYXdTdXJmYWNlM19WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdERyYXdHYW1tYUNvbnRyb2wsIElEaXJlY3REcmF3R2FtbWFDb250cm9sX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0M0RUZXh0dXJlMiwgSURpcmVjdDNEVGV4dHVyZTJfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3QzRFRleHR1cmUsIElEaXJlY3QzRFRleHR1cmUxX1Z0YmwpOwogICAgKCpwcFN1cmYpLT5yZWYgPSAxOwogICAgKCpwcFN1cmYpLT52ZXJzaW9uID0gNzsKICAgICgqcHBTdXJmKS0+ZGRyYXcgPSBUaGlzOwogICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MuZHdTaXplID0gc2l6ZW9mKEREU1VSRkFDRURFU0MyKTsKICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERQSVhFTEZPUk1BVCk7CiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoJigqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLCBwRERTRCk7CgogICAgLyogU3VyZmFjZSBhdHRhY2htZW50cyAqLwogICAgKCpwcFN1cmYpLT5uZXh0X2F0dGFjaGVkID0gTlVMTDsKICAgICgqcHBTdXJmKS0+Zmlyc3RfYXR0YWNoZWQgPSAqcHBTdXJmOwoKICAgIC8qIE5lZWRlZCB0byByZS1jcmVhdGUgdGhlIHN1cmZhY2Ugb24gYW4gaW1wbGVtZW50YXRpb24gY2hhbmdlICovCiAgICAoKnBwU3VyZiktPkltcGxUeXBlID0gSW1wbFR5cGU7CgogICAgLyogRm9yIEQzRERldmljZSBjcmVhdGlvbiAqLwogICAgKCpwcFN1cmYpLT5pc1JlbmRlclRhcmdldCA9IEZBTFNFOwoKICAgIC8qIEEgdHJhY2UgbWVzc2FnZSBmb3IgZGVidWdnaW5nICovCiAgICBUUkFDRSgiKCVwKSBDcmVhdGVkIElEaXJlY3REcmF3U3VyZmFjZSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUgYXQgJXBcbiIsIFRoaXMsICpwcFN1cmYpOwoKICAgIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmICggRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfVEVYVFVSRSB8IEREU0NBUFNfM0RERVZJQ0UpICkKICAgIHsKICAgICAgICAvKiBSZW5kZXIgdGFyZ2V0cyBhbmQgdGV4dHVyZXMgbmVlZCBhIElQYXJlbnQgaW50ZXJmYWNlLAogICAgICAgICAqIGJlY2F1c2UgV2luZUQzRCB3aWxsIGRlc3Ryb3kgdGhlbSB3aGVuIHRoZSBzd2FwY2hhaW4KICAgICAgICAgKiBpcyByZWxlYXNlZAogICAgICAgICAqLwogICAgICAgIHBhckltcGwgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKElQYXJlbnRJbXBsKSk7CiAgICAgICAgaWYoIXBhckltcGwpCiAgICAgICAgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBhbGxvY2F0aW5nIG1lbW9yeSBmb3IgYSBJUGFyZW50IGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgICAgICBwYXJJbXBsLT5yZWYgPSAxOwogICAgICAgIElDT01fSU5JVF9JTlRFUkZBQ0UocGFySW1wbCwgSVBhcmVudCwgSVBhcmVudF9WdGJsKTsKICAgICAgICBQYXJlbnQgPSAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UocGFySW1wbCwgSVBhcmVudCk7CiAgICAgICAgVFJBQ0UoIlVzaW5nIElQYXJlbnQgaW50ZXJmYWNlICVwIGFzIHBhcmVudFxuIiwgcGFySW1wbCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogVXNlIHRoZSBzdXJmYWNlIGFzIHBhcmVudCAqLwogICAgICAgIFBhcmVudCA9IChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKICAgICAgICBUUkFDRSgiVXNpbmcgU3VyZmFjZSBpbnRlcmZhY2UgJXAgYXMgcGFyZW50XG4iLCAqcHBTdXJmKTsKICAgIH0KCiAgICAvKiBOb3cgY3JlYXRlIHRoZSBXaW5lRDNEIFN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlU3VyZmFjZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBERFNELT5kd1dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBERFNELT5kd0hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBEaXNjYXJkICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc1R5cGUsIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRE1VTFRJU0FNUExFX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBNdWx0aVNhbXBsZVF1YWxpdHkgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBTaGFyZWRIYW5kbGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1wbFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyZW50KTsKCiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6Q3JlYXRlU3VyZmFjZSBmYWlsZWQuIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBTZXQgdGhlIGNoaWxkIG9mIHRoZSBwYXJlbnQgaW1wbGVtZW50YXRpb24gaWYgaXQgZXhpc3RzICovCiAgICBpZihwYXJJbXBsKQogICAgewogICAgICAgIHBhckltcGwtPmNoaWxkID0gKElVbmtub3duICopICgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2U7CiAgICAgICAgLyogVGhlIElQYXJlbnQgcmVsZWFzZXMgdGhlIFdpbmVEM0RTdXJmYWNlLCBhbmQKICAgICAgICAgKiB0aGUgZGRyYXcgc3VyZmFjZSBkb2VzIHRoYXQgdG9vLiBIb2xkIGEgcmVmZXJlbmNlCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZigoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlKTsKICAgIH0KCiAgICAvKiBJbmNyZWFzZSB0aGUgc3VyZmFjZSBjb3VudGVyLCBhbmQgYXR0YWNoIHRoZSBzdXJmYWNlICovCiAgICBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+c3VyZmFjZXMpOwogICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+c3VyZmFjZV9saXN0LCAmKCpwcFN1cmYpLT5zdXJmYWNlX2xpc3RfZW50cnkpOwoKICAgIC8qIEhlcmUgd2UgY291bGQgc3RvcmUgYWxsIGNyZWF0ZWQgc3VyZmFjZXMgaW4gdGhlIERpcmVjdERyYXdJbXBsIHN0cnVjdHVyZSwKICAgICAqIEJ1dCB0aGlzIGNvdWxkIGFsc28gYmUgZGVsZWdhdGVkIHRvIFdpbmVERHJhdywgYXMgaXQga2VlcHMgdHJhY2sgb2YgYWxsIGl0cwogICAgICogcmVzb3VyY2VzLiBOb3QgaW1wbGVtZW50ZWQgZm9yIG5vdywgYXMgdGhlcmUgYXJlIG1vcmUgaW1wb3J0YW50IHRoaW5ncyA7KQogICAgICovCgogICAgLyogR2V0IHRoZSBwaXhlbCBmb3JtYXQgb2YgdGhlIFdpbmVEM0RTdXJmYWNlIGFuZCBzdG9yZSBpdC4KICAgICAqIERvbid0IHVzZSB0aGUgRm9ybWF0IGNob29zZW4gYWJvdmUsIFdpbmVEM0QgbWlnaHQgaGF2ZQogICAgICogY2hhbmdlZCBpdAogICAgICovCiAgICBEZXNjLkZvcm1hdCA9ICZGb3JtYXQ7CiAgICBEZXNjLlR5cGUgPSAmUmVzVHlwZTsKICAgIERlc2MuVXNhZ2UgPSAmVXNhZ2U7CiAgICBEZXNjLlBvb2wgPSAmZHVtbXlfZDNkcG9vbDsKICAgIERlc2MuU2l6ZSA9ICZkdW1teV91aW50OwogICAgRGVzYy5NdWx0aVNhbXBsZVR5cGUgPSAmZHVtbXlfbXN0OwogICAgRGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSAmZHVtbXlfZHdvcmQ7CiAgICBEZXNjLldpZHRoID0gJldpZHRoOwogICAgRGVzYy5IZWlnaHQgPSAmSGVpZ2h0OwoKICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9QSVhFTEZPUk1BVDsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERlc2MoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwgJkRlc2MpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0RTdXJmYWNlOjpHZXREZXNjIGZhaWxlZFxuIik7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKCAoSURpcmVjdERyYXdTdXJmYWNlNyAqKSAqcHBTdXJmKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoRm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikKICAgIHsKICAgICAgICBGSVhNRSgiSVdpbmVEM0RTdXJmYWNlOjpHZXREZXNjIHJldHVybmVkIFdJTkVEM0RGTVRfVU5LTk9XTlxuIik7CiAgICB9CiAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCggJigqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdCwgRm9ybWF0KTsKCiAgICAvKiBBbm5vIDE2MDIgc3RvcmVzIHRoZSBwaXRjaCByaWdodCBhZnRlciBzdXJmYWNlIGNyZWF0aW9uLCBzbyBtYWtlIHN1cmUgaXQncyB0aGVyZS4KICAgICAqIEkgY2FuJ3QgTG9ja1JlY3QoKSB0aGUgc3VyZmFjZSBoZXJlIGJlY2F1c2UgaWYgT3BlbkdMIHN1cmZhY2VzIGFyZSBpbiB1c2UsIHRoZQogICAgICogV2luZUQzRERldmljZSBtaWdodCBub3QgYmUgdXNlYWJsZSBmb3IgM0QgeWV0LCBzbyBhbiBleHRyYSBtZXRob2Qgd2FzIGNyZWF0ZWQuCiAgICAgKiBUT0RPOiBUZXN0IG90aGVyIGZvdXJjYyBmb3JtYXRzCiAgICAgKi8KICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpCiAgICB7CiAgICAgICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX0xJTkVBUlNJWkU7CiAgICAgICAgaWYoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkKICAgICAgICB7CiAgICAgICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnUxLmR3TGluZWFyU2l6ZSA9IG1heCg0LCBXaWR0aCkgKiBtYXgoNCwgSGVpZ2h0KSAvIDI7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnUxLmR3TGluZWFyU2l6ZSA9IG1heCg0LCBXaWR0aCkgKiBtYXgoNCwgSGVpZ2h0KTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX1BJVENIOwogICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnUxLmxQaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlKTsKICAgIH0KCiAgICAvKiBBcHBsaWNhdGlvbiBwYXNzZWQgYSBjb2xvciBrZXk/IFNldCBpdCEgKi8KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS0RFU1RPVkVSTEFZKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVE9WRVJMQVksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERDT0xPUktFWSAqKSAmcEREU0QtPnUzLmRkY2tDS0Rlc3RPdmVybGF5KTsKICAgIH0KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS0RFU1RCTFQpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9ERVNUQkxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJnBERFNELT5kZGNrQ0tEZXN0Qmx0KTsKICAgIH0KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS1NSQ09WRVJMQVkpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJnBERFNELT5kZGNrQ0tTcmNPdmVybGF5KTsKICAgIH0KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS1NSQ0JMVCkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX1NSQ0JMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZwRERTRC0+ZGRja0NLU3JjQmx0KTsKICAgIH0KICAgIGlmICggcEREU0QtPmR3RmxhZ3MgJiBERFNEX0xQU1VSRkFDRSkKICAgIHsKICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9TZXRNZW0oKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwgcEREU0QtPmxwU3VyZmFjZSk7CiAgICAgICAgaWYoaHIgIT0gV0lORUQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIG5lZWQgZm9yIGEgdHJhY2UgaGVyZSwgd2luZWQzZCBkb2VzIHRoYXQgZm9yIHVzICovCiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRSgoKnBwU3VyZiksIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcwogKgogKiBDcmVhdGVzIGEgbmV3IG1pcG1hcCBjaGFpbi4KICoKICogUGFyYW1zOgogKiAgcm9vdDogUm9vdCBzdXJmYWNlIHRvIGF0dGFjaCB0aGUgbmV3bHkgY3JlYXRlZCBjaGFpbiB0bwogKiAgY291bnQ6IG51bWJlciBvZiBzdXJmYWNlcyB0byBjcmVhdGUKICogIEREU0Q6IERlc2NyaXB0aW9uIG9mIHRoZSBzdXJmYWNlLiBJbnRlbnRpb25hbGx5IG5vdCBhIHBvaW50ZXIgdG8gYXZvaWQgc2lkZQogKiAgICAgICAgZWZmZWN0cyBvbiB0aGUgY2FsbGVyCiAqICBDdWJlRmFjZVJvb3Q6IFdldGhlciB0aGUgbmV3IHN1cmZhY2UgaXMgYSByb290IG9mIGEgY3ViZSBtYXAgZmFjZS4gVGhpcwogKiAgICAgICAgICAgICAgICBjcmVhdGVzIGFuIGFkZGl0aW9uYWwgc3VyZmFjZSB3aXRob3V0IHRoZSBtaXBtYXBwaW5nIGZsYWdzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKElEaXJlY3REcmF3SW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnJvb3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIGNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgQ3ViZUZhY2VSb290KQp7CiAgICBVSU5UIGksIGosIGxldmVsID0gMDsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpsYXN0ID0gcm9vdDsKCiAgICBmb3IoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKm9iamVjdDIgPSBOVUxMOwoKICAgICAgICAvKiBpbmNyZWFzZSB0aGUgbWlwbWFwIGxldmVsLCBidXQgb25seSBpZiBhIG1pcG1hcCBpcyBjcmVhdGVkCiAgICAgICAgICogSW4gdGhpcyBjYXNlLCBhbHNvIGhhbHZlIHRoZSBzaXplCiAgICAgICAgICovCiAgICAgICAgaWYoRERTRC5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQICYmICFDdWJlRmFjZVJvb3QpCiAgICAgICAgewogICAgICAgICAgICBsZXZlbCsrOwogICAgICAgICAgICBpZihERFNELmR3V2lkdGggPiAxKSBERFNELmR3V2lkdGggLz0gMjsKICAgICAgICAgICAgaWYoRERTRC5kd0hlaWdodCA+IDEpIEREU0QuZHdIZWlnaHQgLz0gMjsKICAgICAgICAgICAgLyogU2V0IHRoZSBtaXBtYXAgc3VibGV2ZWwgZmxhZyBhY2NvcmRpbmcgdG8gbXNkbiAqLwogICAgICAgICAgICBERFNELmRkc0NhcHMuZHdDYXBzMiB8PSBERFNDQVBTMl9NSVBNQVBTVUJMRVZFTDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgRERTRC5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgICAgIH0KICAgICAgICBDdWJlRmFjZVJvb3QgPSBGQUxTRTsKCiAgICAgICAgaHIgPSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsKTsKICAgICAgICBpZihociAhPSBERF9PSykKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CgogICAgICAgIC8qIEFkZCB0aGUgbmV3IHN1cmZhY2UgdG8gdGhlIGNvbXBsZXggYXR0YWNobWVudCBhcnJheSAqLwogICAgICAgIGZvcihqID0gMDsgaiA8IE1BWF9DT01QTEVYX0FUVEFDSEVEOyBqKyspCiAgICAgICAgewogICAgICAgICAgICBpZihsYXN0LT5jb21wbGV4X2FycmF5W2pdKSBjb250aW51ZTsKICAgICAgICAgICAgbGFzdC0+Y29tcGxleF9hcnJheVtqXSA9IG9iamVjdDI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBsYXN0ID0gb2JqZWN0MjsKCiAgICAgICAgLyogUmVtb3ZlIHRoZSAocG9zc2libGUpIGJhY2sgYnVmZmVyIGNhcCBmcm9tIHRoZSBuZXcgc3VyZmFjZSBkZXNjcmlwdGlvbiwKICAgICAgICAgKiBiZWNhdXNlIG9ubHkgb25lIHN1cmZhY2UgaW4gdGhlIGZsaXBwaW5nIGNoYWluIGlzIGEgYmFjayBidWZmZXIsIG9uZQogICAgICAgICAqIGlzIGEgZnJvbnQgYnVmZmVyLCB0aGUgb3RoZXJzIGFyZSBqdXN0IHByaW1hcnkgc3VyZmFjZXMuCiAgICAgICAgICovCiAgICAgICAgRERTRC5kZHNDYXBzLmR3Q2FwcyAmPSB+RERTQ0FQU19CQUNLQlVGRkVSOwogICAgfQogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDcmVhdGVTdXJmYWNlCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURpcmVjdERyYXdTdXJmYWNlIG9iamVjdCBhbmQgcmV0dXJucyBpdHMgaW50ZXJmYWNlLgogKgogKiBUaGUgc3VyZmFjZSBjb25uZWN0aW9ucyB3aXRoIHdpbmVkM2QgYXJlIGEgYml0IHRyaWNreS4gQmFzaWNhbGx5IGl0IHdvcmtzCiAqIGxpa2UgdGhpczoKICoKICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18CiAqIHwgRERyYXcgc3VyZmFjZSAgICAgICAgICB8ICAgICAgICAgICAgICAgfCBXaW5lRDNEU3VyZmFjZSAgfAogKiB8ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgV2luZUQzRFN1cmZhY2UgIHwtLS0tLS0tLS0tLS0tLT58ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgIENoaWxkICAgICAgICAgICB8PC0tLS0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfAogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwKICoKICogVGhlIEREcmF3IHN1cmZhY2UgaXMgdGhlIHBhcmVudCBvZiB0aGUgd2luZWQzZCBzdXJmYWNlLCBhbmQgaXQgcmVsZWFzZXMKICogdGhlIFdpbmVEM0RTdXJmYWNlIHdoZW4gdGhlIGRkcmF3IHN1cmZhY2UgaXMgZGVzdHJveWVkLgogKgogKiBIb3dldmVyLCBmb3IgYWxsIHN1cmZhY2VzIHdoaWNoIGNhbiBiZSBpbiBhIGNvbnRhaW5lciBpbiBXaW5lRDNELAogKiB3ZSBoYXZlIHRvIGRvIHRoaXMuIFRoZXNlIHN1cmZhY2VzIGFyZSB1c3VzYWxseSBjb21wbGV4IHN1cmZhY2VzLAogKiBzbyB0aGlzIGNvbmNlcm5zIHByaW1hcnkgc3VyZmFjZXMgd2l0aCBhIGZyb250IGFuZCBhIGJhY2sgYnVmZmVyLAogKiBhbmQgdGV4dHVyZXMuCiAqCiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfAogKiB8IEREcmF3IHN1cmZhY2UgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgQ29udGFpbnRlciAgICAgIHwKICogfCAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgICAgICAgICAgICBDaGlsZCB8PC0tLS0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfAogKiB8ICAgICAgICAgICAgICAgIFRleHR1cmUgfDwtLS0tLS0tLS0tLS0tPnwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgIFdpbmVEM0RTdXJmYWNlIHw8LS0tLXwgICAgICAgICB8ICAgICAgICAgIExldmVscyB8PC0tfAogKiB8IENvbXBsZXggY29ubmVjdGlvbiAgICAgfCAgICAgfCAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwgICB8CiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIF4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgfCAgICB8IElQYXJlbnQgICAgICAgICAgfCAgICAgfC0tLS0tLS0tPnwgV2luZUQzRFN1cmZhY2UgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgIENoaWxkIHw8LS0tLS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgQ29udGFpbmVyIHw8LS18CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCBERHJhdyBzdXJmYWNlIDIgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfDwtPnwgQ29tcGxleCByb290ICAgQ2hpbGQgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCAgICAgICAgICAgICAgVGV4dHVyZSB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8ICAgICAgIFdpbmVEM0RTdXJmYWNlIHw8LS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgfCAgICB8IElQYXJlbnQgICAgICAgICAgICAgfCAgICAgfC0tLS0tPnwgV2luZUQzRFN1cmZhY2UgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgICAgIENoaWxkIHw8LS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8ICAgfAogKiAgfCAgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgIHwgICAgICAgQ29udGFpbmVyIHw8LS18CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAtLS1Nb3JlIHN1cmZhY2VzIGNhbiBmb2xsb3ctLS0gICAgICAgICAgICAgICAgICB8CiAqCiAqIFRoZSByZWFzb24gaXMgdGhhdCB0aGUgSVdpbmVEM0RTd2FwY2hhaW4ocmVuZGVyIHRhcmdldCBjb250YWluZXIpCiAqIGFuZCB0aGUgSVdpbmVEM0RUZXh1cmUoVGV4dHVyZSBjb250YWluZXIpIHJlbGVhc2UgdGhlIHBhcmVudHMKICogb2YgdGhlaXIgc3VyZmFjZSdzIGNoaWxkcmVuLCBidXQgYnkgcmVsZWFzaW5nIHRoZSBjb21wbGV4IHJvb3QKICogdGhlIHN1cmZhY2VzIHdoaWNoIGFyZSBjb21wbGV4bHkgYXR0YWNoZWQgdG8gaXQgYXJlIGRlc3Ryb3llZAogKiB0b28uIFNlZSBJRGlyZWN0RHJhd1N1cmZhY2U6OlJlbGVhc2UgZm9yIGEgbW9yZSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbi4KICoKICogUGFyYW1zOgogKiAgRERTRDogRGVzY3JpcHRpb24gb2YgdGhlIHN1cmZhY2UgdG8gY3JlYXRlCiAqICBTdXJmOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBhdAogKiAgVW5rT3V0ZXI6IEJhc2ljYWxseSBmb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgYnV0IGRkcmF3IGRvZXNuJ3Qgc3VwcG9ydAogKiAgICAgICAgICAgIGFnZ3JlZ2F0aW9uLCBzbyBpdCBoYXMgdG8gYmUgTlVMTAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyICE9IE5VTEwKICogIERERVJSXyogaWYgYW4gZXJyb3Igb2NjdXJzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqb2JqZWN0ID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBMT05HIGV4dHJhX3N1cmZhY2VzID0gMDsKICAgIEREU1VSRkFDRURFU0MyIGRlc2MyOwogICAgV0lORUQzRERJU1BMQVlNT0RFIE1vZGU7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcClcbiIsIFRoaXMsIEREU0QsIFN1cmYsIFVua091dGVyKTsKCiAgICAvKiBTb21lIGNoZWNrcyBiZWZvcmUgd2Ugc3RhcnQgKi8KICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICB7CiAgICAgICAgVFJBQ0UoIiAoJXApIFJlcXVlc3Rpbmcgc3VyZmFjZSBkZXNjIDpcbiIsIFRoaXMpOwogICAgICAgIEREUkFXX2R1bXBfc3VyZmFjZV9kZXNjKEREU0QpOwogICAgfQoKICAgIGlmIChVbmtPdXRlciAhPSBOVUxMKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIDogb3V0ZXIgIT0gTlVMTD9cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047IC8qIHVuY2hlY2tlZCAqLwogICAgfQoKICAgIGlmIChTdXJmID09IE5VTEwpCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgWW91IHdhbnQgdG8gZ2V0IGJhY2sgYSBzdXJmYWNlPyBEb24ndCBnaXZlIE5VTEwgcHRycyFcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBFX1BPSU5URVI7IC8qIHVuY2hlY2tlZCAqLwogICAgfQoKICAgIGlmICghKEREU0QtPmR3RmxhZ3MgJiBERFNEX0NBUFMpKQogICAgewogICAgICAgIC8qIERWSURFTy5ETEwgZG9lcyBmb3JnZXQgdGhlIEREU0RfQ0FQUyBmbGFnIC4uLiAqc2lnaCogKi8KICAgICAgICBERFNELT5kd0ZsYWdzIHw9IEREU0RfQ0FQUzsKICAgIH0KICAgIGlmIChERFNELT5kZHNDYXBzLmR3Q2FwcyA9PSAwKQogICAgewogICAgICAgIC8qIFRoaXMgaGFzIGJlZW4gY2hlY2tlZCBvbiByZWFsIFdpbmRvd3MgKi8KICAgICAgICBERFNELT5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfTE9DQUxWSURNRU0gfCBERFNDQVBTX1ZJREVPTUVNT1JZOwogICAgfQoKICAgIGlmIChERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfQUxMT0NPTkxPQUQpCiAgICB7CiAgICAgICAgLyogSWYgdGhlIHN1cmZhY2UgaXMgb2YgdGhlICdhbGxvY29ubG9hZCcgdHlwZSwgaWdub3JlIHRoZSBMUFNVUkZBQ0UgZmllbGQgKi8KICAgICAgICBERFNELT5kd0ZsYWdzICY9IH5ERFNEX0xQU1VSRkFDRTsKICAgIH0KCiAgICBpZiAoKEREU0QtPmR3RmxhZ3MgJiBERFNEX0xQU1VSRkFDRSkgJiYgKEREU0QtPmxwU3VyZmFjZSA9PSBOVUxMKSkKICAgIHsKICAgICAgICAvKiBGcmFuayBIZXJiZXJ0J3MgRHVuZSBzcGVjaWZpZXMgYSBudWxsIHBvaW50ZXIgZm9yIHRoZSBzdXJmYWNlLCBpZ25vcmUgdGhlIExQU1VSRkFDRSBmaWVsZCAqLwogICAgICAgIFdBUk4oIiglcCkgTnVsbCBzdXJmYWNlIHBvaW50ZXIgc3BlY2lmaWVkLCBpZ25vcmUgaXQhXG4iLCBUaGlzKTsKICAgICAgICBERFNELT5kd0ZsYWdzICY9IH5ERFNEX0xQU1VSRkFDRTsKICAgIH0KCiAgICBpZigoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19GTElQIHwgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkpID09IChERFNDQVBTX0ZMSVAgfCBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSAmJgogICAgICAgIShUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IEF0dGVtcHQgdG8gY3JlYXRlIGEgZmxpcGFibGUgcHJpbWFyeSBzdXJmYWNlIHdpdGhvdXQgRERTQ0xfRVhDTFVTSVZFIHNldFxuIiwgVGhpcyk7CiAgICAgICAgKlN1cmYgPSBOVUxMOwogICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICB9CgogICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19GUk9OVEJVRkZFUiB8IEREU0NBUFNfQkFDS0JVRkZFUikpIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiB0cmllZCB0byBjcmVhdGUgYW4gZXhwbGljaXQgZnJvbnQgb3IgYmFjayBidWZmZXJcbiIpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEQ0FQUzsKICAgIH0KICAgIC8qIENoZWNrIGN1YmUgbWFwcyBidXQgb25seSBpZiB0aGUgc2l6ZSBpbmNsdWRlcyB0aGVtICovCiAgICBpZiAoRERTRC0+ZHdTaXplID49IHNpemVvZihERFNVUkZBQ0VERVNDMikpCiAgICB7CiAgICAgICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUyAmJgogICAgICAgICAgICEoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCkpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJDdWJlIG1hcCBmYWNlcyByZXF1ZXN0ZWQgd2l0aG91dCBjdWJlIG1hcCBmbGFnXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURDQVBTOwogICAgICAgIH0KICAgICAgICBpZihERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQICYmCiAgICAgICAgICAgKEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVBfQUxMRkFDRVMpID09IDApCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJDdWJlIG1hcCB3aXRob3V0IGZhY2VzIHJlcXVlc3RlZFxuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KCiAgICAgICAgLyogUXVpY2sgdGVzdHMgY29uZmlybSB0aG9zZSBjYW4gYmUgY3JlYXRlZCwgYnV0IHdlIGRvbid0IGRvIHRoYXQgeWV0ICovCiAgICAgICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCAmJgogICAgICAgICAgIChERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQX0FMTEZBQ0VTKSAhPSBERFNDQVBTMl9DVUJFTUFQX0FMTEZBQ0VTKQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIlBhcnRpYWwgY3ViZSBtYXBzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQWNjb3JkaW5nIHRvIHRoZSBtc2RuIHRoaXMgZmxhZyBpcyBpZ25vcmVkIGJ5IENyZWF0ZVN1cmZhY2UgKi8KICAgIGlmIChERFNELT5kd1NpemUgPj0gc2l6ZW9mKEREU1VSRkFDRURFU0MyKSkKICAgICAgICBERFNELT5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwoKICAgIC8qIE1vZGlmeSBzb21lIGZsYWdzICovCiAgICBtZW1zZXQoJmRlc2MyLCAwLCBzaXplb2YoZGVzYzIpKTsKICAgIGRlc2MyLmR3U2l6ZSA9IHNpemVvZihkZXNjMik7ICAgLyogRm9yIHRoZSBzdHJ1Y3QgY29weSAqLwogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKCZkZXNjMiwgRERTRCk7CiAgICBkZXNjMi5kd1NpemUgPSBzaXplb2YoZGVzYzIpOyAgIC8qIFRvIG92ZXJyaWRlIGEgcG9zc2libHkgc21hbGxlciBzaXplICovCiAgICBkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplPXNpemVvZihERFBJWEVMRk9STUFUKTsgLyogSnVzdCB0byBiZSBzdXJlICovCgogICAgLyogR2V0IHRoZSB2aWRlbyBtb2RlIGZyb20gV2luZUQzRCAtIHdlIHdpbGwgbmVlZCBpdCAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBTd2FwY2hhaW4gMCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIHJlYWQgZGlzcGxheSBtb2RlIGZyb20gd2luZWQzZFxuIik7CiAgICAgICAgc3dpdGNoKFRoaXMtPm9yaWdfYnBwKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSA4OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1A4OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1gxUjVHNUI1OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I1RzZCNTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAyNDoKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SOEc4Qjg7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMzI6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDhSOEc4Qjg7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgTW9kZS5XaWR0aCA9IFRoaXMtPm9yaWdfd2lkdGg7CiAgICAgICAgTW9kZS5IZWlnaHQgPSBUaGlzLT5vcmlnX2hlaWdodDsKICAgIH0KCiAgICAvKiBObyBwaXhlbGZvcm1hdCBnaXZlbj8gVXNlIHRoZSBjdXJyZW50IHNjcmVlbiBmb3JtYXQgKi8KICAgIGlmKCEoZGVzYzIuZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpKQogICAgewogICAgICAgIGRlc2MyLmR3RmxhZ3MgfD0gRERTRF9QSVhFTEZPUk1BVDsKICAgICAgICBkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplPXNpemVvZihERFBJWEVMRk9STUFUKTsKCiAgICAgICAgLyogV2FpdDogSXQgY291bGQgYmUgYSBaIGJ1ZmZlciAqLwogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19aQlVGRkVSKQogICAgICAgIHsKICAgICAgICAgICAgc3dpdGNoKGRlc2MyLnUyLmR3TWlwTWFwQ291bnQpIC8qIFdobyBoYWQgdGhpcyBnbG9yaW91cyBpZGVhPyAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYXNlIDE1OgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDE1UzEpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAxNjoKICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBXSU5FRDNERk1UX0QxNik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDI0OgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDI0WDgpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGVzYzIudTQuZGRwZlBpeGVsRm9ybWF0LCBXSU5FRDNERk1UX0QzMik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIEVSUigiVW5rbm93biBaIGJ1ZmZlciBiaXQgZGVwdGhcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIE1vZGUuRm9ybWF0KTsKICAgICAgICB9CiAgICB9CgogICAgLyogTm8gV2lkdGggb3Igbm8gSGVpZ2h0PyBVc2UgdGhlIG9yaWdpbmFsIHNjcmVlbiBzaXplCiAgICAgKi8KICAgIGlmKCEoZGVzYzIuZHdGbGFncyAmIEREU0RfV0lEVEgpIHx8CiAgICAgICAhKGRlc2MyLmR3RmxhZ3MgJiBERFNEX0hFSUdIVCkgKQogICAgewogICAgICAgIC8qIEludmFsaWQgZm9yIG5vbi1yZW5kZXIgdGFyZ2V0cyAqLwogICAgICAgIGlmKCEoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkNyZWF0aW5nIGEgbm9uLVByaW1hcnkgc3VyZmFjZSB3aXRob3V0IFdpZHRoIG9yIEhlaWdodCBpbmZvLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgICAgICpTdXJmID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQoKICAgICAgICBkZXNjMi5kd0ZsYWdzIHw9IEREU0RfV0lEVEggfCBERFNEX0hFSUdIVDsKICAgICAgICBkZXNjMi5kd1dpZHRoID0gTW9kZS5XaWR0aDsKICAgICAgICBkZXNjMi5kd0hlaWdodCA9IE1vZGUuSGVpZ2h0OwogICAgfQoKICAgIC8qIE1pcG1hcCBjb3VudCBmaXhlcyAqLwogICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgIHsKICAgICAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfQ09NUExFWCkKICAgICAgICB7CiAgICAgICAgICAgIGlmKGRlc2MyLmR3RmxhZ3MgJiBERFNEX01JUE1BUENPVU5UKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBNaXBtYXAgY291bnQgaXMgZ2l2ZW4sIG5vdGhpbmcgdG8gZG8gKi8KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIFVuZG9jdW1lbnRlZCBmZWF0dXJlOiBDcmVhdGUgc3VibGV2ZWxzIHVudGlsCiAgICAgICAgICAgICAgICAgKiBlaXRoZXIgdGhlIHdpZHRoIG9yIHRoZSBoZWlnaHQgaXMgMQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBEV09SRCBtaW4gPSBkZXNjMi5kd1dpZHRoIDwgZGVzYzIuZHdIZWlnaHQgPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzYzIuZHdXaWR0aCA6IGRlc2MyLmR3SGVpZ2h0OwogICAgICAgICAgICAgICAgZGVzYzIudTIuZHdNaXBNYXBDb3VudCA9IDA7CiAgICAgICAgICAgICAgICB3aGlsZSggbWluICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkZXNjMi51Mi5kd01pcE1hcENvdW50ICs9IDE7CiAgICAgICAgICAgICAgICAgICAgbWluID4+PSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vdC1jb21wbGV4IG1pcG1hcCAtPiBNaXBtYXBjb3VudCA9IDEgKi8KICAgICAgICAgICAgZGVzYzIudTIuZHdNaXBNYXBDb3VudCA9IDE7CiAgICAgICAgfQogICAgICAgIGV4dHJhX3N1cmZhY2VzID0gZGVzYzIudTIuZHdNaXBNYXBDb3VudCAtIDE7CgogICAgICAgIC8qIFRoZXJlJ3MgYSBtaXBtYXAgY291bnQgaW4gdGhlIGNyZWF0ZWQgc3VyZmFjZSBpbiBhbnkgY2FzZSAqLwogICAgICAgIGRlc2MyLmR3RmxhZ3MgfD0gRERTRF9NSVBNQVBDT1VOVDsKICAgIH0KICAgIC8qIElmIG5vIG1pcG1hcCBpcyBnaXZlbiwgdGhlIHRleHR1cmUgaGFzIG9ubHkgb25lIGxldmVsICovCgogICAgLyogVGhlIGZpcnN0IHN1cmZhY2UgaXMgYSBmcm9udCBidWZmZXIsIHRoZSBiYWNrIGJ1ZmZlciBpcyBjcmVhdGVkIGFmdGVyd2FyZHMgKi8KICAgIGlmKCAoZGVzYzIuZHdGbGFncyAmIEREU0RfQ0FQUykgJiYgKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkgKQogICAgewogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfRlJPTlRCVUZGRVI7CiAgICB9CgogICAgLyogVGhlIHJvb3Qgc3VyZmFjZSBpbiBhIGN1YmUgbWFwIGlzIHBvc2l0aXZlIHggKi8KICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVApCiAgICB7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9DVUJFTUFQX0FMTEZBQ0VTOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVg7CiAgICB9CgogICAgLyogQ3JlYXRlIHRoZSBmaXJzdCBzdXJmYWNlICovCiAgICBociA9IElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlKFRoaXMsICZkZXNjMiwgJm9iamVjdCwgMCk7CiAgICBpZiggaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgRVJSKCJJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZSBmYWlsZWQgd2l0aCAlMDh4XG4iLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgb2JqZWN0LT5pc19jb21wbGV4X3Jvb3QgPSBUUlVFOwoKICAgICpTdXJmID0gSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKCiAgICAvKiBDcmVhdGUgQWRkaXRpb25hbCBzdXJmYWNlcyBpZiBuZWNlc3NhcnkKICAgICAqIFRoaXMgYXBwbGllcyB0byBQcmltYXJ5IHN1cmZhY2VzIHdoaWNoIGhhdmUgYSBiYWNrIGJ1ZmZlciBjb3VudAogICAgICogc2V0LCBidXQgbm90IHRvIG1pcG1hcCB0ZXh0dXJlcy4gSW4gY2FzZSBvZiBNaXBtYXAgdGV4dHVyZXMsCiAgICAgKiB3aW5lRDNEIHRha2VzIGNhcmUgb2YgdGhlIGNyZWF0aW9uIG9mIGFkZGl0aW9uYWwgc3VyZmFjZXMKICAgICAqLwogICAgaWYoRERTRC0+ZHdGbGFncyAmIEREU0RfQkFDS0JVRkZFUkNPVU5UKQogICAgewogICAgICAgIGV4dHJhX3N1cmZhY2VzID0gRERTRC0+ZHdCYWNrQnVmZmVyQ291bnQ7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJj0gfkREU0NBUFNfRlJPTlRCVUZGRVI7IC8qIEl0J3Mgbm90IGEgZnJvbnQgYnVmZmVyICovCiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19CQUNLQlVGRkVSOwogICAgfQoKICAgIGhyID0gRERfT0s7CiAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKQogICAgewogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVaOwogICAgICAgIGhyIHw9IENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcyhUaGlzLCBvYmplY3QsIGV4dHJhX3N1cmZhY2VzICsgMSwgZGVzYzIsIFRSVUUpOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVo7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWjsKICAgICAgICBociB8PSBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoVGhpcywgb2JqZWN0LCBleHRyYV9zdXJmYWNlcyArIDEsIGRlc2MyLCBUUlVFKTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVaOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVk7CiAgICAgICAgaHIgfD0gQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKFRoaXMsIG9iamVjdCwgZXh0cmFfc3VyZmFjZXMgKyAxLCBkZXNjMiwgVFJVRSk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVZOwogICAgICAgIGhyIHw9IENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcyhUaGlzLCBvYmplY3QsIGV4dHJhX3N1cmZhY2VzICsgMSwgZGVzYzIsIFRSVUUpOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWDsKICAgICAgICBociB8PSBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoVGhpcywgb2JqZWN0LCBleHRyYV9zdXJmYWNlcyArIDEsIGRlc2MyLCBUUlVFKTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVYOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVg7CiAgICB9CgogICAgaHIgfD0gQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKFRoaXMsIG9iamVjdCwgZXh0cmFfc3VyZmFjZXMsIGRlc2MyLCBGQUxTRSk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICAvKiBUaGlzIGRlc3Ryb3lzIGFuZCBwb3NzaWJseSBjcmVhdGVkIHN1cmZhY2VzIHRvbyAqLwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9SZWxlYXNlKCBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3U3VyZmFjZTcpICk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIEFkZHJlZiB0aGUgZGRyYXcgaW50ZXJmYWNlIHRvIGtlZXAgYW4gcmVmZXJlbmNlIGZvciBlYWNoIHN1cmZhY2UgKi8KICAgIElEaXJlY3REcmF3N19BZGRSZWYoaWZhY2UpOwogICAgb2JqZWN0LT5pZmFjZVRvUmVsZWFzZSA9IChJVW5rbm93biAqKSBpZmFjZTsKCiAgICAvKiBJZiB0aGUgaW1wbGVtZW50YXRpb24gaXMgT3BlbkdMIGFuZCB0aGVyZSdzIG5vIGQzZGRldmljZSwgYXR0YWNoIGEgZDNkZGV2aWNlCiAgICAgKiBCdXQgYXR0YWNoIHRoZSBkM2RkZXZpY2Ugb25seSBpZiB0aGUgY3VycmVudGx5IGNyZWF0ZWQgc3VyZmFjZSB3YXMKICAgICAqIGEgcHJpbWFyeSBzdXJmYWNlICgyRCBhcHAgaW4gM0QgbW9kZSkgb3IgYSAzRERFVklDRSBzdXJmYWNlICgzRCBhcHApCiAgICAgKiBUaGUgb25seSBjYXNlIEkgY2FuIHRoaW5rIG9mIHdoZXJlIHRoaXMgZG9lc24ndCBhcHBseSBpcyB3aGVuIGEKICAgICAqIDJEIGFwcCB3YXMgY29uZmlndXJlZCBieSB0aGUgdXNlciB0byBydW4gd2l0aCBPcGVuR0wgYW5kIGl0IGRpZG4ndCBjcmVhdGUKICAgICAqIHRoZSByZW5kZXIgdGFyZ2V0IGFzIGZpcnN0IHN1cmZhY2UuIEluIHRoaXMgY2FzZSB0aGUgcmVuZGVyIHRhcmdldCBjcmVhdGlvbgogICAgICogd2lsbCBjYXVzZSB0aGUgM0QgaW5pdC4KICAgICAqLwogICAgaWYoIChUaGlzLT5JbXBsVHlwZSA9PSBTVVJGQUNFX09QRU5HTCkgJiYgIShUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpICYmCiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfM0RERVZJQ0UpICkKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICp0YXJnZXQgPSBvYmplY3QsICpzdXJmYWNlOwogICAgICAgIHN0cnVjdCBsaXN0ICplbnRyeTsKCiAgICAgICAgLyogU2VhcmNoIGZvciB0aGUgcHJpbWFyeSB0byB1c2UgYXMgcmVuZGVyIHRhcmdldCAqLwogICAgICAgIExJU1RfRk9SX0VBQ0goZW50cnksICZUaGlzLT5zdXJmYWNlX2xpc3QpCiAgICAgICAgewogICAgICAgICAgICBzdXJmYWNlID0gTElTVF9FTlRSWShlbnRyeSwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgc3VyZmFjZV9saXN0X2VudHJ5KTsKICAgICAgICAgICAgaWYoKHN1cmZhY2UtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU19GUk9OVEJVRkZFUikpID09CiAgICAgICAgICAgICAgIChERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU19GUk9OVEJVRkZFUikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGZvdW5kICovCiAgICAgICAgICAgICAgICB0YXJnZXQgPSBzdXJmYWNlOwogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHByaW1hcnkgJXAgYXMgcmVuZGVyIHRhcmdldFxuIiwgdGFyZ2V0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiKCVwKSBBdHRhY2hpbmcgYSBEM0REZXZpY2UsIHJlbmRlcnRhcmdldCA9ICVwXG4iLCBUaGlzLCB0YXJnZXQpOwogICAgICAgIGhyID0gSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZShUaGlzLCB0YXJnZXQpOwogICAgICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZSBmYWlsZWQsIGhyID0gJXhcbiIsIGhyKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQ3JlYXRlIGEgV2luZUQzRFRleHR1cmUgaWYgYSB0ZXh0dXJlIHdhcyByZXF1ZXN0ZWQgKi8KICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19URVhUVVJFKQogICAgewogICAgICAgIFVJTlQgbGV2ZWxzOwogICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0OwogICAgICAgIFdJTkVEM0RQT09MIFBvb2wgPSBXSU5FRDNEUE9PTF9ERUZBVUxUOwoKICAgICAgICBUaGlzLT50ZXhfcm9vdCA9IG9iamVjdDsKCiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGEgbWlwbWFwIGlzIGNyZWF0ZWQsIGNyZWF0ZSBlbm91Z2ggbGV2ZWxzICovCiAgICAgICAgICAgIGxldmVscyA9IGRlc2MyLnUyLmR3TWlwTWFwQ291bnQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIG1pcG1hcCBpcyBjcmVhdGVkLCBjcmVhdGUgb25lIGxldmVsICovCiAgICAgICAgICAgIGxldmVscyA9IDE7CiAgICAgICAgfQoKICAgICAgICAvKiBERFNDQVBTX1NZU1RFTU1FTU9SWSB0ZXh0dXJlcyBhcmUgaW4gV0lORUQzRFBPT0xfU1lTVEVNTUVNICovCiAgICAgICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1NZU1RFTU1FTU9SWSkKICAgICAgICB7CiAgICAgICAgICAgIFBvb2wgPSBXSU5FRDNEUE9PTF9TWVNURU1NRU07CiAgICAgICAgfQogICAgICAgIC8qIFNob3VsZCBJIGZvcndhcmQgdGhlIE1BTkVHRUQgY2FwIHRvIHRoZSBtYW5hZ2VkIHBvb2wgPyAqLwoKICAgICAgICAvKiBHZXQgdGhlIGZvcm1hdC4gSXQncyBzZXQgYWxyZWFkeSBieSBDcmVhdGVOZXdTdXJmYWNlICovCiAgICAgICAgRm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmb2JqZWN0LT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICAgICAgLyogVGhlIHN1cmZhY2VzIGFyZSBhbHJlYWR5IGNyZWF0ZWQsIHRoZSBjYWxsYmFjayBvbmx5CiAgICAgICAgICogcGFzc2VzIHRoZSBJV2luZUQzRFN1cmZhY2UgdG8gV2luZUQzRAogICAgICAgICAqLwogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVApCiAgICAgICAgewogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZUN1YmVUZXh0dXJlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTRC0+ZHdXaWR0aCwgLyogRWRnZWxlbmd0aCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiB1c2FnZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzREN1YmVUZXh0dXJlICoqKSAmb2JqZWN0LT53aW5lRDNEVGV4dHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBTaGFyZWRIYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlU3VyZmFjZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVGV4dHVyZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTRC0+ZHdXaWR0aCwgRERTRC0+ZHdIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMsIC8qIE1pcE1hcENvdW50ID0gTGV2ZWxzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiB1c2FnZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzRFRleHR1cmUgKiopICZvYmplY3QtPndpbmVEM0RUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU2hhcmVkSGFuZGxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVTdXJmYWNlICk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnRleF9yb290ID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCiNkZWZpbmUgRERFTlVNU1VSRkFDRVNfU0VBUkNIVFlQRSAoRERFTlVNU1VSRkFDRVNfQ0FOQkVDUkVBVEVEfERERU5VTVNVUkZBQ0VTX0RPRVNFWElTVCkKI2RlZmluZSBEREVOVU1TVVJGQUNFU19NQVRDSFRZUEUgKERERU5VTVNVUkZBQ0VTX0FMTHxEREVOVU1TVVJGQUNFU19NQVRDSHxEREVOVU1TVVJGQUNFU19OT01BVENIKQoKc3RhdGljIEJPT0wKTWFpbl9EaXJlY3REcmF3X0REUElYRUxGT1JNQVRfTWF0Y2goY29uc3QgRERQSVhFTEZPUk1BVCAqcmVxdWVzdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBERFBJWEVMRk9STUFUICpwcm92aWRlZCkKewogICAgLyogU29tZSBmbGFncyBtdXN0IGJlIHByZXNlbnQgaW4gYm90aCBvciBuZWl0aGVyIGZvciBhIG1hdGNoLiAqLwogICAgc3RhdGljIGNvbnN0IERXT1JEIG11c3RfbWF0Y2ggPSBERFBGX1BBTEVUVEVJTkRFWEVEMSB8IEREUEZfUEFMRVRURUlOREVYRUQyCiAgICAgICAgfCBERFBGX1BBTEVUVEVJTkRFWEVENCB8IEREUEZfUEFMRVRURUlOREVYRUQ4IHwgRERQRl9GT1VSQ0MKICAgICAgICB8IEREUEZfWkJVRkZFUiB8IEREUEZfU1RFTkNJTEJVRkZFUjsKCiAgICBpZiAoKHJlcXVlc3RlZC0+ZHdGbGFncyAmIHByb3ZpZGVkLT5kd0ZsYWdzKSAhPSByZXF1ZXN0ZWQtPmR3RmxhZ3MpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmICgocmVxdWVzdGVkLT5kd0ZsYWdzICYgbXVzdF9tYXRjaCkgIT0gKHByb3ZpZGVkLT5kd0ZsYWdzICYgbXVzdF9tYXRjaCkpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBERFBGX0ZPVVJDQykKICAgICAgICBpZiAocmVxdWVzdGVkLT5kd0ZvdXJDQyAhPSBwcm92aWRlZC0+ZHdGb3VyQ0MpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfWkJVRkZFUnxERFBGX0FMUEhBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxERFBGX0xVTUlOQU5DRXxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51MS5kd1JHQkJpdENvdW50ICE9IHByb3ZpZGVkLT51MS5kd1JHQkJpdENvdW50KQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1NURU5DSUxCVUZGRVIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfEREUEZfTFVNSU5BTkNFfEREUEZfQlVNUERVRFYpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnUyLmR3UkJpdE1hc2sgIT0gcHJvdmlkZWQtPnUyLmR3UkJpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfWkJVRkZFUnxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51My5kd0dCaXRNYXNrICE9IHByb3ZpZGVkLT51My5kd0dCaXRNYXNrKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogSSBjb3VsZCBiZSB3cm9uZyBhYm91dCB0aGUgYnVtcG1hcHBpbmcuIE1TRE4gZG9jcyBhcmUgdmFndWUuICovCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfU1RFTkNJTEJVRkZFUgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTQuZHdCQml0TWFzayAhPSBwcm92aWRlZC0+dTQuZHdCQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9BTFBIQVBJWEVMU3xERFBGX1pQSVhFTFMpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnU1LmR3UkdCQWxwaGFCaXRNYXNrICE9IHByb3ZpZGVkLT51NS5kd1JHQkFscGhhQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTApJRGlyZWN0RHJhd0ltcGxfRERTRF9NYXRjaChjb25zdCBERFNVUkZBQ0VERVNDMiogcmVxdWVzdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBERFNVUkZBQ0VERVNDMiogcHJvdmlkZWQpCnsKICAgIHN0cnVjdCBjb21wYXJlX2luZm8KICAgIHsKICAgICAgICBEV09SRCBmbGFnOwogICAgICAgIHB0cmRpZmZfdCBvZmZzZXQ7CiAgICAgICAgc2l6ZV90IHNpemU7CiAgICB9OwoKI2RlZmluZSBDTVAoRkxBRywgRklFTEQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgeyBERFNEXyMjRkxBRywgb2Zmc2V0b2YoRERTVVJGQUNFREVTQzIsIEZJRUxEKSwgXAogICAgICAgICAgc2l6ZW9mKCgoRERTVVJGQUNFREVTQzIgKikoTlVMTCkpLT5GSUVMRCkgfQoKICAgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgY29tcGFyZV9pbmZvIGNvbXBhcmVbXSA9CiAgICB7CiAgICAgICAgQ01QKEFMUEhBQklUREVQVEgsIGR3QWxwaGFCaXREZXB0aCksCiAgICAgICAgQ01QKEJBQ0tCVUZGRVJDT1VOVCwgZHdCYWNrQnVmZmVyQ291bnQpLAogICAgICAgIENNUChDQVBTLCBkZHNDYXBzKSwKICAgICAgICBDTVAoQ0tERVNUQkxULCBkZGNrQ0tEZXN0Qmx0KSwKICAgICAgICBDTVAoQ0tERVNUT1ZFUkxBWSwgdTMgLyogZGRja0NLRGVzdE92ZXJsYXkgKi8pLAogICAgICAgIENNUChDS1NSQ0JMVCwgZGRja0NLU3JjQmx0KSwKICAgICAgICBDTVAoQ0tTUkNPVkVSTEFZLCBkZGNrQ0tTcmNPdmVybGF5KSwKICAgICAgICBDTVAoSEVJR0hULCBkd0hlaWdodCksCiAgICAgICAgQ01QKExJTkVBUlNJWkUsIHUxIC8qIGR3TGluZWFyU2l6ZSAqLyksCiAgICAgICAgQ01QKExQU1VSRkFDRSwgbHBTdXJmYWNlKSwKICAgICAgICBDTVAoTUlQTUFQQ09VTlQsIHUyIC8qIGR3TWlwTWFwQ291bnQgKi8pLAogICAgICAgIENNUChQSVRDSCwgdTEgLyogbFBpdGNoICovKSwKICAgICAgICAvKiBQSVhFTEZPUk1BVDogbWFudWFsICovCiAgICAgICAgQ01QKFJFRlJFU0hSQVRFLCB1MiAvKiBkd1JlZnJlc2hSYXRlICovKSwKICAgICAgICBDTVAoVEVYVFVSRVNUQUdFLCBkd1RleHR1cmVTdGFnZSksCiAgICAgICAgQ01QKFdJRFRILCBkd1dpZHRoKSwKICAgICAgICAvKiBaQlVGRkVSQklUREVQVEg6ICJvYnNvbGV0ZSIgKi8KICAgIH07CgojdW5kZWYgQ01QCgogICAgdW5zaWduZWQgaW50IGk7CgogICAgaWYgKChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBwcm92aWRlZC0+ZHdGbGFncykgIT0gcmVxdWVzdGVkLT5kd0ZsYWdzKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKGk9MDsgaSA8IHNpemVvZihjb21wYXJlKS9zaXplb2YoY29tcGFyZVswXSk7IGkrKykKICAgIHsKICAgICAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgY29tcGFyZVtpXS5mbGFnCiAgICAgICAgICAgICYmIG1lbWNtcCgoY29uc3QgY2hhciAqKXByb3ZpZGVkICsgY29tcGFyZVtpXS5vZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKXJlcXVlc3RlZCArIGNvbXBhcmVbaV0ub2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgY29tcGFyZVtpXS5zaXplKSAhPSAwKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpCiAgICB7CiAgICAgICAgaWYgKCFNYWluX0RpcmVjdERyYXdfRERQSVhFTEZPUk1BVF9NYXRjaCgmcmVxdWVzdGVkLT51NC5kZHBmUGl4ZWxGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwcm92aWRlZC0+dTQuZGRwZlBpeGVsRm9ybWF0KSkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgojdW5kZWYgRERFTlVNU1VSRkFDRVNfU0VBUkNIVFlQRQojdW5kZWYgRERFTlVNU1VSRkFDRVNfTUFUQ0hUWVBFCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFbnVtU3VyZmFjZXMKICoKICogTG9vcHMgdGhyb3VnaCBhbGwgc3VyZmFjZXMgYXR0YWNoZWQgdG8gdGhpcyBkZXZpY2UgYW5kIGNhbGxzIHRoZQogKiBhcHBsaWNhdGlvbiBjYWxsYmFjay4gVGhpcyBjYW4ndCBiZSByZWxheWVkIHRvIFdpbmVEM0REZXZpY2UsCiAqIGJlY2F1c2Ugc29tZSBXaW5lRDNEU3VyZmFjZXMnIHBhcmVudHMgYXJlIElQYXJlbnQgb2JqZWN0cwogKgogKiBQYXJhbXM6CiAqICBGbGFnczogU29tZSBmaWx0ZXJpbmcgZmxhZ3MuIFNlZSBJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzQ2FsbGJhY2sKICogIEREU0Q6IERlc2NyaXB0aW9uIHRvIGZpbHRlciBmb3IKICogIENvbnRleHQ6IEFwcGxpY2F0aW9uLXByb3ZpZGVkIHBvaW50ZXIsIGl0J3MgcGFzc2VkIHVubW9kaWZpZWQgdG8gdGhlCiAqICAgICAgICAgICBDYWxsYmFjayBmdW5jdGlvbgogKiAgQ2FsbGJhY2s6IEFkZHJlc3MgdG8gY2FsbCBmb3IgZWFjaCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBjYWxsYmFjayBpcyBOVUxMCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9FbnVtU3VyZmFjZXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNU1VSRkFDRVNDQUxMQkFDSzcgQ2FsbGJhY2spCnsKICAgIC8qIFRoZSBzdXJmYWNlIGVudW1lcmF0aW9uIGlzIGhhbmRsZWQgYnkgV2luZUREcmF3LAogICAgICogYmVjYXVzZSBpdCBrZWVwcyB0cmFjayBvZiBhbGwgc3VyZmFjZXMgYXR0YWNoZWQgdG8KICAgICAqIGl0LiBUaGUgZmlsdGVyaW5nIGlzIGRvbmUgYnkgb3VyIGNhbGxiYWNrIGZ1bmN0aW9uLAogICAgICogYmVjYXVzZSBXaW5lRERyYXcgZG9lc24ndCBoYW5kbGUgZGRyYXctbGlrZSBzdXJmYWNlCiAgICAgKiBjYXBzIHN0cnVjdHVyZXMKICAgICAqLwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICBCT09MIGFsbCwgbm9tYXRjaDsKICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICBzdHJ1Y3QgbGlzdCAqZW50cnksICplbnRyeTI7CgogICAgYWxsID0gRmxhZ3MgJiBEREVOVU1TVVJGQUNFU19BTEw7CiAgICBub21hdGNoID0gRmxhZ3MgJiBEREVOVU1TVVJGQUNFU19OT01BVENIOwoKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgRERTRCwgQ29udGV4dCwgQ2FsbGJhY2spOwoKICAgIGlmKCFDYWxsYmFjaykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBVc2UgdGhlIF9TQUZFIGVudW1lcmF0aW9uLCB0aGUgYXBwIG1heSBkZXN0cm95IGVudW1lcmF0ZWQgc3VyZmFjZXMgKi8KICAgIExJU1RfRk9SX0VBQ0hfU0FGRShlbnRyeSwgZW50cnkyLCAmVGhpcy0+c3VyZmFjZV9saXN0KQogICAgewogICAgICAgIHN1cmYgPSBMSVNUX0VOVFJZKGVudHJ5LCBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBzdXJmYWNlX2xpc3RfZW50cnkpOwogICAgICAgIGlmIChhbGwgfHwgKG5vbWF0Y2ggIT0gSURpcmVjdERyYXdJbXBsX0REU0RfTWF0Y2goRERTRCwgJnN1cmYtPnN1cmZhY2VfZGVzYykpKQogICAgICAgIHsKICAgICAgICAgICAgZGVzYyA9IHN1cmYtPnN1cmZhY2VfZGVzYzsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgICAgICBpZihDYWxsYmFjayggSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyksICZkZXNjLCBDb250ZXh0KSAhPSBEREVOVU1SRVRfT0spCiAgICAgICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIEREX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKZmluZFJlbmRlclRhcmdldChJRGlyZWN0RHJhd1N1cmZhY2U3ICpzdXJmYWNlLAogICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpkZXNjLAogICAgICAgICAgICAgICAgIHZvaWQgKmN0eCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHN1cmZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnRhcmdldCA9IChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICoqKSBjdHg7CgogICAgaWYoIXN1cmYtPmlzUmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgKnRhcmdldCA9IHN1cmY7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmZhY2UpOwogICAgICAgIHJldHVybiBEREVOVU1SRVRfQ0FOQ0VMOwogICAgfQoKICAgIC8qIFJlY3Vyc2UgaW50byB0aGUgc3VyZmFjZSB0cmVlICovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0VudW1BdHRhY2hlZFN1cmZhY2VzKHN1cmZhY2UsIGN0eCwgZmluZFJlbmRlclRhcmdldCk7CgogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmZhY2UpOwogICAgaWYoKnRhcmdldCkgcmV0dXJuIERERU5VTVJFVF9DQU5DRUw7CiAgICBlbHNlIHJldHVybiBEREVOVU1SRVRfT0s7IC8qIENvbnRpbnVlIHdpdGggdGhlIG5leHQgbmVpZ2hib3Igc3VyZmFjZSAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZVJlbmRlclRhcmdldAogKgogKiBDYWxsYmFjayBjYWxsZWQgYnkgV2luZUQzRCB0byBjcmVhdGUgU3VyZmFjZXMgZm9yIHJlbmRlciB0YXJnZXQgdXNhZ2UKICogVGhpcyBmdW5jdGlvbiB0YWtlcyB0aGUgRDNEIHRhcmdldCBmcm9tIHRoZSBJRGlyZWN0RHJhd0ltcGwgc3RydWN0dXJlLAogKiBhbmQgcmV0dXJucyB0aGUgV2luZUQzRFN1cmZhY2UuIFRvIGF2b2lkIGRvdWJsZSB1c2FnZSwgdGhlIHN1cmZhY2UKICogaXMgbWFya2VkIGFzIHJlbmRlciB0YXJnZXQgYWZ0ZXJ3YXJkcwogKgogKiBQYXJhbXMKICogIGRldmljZTogVGhlIFdpbmVEM0REZXZpY2UncyBwYXJlbnQKICogIFdpZHRoLCBIZWlnaHQsIEZvcm1hdDogRGltZW5zaW9ucyBhbmQgcGl4ZWxmb3JtYXQgb2YgdGhlIHJlbmRlciB0YXJnZXQKICogICAgICAgICAgICAgICAgICAgICAgICAgSWdub3JlZCwgYmVjYXVzZSB0aGUgc3VyZmFjZSBhbHJlYWR5IGV4aXN0cwogKiAgTXVsdGlTYW1wbGUsIE11bHRpc2FtcGxlUXVhbGl0eSwgTG9ja2FibGU6IElnbm9yZWQgZm9yIHRoZSBzYW1lIHJlYXNvbgogKiAgTG9ja2FibGU6IGlnbm9yZWQKICogIHBwU3VyZmFjZTogQWRkcmVzcyB0byBwYXNzIHRoZSBzdXJmYWNlIHBvaW50ZXIgYmFjayBhdAogKiAgcFNoYXJlZEhhbmRsZTogSWdub3JlZAogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRDNEX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVSZW5kZXJUYXJnZXQoSVVua25vd24gKmRldmljZSwgSVVua25vd24gKnBTdXBlcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBNdWx0aXNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBMb2NrYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UqKiBwcFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFKiBwU2hhcmVkSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmQzZFN1cmZhY2UgPSBUaGlzLT5kM2RfdGFyZ2V0LCAqdGFyZ2V0ID0gTlVMTDsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgZGV2aWNlKTsKCiAgICBpZihkM2RTdXJmYWNlLT5pc1JlbmRlclRhcmdldCkKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0VudW1BdHRhY2hlZFN1cmZhY2VzKElDT01fSU5URVJGQUNFKGQzZFN1cmZhY2UsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRhcmdldCwgZmluZFJlbmRlclRhcmdldCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdGFyZ2V0ID0gZDNkU3VyZmFjZTsKICAgIH0KCiAgICBpZighdGFyZ2V0KQogICAgewogICAgICAgIHRhcmdldCA9IFRoaXMtPmQzZF90YXJnZXQ7CiAgICAgICAgRVJSKCIgKCVwKSA6IE5vIERpcmVjdERyYXdTdXJmYWNlIGZvdW5kIHRvIGNyZWF0ZSB0aGUgYmFjayBidWZmZXIuIFVzaW5nIHRoZSBmcm9udCBidWZmZXIgYXMgYmFjayBidWZmZXIuIFVuY2VydGFpbiBjb25zZXF1ZW5jZXNcbiIsIFRoaXMpOwogICAgfQoKICAgIC8qIFRPRE86IFJldHVybiBmYWlsdXJlIGlmIHRoZSBkaW1lbnNpb25zIGRvIG5vdCBtYXRjaCwgYnV0IHRoaXMgc2hvdWxkbid0IGhhcHBlbiAqLwoKICAgICpwcFN1cmZhY2UgPSB0YXJnZXQtPldpbmVEM0RTdXJmYWNlOwogICAgdGFyZ2V0LT5pc1JlbmRlclRhcmdldCA9IFRSVUU7CiAgICBUUkFDRSgiUmV0dXJuaW5nIHdpbmVEM0RTdXJmYWNlICVwLCBpdCBiZWxvbmdzIHRvIHN1cmZhY2UgJXBcbiIsICpwcFN1cmZhY2UsIGQzZFN1cmZhY2UpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlKElVbmtub3duICpkZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwU3VwZXJpb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE11bHRpc2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBEaXNjYXJkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UqKiBwcFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSogcFNoYXJlZEhhbmRsZSkKewogICAgLyogQ3JlYXRlIGEgRGVwdGggU3RlbmNpbCBzdXJmYWNlIHRvIG1ha2UgV2luZUQzRCBoYXBweSAqLwogICAgSFJFU1VMVCBociA9IEQzRF9PSzsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgRERTVVJGQUNFREVTQzIgZGRzZDsKCiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIGRldmljZSk7CgogICAgKnBwU3VyZmFjZSA9IE5VTEw7CgogICAgLyogQ3JlYXRlIGEgRGlyZWN0RHJhdyBzdXJmYWNlICovCiAgICBtZW1zZXQoJmRkc2QsIDAsIHNpemVvZihkZHNkKSk7CiAgICBkZHNkLmR3U2l6ZSA9IHNpemVvZihkZHNkKTsKICAgIGRkc2QudTQuZGRwZlBpeGVsRm9ybWF0LmR3U2l6ZSA9IHNpemVvZihERFBJWEVMRk9STUFUKTsKICAgIGRkc2QuZHdGbGFncyA9IEREU0RfUElYRUxGT1JNQVQgfCBERFNEX1dJRFRIIHwgRERTRF9IRUlHSFQgfCBERFNEX0NBUFM7CiAgICBkZHNkLmRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19PRkZTQ1JFRU5QTEFJTjsKICAgIGRkc2QuZHdIZWlnaHQgPSBIZWlnaHQ7CiAgICBkZHNkLmR3V2lkdGggPSBXaWR0aDsKICAgIGlmKEZvcm1hdCAhPSAwKQogICAgewogICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmZGRzZC51NC5kZHBmUGl4ZWxGb3JtYXQsIEZvcm1hdCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgIGRkc2QuZHdGbGFncyBePSBERFNEX1BJWEVMRk9STUFUOwogICAgfQoKICAgIFRoaXMtPmRlcHRoc3RlbmNpbCA9IFRSVUU7CiAgICBociA9IElEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlKChJRGlyZWN0RHJhdzcgKikgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmRkc2QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJRGlyZWN0RHJhd1N1cmZhY2U3ICoqKSAmVGhpcy0+RGVwdGhTdGVuY2lsQnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIFRoaXMtPmRlcHRoc3RlbmNpbCA9IEZBTFNFOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIiAoJXApIENyZWF0aW5nIGEgRGVwdGhTdGVuY2lsIFN1cmZhY2UgZmFpbGVkLCByZXN1bHQgPSAleFxuIiwgVGhpcywgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KICAgICpwcFN1cmZhY2UgPSBUaGlzLT5EZXB0aFN0ZW5jaWxCdWZmZXItPldpbmVEM0RTdXJmYWNlOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEQzRDdDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluCiAqCiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciBXaW5lRDNEIHdoaWNoIGNyZWF0ZXMgYSBuZXcgV2luZUQzRFN3YXBjaGFpbgogKiBpbnRlcmZhY2UuIEl0IGFsc28gY3JlYXRlcyBhbiBJUGFyZW50IGludGVyZmFjZSB0byBzdG9yZSB0aGF0IHBvaW50ZXIsCiAqIHNvIHRoZSBXaW5lRDNEU3dhcGNoYWluIGhhcyBhIHBhcmVudCBhbmQgY2FuIGJlIHJlbGVhc2VkIHdoZW4gdGhlIEQzRAogKiBkZXZpY2UgaXMgZGVzdHJveWVkCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKElVbmtub3duICpkZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMqIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbiAqKiBwcFN3YXBDaGFpbikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGRldmljZSk7CiAgICBJUGFyZW50SW1wbCAqb2JqZWN0ID0gTlVMTDsKICAgIEhSRVNVTFQgcmVzID0gRDNEX09LOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgZGV2aWNlKTsKCiAgICBvYmplY3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJUGFyZW50SW1wbCkpOwogICAgaWYgKE5VTEwgPT0gb2JqZWN0KQogICAgewogICAgICAgIEZJWE1FKCJBbGxvY2F0aW9uIG9mIG1lbW9yeSBmYWlsZWRcbiIpOwogICAgICAgICpwcFN3YXBDaGFpbiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIERERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElQYXJlbnQsIElQYXJlbnRfVnRibCk7CiAgICBvYmplY3QtPnJlZiA9IDE7CgogICAgcmVzID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbihUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzd2FwY2hhaW4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24qKSBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElQYXJlbnQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlUmVuZGVyVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlRGVwdGhTdGVuY2lsU3VyZmFjZSk7CiAgICBpZiAocmVzICE9IEQzRF9PSykKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBjYWxsIHRvIElXaW5lRDNERGV2aWNlX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4gZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwICwgb2JqZWN0KTsKICAgICAgICAqcHBTd2FwQ2hhaW4gPSBOVUxMOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgICpwcFN3YXBDaGFpbiA9IHN3YXBjaGFpbjsKICAgICAgICBvYmplY3QtPmNoaWxkID0gKElVbmtub3duICopIHN3YXBjaGFpbjsKICAgIH0KCiAgICByZXR1cm4gcmVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZQogKgogKiBJbml0aWFsaXplcyB0aGUgRDNEIGNhcGFiaWxpdGllcyBvZiBXaW5lRDNECiAqCiAqIFBhcmFtczoKICogIHByaW1hcnk6IFRoZSBwcmltYXJ5IHN1cmZhY2UgZm9yIEQzRAogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzLAogKiAgRERFUlJfKiBvdGhlcndpc2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcHJpbWFyeSkKewogICAgSFJFU1VMVCBocjsKICAgIEhXTkQgICAgICAgICAgICAgICAgICB3aW5kb3c7CgogICAgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyBsb2NhbFBhcmFtZXRlcnM7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHByaW1hcnkpOwoKICAgIC8qIEdldCB0aGUgd2luZG93ICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd2luZG93KTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNERGV2aWNlOjpHZXRIV05EIGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIElmIHRoZXJlJ3Mgbm8gd2luZG93LCBjcmVhdGUgYSBoaWRkZW4gd2luZG93LiBXaW5lRDNEIG5lZWRzIGl0ICovCiAgICBpZih3aW5kb3cgPT0gMCkKICAgIHsKICAgICAgICB3aW5kb3cgPSBDcmVhdGVXaW5kb3dFeEEoMCwgVGhpcy0+Y2xhc3NuYW1lLCAiSGlkZGVuIEQzRCBXaW5kb3ciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXU19ESVNBQkxFRCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMLCBHZXRNb2R1bGVIYW5kbGVBKDApLCBOVUxMKTsKCiAgICAgICAgU2hvd1dpbmRvdyh3aW5kb3csIFNXX0hJREUpOyAgIC8qIEp1c3QgdG8gYmUgc3VyZSAqLwogICAgICAgIFdBUk4oIiglcCkgTm8gd2luZG93IGZvciB0aGUgRGlyZWN0M0REZXZpY2UsIGNyZWF0ZWQgYSBoaWRkZW4gd2luZG93LiBIV05EPSVwXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgICAgIFRoaXMtPmQzZF93aW5kb3cgPSB3aW5kb3c7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCkgVXNpbmcgZXhpc3Rpbmcgd2luZG93ICVwIGZvciBEaXJlY3QzRCByZW5kZXJpbmdcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICB9CgogICAgLyogU3RvcmUgdGhlIGZ1dHVyZSBSZW5kZXIgVGFyZ2V0IHN1cmZhY2UgKi8KICAgIFRoaXMtPmQzZF90YXJnZXQgPSBwcmltYXJ5OwoKICAgIC8qIFVzZSB0aGUgc3VyZmFjZSBkZXNjcmlwdGlvbiBmb3IgdGhlIGRldmljZSBwYXJhbWV0ZXJzLCBub3QgdGhlCiAgICAgKiBEZXZpY2Ugc2V0dGluZ3MuIFRoZSBhcHAgbWlnaHQgcmVuZGVyIHRvIGFuIG9mZnNjcmVlbiBzdXJmYWNlCiAgICAgKi8KICAgIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVyV2lkdGggICAgICAgICAgICAgICAgID0gcHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3V2lkdGg7CiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckhlaWdodCAgICAgICAgICAgICAgICA9IHByaW1hcnktPnN1cmZhY2VfZGVzYy5kd0hlaWdodDsKICAgIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVyRm9ybWF0ICAgICAgICAgICAgICAgID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmcHJpbWFyeS0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdCk7CiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckNvdW50ICAgICAgICAgICAgICAgICA9IChwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdGbGFncyAmIEREU0RfQkFDS0JVRkZFUkNPVU5UKSA/IHByaW1hcnktPnN1cmZhY2VfZGVzYy5kd0JhY2tCdWZmZXJDb3VudCA6IDA7CiAgICBsb2NhbFBhcmFtZXRlcnMuTXVsdGlTYW1wbGVUeXBlICAgICAgICAgICAgICAgICA9IFdJTkVEM0RNVUxUSVNBTVBMRV9OT05FOwogICAgbG9jYWxQYXJhbWV0ZXJzLk11bHRpU2FtcGxlUXVhbGl0eSAgICAgICAgICAgICAgPSAwOwogICAgbG9jYWxQYXJhbWV0ZXJzLlN3YXBFZmZlY3QgICAgICAgICAgICAgICAgICAgICAgPSBXSU5FRDNEU1dBUEVGRkVDVF9DT1BZOwogICAgbG9jYWxQYXJhbWV0ZXJzLmhEZXZpY2VXaW5kb3cgICAgICAgICAgICAgICAgICAgPSB3aW5kb3c7CiAgICBsb2NhbFBhcmFtZXRlcnMuV2luZG93ZWQgICAgICAgICAgICAgICAgICAgICAgICA9ICEoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9GVUxMU0NSRUVOKTsKICAgIGxvY2FsUGFyYW1ldGVycy5FbmFibGVBdXRvRGVwdGhTdGVuY2lsICAgICAgICAgID0gRkFMU0U7CiAgICBsb2NhbFBhcmFtZXRlcnMuQXV0b0RlcHRoU3RlbmNpbEZvcm1hdCAgICAgICAgICA9IFdJTkVEM0RGTVRfRDE2OwogICAgbG9jYWxQYXJhbWV0ZXJzLkZsYWdzICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAwOwogICAgbG9jYWxQYXJhbWV0ZXJzLkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6ICAgICAgPSBXSU5FRDNEUFJFU0VOVF9SQVRFX0RFRkFVTFQ7IC8qIERlZmF1bHQgcmF0ZTogSXQncyBhbHJlYWR5IHNldCAqLwogICAgbG9jYWxQYXJhbWV0ZXJzLlByZXNlbnRhdGlvbkludGVydmFsICAgICAgICAgICAgPSBXSU5FRDNEUFJFU0VOVF9JTlRFUlZBTF9ERUZBVUxUOwoKICAgIFRSQUNFKCJQYXNzaW5nIG1vZGUgJWRcbiIsIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVyRm9ybWF0KTsKCiAgICAvKiBTZXQgdGhpcyBOT1csIG90aGVyd2lzZSBjcmVhdGluZyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIHdpbGwgY2F1c2UgYQogICAgICogcmVjdXJzaXZlIGxvb3AgdW50aWwgcmFtIG9yIGVtdWxhdGVkIHZpZGVvIG1lbW9yeSBpcyBmdWxsCiAgICAgKi8KICAgIFRoaXMtPmQzZF9pbml0aWFsaXplZCA9IFRSVUU7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9Jbml0M0QoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsb2NhbFBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbik7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIFRoaXMtPndpbmVEM0REZXZpY2UgPSBOVUxMOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBDcmVhdGUgYW4gSW5kZXggQnVmZmVyIHBhcmVudCAqLwogICAgVFJBQ0UoIiglcCkgU3VjY2Vzc2Z1bGx5IGluaXRpYWxpemVkIDNEXG4iLCBUaGlzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdDcmVhdGVDbGlwcGVyIChERFJBVy5AKQogKgogKiBDcmVhdGVzIGEgbmV3IElEaXJlY3REcmF3Q2xpcHBlciBvYmplY3QuCiAqCiAqIFBhcmFtczoKICogIENsaXBwZXI6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIGludGVyZmFjZSBwb2ludGVyIHRvCiAqICBVbmtPdXRlcjogRm9yIGFnZ3JlZ2F0aW9uIHN1cHBvcnQsIHdoaWNoIGRkcmF3IGRvZXNuJ3QgaGF2ZS4gSGFzIHRvIGJlCiAqICAgICAgICAgICAgTlVMTAogKgogKiBSZXR1cm5zOgogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyICE9IE5VTEwKICogIEVfT1VUT0ZNRU1PUlkgaWYgYWxsb2NhdGluZyB0aGUgb2JqZWN0IGZhaWxlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdDcmVhdGVDbGlwcGVyKERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKipDbGlwcGVyLAogICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIElEaXJlY3REcmF3Q2xpcHBlckltcGwqIG9iamVjdDsKICAgIFRSQUNFKCIoJTA4eCwlcCwlcClcbiIsIEZsYWdzLCBDbGlwcGVyLCBVbmtPdXRlcik7CgogICAgaWYgKFVua091dGVyICE9IE5VTEwpIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAgICAgIHNpemVvZihJRGlyZWN0RHJhd0NsaXBwZXJJbXBsKSk7CiAgICBpZiAob2JqZWN0ID09IE5VTEwpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd0NsaXBwZXIsIElEaXJlY3REcmF3Q2xpcHBlcl9WdGJsKTsKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+d2luZUQzRENsaXBwZXIgPSBwV2luZURpcmVjdDNEQ3JlYXRlQ2xpcHBlcigoSVVua25vd24gKikgb2JqZWN0KTsKICAgIGlmKCFvYmplY3QtPndpbmVEM0RDbGlwcGVyKQogICAgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgKkNsaXBwZXIgPSAoSURpcmVjdERyYXdDbGlwcGVyICopIG9iamVjdDsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6Q3JlYXRlQ2xpcHBlcgogKgogKiBDcmVhdGVzIGEgRERyYXcgY2xpcHBlci4gU2VlIERpcmVjdERyYXdDcmVhdGVDbGlwcGVyIGZvciBkZXRhaWxzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVDbGlwcGVyKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKipDbGlwcGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwLCVwKVxuIiwgVGhpcywgRmxhZ3MsIENsaXBwZXIsIFVua091dGVyKTsKICAgIHJldHVybiBEaXJlY3REcmF3Q3JlYXRlQ2xpcHBlcihGbGFncywgQ2xpcHBlciwgVW5rT3V0ZXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDcmVhdGVQYWxldHRlCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURpcmVjdERyYXdQYWxldHRlIG9iamVjdAogKgogKiBQYXJhbXM6CiAqICBGbGFnczogVGhlIGZsYWdzIGZvciB0aGUgbmV3IGNsaXBwZXIKICogIENvbG9yVGFibGU6IENvbG9yIHRhYmxlIHRvIGFzc2lnbiB0byB0aGUgbmV3IGNsaXBwZXIKICogIFBhbGV0dGU6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIGludGVyZmFjZSBwb2ludGVyIHRvCiAqICBVbmtPdXRlcjogRm9yIGFnZ3JlZ2F0aW9uIHN1cHBvcnQsIHdoaWNoIGRkcmF3IGRvZXNuJ3QgaGF2ZS4gSGFzIHRvIGJlCiAqICAgICAgICAgICAgTlVMTAogKgogKiBSZXR1cm5zOgogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyICE9IE5VTEwKICogIEVfT1VUT0ZNRU1PUlkgaWYgYWxsb2NhdGluZyB0aGUgb2JqZWN0IGZhaWxlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlUGFsZXR0ZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFMRVRURUVOVFJZICpDb2xvclRhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGUgKipQYWxldHRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqcFVua091dGVyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdQYWxldHRlSW1wbCAqb2JqZWN0OwogICAgSFJFU1VMVCBociA9IERERVJSX0dFTkVSSUM7CiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwLCVwLCVwKVxuIiwgVGhpcywgRmxhZ3MsIENvbG9yVGFibGUsIFBhbGV0dGUsIHBVbmtPdXRlcik7CgogICAgaWYocFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgV0FSTigicFVua091dGVyIGlzICVwLCByZXR1cm5pbmcgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OXG4iLCBwVW5rT3V0ZXIpOwogICAgICAgIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CiAgICB9CgogICAgLyogVGhlIHJlZmNvdW50IHRlc3Qgc2hvd3MgdGhhdCBhIGNvb3BsZXZlbCBpcyByZXF1aXJlZCBmb3IgdGhpcyAqLwogICAgaWYoIVRoaXMtPmNvb3BlcmF0aXZlX2xldmVsKQogICAgewogICAgICAgIFdBUk4oIk5vIGNvb3BlcmF0aXZlIGxldmVsIHNldCwgcmV0dXJuaW5nIERERVJSX05PQ09PUEVSQVRJVkVMRVZFTFNFVFxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX05PQ09PUEVSQVRJVkVMRVZFTFNFVDsKICAgIH0KCiAgICBvYmplY3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKElEaXJlY3REcmF3UGFsZXR0ZUltcGwpKTsKICAgIGlmKCFvYmplY3QpCiAgICB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgcGFsZXR0ZSBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3UGFsZXR0ZSwgSURpcmVjdERyYXdQYWxldHRlX1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT5kZHJhd19vd25lciA9IFRoaXM7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVQYWxldHRlKFRoaXMtPndpbmVEM0REZXZpY2UsIEZsYWdzLCBDb2xvclRhYmxlLCAmb2JqZWN0LT53aW5lRDNEUGFsZXR0ZSwgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlKSApOwogICAgaWYoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgSURpcmVjdERyYXc3X0FkZFJlZihpZmFjZSk7CiAgICBvYmplY3QtPmlmYWNlVG9SZWxlYXNlID0gKElVbmtub3duICopIGlmYWNlOwogICAgKlBhbGV0dGUgPSBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3UGFsZXR0ZSk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkR1cGxpY2F0ZVN1cmZhY2UKICoKICogRHVwbGljYXRlcyBhIHN1cmZhY2UuIFRoZSBzdXJmYWNlIG1lbW9yeSBwb2ludHMgdG8gdGhlIHNhbWUgbWVtb3J5IGFzCiAqIHRoZSBvcmlnaW5hbCBzdXJmYWNlLCBhbmQgaXQncyByZWxlYXNlZCB3aGVuIHRoZSBsYXN0IHN1cmZhY2UgcmVmZXJlbmNpbmcKICogaXQgaXMgcmVsZWFzZWQuIEkgZ3Vlc3MgdGhhdCdzIGJleW9uZCBXaW5lJ3Mgc3VyZmFjZSBtYW5hZ2VtZW50IHJpZ2h0IG5vdwogKiAoSWRlYTogY3JlYXRlIGEgbmV3IEREcmF3IHN1cmZhY2Ugd2l0aCB0aGUgc2FtZSBXaW5lRDNEU3VyZmFjZS4gSSBuZWVkIGEKICogdGVzdCBhcHBsaWNhdGlvbiB0byBpbXBsZW1lbnQgdGhpcykKICoKICogUGFyYW1zOgogKiAgU3JjOiBBZGRyZXNzIG9mIHRoZSBzb3VyY2Ugc3VyZmFjZQogKiAgRGVzdDogQWRkcmVzcyB0byB3cml0ZSB0aGUgbmV3IHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgU2VlIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRHVwbGljYXRlU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipEZXN0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqU3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyYyk7CgogICAgRklYTUUoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIFN1cmYsIERlc3QpOwoKICAgIC8qIEZvciBub3csIHNpbXBseSBjcmVhdGUgYSBuZXcsIGluZGVwZW5kZW50IHN1cmZhY2UgKi8KICAgIHJldHVybiBJRGlyZWN0RHJhdzdfQ3JlYXRlU3VyZmFjZShpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3VyZi0+c3VyZmFjZV9kZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzcgVlRhYmxlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KY29uc3QgSURpcmVjdERyYXc3VnRibCBJRGlyZWN0RHJhdzdfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gKioqLwogICAgSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3SW1wbF9SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0RHJhdyAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfQ29tcGFjdCwKICAgIElEaXJlY3REcmF3SW1wbF9DcmVhdGVDbGlwcGVyLAogICAgSURpcmVjdERyYXdJbXBsX0NyZWF0ZVBhbGV0dGUsCiAgICBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlU3VyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9EdXBsaWNhdGVTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0VudW1EaXNwbGF5TW9kZXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzLAogICAgSURpcmVjdERyYXdJbXBsX0ZsaXBUb0dESVN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0Q2FwcywKICAgIElEaXJlY3REcmF3SW1wbF9HZXREaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRGb3VyQ0NDb2RlcywKICAgIElEaXJlY3REcmF3SW1wbF9HZXRHRElTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0dldE1vbml0b3JGcmVxdWVuY3ksCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0U2NhbkxpbmUsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0VmVydGljYWxCbGFua1N0YXR1cywKICAgIElEaXJlY3REcmF3SW1wbF9Jbml0aWFsaXplLAogICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVEaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsLAogICAgSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlLAogICAgSURpcmVjdERyYXdJbXBsX1dhaXRGb3JWZXJ0aWNhbEJsYW5rLAogICAgLyoqKiBJRGlyZWN0RHJhdzIgKioqLwogICAgSURpcmVjdERyYXdJbXBsX0dldEF2YWlsYWJsZVZpZE1lbSwKICAgIC8qKiogSURpcmVjdERyYXc3ICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9HZXRTdXJmYWNlRnJvbURDLAogICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVBbGxTdXJmYWNlcywKICAgIElEaXJlY3REcmF3SW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbCwKICAgIElEaXJlY3REcmF3SW1wbF9HZXREZXZpY2VJZGVudGlmaWVyLAogICAgLyoqKiBJRGlyZWN0RHJhdzcgKioqLwogICAgSURpcmVjdERyYXdJbXBsX1N0YXJ0TW9kZVRlc3QsCiAgICBJRGlyZWN0RHJhd0ltcGxfRXZhbHVhdGVNb2RlCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX0ZpbmREZWNsCiAqCiAqIEZpbmRzIHRoZSBXaW5lRDNEIHZlcnRleCBkZWNsYXJhdGlvbiBmb3IgYSBzcGVjaWZpYyBmdmYsIGFuZCBjcmVhdGVzIG9uZQogKiBpZiBub25lIHdhcyBmb3VuZC4KICoKICogVGhpcyBmdW5jdGlvbiBpcyBpbiBkZHJhdy5jIGFuZCB0aGUgRERyYXcgb2JqZWN0IHNwYWNlIGJlY2F1c2UgRDNENwogKiB2ZXJ0ZXggYnVmZmVycyBhcmUgY3JlYXRlZCB1c2luZyB0aGUgSURpcmVjdDNEIGludGVyZmFjZSB0byB0aGUgZGRyYXcKICogb2JqZWN0LCBzbyB0aGV5IGNhbiBiZSB2YWxpZCBhY3Jvc3MgRDNEIGRldmljZXModGhlb3JldGljYWxseS4gVGhlIGRkcmF3CiAqIG9iamVjdCBhbHNvIG93bnMgdGhlIHdpbmVkM2QgZGV2aWNlCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBUaGlzOiBEZXZpY2UKICogIGZ2ZjogRnZmIHRvIGZpbmQgdGhlIGRlY2wgZm9yCiAqCiAqIFJldHVybnM6CiAqICBOVUxMIGluIGNhc2Ugb2YgYW4gZXJyb3IsIHRoZSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uIGludGVyZmFjZSBmb3IgdGhlCiAqICBmdmYgb3RoZXJ3aXNlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCklXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKgpJRGlyZWN0RHJhd0ltcGxfRmluZERlY2woSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZnZmKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiogcERlY2wgPSBOVUxMOwogICAgaW50IHAsIGxvdywgaGlnaDsgLyogZGVsaWJlcmF0ZWx5IHNpZ25lZCAqLwogICAgc3RydWN0IEZ2ZlRvRGVjbCAqY29udmVydGVkRGVjbHMgPSBUaGlzLT5kZWNsczsKCiAgICBUUkFDRSgiU2VhcmNoaW5nIGZvciBkZWNsYXJhdGlvbiBmb3IgZnZmICUwOHguLi4gIiwgZnZmKTsKCiAgICBsb3cgPSAwOwogICAgaGlnaCA9IFRoaXMtPm51bUNvbnZlcnRlZERlY2xzIC0gMTsKICAgIHdoaWxlKGxvdyA8PSBoaWdoKSB7CiAgICAgICAgcCA9IChsb3cgKyBoaWdoKSA+PiAxOwogICAgICAgIFRSQUNFKCIlZCAiLCBwKTsKICAgICAgICBpZihjb252ZXJ0ZWREZWNsc1twXS5mdmYgPT0gZnZmKSB7CiAgICAgICAgICAgIFRSQUNFKCJmb3VuZCAlcFxuIiwgY29udmVydGVkRGVjbHNbcF0uZGVjbCk7CiAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZWREZWNsc1twXS5kZWNsOwogICAgICAgIH0gZWxzZSBpZihjb252ZXJ0ZWREZWNsc1twXS5mdmYgPCBmdmYpIHsKICAgICAgICAgICAgbG93ID0gcCArIDE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaGlnaCA9IHAgLSAxOwogICAgICAgIH0KICAgIH0KICAgIFRSQUNFKCJub3QgZm91bmQuIENyZWF0aW5nIGFuZCBpbnNlcnRpbmcgYXQgcG9zaXRpb24gJWQuXG4iLCBsb3cpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb25Gcm9tRlZGKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcERlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ2Zik7CiAgICBpZiAoaHIgIT0gU19PSykgcmV0dXJuIE5VTEw7CgogICAgaWYoVGhpcy0+ZGVjbEFycmF5U2l6ZSA9PSBUaGlzLT5udW1Db252ZXJ0ZWREZWNscykgewogICAgICAgIGludCBncm93ID0gbWF4KFRoaXMtPmRlY2xBcnJheVNpemUgLyAyLCA4KTsKICAgICAgICBjb252ZXJ0ZWREZWNscyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvbnZlcnRlZERlY2xzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGNvbnZlcnRlZERlY2xzWzBdKSAqIChUaGlzLT5udW1Db252ZXJ0ZWREZWNscyArIGdyb3cpKTsKICAgICAgICBpZighY29udmVydGVkRGVjbHMpIHsKICAgICAgICAgICAgLyogVGhpcyB3aWxsIGRlc3Ryb3kgaXQgKi8KICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9SZWxlYXNlKHBEZWNsKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmRlY2xzID0gY29udmVydGVkRGVjbHM7CiAgICAgICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSArPSBncm93OwogICAgfQoKICAgIG1lbW1vdmUoY29udmVydGVkRGVjbHMgKyBsb3cgKyAxLCBjb252ZXJ0ZWREZWNscyArIGxvdywgc2l6ZW9mKGNvbnZlcnRlZERlY2xzWzBdKSAqIChUaGlzLT5udW1Db252ZXJ0ZWREZWNscyAtIGxvdykpOwogICAgY29udmVydGVkRGVjbHNbbG93XS5kZWNsID0gcERlY2w7CiAgICBjb252ZXJ0ZWREZWNsc1tsb3ddLmZ2ZiA9IGZ2ZjsKICAgIFRoaXMtPm51bUNvbnZlcnRlZERlY2xzKys7CgogICAgVFJBQ0UoIlJldHVybmluZyAlcC4gJWQgZGVjbHMgaW4gYXJyYXlcbiIsIHBEZWNsLCBUaGlzLT5udW1Db252ZXJ0ZWREZWNscyk7CiAgICByZXR1cm4gcERlY2w7Cn0K