LyoKICogQ29weXJpZ2h0IDE5OTctMjAwMCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IDIwMDAtMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCnN0YXRpYyBCT09MIElEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKGNvbnN0IEREU1VSRkFDRURFU0MyKiByZXF1ZXN0ZWQsIGNvbnN0IEREU1VSRkFDRURFU0MyKiBwcm92aWRlZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcHJpbWFyeSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsIEREU1VSRkFDRURFU0MyICpwRERTRCwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnBwU3VyZiwgVUlOVCBsZXZlbCk7CgovKiBEZXZpY2UgaWRlbnRpZmllci4gRG9uJ3QgcmVsYXkgaXQgdG8gV2luZUQzRCAqLwpzdGF0aWMgY29uc3QgRERERVZJQ0VJREVOVElGSUVSMiBkZXZpY2VpZGVudGlmaWVyID0KewogICAgImRpc3BsYXkiLAogICAgIkRpcmVjdERyYXcgSEFMIiwKICAgIHsgeyAweDAwMDEwMDAxLCAweDAwMDEwMDAxIH0gfSwKICAgIDAsIDAsIDAsIDAsCiAgICAvKiBhODM3M2MxMC03YWM0LTRkZWItODQ5YS0wMDk4NDRkMDhiMmQgKi8KICAgIHsweGE4MzczYzEwLDB4N2FjNCwweDRkZWIsIHsweDg0LDB4OWEsMHgwMCwweDk4LDB4NDQsMHhkMCwweDhiLDB4MmR9fSwKICAgIDAKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBNZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJpZXMgZGlmZmVyZW50IGludGVyZmFjZXMgb2YgdGhlIERpcmVjdERyYXcgb2JqZWN0LiBJdCBjYW4gcmV0dXJuCiAqIElEaXJlY3REcmF3IGludGVyZmFjZXMgaW4gdmVyc2lvbiAxLCAyLCA0IGFuZCA3LCBhbmQgSURpcmVjdDNEIGludGVyZmFjZXMKICogaW4gdmVyc2lvbiAxLCAyLCAzIGFuZCA3LiBBbiBJRGlyZWN0M0REZXZpY2UgY2FuIGJlIGNyZWF0ZWQgd2l0aCB0aGlzCiAqIG1ldGhvZC4KICogVGhlIHJldHVybmVkIGludGVyZmFjZSBpcyBBZGRSZWYoKS1lZCBiZWZvcmUgaXQncyByZXR1cm5lZAogKgogKiBSdWxlcyBmb3IgUXVlcnlJbnRlcmZhY2U6CiAqICBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/IFwKICogICAgdXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG1sLzZkYjE3ZWQ4LTA2ZTQtNGJhZS1iYzI2LTExMzE3NmNjN2UwZS5hc3AKICoKICogVXNlZCBmb3IgdmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIHJlZmlpZDogSW50ZXJmYWNlIElEIGFza2VkIGZvcgogKiAgb2JqOiBVc2VkIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIFNfT0sgaWYgYW4gaW50ZXJmYWNlIHdhcyBmb3VuZAogKiAgRV9OT0lOVEVSRkFDRSBpZiB0aGUgcmVxdWVzdGVkIGludGVyZmFjZSB3YXNuJ3QgZm91bmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmVmaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICAgIC8qIENhbiBjaGFuZ2Ugc3VyZmFjZSBpbXBsIHR5cGUgKi8KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgLyogQWNjb3JkaW5nIHRvIENPTSBkb2NzLCBpZiB0aGUgUXVlcnlJbnRlcmZhY2UgZmFpbHMsIG9iaiBzaG91bGQgYmUgc2V0IHRvIE5VTEwgKi8KICAgICpvYmogPSBOVUxMOwoKICAgIGlmKCFyZWZpaWQpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAvKiBDaGVjayBEaXJlY3REcmF3IEludGVyZmFjZXMgKi8KICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSVVua25vd24sIHJlZmlpZCApIHx8CiAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3NywgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzQsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc0KTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXc0IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXczLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3Myk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3MyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3MiwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzIpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzIgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdywgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3IGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CgogICAgLyogRGlyZWN0M0QKICAgICAqIFRoZSByZWZjb3VudCB1bml0IHRlc3QgcmV2ZWFsZWQgdGhhdCBhbiBJRGlyZWN0M0Q3IGludGVyZmFjZSBjYW4gb25seSBiZSBxdWVyaWVkCiAgICAgKiBmcm9tIGEgRGlyZWN0RHJhdyBvYmplY3QgdGhhdCB3YXMgY3JlYXRlZCBhcyBhbiBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlLiBObyBpZGVhCiAgICAgKiB3aG8gaGFkIHRoaXMgaWRlYSBhbmQgd2h5LiBUaGUgb2xkZXIgaW50ZXJmYWNlcyBjYW4gcXVlcnkgYW5kIElEaXJlY3QzRCB2ZXJzaW9uCiAgICAgKiBiZWNhdXNlIHRoZXkgYXJlIGFsbCBjcmVhdGVkIGFzIElEaXJlY3REcmF3KDEpLiBUaGlzIGlzbid0IHJlYWxseSBjcnVjaWFsIGJlaGF2aW9yLAogICAgICogYW5kIG1lc3N5IHRvIGltcGxlbWVudCB3aXRoIHRoZSBjb21tb24gY3JlYXRpb24gZnVuY3Rpb24sIHNvIGl0IGhhcyBiZWVuIGxlZnQgb3V0IGhlcmUuCiAgICAgKi8KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QgICwgcmVmaWlkICkgfHwKICAgICAgICAgICAgICBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QyICwgcmVmaWlkICkgfHwKICAgICAgICAgICAgICBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QzICwgcmVmaWlkICkgfHwKICAgICAgICAgICAgICBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0Q3ICwgcmVmaWlkICkgKQogICAgewogICAgICAgIC8qIENoZWNrIHRoZSBzdXJmYWNlIGltcGxlbWVudGF0aW9uICovCiAgICAgICAgaWYoVGhpcy0+SW1wbFR5cGUgPT0gU1VSRkFDRV9VTktOT1dOKQogICAgICAgIHsKICAgICAgICAgICAgLyogQXBwcyBtYXkgY3JlYXRlIHRoZSBJRGlyZWN0M0QgSW50ZXJmYWNlIGJlZm9yZSB0aGUgcHJpbWFyeSBzdXJmYWNlLgogICAgICAgICAgICAgKiBzZXQgdGhlIHN1cmZhY2UgaW1wbGVtZW50YXRpb24gKi8KICAgICAgICAgICAgVGhpcy0+SW1wbFR5cGUgPSBTVVJGQUNFX09QRU5HTDsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQ2hvb3NpbmcgT3BlbkdMIHN1cmZhY2VzIGJlY2F1c2UgYSBEaXJlY3QzRCBpbnRlcmZhY2Ugd2FzIHJlcXVlc3RlZFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wgJiYgRGVmYXVsdFN1cmZhY2VUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiKCVwKSBUaGUgQXBwIGlzIHJlcXVlc3RpbmcgYSBEM0QgZGV2aWNlLCBidXQgYSBub24tT3BlbkdMIHN1cmZhY2UgdHlwZSB3YXMgY2hvb3Nlbi4gUHJlcGFyZSBmb3IgdHJvdWJsZSFcbiIsIFRoaXMpOwogICAgICAgICAgICBFUlIoIiAoJXApIFlvdSBtYXkgd2FudCB0byBjb250YWN0IHdpbmUtZGV2ZWwgZm9yIGhlbHBcbiIsIFRoaXMpOwogICAgICAgICAgICAvKiBTaG91bGQgSSBhc3NlcnQoMCkgaGVyZT8/PyAqLwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiVGhlIGFwcCByZXF1ZXN0cyBhIERpcmVjdDNEIGludGVyZmFjZSwgYnV0IG5vbi1vcGVuZ2wgc3VyZmFjZXMgd2hlcmUgc2V0IGluIHdpbmVjZmdcbiIpOwogICAgICAgICAgICAvKiBEbyBub3QgYWJvcnQgaGVyZSwgb25seSByZWplY3QgM0QgRGV2aWNlIGNyZWF0aW9uICovCiAgICAgICAgfQoKICAgICAgICBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRCAgLCByZWZpaWQgKSApCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5kM2R2ZXJzaW9uID0gMTsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRCk7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEIGludGVyZmFjZSBhdCAlcC5cbiIsICpvYmopOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEMiAgLCByZWZpaWQgKSApCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5kM2R2ZXJzaW9uID0gMjsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDIpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRDIgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QzICAsIHJlZmlpZCApICkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSAzOwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEMyk7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEMyBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0Q3ICAsIHJlZmlpZCApKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDc7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0Q3KTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0Q3IGludGVyZmFjZSBhdCAlcC5cbiIsICpvYmopOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBVbmtub3duIGludGVyZmFjZSAqLwogICAgZWxzZQogICAgewogICAgICAgIEVSUigiKCVwKS0+KCVzLCAlcCk6IE5vIGludGVyZmFjZSBmb3VuZFxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CgogICAgSVVua25vd25fQWRkUmVmKCAoSVVua25vd24gKikgKm9iaiApOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpBZGRSZWYKICoKICogSW5jcmVhc2VzIHRoZSBpbnRlcmZhY2VzIHJlZmNvdW50LCBiYXNpY2FsbHkKICoKICogRERyYXcgcmVmY291bnRpbmcgaXMgYSBiaXQgdHJpY2t5LiBUaGUgZGlmZmVyZW50IERpcmVjdERyYXcgaW50ZXJmYWNlCiAqIHZlcnNpb25zIGhhdmUgaW5kaXZpZHVhbCByZWZjb3VudHMsIGJ1dCB0aGUgSURpcmVjdDNEIGludGVyZmFjZXMgZG8gbm90LgogKiBBbGwgaW50ZXJmYWNlcyBhcmUgZnJvbSBvbmUgb2JqZWN0LCB0aGF0IG1lYW5zIGNhbGxpbmcgUXVlcnlJbnRlcmZhY2Ugb24gYW4KICogSURpcmVjdERyYXc3IGludGVyZmFjZSBmb3IgYW4gSURpcmVjdERyYXc0IGludGVyZmFjZSBkb2VzIG5vdCBjcmVhdGUgYSBuZXcKICogSURpcmVjdERyYXdJbXBsIG9iamVjdC4KICoKICogVGhhdCBtZWFucyBhbGwgQWRkUmVmIGFuZCBSZWxlYXNlIGltcGxlbWVudGF0aW9ucyBvZiBJRGlyZWN0RHJhd1ggd29yawogKiB3aXRoIHRoZWlyIG93biBjb3VudGVyLCBhbmQgSURpcmVjdDNEWDo6QWRkUmVmIHRodW5rIHRvIElEaXJlY3REcmF3ICgxKSwKICogZXhjZXB0IG9mIElEaXJlY3QzRDcgd2hpY2ggdGh1bmtzIHRvIElEaXJlY3REcmF3NwogKgogKiBSZXR1cm5zOiBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQWRkUmVmKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmNyk7CgogICAgVFJBQ0UoIiglcCkgOiBpbmNyZW1lbnRpbmcgSURpcmVjdERyYXc3IHJlZmNvdW50IGZyb20gJXUuXG4iLCBUaGlzLCByZWYgLTEpOwoKICAgIGlmKHJlZiA9PSAxKSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+bnVtSWZhY2VzKTsKCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX0Rlc3Ryb3kKICoKICogRGVzdHJveXMgYSBkZHJhdyBvYmplY3QgaWYgYWxsIHJlZmNvdW50cyBhcmUgMC4gVGhpcyBpcyB0byBzaGFyZSBjb2RlCiAqIGJldHdlZW4gdGhlIElEaXJlY3REcmF3WDo6UmVsZWFzZSBmdW5jdGlvbnMKICoKICogUGFyYW1zOgogKiAgVGhpczogRGlyZWN0RHJhdyBvYmplY3QgdG8gZGVzdHJveQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQKSURpcmVjdERyYXdJbXBsX0Rlc3Ryb3koSURpcmVjdERyYXdJbXBsICpUaGlzKQp7CiAgICAvKiBDbGVhciB0aGUgY29vcGxldmVsIHRvIHJlc3RvcmUgd2luZG93IGFuZCBkaXNwbGF5IG1vZGUgKi8KICAgIElEaXJlY3REcmF3N19TZXRDb29wZXJhdGl2ZUxldmVsKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfTk9STUFMKTsKCiAgICAvKiBEZXN0cm95IHRoZSBkZXZpY2Ugd2luZG93IGlmIHdlIGNyZWF0ZWQgb25lICovCiAgICBpZihUaGlzLT5kZXZpY2V3aW5kb3cgIT0gMCkKICAgIHsKICAgICAgICBUUkFDRSgiICglcCkgRGVzdHJveWluZyB0aGUgZGV2aWNlIHdpbmRvdyAlcFxuIiwgVGhpcywgVGhpcy0+ZGV2aWNld2luZG93KTsKICAgICAgICBEZXN0cm95V2luZG93KFRoaXMtPmRldmljZXdpbmRvdyk7CiAgICAgICAgVGhpcy0+ZGV2aWNld2luZG93ID0gMDsKICAgIH0KCiAgICAvKiBVbnJlZ2lzdGVyIHRoZSB3aW5kb3cgY2xhc3MgKi8KICAgIFVucmVnaXN0ZXJDbGFzc0EoVGhpcy0+Y2xhc3NuYW1lLCAwKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgbGlzdF9yZW1vdmUoJlRoaXMtPmRkcmF3X2xpc3RfZW50cnkpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAvKiBSZWxlYXNlIHRoZSBhdHRhY2hlZCBXaW5lRDNEIHN0dWZmICovCiAgICBJV2luZUQzRERldmljZV9SZWxlYXNlKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgSVdpbmVEM0RfUmVsZWFzZShUaGlzLT53aW5lRDNEKTsKCiAgICAvKiBOb3cgZnJlZSB0aGUgb2JqZWN0ICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVsZWFzZQogKgogKiBEZWNyZWFzZXMgdGhlIHJlZmNvdW50LiBJZiB0aGUgcmVmY291bnQgZmFsbHMgdG8gMCwgdGhlIG9iamVjdCBpcyBkZXN0cm95ZWQKICoKICogUmV0dXJuczogVGhlIG5ldyByZWZjb3VudAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1JlbGVhc2UoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWY3KTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgZGVjcmVtZW50aW5nIElEaXJlY3REcmF3NyByZWZjb3VudCBmcm9tICV1LlxuIiwgVGhpcywgcmVmICsxKTsKCiAgICBpZihyZWYgPT0gMCkKICAgIHsKICAgICAgICBVTE9ORyBpZmFjZWNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPm51bUlmYWNlcyk7CiAgICAgICAgaWYoaWZhY2Vjb3VudCA9PSAwKSBJRGlyZWN0RHJhd0ltcGxfRGVzdHJveShUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXcgbWV0aG9kcwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpTZXRDb29wZXJhdGl2ZUxldmVsCiAqCiAqIFNldHMgdGhlIGNvb3BlcmF0aXZlIGxldmVsIGZvciB0aGUgRGlyZWN0RHJhdyBvYmplY3QsIGFuZCB0aGUgd2luZG93CiAqIGFzc2lnbmVkIHRvIGl0LiBUaGUgY29vcGVyYXRpdmUgbGV2ZWwgZGV0ZXJtaW5lcyB0aGUgZ2VuZXJhbCBiZWhhdmlvcgogKiBvZiB0aGUgRGlyZWN0RHJhdyBhcHBsaWNhdGlvbgogKgogKiBXYXJuaW5nOiBUaGlzIGlzIHF1aXRlIHRyaWNreSwgYXMgaXQncyBub3QgcmVhbGx5IGRvY3VtZW50ZWQgd2hpY2gKICogY29vcGVyYXRpdmUgbGV2ZWxzIGNhbiBiZSBjb21iaW5lZCB3aXRoIGVhY2ggb3RoZXIuIElmIGEgZ2FtZSBmYWlscwogKiBhZnRlciB0aGlzIGZ1bmN0aW9uLCB0cnkgdG8gY2hlY2sgdGhlIGNvb3BlcmF0aXZlIGxldmVscyBwYXNzZWQgb24KICogV2luZG93cywgYW5kIGlmIGl0IHJldHVybnMgc29tZXRoaW5nIGRpZmZlcmVudC4KICoKICogSWYgeW91IHRoaW5rIHRoYXQgdGhpcyBmdW5jdGlvbiBjYXVzZWQgdGhlIGZhaWx1cmUgYmVjYXVzZSBpdCB3cml0ZXMgYQogKiBmaXhtZSwgYmUgc3VyZSB0byBydW4gYWdhaW4gd2l0aCBhICtkZHJhdyB0cmFjZS4KICoKICogV2hhdCBpcyBrbm93biBhYm91dCBjb29wZXJhdGl2ZSBsZXZlbHMgKFNlZSB0aGUgZGRyYXcgbW9kZXMgdGVzdCk6CiAqIEREU0NMX0VYQ0xVU0lWRSBhbmQgRERTQ0xfRlVMTFNDUkVFTiBtdXN0IGJlIHVzZWQgd2l0aCBlYWNoIG90aGVyCiAqIEREU0NMX05PUk1BTCBpcyBub3QgY29tcGF0aWJsZSB3aXRoIEREU0NMX0VYQ0xVU0lWRSBvciBERFNDTF9GVUxMU0NSRUVOCiAqIEREU0NMX1NFVEZPQ1VTV0lORE9XIGNhbiBiZSBwYXNzZWQgb25seSBpbiBERFNDTF9OT1JNQUwgbW9kZSwgYnV0IGFmdGVyIHRoYXQKICogRERTQ0xfRlVMTFNDUkVFTiBjYW4gYmUgYWN0aXZhdGVkCiAqIEREU0NMX1NFVEZPQ1VTV0lORE9XIG1heSBvbmx5IGJlIHVzZWQgd2l0aCBERFNDTF9OT1dJTkRPV0NIQU5HRVMKICoKICogSGFuZGxlZCBmbGFnczogRERTQ0xfTk9STUFMLCBERFNDTF9GVUxMU0NSRUVOLCBERFNDTF9FWENMVVNJVkUsCiAqICAgICAgICAgICAgICAgIEREU0NMX1NFVEZPQ1VTV0lORE9XIChwYXJ0aWFsbHkpLAogKiAgICAgICAgICAgICAgICBERFNDTF9NVUxUSVRIUkVBREVEICh3b3JrIGluIHByb2dyZXNzKQogKgogKiBVbmhhbmRsZWQgZmxhZ3MsIHdoaWNoIHNob3VsZCBiZSBpbXBsZW1lbnRlZAogKiAgRERTQ0xfU0VUREVWSUNFV0lORE9XOiBTZXRzIGEgd2luZG93IHNwZWNpYWxseSB1c2VkIGZvciByZW5kZXJpbmcgKEkgZG9uJ3QKICogIGV4cGVjdCBhbnkgZGlmZmVyZW5jZSB0byBhIG5vcm1hbCB3aW5kb3cgZm9yIHdpbmUpCiAqICBERFNDTF9DUkVBVEVERVZJQ0VXSU5ET1c6IFRlbGxzIGRkcmF3IHRvIGNyZWF0ZSBpdHMgb3duIHdpbmRvdyBmb3IKICogIHJlbmRlcmluZyAoUG9zc2libGUgdGVzdCBjYXNlOiBIYWxmLWxpZmUpCiAqCiAqIFVuc3VyZSBhYm91dCB0aGVzZTogRERTQ0xfRlBVU0VUVVAgRERTQ0xfRlBVUkVTRVJWRQogKgogKiBUaGVzZSBzZWVtIG5vdCByZWFsbHkgaW1wb3JhbnQgZm9yIHdpbmUKICogIEREU0NMX0FMTE9XUkVCT09ULCBERFNDTF9OT1dJTkRPV0NIQU5HRVMsIEREU0NMX0FMTE9XTU9ERVgKICoKICogUmV0dXJuczoKICogIEREX09LIGlmIHRoZSBjb29wZXJhdGl2ZSBsZXZlbCB3YXMgc2V0IHN1Y2Nlc3NmdWxseQogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgcGFzc2VkIGNvb3BlcmF0aXZlIGxldmVsIGNvbWJpbmF0aW9uIGlzIGludmFsaWQKICogIERERVJSX0hXTkRBTFJFQURZU0VUIGlmIEREU0NMX1NFVEZPQ1VTV0lORE9XIGlzIHBhc3NlZCBpbiBleGNsdXNpdmUgbW9kZQogKiAgIChQcm9iYWJseSBvdGhlcnMgdG9vLCBoYXZlIHRvIGludmVzdGlnYXRlKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbChJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIGh3bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNvb3BsZXZlbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEhXTkQgd2luZG93OwogICAgSFJFU1VMVCBocjsKCiAgICBGSVhNRSgiKCVwKS0+KCVwLCUwOHgpXG4iLFRoaXMsaHduZCxjb29wbGV2ZWwpOwogICAgRERSQVdfZHVtcF9jb29wZXJhdGl2ZWxldmVsKGNvb3BsZXZlbCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICAvKiBHZXQgdGhlIG9sZCB3aW5kb3cgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCAmd2luZG93KTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNERGV2aWNlOjpHZXRIV05EIGZhaWxlZCwgaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogVGVzdHMgc3VnZ2VzdCB0aGF0IHdlIG5lZWQgb25lIG9mIHRoZW06ICovCiAgICBpZighKGNvb3BsZXZlbCAmIChERFNDTF9TRVRGT0NVU1dJTkRPVyB8CiAgICAgICAgICAgICAgICAgICAgICBERFNDTF9OT1JNQUwgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICBERFNDTF9FWENMVVNJVkUgICAgICApKSkKICAgIHsKICAgICAgICBUUkFDRSgiSW5jb3JyZWN0IGNvb3BsZXZlbCBmbGFncywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogSGFuZGxlIHRob3NlIGxldmVscyBmaXJzdCB3aGljaCBzZXQgdmFyaW91cyBod25kcyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfU0VURk9DVVNXSU5ET1cpCiAgICB7CiAgICAgICAgLyogVGhpcyBpc24ndCBjb21wYXRpYmxlIHdpdGggYSBsb3Qgb2YgZmxhZ3MgKi8KICAgICAgICBpZihjb29wbGV2ZWwgJiAoIEREU0NMX01VTFRJVEhSRUFERUQgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9GUFVTRVRVUCAgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlBVUFJFU0VSVkUgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0FMTE9XUkVCT09UICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9BTExPV01PREVYICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfU0VUREVWSUNFV0lORE9XIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX05PUk1BTCAgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9FWENMVVNJVkUgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlVMTFNDUkVFTiAgICAgICkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIkNhbGxlZCB3aXRoIGluY29tcGF0aWJsZSBmbGFncywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRlVMTFNDUkVFTikgJiYgd2luZG93KQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgRERTQ0xfU0VURk9DVVNXSU5ET1cgd2l0aCBhbiBhbHJlYWR5IHNldCB3aW5kb3csIHJldHVybmluZyBEREVSUl9IV05EQUxSRUFEWVNFVFxuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9IV05EQUxSRUFEWVNFVDsKICAgICAgICB9CgogICAgICAgIFRoaXMtPmZvY3Vzd2luZG93ID0gaHduZDsKICAgICAgICAvKiBXb24ndCB1c2UgdGhlIGh3bmQgcGFyYW0gZm9yIGFueXRoaW5nIGVsc2UgKi8KICAgICAgICBod25kID0gTlVMTDsKCiAgICAgICAgLyogVXNlIHRoZSBmb2N1cyB3aW5kb3cgZm9yIGRyYXdpbmcgdG9vICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBUaGlzLT5mb2N1c3dpbmRvdyk7CgogICAgICAgIC8qIERlc3Ryb3kgdGhlIGRldmljZSB3aW5kb3csIGlmIHdlIGhhdmUgb25lICovCiAgICAgICAgaWYoVGhpcy0+ZGV2aWNld2luZG93KQogICAgICAgIHsKICAgICAgICAgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIC8qIEREU0NMX05PUk1BTCBvciBERFNDTF9GVUxMU0NSRUVOIHwgRERTQ0xfRVhDTFVTSVZFICovCiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9OT1JNQUwpCiAgICB7CiAgICAgICAgLyogQ2FuJ3QgY29leGlzdCB3aXRoIGZ1bGxzY3JlZW4gb3IgZXhjbHVzaXZlICovCiAgICAgICAgaWYoY29vcGxldmVsICYgKEREU0NMX0ZVTExTQ1JFRU4gfCBERFNDTF9FWENMVVNJVkUpICkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIEREU0NMX05PUk1BTCBpcyBub3QgY29tcGF0aXZlIHdpdGggRERTQ0xfRlVMTFNDUkVFTiBvciBERFNDTF9FWENMVVNJVkVcbiIsIFRoaXMpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CgogICAgICAgIC8qIFN3aXRjaGluZyBmcm9tIGZ1bGxzY3JlZW4/ICovCiAgICAgICAgaWYoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9GVUxMU0NSRUVOKQogICAgICAgIHsKICAgICAgICAgICAgLyogUmVzdG9yZSB0aGUgZGlzcGxheSBtb2RlICovCiAgICAgICAgICAgIElEaXJlY3REcmF3N19SZXN0b3JlRGlzcGxheU1vZGUoaWZhY2UpOwoKICAgICAgICAgICAgVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJj0gfkREU0NMX0ZVTExTQ1JFRU47CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9FWENMVVNJVkU7CiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9BTExPV01PREVYOwogICAgICAgIH0KCiAgICAgICAgLyogRG9uJ3Qgb3ZlcnJpZGUgZm9jdXMgd2luZG93cyBvciBwcml2YXRlIGRldmljZSB3aW5kb3dzICovCiAgICAgICAgaWYoIGh3bmQgJiYKICAgICAgICAgICAgIShUaGlzLT5mb2N1c3dpbmRvdykgJiYKICAgICAgICAgICAgIShUaGlzLT5kZXZpY2V3aW5kb3cpICYmCiAgICAgICAgICAgIChod25kICE9IHdpbmRvdykgKQogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBod25kKTsKICAgICAgICB9CgogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFKTsKICAgIH0KICAgIGVsc2UgaWYoY29vcGxldmVsICYgRERTQ0xfRlVMTFNDUkVFTikKICAgIHsKICAgICAgICAvKiBOZWVkcyBERFNDTF9FWENMVVNJVkUgKi8KICAgICAgICBpZighKGNvb3BsZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfRlVMTFNDUkVFTiBuZWVkcyBERFNDTF9FWENMVVNJVkVcbiIsIFRoaXMpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgLyogTmVlZCBhIEhXTkQKICAgICAgICBpZihod25kID09IDApCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBERFNDTF9GVUxMU0NSRUVOIG5lZWRzIGEgSFdORFxuIiwgVGhpcyk7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgIH0KICAgICAgICAqLwoKICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfTk9STUFMOwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUpOwoKICAgICAgICAvKiBEb24ndCBvdmVycmlkZSBmb2N1cyB3aW5kb3dzIG9yIHByaXZhdGUgZGV2aWNlIHdpbmRvd3MgKi8KICAgICAgICBpZiggaHduZCAmJgogICAgICAgICAgICAhKFRoaXMtPmZvY3Vzd2luZG93KSAmJgogICAgICAgICAgICAhKFRoaXMtPmRldmljZXdpbmRvdykgJiYKICAgICAgICAgICAgKGh3bmQgIT0gd2luZG93KSApCiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsIGh3bmQpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYoY29vcGxldmVsICYgRERTQ0xfRVhDTFVTSVZFKQogICAgewogICAgICAgIFRSQUNFKCIoJXApIEREU0NMX0VYQ0xVU0lWRSBuZWVkcyBERFNDTF9GVUxMU0NSRUVOXG4iLCBUaGlzKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0NSRUFURURFVklDRVdJTkRPVykKICAgIHsKICAgICAgICAvKiBEb24ndCBjcmVhdGUgYSBkZXZpY2Ugd2luZG93IGlmIGEgZm9jdXMgd2luZG93IGlzIHNldCAqLwogICAgICAgIGlmKCAhKFRoaXMtPmZvY3Vzd2luZG93KSApCiAgICAgICAgewogICAgICAgICAgICBIV05EIGRldmljZXdpbmRvdyA9IENyZWF0ZVdpbmRvd0V4QSgwLCBUaGlzLT5jbGFzc25hbWUsICJERHJhdyBkZXZpY2Ugd2luZG93IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfUE9QVVAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgR2V0TW9kdWxlSGFuZGxlQSgwKSwgTlVMTCk7CgogICAgICAgICAgICBTaG93V2luZG93KGRldmljZXdpbmRvdywgU1dfU0hPVyk7ICAgLyogSnVzdCB0byBiZSBzdXJlICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIENyZWF0ZWQgYSBERHJhdyBkZXZpY2Ugd2luZG93LiBIV05EPSVwXG4iLCBUaGlzLCBkZXZpY2V3aW5kb3cpOwoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBkZXZpY2V3aW5kb3cpOwogICAgICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSBkZXZpY2V3aW5kb3c7CiAgICAgICAgfQogICAgfQoKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX01VTFRJVEhSRUFERUQgJiYgIShUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX01VTFRJVEhSRUFERUQpKQogICAgewogICAgICAgIC8qIEVuYWJsZSB0aHJlYWQgc2FmZXR5IGluIHdpbmVkM2QgKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRNdWx0aXRocmVhZGVkKFRoaXMtPndpbmVEM0REZXZpY2UpOwogICAgfQoKICAgIC8qIFVuaGFuZGxlZCBmbGFncyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dSRUJPT1QpCiAgICAgICAgV0FSTigiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9BTExPV1JFQk9PVCwgaGFybWxlc3NcbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dNT0RFWCkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0FMTE9XTU9ERVgsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZQVVNFVFVQKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfRlBVU0VUVVAsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZQVVBSRVNFUlZFKQogICAgICAgIFdBUk4oIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfRlBVUFJFU0VSVkUsIGhhcm1sZXNzXG4iLCBUaGlzKTsKCiAgICAvKiBTdG9yZSB0aGUgY29vcGVyYXRpdmVfbGV2ZWwgKi8KICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsIHw9IGNvb3BsZXZlbDsKICAgIFRSQUNFKCJTZXRDb29wZXJhdGl2ZUxldmVsIHJldHVuaW5nIEREX09LXG4iKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlNldERpc3BsYXlNb2RlCiAqCiAqIFNldHMgdGhlIGRpc3BsYXkgc2NyZWVuIHJlc29sdXRpb24sIGNvbG9yIGRlcHRoIGFuZCByZWZyZXNoIGZyZXF1ZW5jeQogKiB3aGVuIGluIGZ1bGxzY3JlZW4gbW9kZSAoaW4gdGhlb3J5KS4KICogUG9zc2libGUgcmV0dXJuIHZhbHVlcyBsaXN0ZWQgaW4gdGhlIFNESyBzdWdnZXN0IHRoYXQgdGhpcyBtZXRob2QgZmFpbHMKICogd2hlbiBub3QgaW4gZnVsbHNjcmVlbiBtb2RlLCBidXQgdGhpcyBpcyB3cm9uZy4gV2luZG93cyAyMDAwIGhhcHBpbHkgc2V0cwogKiB0aGUgZGlzcGxheSBtb2RlIGluIEREU0NMX05PUk1BTCBtb2RlIHdpdGhvdXQgYW4gaHduZCBzcGVjaWZpZWQuCiAqIEl0IHNlZW1zIHRvIGJlIHZhbGlkIHRvIHBhc3MgMCBmb3IgV2l0aCBhbmQgSGVpZ2h0LCB0aGlzIGhhcyB0byBiZSB0ZXN0ZWQKICogSXQgY291bGQgbWVhbiB0aGF0IHRoZSBjdXJyZW50IHZpZGVvIG1vZGUgc2hvdWxkIGJlIGxlZnQgYXMtaXMuIChCdXQgd2h5CiAqIGNhbGwgaXQgdGhlbj8pCiAqCiAqIFBhcmFtczoKICogIEhlaWdodCwgV2lkdGg6IFNjcmVlbiBkaW1lbnNpb24KICogIEJQUDogQ29sb3IgZGVwdGggaW4gQml0cyBwZXIgcGl4ZWwKICogIFJlZnJlc2hyYXRlOiBTY3JlZW4gcmVmcmVzaCByYXRlCiAqICBGbGFnczogT3RoZXIgc3R1ZmYKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU2V0RGlzcGxheU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQlBQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgUmVmcmVzaFJhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJWQsJWQsJXg6IFJlbGF5IVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgQlBQLCBSZWZyZXNoUmF0ZSwgRmxhZ3MpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBpZiggIVdpZHRoIHx8ICFIZWlnaHQgKQogICAgewogICAgICAgIEVSUigiV2lkdGg9JWQsIEhlaWdodD0lZCwgd2hhdCB0byBkbz9cbiIsIFdpZHRoLCBIZWlnaHQpOwogICAgICAgIC8qIEl0IGxvb2tzIGxpa2UgTmVlZCBmb3IgU3BlZWQgUG9yc2NoZSBVbmxlYXNoZWQgZXhwZWN0cyBERF9PSyBoZXJlICovCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERfT0s7CiAgICB9CgogICAgLyogQ2hlY2sgdGhlIGV4Y2x1c2l2ZSBtb2RlCiAgICBpZighKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRVhDTFVTSVZFKSkKICAgICAgICByZXR1cm4gRERFUlJfTk9FWENMVVNJVkVNT0RFOwogICAgICogVGhpcyBpcyBXUk9ORy4gRG9uJ3Qga25vdyBpZiB0aGUgU0RLIGlzIGNvbXBsZXRlbHkKICAgICAqIHdyb25nIGFuZCBpZiB0aGVyZSBhcmUgYW55IGNvbmRpdGlvbnMgd2hlbiBEREVSUl9OT0VYQ0xVU0lWRQogICAgICogaXMgcmV0dXJuZWQsIGJ1dCBIYWxmLUxpZmUgMS4xLjEuMSAoU3RlYW0gdmVyc2lvbikKICAgICAqIGRlcGVuZHMgb24gdGhpcwogICAgICovCgogICAgTW9kZS5XaWR0aCA9IFdpZHRoOwogICAgTW9kZS5IZWlnaHQgPSBIZWlnaHQ7CiAgICBNb2RlLlJlZnJlc2hSYXRlID0gUmVmcmVzaFJhdGU7CiAgICBzd2l0Y2goQlBQKQogICAgewogICAgICAgIGNhc2UgODogIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9QODsgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNTogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1gxUjVHNUI1OyBicmVhazsKICAgICAgICBjYXNlIDE2OiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUjVHNkI1OyAgIGJyZWFrOwogICAgICAgIGNhc2UgMjQ6IE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SOEc4Qjg7ICAgYnJlYWs7CiAgICAgICAgY2FzZSAzMjogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX0E4UjhHOEI4OyBicmVhazsKICAgIH0KCiAgICAvKiBUT0RPOiBUaGUgcG9zc2libGUgcmV0dXJuIHZhbHVlcyBmcm9tIG1zZG4gc3VnZ2VzdCB0aGF0CiAgICAgKiB0aGUgc2NyZWVuIG1vZGUgY2FuJ3QgYmUgY2hhbmdlZCBpZiBhIHN1cmZhY2UgaXMgbG9ja2VkCiAgICAgKiBvciBzb21lIGRyYXdpbmcgaXMgaW4gcHJvZ3Jlc3MKICAgICAqLwoKICAgIC8qIFRPRE86IExvc2UgdGhlIHByaW1hcnkgc3VyZmFjZSAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9TZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBGaXJzdCBzd2FwY2hhaW4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHN3aXRjaChocikKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOiAgICAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7CiAgICAgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVzdG9yZURpc3BsYXlNb2RlCiAqCiAqIFJlc3RvcmVzIHRoZSBkaXNwbGF5IG1vZGUgdG8gd2hhdCBpdCB3YXMgYXQgY3JlYXRpb24gdGltZS4gQmFzaWNhbGx5LgogKgogKiBBIHByb2JsZW0gYXJpc2VzIHdoZW4gdGhlcmUgYXJlIDIgRGlyZWN0RHJhdyBvYmplY3RzIHVzaW5nIHRoZSBzYW1lIGh3bmQ6CiAqICAtPiBERF8xIGZpbmRzIHRoZSBzY3JlZW4gYXQgMTQwMHgxMDUweDMyIHdoZW4gY3JlYXRlZCwgc2V0cyBpdCB0byA2NDB4NDgweDE2CiAqICAtPiBERF8yIGlzIGNyZWF0ZWQsIGZpbmRzIHRoZSBzY3JlZW4gYXQgNjQweDQ4MHgxNiwgc2V0cyBpdCB0byAxMDI0eDc2OHgzMgogKiAgLT4gRERfMSBpcyByZWxlYXNlZC4gVGhlIHNjcmVlbiBzaG91bGQgYmUgbGVmdCBhdCAxMDI0eDc2OHgzMi4KICogIC0+IEREXzIgaXMgcmVsZWFzZWQuIFRoZSBzY3JlZW4gc2hvdWxkIGJlIHNldCB0byAxNDAweDEwNTB4MzIKICogVGhpcyBjYXNlIGlzIHVuaGFuZGxlZCByaWdodCBub3csIGJ1dCBFbXBpcmUgRWFydGggZG9lcyBpdCB0aGlzIHdheS4KICogKEJ1dCBwZXJoYXBzIHRoZXJlIGlzIHNvbWV0aGluZyBpbiBTZXRDb29wZXJhdGl2ZUxldmVsIHRvIHByZXZlbnQgdGhpcykKICoKICogVGhlIG1zZG4gc2F5cyB0aGF0IHRoaXMgbWV0aG9kIHJlc2V0cyB0aGUgZGlzcGxheSBtb2RlIHRvIHdoYXQgaXQgd2FzIGJlZm9yZQogKiBTZXREaXNwbGF5TW9kZSB3YXMgY2FsbGVkLiBXaGF0IGlmIFNldERpc3BsYXlNb2RlcyBpcyBjYWxsZWQgMiB0aW1lcz8/CiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX05PRVhDTFVTSVZFIG1vZGUgaWYgdGhlIGRldmljZSBpc24ndCBpbiBmdWxsc2NyZWVuIG1vZGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVEaXNwbGF5TW9kZShJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBJRGlyZWN0RHJhdzdfU2V0RGlzcGxheU1vZGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ193aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ19oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPm9yaWdfYnBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0Q2FwcwogKgogKiBSZXR1cm5zIHRoZSBkcml2ZXMgY2FwYWJpbGl0aWVzCiAqCiAqIFVzZWQgZm9yIHZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBEcml2ZXJDYXBzOiBTdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIEhhcmR3YXJlIGFjY2VsZXJhdGVkIGNhcHMgdG8KICogIEhlbENhcHM6IFN0cnVjdHVyZSB0byB3cml0ZSB0aGUgZW11bGF0aW9uIGNhcHMgdG8KICoKICogUmV0dXJucwogKiAgVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIEREX09LIG9ubHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldENhcHMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTICpEcml2ZXJDYXBzLAogICAgICAgICAgICAgICAgICAgICAgICBERENBUFMgKkhFTENhcHMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgRHJpdmVyQ2FwcywgSEVMQ2Fwcyk7CgogICAgLyogT25lIHN0cnVjdHVyZSBtdXN0IGJlICE9IE5VTEwgKi8KICAgIGlmKCAoIURyaXZlckNhcHMpICYmICghSEVMQ2FwcykgKQogICAgewogICAgICAgIEVSUigiKCVwKSBJbnZhbGlkIHBhcmFtcyB0byBJRGlyZWN0RHJhd0ltcGxfR2V0Q2Fwc1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoRHJpdmVyQ2FwcykKICAgIHsKICAgICAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoRHJpdmVyQ2FwcywgJlRoaXMtPmNhcHMpOwogICAgICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiRHJpdmVyIENhcHMgOlxuIik7CiAgICAgICAgICAgIEREUkFXX2R1bXBfRERDQVBTKERyaXZlckNhcHMpOwogICAgICAgIH0KCiAgICB9CiAgICBpZihIRUxDYXBzKQogICAgewogICAgICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRShIRUxDYXBzLCAmVGhpcy0+Y2Fwcyk7CiAgICAgICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJIRUwgQ2FwcyA6XG4iKTsKICAgICAgICAgICAgRERSQVdfZHVtcF9ERENBUFMoSEVMQ2Fwcyk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6Q29tcGFjdAogKgogKiBObyBpZGVhIHdoYXQgaXQgZG9lcywgTVNETiBzYXlzIGl0J3Mgbm90IGltcGxlbWVudGVkLgogKgogKiBSZXR1cm5zCiAqICBERF9PSywgYnV0IHRoaXMgaXMgdW5jaGVja2VkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9Db21wYWN0KElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXREaXNwbGF5TW9kZQogKgogKiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IGRpc3BsYXkgbW9kZQogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIEREU0Q6IEFkZHJlc3Mgb2YgYSBzdXJmYWNlIGRlc2NyaXB0aW9uIHN0cnVjdHVyZSB0byB3cml0ZSB0aGUgaW5mbyB0bwogKgogKiBSZXR1cm5zCiAqICBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0RGlzcGxheU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNEKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwogICAgRFdPUkQgU2l6ZTsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIiwgVGhpcywgRERTRCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIC8qIFRoaXMgc2VlbXMgc2FuZSAqLwogICAgaWYoIUREU0QpIAogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogVGhlIG5lY2Vzc2FyeSBtZW1iZXJzIG9mIExQRERTVVJGQUNFREVTQyBhbmQgTFBERFNVUkZBQ0VERVNDMiBhcmUgZXF1YWwsCiAgICAgKiBzbyBvbmUgbWV0aG9kIGNhbiBiZSB1c2VkIGZvciBhbGwgdmVyc2lvbnMgKEhvcGVmdWxseSkKICAgICAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogc3dhcGNoYWluIDAgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwogICAgaWYoIGhyICE9IEQzRF9PSyApCiAgICB7CiAgICAgICAgRVJSKCIgKCVwKSBJV2luZUQzRERldmljZTo6R2V0RGlzcGxheU1vZGUgcmV0dXJuZWQgJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIFNpemUgPSBERFNELT5kd1NpemU7CiAgICBtZW1zZXQoRERTRCwgMCwgU2l6ZSk7CgogICAgRERTRC0+ZHdTaXplID0gU2l6ZTsKICAgIEREU0QtPmR3RmxhZ3MgfD0gRERTRF9IRUlHSFQgfCBERFNEX1dJRFRIIHwgRERTRF9QSVhFTEZPUk1BVCB8IEREU0RfUElUQ0ggfCBERFNEX1JFRlJFU0hSQVRFOwogICAgRERTRC0+ZHdXaWR0aCA9IE1vZGUuV2lkdGg7CiAgICBERFNELT5kd0hlaWdodCA9IE1vZGUuSGVpZ2h0OyAKICAgIEREU0QtPnUyLmR3UmVmcmVzaFJhdGUgPSA2MDsKICAgIEREU0QtPmRkc0NhcHMuZHdDYXBzID0gMDsKICAgIEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQsIE1vZGUuRm9ybWF0KTsKICAgIEREU0QtPnUxLmxQaXRjaCA9IE1vZGUuV2lkdGggKiBERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQudTEuZHdSR0JCaXRDb3VudCAvIDg7CgogICAgaWYoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgc3VyZmFjZSBkZXNjIDpcbiIpOwogICAgICAgIEREUkFXX2R1bXBfc3VyZmFjZV9kZXNjKEREU0QpOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldEZvdXJDQ0NvZGVzCiAqCiAqIFJldHVybnMgYW4gYXJyYXkgb2Ygc3VwcG9ydGVkIEZvdXJDQyBjb2Rlcy4KICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBOdW1Db2RlczogQ29udGFpbnMgdGhlIG51bWJlciBvZiBDb2RlcyB0aGF0IENvZGVzIGNhbiBjYXJyeS4gUmV0dXJucyB0aGUgbnVtYmVyCiAqICAgICAgICAgICAgb2YgZW51bWVyYXRlZCBjb2RlcwogKiAgQ29kZXM6IFBvaW50ZXIgdG8gYW4gYXJyYXkgb2YgRFdPUkRzIHdoZXJlIHRoZSBzdXBwb3J0ZWQgY29kZXMgYXJlIHdyaXR0ZW4KICogICAgICAgICB0bwogKgogKiBSZXR1cm5zCiAqICBBbHdheXMgcmV0dXJucyBERF9PSywgYXMgaXQncyBhIHN0dWIgZm9yIG5vdwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0Rm91ckNDQ29kZXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpOdW1Db2RlcywgRFdPUkQgKkNvZGVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCwgJXApOiBTdHViIVxuIiwgVGhpcywgTnVtQ29kZXMsIENvZGVzKTsKCiAgICBpZihOdW1Db2RlcykgKk51bUNvZGVzID0gMDsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldE1vbml0b3JGcmVxdWVuY3kKICoKICogUmV0dXJucyB0aGUgbW9uaXRvcidzIGZyZXF1ZW5jeQogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIEZyZXE6IFBvaW50ZXIgdG8gYSBEV09SRCB0byB3cml0ZSB0aGUgZnJlcXVlbmN5IHRvCiAqCiAqIFJldHVybnMKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRNb25pdG9yRnJlcXVlbmN5KElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpGcmVxKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIEZyZXEpOwoKICAgIC8qIElkZWFsbHkgdGhpcyBzaG91bGQgYmUgaW4gV2luZUQzRCwgYXMgaXQgY29uY2VybnMgdGhlIHNjcmVlbiBzZXR1cCwKICAgICAqIGJ1dCBmb3Igbm93IHRoaXMgc2hvdWxkIG1ha2UgdGhlIGdhbWVzIGhhcHB5CiAgICAgKi8KICAgICpGcmVxID0gNjA7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldFZlcnRpY2FsQmxhbmtTdGF0dXMKICoKICogUmV0dXJucyB0aGUgVmVydGljYWwgYmxhbmsgc3RhdHVzIG9mIHRoZSBtb25pdG9yLiBUaGlzIHNob3VsZCBiZSBpbiBXaW5lRDNECiAqIHRvbyBiYXNpY2FsbHksIGJ1dCBhcyBpdCdzIGEgc2VtaSBzdHViLCBJIGRpZG4ndCBjcmVhdGUgYSBmdW5jdGlvbiB0aGVyZQogKgogKiBQYXJhbXM6CiAqICBzdGF0dXM6IFBvaW50ZXIgdG8gYSBCT09MIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSB2ZXJ0aWNhbCBibGFuayBzdGF0dXMKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBzdGF0dXMgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0VmVydGljYWxCbGFua1N0YXR1cyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MICpzdGF0dXMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgc3RhdHVzKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUsIHRoZSBNU0ROIHN1Z2dlc3RzIGl0IHRvbyAqLwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGlmKCFzdGF0dXMpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICAqc3RhdHVzID0gVGhpcy0+ZmFrZV92Ymxhbms7CiAgICBUaGlzLT5mYWtlX3ZibGFuayA9ICFUaGlzLT5mYWtlX3ZibGFuazsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldEF2YWlsYWJsZVZpZE1lbQogKgogKiBSZXR1cm5zIHRoZSB0b3RhbCBhbmQgZnJlZSB2aWRlbyBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgQ2FwczogU3BlY2lmaWVzIHRoZSBtZW1vcnkgdHlwZSBhc2tlZCBmb3IKICogIHRvdGFsOiBQb2ludGVyIHRvIGEgRFdPUkQgdG8gYmUgZmlsbGVkIHdpdGggdGhlIHRvdGFsIG1lbW9yeQogKiAgZnJlZTogUG9pbnRlciB0byBhIERXT1JEIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSBmcmVlIG1lbW9yeQogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIG9mIGZyZWUgYW5kIHRvdGFsIGFyZSBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRBdmFpbGFibGVWaWRNZW0oSURpcmVjdERyYXc3ICppZmFjZSwgRERTQ0FQUzIgKkNhcHMsIERXT1JEICp0b3RhbCwgRFdPUkQgKmZyZWUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCAlcCwgJXApXG4iLCBUaGlzLCBDYXBzLCB0b3RhbCwgZnJlZSk7CgogICAgaWYoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApIEFza2VkIGZvciBtZW1vcnkgd2l0aCBkZXNjcmlwdGlvbjogIiwgVGhpcyk7CiAgICAgICAgRERSQVdfZHVtcF9ERFNDQVBTMihDYXBzKTsKICAgICAgICBUUkFDRSgiXG4iKTsKICAgIH0KICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgLyogVG9kbzogU3lzdGVtIG1lbW9yeSB2cyBsb2NhbCB2aWRlbyBtZW1vcnkgdnMgbm9uLWxvY2FsIHZpZGVvIG1lbW9yeQogICAgICogVGhlIE1TRE4gYWxzbyBtZW50aW9ucyBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRleHR1cmUgbWVtb3J5IGFuZCBvdGhlcgogICAgICogcmVzb3VyY2VzLCBidXQgdGhhdCdzIG5vdCBpbXBvcnRhbnQKICAgICAqLwoKICAgIGlmKCAoIXRvdGFsKSAmJiAoIWZyZWUpICkKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKHRvdGFsKSAqdG90YWwgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBpZihmcmVlKSAqZnJlZSA9IElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6SW5pdGlhbGl6ZQogKgogKiBJbml0aWFsaXplcyBhIERpcmVjdERyYXcgaW50ZXJmYWNlLgogKgogKiBQYXJhbXM6CiAqICBHVUlEOiBJbnRlcmZhY2UgaWRlbnRpZmllci4gV2VsbCwgZG9uJ3Qga25vdyB3aGF0IHRoaXMgaXMgcmVhbGx5IGdvb2QKICogICBmb3IKICoKICogUmV0dXJucwogKiAgUmV0dXJucyBERF9PSyBvbiB0aGUgZmlyc3QgY2FsbCwKICogIERERVJSX0FMUkVBRFlJTklUSUFMSVpFRCBvbiByZXBlYXRlZCBjYWxscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfSW5pdGlhbGl6ZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBHVUlEICpHdWlkKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcyk6IE5vLW9wXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKEd1aWQpKTsKCiAgICBpZihUaGlzLT5pbml0aWFsaXplZCkKICAgIHsKICAgICAgICByZXR1cm4gRERFUlJfQUxSRUFEWUlOSVRJQUxJWkVEOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldHVybiBERF9PSzsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RmxpcFRvR0RJU3VyZmFjZQogKgogKiAiTWFrZXMgdGhlIHN1cmZhY2UgdGhhdCB0aGUgR0RJIHdyaXRlcyB0byB0aGUgcHJpbWFyeSBzdXJmYWNlIgogKiBMb29rcyBsaWtlIHNvbWUgd2luZG93cyBzcGVjaWZpYyB0aGluZyB3ZSBkb24ndCBoYXZlIHRvIGNhcmUgYWJvdXQuCiAqIEFjY29yZGluZyB0byBNU0ROIGl0IHBlcm1pdHMgR0RJIGRpYWxvZyBib3hlcyBpbiBGVUxMU0NSRUVOIG1vZGUuIEdvb2QgdG8KICogc2hvdyBlcnJvciBib3hlcyA7KQogKiBXZWxsLCBqdXN0IHJldHVybiBERF9PSy4KICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9GbGlwVG9HRElTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpXYWl0Rm9yVmVydGljYWxCbGFuawogKgogKiBUaGlzIG1ldGhvZCBhbGxvd3MgYXBwbGljYXRpb25zIHRvIGdldCBpbiBzeW5jIHdpdGggdGhlIHZlcnRpY2FsIGJsYW5rCiAqIGludGVydmFsLgogKiBUaGUgd29ybWhvbGUgZGVtbyBpbiB0aGUgRGlyZWN0WCA3IHNkayB1c2VzIHRoaXMgY2FsbCwgYW5kIGl0IGRvZXNuJ3QKICogcmVkcmF3IHRoZSBzY3JlZW4sIG1vc3QgbGlrZWx5IGJlY2F1c2Ugb2YgdGhpcyBzdHViCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBGbGFnczogb25lIG9mIEREV0FJVFZCX0JMT0NLQkVHSU4sIEREV0FJVFZCX0JMT0NLQkVHSU5FVkVOVAogKiAgICAgICAgIG9yIEREV0FJVFZCX0JMT0NLRU5ECiAqICBoOiBOb3QgdXNlZCwgYWNjb3JkaW5nIHRvIE1TRE4KICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfV2FpdEZvclZlcnRpY2FsQmxhbmsoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFIGgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCV4LCVwKTogU3R1YlxuIiwgVGhpcywgRmxhZ3MsIGgpOwoKICAgIC8qIE1TRE4gc2F5cyBERFdBSVRWQl9CTE9DS0JFR0lORVZFTlQgaXMgbm90IHN1cHBvcnRlZCAqLwogICAgaWYoRmxhZ3MgJiBERFdBSVRWQl9CTE9DS0JFR0lORVZFTlQpCiAgICAgICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOyAvKiB1bmNoZWNrZWQgKi8KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldFNjYW5MaW5lCiAqCiAqIFJldHVybnMgdGhlIHNjYW4gbGluZSB0aGF0IGlzIGJlaW5nIGRyYXduIG9uIHRoZSBtb25pdG9yCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBTY2FubGluZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgc2NhbiBsaW5lIHZhbHVlIHRvCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdERyYXdJbXBsX0dldFNjYW5MaW5lKElEaXJlY3REcmF3NyAqaWZhY2UsIERXT1JEICpTY2FubGluZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIHN0YXRpYyBCT09MIGhpZGUgPSBGQUxTRTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwoKICAgIC8qIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9mdGVuLCBzbyBwcmludCB0aGUgZml4bWUgb25seSBvbmNlICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoIWhpZGUpCiAgICB7CiAgICAgICAgRklYTUUoIiglcCktPiglcCk6IFNlbWktU3R1YlxuIiwgVGhpcywgU2NhbmxpbmUpOwogICAgICAgIGhpZGUgPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlX0dldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwoKICAgIC8qIEZha2UgdGhlIGxpbmUgc3dlZXBpbmcgb2YgdGhlIG1vbml0b3IgKi8KICAgIC8qIEZJWE1FOiBXZSBzaG91bGQgc3luY2hyb25pemUgd2l0aCBhIHNvdXJjZSB0byBrZWVwIHRoZSByZWZyZXNoIHJhdGUgKi8gCiAgICAqU2NhbmxpbmUgPSBUaGlzLT5jdXJfc2NhbmxpbmUrKzsKICAgIC8qIEFzc3VtZSAyMCBzY2FuIGxpbmVzIGluIHRoZSB2ZXJ0aWNhbCBibGFuayAqLwogICAgaWYgKFRoaXMtPmN1cl9zY2FubGluZSA+PSBNb2RlLkhlaWdodCArIDIwKQogICAgICAgIFRoaXMtPmN1cl9zY2FubGluZSA9IDA7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6VGVzdENvb3BlcmF0aXZlTGV2ZWwKICoKICogSW5mb3JtcyB0aGUgYXBwbGljYXRpb24gYWJvdXQgdGhlIHN0YXRlIG9mIHRoZSB2aWRlbyBhZGFwdGVyLCBkZXBlbmRpbmcKICogb24gdGhlIGNvb3BlcmF0aXZlIGxldmVsCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgZGV2aWNlIGlzIGluIGEgc2FuZSBzdGF0ZQogKiAgRERFUlJfTk9FWENMVVNJVkVNT0RFIG9yIERERVJSX0VYQ0xVU0lWRU1PREVBTFJFQURZU0VUCiAqICBpZiB0aGUgc3RhdGUgaXMgbm90IGNvcnJlY3QoU2VlIGJlbG93KQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1Rlc3RDb29wZXJhdGl2ZUxldmVsKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAvKiBEZXNjcmlwdGlvbiBmcm9tIE1TRE46CiAgICAgKiBGb3IgZnVsbHNjcmVlbiBhcHBzIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREUgaWYgdGhlIHVzZXIgc3dpdGNoZWQKICAgICAqIGF3YXkgZnJvbSB0aGUgYXBwIHdpdGggZS5nLiBhbHQtdGFiLiBXaW5kb3dlZCBhcHBzIHJlY2VpdmUgCiAgICAgKiBEREVSUl9FWENMVVNJVkVNT0RFQUxSRUFEWVNFVCBpZiBhbm90aGVyIGFwcGxpY2F0aW9uIGNyZWF0ZWQgYSAKICAgICAqIERpcmVjdERyYXcgb2JqZWN0IGluIGV4Y2x1c2l2ZSBtb2RlLiBEREVSUl9XUk9OR01PREUgaXMgcmV0dXJuZWQsCiAgICAgKiB3aGVuIHRoZSB2aWRlbyBtb2RlIGhhcyBjaGFuZ2VkCiAgICAgKi8KCiAgICBociA9ICBJV2luZUQzRERldmljZV9UZXN0Q29vcGVyYXRpdmVMZXZlbChUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBGaXggdGhlIHJlc3VsdCB2YWx1ZS4gVGhlc2UgdmFsdWVzIGFyZSBtYXBwZWQgZnJvbSB0aGVpcgogICAgICogZDNkOSBjb3VudGVycGFydC4KICAgICAqLwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VMT1NUOgogICAgICAgICAgICBpZihUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIERERVJSX0VYQ0xVU0lWRU1PREVBTFJFQURZU0VUOwogICAgICAgICAgICB9CgogICAgICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VOT1RSRVNFVDoKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIEREX09LOwoKICAgICAgICBjYXNlIFdJTkVEM0RfT0s6CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKCiAgICAgICAgY2FzZSBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCIoJXApIFVuZXhwZWN0ZWQgcmV0dXJuIHZhbHVlICUwOHggZnJvbSB3aW5lRDNELCAiCiAgICAgICAgICAgICAgICAiIHJldHVybmluZyBERF9PS1xuIiwgVGhpcywgaHIpOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldEdESVN1cmZhY2UKICoKICogUmV0dXJucyB0aGUgc3VyZmFjZSB0aGF0IEdESSBpcyB0cmVhdGluZyBhcyB0aGUgcHJpbWFyeSBzdXJmYWNlLgogKiBGb3IgV2luZSB0aGlzIGlzIHRoZSBmcm9udCBidWZmZXIKICoKICogUGFyYW1zOgogKiAgR0RJU3VyZmFjZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgc3VyZmFjZSBwb2ludGVyIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgc3VyZmFjZSB3YXMgZm91bmQKICogIERERVJSX05PVEZPVU5EIGlmIHRoZSBHREkgc3VyZmFjZSB3YXNuJ3QgZm91bmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRHRElTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipHRElTdXJmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSVdpbmVEM0RTdXJmYWNlICpTdXJmOwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqZGRzdXJmOwogICAgSFJFU1VMVCBocjsKICAgIEREU0NBUFMyIGRkc0NhcHM7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgR0RJU3VyZmFjZSk7CgogICAgLyogR2V0IHRoZSBiYWNrIGJ1ZmZlciBmcm9tIHRoZSB3aW5lRDNERGV2aWNlIGFuZCBzZWFyY2ggaXRzCiAgICAgKiBhdHRhY2hlZCBzdXJmYWNlcyBmb3IgdGhlIGZyb250IGJ1ZmZlcgogICAgICovCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRCYWNrQnVmZmVyKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU3dhcENoYWluICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogZmlyc3QgYmFjayBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RCQUNLQlVGRkVSX1RZUEVfTU9OTywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3VyZik7CgogICAgaWYoIChociAhPSBEM0RfT0spIHx8CiAgICAgICAgKCFTdXJmKSApCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6R2V0QmFja0J1ZmZlciBmYWlsZWRcbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX05PVEZPVU5EOwogICAgfQoKICAgIC8qIEdldEJhY2tCdWZmZXIgQWRkUmVmKCllZCB0aGUgc3VyZmFjZSwgcmVsZWFzZSBpdCAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoU3VyZik7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChTdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKiopICZkZHN1cmYpOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGRkc3VyZik7ICAvKiBGb3IgdGhlIEdldFBhcmVudCAqLwoKICAgIC8qIEZpbmQgdGhlIGZyb250IGJ1ZmZlciAqLwogICAgZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX0ZST05UQlVGRkVSOwogICAgaHIgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShkZHN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZHNDYXBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRElTdXJmYWNlKTsKICAgIGlmKGhyICE9IEREX09LKQogICAgewogICAgICAgIEVSUigiSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0QXR0YWNoZWRTdXJmYWNlIGZhaWxlZCwgaHIgPSAleFxuIiwgaHIpOwogICAgfQoKICAgIC8qIFRoZSBBZGRSZWYgaXMgT0sgdGhpcyB0aW1lICovCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFbnVtRGlzcGxheU1vZGVzCiAqCiAqIEVudW1lcmF0ZXMgdGhlIHN1cHBvcnRlZCBEaXNwbGF5IG1vZGVzLiBUaGUgbW9kZXMgY2FuIGJlIGZpbHRlcmVkIHdpdGgKICogdGhlIEREU0QgcGFyYW1ldGVyLgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogY2FuIGJlIERERURNX1JFRlJFU0hSQVRFUyBhbmQgRERFRE1fU1RBTkRBUkRWR0FNT0RFUwogKiAgRERTRDogU3VyZmFjZSBkZXNjcmlwdGlvbiB0byBmaWx0ZXIgdGhlIG1vZGVzCiAqICBDb250ZXh0OiBQb2ludGVyIHBhc3NlZCBiYWNrIHRvIHRoZSBjYWxsYmFjayBmdW5jdGlvbgogKiAgY2I6IEFwcGxpY2F0aW9uLXByb3ZpZGVkIGNhbGxiYWNrIGZ1bmN0aW9uCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBjYWxsYmFjayB3YXNuJ3Qgc2V0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRW51bURpc3BsYXlNb2RlcyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNTU9ERVNDQUxMQkFDSzIgY2IpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICB1bnNpZ25lZCBpbnQgbW9kZW51bSwgZm10OwogICAgV0lORUQzREZPUk1BVCBwaXhlbGZvcm1hdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtb2RlOwogICAgRERTVVJGQUNFREVTQzIgY2FsbGJhY2tfc2Q7CgogICAgV0lORUQzREZPUk1BVCBjaGVja0Zvcm1hdExpc3RbXSA9CiAgICB7CiAgICAgICAgV0lORUQzREZNVF9SOEc4QjgsCiAgICAgICAgV0lORUQzREZNVF9BOFI4RzhCOCwKICAgICAgICBXSU5FRDNERk1UX1g4UjhHOEI4LAogICAgICAgIFdJTkVEM0RGTVRfUjVHNkI1LAogICAgICAgIFdJTkVEM0RGTVRfWDFSNUc1QjUsCiAgICAgICAgV0lORUQzREZNVF9BMVI1RzVCNSwKICAgICAgICBXSU5FRDNERk1UX0E0UjRHNEI0LAogICAgICAgIFdJTkVEM0RGTVRfUjNHM0IyLAogICAgICAgIFdJTkVEM0RGTVRfQThSM0czQjIsCiAgICAgICAgV0lORUQzREZNVF9YNFI0RzRCNCwKICAgICAgICBXSU5FRDNERk1UX0EyQjEwRzEwUjEwLAogICAgICAgIFdJTkVEM0RGTVRfQThCOEc4UjgsCiAgICAgICAgV0lORUQzREZNVF9YOEI4RzhSOCwKICAgICAgICBXSU5FRDNERk1UX0EyUjEwRzEwQjEwLAogICAgICAgIFdJTkVEM0RGTVRfQThQOCwKICAgICAgICBXSU5FRDNERk1UX1A4CiAgICB9OwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXApOiBSZWxheVxuIiwgVGhpcywgRERTRCwgQ29udGV4dCwgY2IpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAvKiBUaGlzIGxvb2tzIHNhbmUgKi8KICAgIGlmKCFjYikKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKEREU0QpCiAgICB7CiAgICAgICAgaWYgKChERFNELT5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkgJiYgKEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdC5kd0ZsYWdzICYgRERQRl9SR0IpICkKICAgICAgICAgICAgcGl4ZWxmb3JtYXQgPSBQaXhlbEZvcm1hdF9ERDJXaW5lRDNEKCZERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgfQoKICAgIGZvcihmbXQgPSAwOyBmbXQgPCAoc2l6ZW9mKGNoZWNrRm9ybWF0TGlzdCkgLyBzaXplb2YoY2hlY2tGb3JtYXRMaXN0WzBdKSk7IGZtdCsrKQogICAgewogICAgICAgIGlmKHBpeGVsZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTiAmJiBjaGVja0Zvcm1hdExpc3RbZm10XSAhPSBwaXhlbGZvcm1hdCkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgbW9kZW51bSA9IDA7CiAgICAgICAgd2hpbGUoSVdpbmVEM0RfRW51bUFkYXB0ZXJNb2RlcyhUaGlzLT53aW5lRDNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREFEQVBURVJfREVGQVVMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrRm9ybWF0TGlzdFtmbXRdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZW51bSsrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1vZGUpID09IFdJTkVEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBpZihERFNEKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZihERFNELT5kd0ZsYWdzICYgRERTRF9XSURUSCAmJiBtb2RlLldpZHRoICE9IEREU0QtPmR3V2lkdGgpIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYoRERTRC0+ZHdGbGFncyAmIEREU0RfSEVJR0hUICYmIG1vZGUuSGVpZ2h0ICE9IEREU0QtPmR3SGVpZ2h0KSBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbWVtc2V0KCZjYWxsYmFja19zZCwgMCwgc2l6ZW9mKGNhbGxiYWNrX3NkKSk7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLmR3U2l6ZSA9IHNpemVvZihjYWxsYmFja19zZCk7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERQSVhFTEZPUk1BVCk7CgogICAgICAgICAgICBjYWxsYmFja19zZC5kd0ZsYWdzID0gRERTRF9IRUlHSFR8RERTRF9XSURUSHxERFNEX1BJWEVMRk9STUFUfEREU0RfUElUQ0g7CiAgICAgICAgICAgIGlmKEZsYWdzICYgRERFRE1fUkVGUkVTSFJBVEVTKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjYWxsYmFja19zZC5kd0ZsYWdzIHw9IEREU0RfUkVGUkVTSFJBVEU7CiAgICAgICAgICAgICAgICBjYWxsYmFja19zZC51Mi5kd1JlZnJlc2hSYXRlID0gbW9kZS5SZWZyZXNoUmF0ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY2FsbGJhY2tfc2QuZHdXaWR0aCA9IG1vZGUuV2lkdGg7CiAgICAgICAgICAgIGNhbGxiYWNrX3NkLmR3SGVpZ2h0ID0gbW9kZS5IZWlnaHQ7CgogICAgICAgICAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmY2FsbGJhY2tfc2QudTQuZGRwZlBpeGVsRm9ybWF0LCBtb2RlLkZvcm1hdCk7CgogICAgICAgICAgICBUUkFDRSgiRW51bWVyYXRpbmcgJWR4JWRAJWRcbiIsIGNhbGxiYWNrX3NkLmR3V2lkdGgsIGNhbGxiYWNrX3NkLmR3SGVpZ2h0LCBjYWxsYmFja19zZC51NC5kZHBmUGl4ZWxGb3JtYXQudTEuZHdSR0JCaXRDb3VudCk7CgogICAgICAgICAgICBpZihjYigmY2FsbGJhY2tfc2QsIENvbnRleHQpID09IERERU5VTVJFVF9DQU5DRUwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBhc2tlZCB0byB0ZXJtaW5hdGUgdGhlIGVudW1lcmF0aW9uXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIkVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFdmFsdWF0ZU1vZGUKICoKICogVXNlZCB3aXRoIElEaXJlY3REcmF3Nzo6U3RhcnRNb2RlVGVzdCB0byB0ZXN0IHZpZGVvIG1vZGVzLgogKiBFdmFsdWF0ZU1vZGUgaXMgdXNlZCB0byBwYXNzIG9yIGZhaWwgYSBtb2RlLCBhbmQgY29udGludWUgd2l0aCB0aGUgbmV4dAogKiBtb2RlCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBEREVNX01PREVQQVNTRUQgb3IgRERFTV9NT0RFRkFJTEVECiAqICBUaW1lb3V0OiBSZXR1cm5zIHRoZSBhbW91bnQgb2Ygc2Vjb25kcyBsZWZ0IGJlZm9yZSB0aGUgbW9kZSB3b3VsZCBoYXZlCiAqICAgICAgICAgICBiZWVuIGZhaWxlZCBhdXRvbWF0aWNhbGx5CiAqCiAqIFJldHVybnM6CiAqICBUaGlzIGltcGxlbWVudGF0aW9uIGFsd2F5cyBERF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRXZhbHVhdGVNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgKlRpbWVvdXQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVkLCVwKTogU3R1YiFcbiIsIFRoaXMsIEZsYWdzLCBUaW1lb3V0KTsKCiAgICAvKiBXaGVuIGltcGxlbWVudGluZyB0aGlzLCBpbXBsZW1lbnQgaXQgaW4gV2luZUQzRCAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0RGV2aWNlSWRlbnRpZmllcgogKgogKiBSZXR1cm5zIHRoZSBkZXZpY2UgaWRlbnRpZmllciwgd2hpY2ggZ2l2ZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGRyaXZlcgogKiBPdXIgZGV2aWNlIGlkZW50aWZpZXIgaXMgZGVmaW5lZCBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoaXMgZmlsZS4KICoKICogUGFyYW1zOgogKiAgRERESTogQWRkcmVzcyBmb3IgdGhlIHJldHVybmVkIHN0cnVjdHVyZQogKiAgRmxhZ3M6IENhbiBiZSBEREdESV9HRVRIT1NUSURFTlRJRklFUgogKgogKiBSZXR1cm5zOgogKiAgT24gc3VjY2VzcyBpdCByZXR1cm5zIEREX09LCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIEREREkgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0RGV2aWNlSWRlbnRpZmllcihJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERERFVklDRUlERU5USUZJRVIyICpERERJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJTA4eClcbiIsIFRoaXMsIEREREksIEZsYWdzKTsKCiAgICBpZighRERESSkKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBUaGUgRERHRElfR0VUSE9TVElERU5USUZJRVIgcmV0dXJucyB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIDJECiAgICAgKiBob3N0IGFkYXB0ZXIsIGlmIHRoZXJlJ3MgYSBzZWNvbmRhcnkgM0QgYWRhcHRlci4gVGhpcyBkb2Vzbid0IGFwcGx5CiAgICAgKiB0byBhbnkgbW9kZXJuIGhhcmR3YXJlLCBub3IgaXMgaXQgaW50ZXJlc3RpbmcgZm9yIFdpbmUsIHNvIGlnbm9yZSBpdAogICAgICovCgogICAgKkREREkgPSBkZXZpY2VpZGVudGlmaWVyOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXRTdXJmYWNlRnJvbURDCiAqCiAqIFJldHVybnMgdGhlIFN1cmZhY2UgZm9yIGEgR0RJIGRldmljZSBjb250ZXh0IGhhbmRsZS4KICogSXMgdGhpcyByZWxhdGVkIHRvIElEaXJlY3REcmF3U3VyZmFjZTo6R2V0REMgPz8/CiAqCiAqIFBhcmFtczoKICogIGhkYzogaGRjIHRvIHJldHVybiB0aGUgc3VyZmFjZSBmb3IKICogIFN1cmZhY2U6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0U3VyZmFjZUZyb21EQyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIREMgaGRjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqU3VyZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJXAsJXApOiBTdHViIVxuIiwgVGhpcywgaGRjLCBTdXJmYWNlKTsKCiAgICAvKiBJbXBsZW1lbnRhdGlvbiBpZGVhIGlmIG5lZWRlZDogTG9vcCB0aHJvdWdoIGFsbCBzdXJmYWNlcyBhbmQgY29tcGFyZQogICAgICogdGhlaXIgaGRjIHdpdGggaGRjLiBJbXBsZW1lbnQgaXQgaW4gV2luZUQzRCEgKi8KICAgIHJldHVybiBEREVSUl9OT1RGT1VORDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVzdG9yZUFsbFN1cmZhY2VzCiAqCiAqIENhbGxzIHRoZSByZXN0b3JlIG1ldGhvZCBvZiBhbGwgc3VyZmFjZXMKICoKICogUGFyYW1zOgogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRERfT0sgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZUFsbFN1cmZhY2VzKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKTogU3R1YlxuIiwgVGhpcyk7CgogICAgLyogVGhpcyBpc24ndCBoYXJkIHRvIGltcGxlbWVudDogRW51bWVyYXRlIGFsbCBXaW5lRDNEIHN1cmZhY2VzLAogICAgICogZ2V0IHRoZWlyIHBhcmVudCBhbmQgY2FsbCB0aGVpciByZXN0b3JlIG1ldGhvZC4gRG8gbm90IGltcGxlbWVudAogICAgICogaXQgaW4gV2luZUQzRCwgYXMgcmVzdG9yaW5nIGEgc3VyZmFjZSBtZWFucyByZS1jcmVhdGluZyB0aGUKICAgICAqIFdpbmVEM0REU3VyZmFjZQogICAgICovCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlN0YXJ0TW9kZVRlc3QKICoKICogVGVzdHMgdGhlIHNwZWNpZmllZCB2aWRlbyBtb2RlcyB0byB1cGRhdGUgdGhlIHN5c3RlbSByZWdpc3RyeSB3aXRoCiAqIHJlZnJlc2ggcmF0ZSBpbmZvcm1hdGlvbi4gU3RhcnRNb2RlVGVzdCBzdGFydHMgdGhlIG1vZGUgdGVzdCwKICogRXZhbHVhdGVNb2RlIGlzIHVzZWQgdG8gZmFpbCBvciBwYXNzIGEgbW9kZS4gSWYgRXZhbHVhdGVNb2RlCiAqIGlzbid0IGNhbGxlZCB3aXRoaW4gMTUgc2Vjb25kcywgdGhlIG1vZGUgaXMgZmFpbGVkIGF1dG9tYXRpY2FsbHkKICoKICogQXMgcmVmcmVzaCByYXRlcyBhcmUgaGFuZGxlZCBieSB0aGUgWCBzZXJ2ZXIsIEkgZG9uJ3QgdGhpbmsgdGhpcwogKiBNZXRob2QgaXMgaW1wb3J0YW50CiAqCiAqIFBhcmFtczoKICogIE1vZGVzOiBBbiBhcnJheSBvZiBtb2RlIHNwZWNpZmljYXRpb25zCiAqICBOdW1Nb2RlczogVGhlIG51bWJlciBvZiBtb2RlcyBpbiBNb2RlcwogKiAgRmxhZ3M6IFNvbWUgZmxhZ3MuLi4KICoKICogUmV0dXJuczoKICogIFJldHVybnMgRERFUlJfVEVTVEZJTklTSEVEIGlmIGZsYWdzIGNvbnRhaW5zIEREU01UX0lTVEVTVFJFUVVJUkVELAogKiAgaWYgbm8gbW9kZXMgYXJlIHBhc3NlZCwgRERFUlJfSU5WQUxJRFBBUkFNUyBpcyByZXR1cm5lZCwKICogIG90aGVyd2lzZSBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU3RhcnRNb2RlVGVzdChJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSVpFICpNb2RlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTnVtTW9kZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgV0FSTigiKCVwKS0+KCVwLCAlZCwgJXgpOiBTZW1pLVN0dWIsIG1vc3QgbGlrZWx5IGhhcm1sZXNzXG4iLCBUaGlzLCBNb2RlcywgTnVtTW9kZXMsIEZsYWdzKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUgKi8KICAgIGlmKCAoIU1vZGVzKSB8fCAoTnVtTW9kZXMgPT0gMCkgKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBERFNNVF9JU1RFU1RSRVFVSVJFRCBhc2tzIGlmIGEgbW9kZSB0ZXN0IGlzIG5lY2Vzc2FyeS4KICAgICAqIEFzIGl0IGlzIG5vdCwgRERFUlJfVEVTVEZJTklTSEVEIGlzIHJldHVybmVkCiAgICAgKiAoaG9wZWZ1bGx5IHRoYXQncyBjb3JyZWN0CiAgICAgKgogICAgaWYoRmxhZ3MgJiBERFNNVF9JU1RFU1RSRVFVSVJFRCkgcmV0dXJuIERERVJSX1RFU1RGSU5JU0hFRDsKICAgICAqIHdlbGwsIHRoYXQgdmFsdWUgZG9lc24ndCAoeWV0KSBleGlzdCBpbiB0aGUgd2luZSBoZWFkZXJzLCBzbyBpZ25vcmUgaXQKICAgICAqLwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2sKICoKICogRW51bWVyYXRpb24gY2FsbGJhY2sgZm9yIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzLgogKiBJdCByZS1yZWNyZWF0ZXMgdGhlIFdpbmVEM0RTdXJmYWNlLiBJdCdzIHByZXR0eSBzdHJhaWdodGZvcndhcmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVTdXJmYWNlc0NhbGxiYWNrKElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZkltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJmKTsKICAgIElEaXJlY3REcmF3SW1wbCAqVGhpcyA9IHN1cmZJbXBsLT5kZHJhdzsKICAgIElVbmtub3duICpQYXJlbnQ7CiAgICBJUGFyZW50SW1wbCAqcGFySW1wbCA9IE5VTEw7CiAgICBJV2luZUQzRFN1cmZhY2UgKndpbmVEM0RTdXJmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIHZvaWQgKnRtcDsKICAgIElXaW5lRDNEQ2xpcHBlciAqY2xpcHBlciA9IE5VTEw7CgogICAgV0lORUQzRFNVUkZBQ0VfREVTQyAgICAgRGVzYzsKICAgIFdJTkVEM0RGT1JNQVQgICAgICAgICAgIEZvcm1hdDsKICAgIFdJTkVEM0RSRVNPVVJDRVRZUEUgICAgIFR5cGU7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICBVc2FnZTsKICAgIFdJTkVEM0RQT09MICAgICAgICAgICAgIFBvb2w7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICBTaXplOwoKICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlVHlwZTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIE11bHRpU2FtcGxlUXVhbGl0eTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgIFdpZHRoOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgSGVpZ2h0OwoKICAgIFRSQUNFKCIoJXApOiBFbnVtZXJhdGVkIFN1cmZhY2UgJXBcbiIsIFRoaXMsIHN1cmZJbXBsKTsKCiAgICAvKiBGb3IgdGhlIGVudW1lcmF0aW9uICovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7CgogICAgaWYoc3VyZkltcGwtPkltcGxUeXBlID09IFRoaXMtPkltcGxUeXBlKSByZXR1cm4gRERFTlVNUkVUX09LOyAvKiBDb250aW51ZSAqLwoKICAgIC8qIEdldCB0aGUgb2JqZWN0cyAqLwogICAgd2luZUQzRFN1cmZhY2UgPSBzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KHdpbmVEM0RTdXJmYWNlLCAmUGFyZW50KTsKICAgIElVbmtub3duX1JlbGVhc2UoUGFyZW50KTsgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KCiAgICAvKiBJcyB0aGUgcGFyZW50IGFuIElQYXJlbnQgaW50ZXJmYWNlPyAqLwogICAgaWYoSVVua25vd25fUXVlcnlJbnRlcmZhY2UoUGFyZW50LCAmSUlEX0lQYXJlbnQsICZ0bXApID09IFNfT0spCiAgICB7CiAgICAgICAgLyogSXQgaXMgYSBJUGFyZW50IGludGVyZmFjZSEgKi8KICAgICAgICBJVW5rbm93bl9SZWxlYXNlKFBhcmVudCk7IC8qIEZvciB0aGUgUXVlcnlJbnRlcmZhY2UgKi8KICAgICAgICBwYXJJbXBsID0gSUNPTV9PQkpFQ1QoSVBhcmVudEltcGwsIElQYXJlbnQsIFBhcmVudCk7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgcmVmZXJlbmNlIHRoZSBwYXJlbnQgaW50ZXJmYWNlIGlzIGhvbGRpbmcgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSh3aW5lRDNEU3VyZmFjZSk7CiAgICB9CgogICAgLyogZ2V0IHRoZSBjbGlwcGVyICovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q2xpcHBlcih3aW5lRDNEU3VyZmFjZSwgJmNsaXBwZXIpOwoKICAgIC8qIEdldCB0aGUgc3VyZmFjZSBwcm9wZXJ0aWVzICovCiAgICBEZXNjLkZvcm1hdCA9ICZGb3JtYXQ7CiAgICBEZXNjLlR5cGUgPSAmVHlwZTsKICAgIERlc2MuVXNhZ2UgPSAmVXNhZ2U7CiAgICBEZXNjLlBvb2wgPSAmUG9vbDsKICAgIERlc2MuU2l6ZSA9ICZTaXplOwogICAgRGVzYy5NdWx0aVNhbXBsZVR5cGUgPSAmTXVsdGlTYW1wbGVUeXBlOwogICAgRGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSAmTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgRGVzYy5XaWR0aCA9ICZXaWR0aDsKICAgIERlc2MuSGVpZ2h0ID0gJkhlaWdodDsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHdpbmVEM0RTdXJmYWNlLCAmRGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spIHJldHVybiBocjsKCiAgICAvKiBDcmVhdGUgdGhlIG5ldyBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaWR0aCwgSGVpZ2h0LCBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBEaXNjYXJkICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cmZJbXBsLT5taXBtYXBfbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpU2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFNoYXJlZEhhbmRsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJlbnQpOwoKICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICByZXR1cm4gaHI7CgogICAgSVdpbmVEM0RTdXJmYWNlX1NldENsaXBwZXIoc3VyZkltcGwtPldpbmVEM0RTdXJmYWNlLCBjbGlwcGVyKTsKCiAgICAvKiBVcGRhdGUgdGhlIElQYXJlbnQgaWYgaXQgZXhpc3RzICovCiAgICBpZihwYXJJbXBsKQogICAgewogICAgICAgIHBhckltcGwtPmNoaWxkID0gKElVbmtub3duICopIHN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZTsKICAgICAgICAvKiBBZGQgYSByZWZlcmVuY2UgZm9yIHRoZSBJUGFyZW50ICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2UpOwogICAgfQogICAgLyogVE9ETzogQ29weSB0aGUgc3VyZmFjZSBjb250ZW50LCBleGNlcHQgZm9yIHJlbmRlciB0YXJnZXRzICovCgogICAgaWYoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uod2luZUQzRFN1cmZhY2UpID09IDApCiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgcmVsZWFzZWQgc3VjY2Vzc2Z1bCwgbmV4dCBzdXJmYWNlXG4iKTsKICAgIGVsc2UKICAgICAgICBFUlIoIlNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIG9sZCBXaW5lRDNEU3VyZmFjZVxuIik7CgogICAgc3VyZkltcGwtPkltcGxUeXBlID0gVGhpcy0+SW1wbFR5cGU7CgogICAgaWYoY2xpcHBlcikKICAgIHsKICAgICAgICBJV2luZUQzRENsaXBwZXJfUmVsZWFzZShjbGlwcGVyKTsKICAgIH0KICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcwogKgogKiBBIGZ1bmN0aW9uLCB0aGF0IGNvbnZlcnRzIGFsbCB3aW5lRDNEU3VyZmFjZXMgdG8gdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiB0eXBlCiAqIEl0IGVudW1lcmF0ZXMgYWxsIHN1cmZhY2VzIHdpdGggSVdpbmVEM0REZXZpY2U6OkVudW1TdXJmYWNlcywgY3JlYXRlcyBhCiAqIG5ldyBXaW5lRDNEU3VyZmFjZSwgY29waWVzIHRoZSBjb250ZW50IGFuZCByZWxlYXNlcyB0aGUgb2xkIHN1cmZhY2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcyhJRGlyZWN0RHJhd0ltcGwgKlRoaXMpCnsKICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICBUUkFDRSgiKCVwKTogU3dpdGNoIHRvIGltcGxlbWVudGF0aW9uICVkXG4iLCBUaGlzLCBUaGlzLT5JbXBsVHlwZSk7CgogICAgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wgJiYgVGhpcy0+ZDNkX2luaXRpYWxpemVkKQogICAgewogICAgICAgIC8qIFNob3VsZCBoYXBwZW4gYWxtb3N0IG5ldmVyICovCiAgICAgICAgRklYTUUoIiglcCkgU3dpdGNoaW5nIHRvIG5vbi1vcGVuZ2wgc3VyZmFjZXMgd2l0aCBkM2Qgc3RhcnRlZC4gSXMgdGhpcyBhIGJ1Zz9cbiIsIFRoaXMpOwogICAgICAgIC8qIFNodXRkb3duIGQzZCAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX1VuaW5pdDNEKFRoaXMtPndpbmVEM0REZXZpY2UsIEQzRDdDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZSwgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4pOwogICAgfQogICAgLyogQ29udHJhcnk6IEQzRCBzdGFydGluZyBpcyBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIsIGJlY2F1c2UgaXQga25vd3MgdGhlIHJlbmRlciB0YXJnZXQgKi8KCiAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICBkZXNjLmR3U2l6ZSA9IHNpemVvZihkZXNjKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXc3X0VudW1TdXJmYWNlcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2spOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZVN1cmZhY2UKICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIElEaXJlY3QzRERldmljZV9DcmVhdGVUZXh0dXJlLiBJdCBzZWFyY2hlcyBmb3IgdGhlCiAqIGNvcnJlY3QgbWlwbWFwIHN1YmxldmVsLCBhbmQgcmV0dXJucyBpdCB0byBXaW5lRDNELgogKiBUaGUgc3VyZmFjZXMgYXJlIGNyZWF0ZWQgYWxyZWFkeSBieSBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgV2l0aCwgSGVpZ2h0OiBXaXRoIGFuZCBoZWlnaHQgb2YgdGhlIHN1cmZhY2UKICogIEZvcm1hdDogVGhlIHJlcXVlc3RlZCBmb3JtYXQKICogIFVzYWdlLCBQb29sOiBEM0RVU0FHRSBhbmQgRDNEUE9PTCBvZiB0aGUgc3VyZmFjZQogKiAgbGV2ZWw6IFRoZSBtaXBtYXAgbGV2ZWwKICogIEZhY2U6IFRoZSBjdWJlIG1hcCBmYWNlIHR5cGUKICogIFN1cmZhY2U6IFBvaW50ZXIgdG8gcGFzcyB0aGUgY3JlYXRlZCBzdXJmYWNlIGJhY2sgYXQKICogIFNoYXJlZEhhbmRsZTogTlVMTAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVTdXJmYWNlKElVbmtub3duICpkZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwU3VwZXJpb3IsCiAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RQT09MIFBvb2wsIFVJTlQgbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RDVUJFTUFQX0ZBQ0VTIEZhY2UsCiAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqKlN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSAqU2hhcmVkSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYgPSBOVUxMOwogICAgaW50IGkgPSAwOwogICAgRERTQ0FQUzIgc2VhcmNoY2FwcyA9IFRoaXMtPnRleF9yb290LT5zdXJmYWNlX2Rlc2MuZGRzQ2FwczsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFjay4gc3VyZj0lcC4gRmFjZSAlZCBsZXZlbCAlZFxuIiwgZGV2aWNlLCBUaGlzLT50ZXhfcm9vdCwgRmFjZSwgbGV2ZWwpOwoKICAgIHNlYXJjaGNhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUzsKICAgIHN3aXRjaChGYWNlKQogICAgewogICAgICAgIGNhc2UgV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YOgogICAgICAgICAgICBUUkFDRSgiQXNrZWQgZm9yIHBvc2l0aXZlIHhcbiIpOwogICAgICAgICAgICBpZihzZWFyY2hjYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKSB7CiAgICAgICAgICAgICAgICBzZWFyY2hjYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVg7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3VyZiA9IFRoaXMtPnRleF9yb290OyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWDoKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBuZWdhdGl2ZSB4XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVYOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWToKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBwb3NpdGl2ZSB5XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVZOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWToKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBuZWdhdGl2ZSB5XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVZOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWjoKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBwb3NpdGl2ZSB6XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVaOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfTkVHQVRJVkVfWjoKICAgICAgICAgICAgVFJBQ0UoIkFza2VkIGZvciBuZWdhdGl2ZSB6XG4iKTsKICAgICAgICAgICAgc2VhcmNoY2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVaOyBicmVhazsKICAgICAgICBkZWZhdWx0OiB7RVJSKCJVbmV4cGVjdGVkIGN1YmUgZmFjZVxuIik7fSAvKiBTdHVwaWQgY29tcGlsZXIgKi8KICAgIH0KCiAgICBpZighc3VyZikKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICphdHRhY2hlZDsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRShUaGlzLT50ZXhfcm9vdCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlYXJjaGNhcHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0dGFjaGVkKTsKICAgICAgICBzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgYXR0YWNoZWQpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShhdHRhY2hlZCk7CiAgICB9CiAgICBpZighc3VyZikgRVJSKCJyb290IHNlYXJjaCBzdXJmYWNlIG5vdCBmb3VuZFxuIik7CgogICAgLyogRmluZCB0aGUgd2FudGVkIG1pcG1hcC4gVGhlcmUgYXJlIGVub3VnaCBtaXBtYXBzIGluIHRoZSBjaGFpbiAqLwogICAgd2hpbGUoaSA8IGxldmVsKQogICAgewogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKmF0dGFjaGVkOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfR2V0QXR0YWNoZWRTdXJmYWNlKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWFyY2hjYXBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdHRhY2hlZCk7CiAgICAgICAgaWYoIWF0dGFjaGVkKSBFUlIoIlN1cmZhY2Ugbm90IGZvdW5kXG4iKTsKICAgICAgICBzdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgYXR0YWNoZWQpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShhdHRhY2hlZCk7CiAgICAgICAgaSsrOwogICAgfQoKICAgIC8qIFJldHVybiB0aGUgc3VyZmFjZSAqLwogICAgKlN1cmZhY2UgPSBzdXJmLT5XaW5lRDNEU3VyZmFjZTsKCiAgICBUUkFDRSgiUmV0dXJuaW5nIHdpbmVEM0RTdXJmYWNlICVwLCBpdCBiZWxvbmdzIHRvIHN1cmZhY2UgJXBcbiIsICpTdXJmYWNlLCBzdXJmKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KClVMT05HIFdJTkFQSSBEM0Q3Q0JfRGVzdHJveVN3YXBDaGFpbihJV2luZUQzRFN3YXBDaGFpbiAqcFN3YXBDaGFpbikgewogICAgSVVua25vd24qIHN3YXBDaGFpblBhcmVudDsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgcFN3YXBDaGFpbik7CgogICAgSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UGFyZW50KHBTd2FwQ2hhaW4sICZzd2FwQ2hhaW5QYXJlbnQpOwogICAgSVVua25vd25fUmVsZWFzZShzd2FwQ2hhaW5QYXJlbnQpOwogICAgcmV0dXJuIElVbmtub3duX1JlbGVhc2Uoc3dhcENoYWluUGFyZW50KTsKfQoKVUxPTkcgV0lOQVBJIEQzRDdDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZShJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlKSB7CiAgICBJVW5rbm93biogc3VyZmFjZVBhcmVudDsKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgcFN1cmZhY2UpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQocFN1cmZhY2UsIChJVW5rbm93biAqKikgJnN1cmZhY2VQYXJlbnQpOwogICAgSVVua25vd25fUmVsZWFzZShzdXJmYWNlUGFyZW50KTsKICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKHN1cmZhY2VQYXJlbnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UKICoKICogQSBoZWxwZXIgZnVuY3Rpb24gZm9yIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZS4gSXQgY3JlYXRlcyBhIG5ldyBzdXJmYWNlCiAqIHdpdGggdGhlIHBhc3NlZCBwYXJhbWV0ZXJzLgogKgogKiBQYXJhbXM6CiAqICBERFNEOiBEZXNjcmlwdGlvbiBvZiB0aGUgc3VyZmFjZSB0byBjcmVhdGUKICogIFN1cmY6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKnBERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICoqcHBTdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIGxldmVsKQp7CiAgICBIUkVTVUxUIGhyOwogICAgVUlOVCBXaWR0aCA9IDAsIEhlaWdodCA9IDA7CiAgICBXSU5FRDNERk9STUFUIEZvcm1hdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIFdJTkVEM0RSRVNPVVJDRVRZUEUgUmVzVHlwZSA9IFdJTkVEM0RSVFlQRV9TVVJGQUNFOwogICAgRFdPUkQgVXNhZ2UgPSAwOwogICAgV0lORUQzRFNVUkZUWVBFIEltcGxUeXBlID0gVGhpcy0+SW1wbFR5cGU7CiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDIERlc2M7CiAgICBJVW5rbm93biAqUGFyZW50OwogICAgSVBhcmVudEltcGwgKnBhckltcGwgPSBOVUxMOwogICAgV0lORUQzRFBPT0wgUG9vbCA9IFdJTkVEM0RQT09MX0RFRkFVTFQ7CgogICAgLyogRHVtbWllcyBmb3IgR2V0RGVzYyAqLwogICAgV0lORUQzRFBPT0wgZHVtbXlfZDNkcG9vbDsKICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIGR1bW15X21zdDsKICAgIFVJTlQgZHVtbXlfdWludDsKICAgIERXT1JEIGR1bW15X2R3b3JkOwoKICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICB7CiAgICAgICAgVFJBQ0UoIiAoJXApIFJlcXVlc3Rpbmcgc3VyZmFjZSBkZXNjIDpcbiIsIFRoaXMpOwogICAgICAgIEREUkFXX2R1bXBfc3VyZmFjZV9kZXNjKHBERFNEKTsKICAgIH0KCiAgICAvKiBTZWxlY3QgdGhlIHN1cmZhY2UgdHlwZSwgaWYgaXQgd2Fzbid0IGNob29zZW4geWV0ICovCiAgICBpZihJbXBsVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICB7CiAgICAgICAgLyogVXNlIEdMIFN1cmZhY2VzIGlmIGEgRDNEREVWSUNFIFN1cmZhY2UgaXMgcmVxdWVzdGVkICovCiAgICAgICAgaWYocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU18zRERFVklDRSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIENob29zaW5nIEdMIHN1cmZhY2VzIGJlY2F1c2UgYSAzRERFVklDRSBTdXJmYWNlIHdhcyByZXF1ZXN0ZWRcbiIsIFRoaXMpOwogICAgICAgICAgICBJbXBsVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgIH0KCiAgICAgICAgLyogT3RoZXJ3aXNlIHVzZSBHREkgc3VyZmFjZXMgZm9yIG5vdyAqLwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIENob29zaW5nIEdESSBzdXJmYWNlcyBmb3IgMkQgcmVuZGVyaW5nXG4iLCBUaGlzKTsKICAgICAgICAgICAgSW1wbFR5cGUgPSBTVVJGQUNFX0dESTsKICAgICAgICB9CgogICAgICAgIC8qIFBvbGljeSBpZiBhbGwgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbnMgYXJlIGF2YWlsYWJsZToKICAgICAgICAgKiBGaXJzdCwgY2hlY2sgaWYgYSBkZWZhdWx0IHR5cGUgd2FzIHNldCB3aXRoIHdpbmVjZmcuIElmIG5vdCwKICAgICAgICAgKiB0cnkgWHJlbmRlciBzdXJmYWNlcywgYW5kIHVzZSB0aGVtIGlmIHRoZXkgd29yay4gTmV4dCwgY2hlY2sgaWYKICAgICAgICAgKiBhY2NlbGVyYXRlZCBPcGVuR0wgaXMgYXZhaWxhYmxlLCBhbmQgdXNlIEdMIHN1cmZhY2VzIGluIHRoaXMKICAgICAgICAgKiBjYXNlLiBJZiBhbGwgZWxzZSBmYWlscywgdXNlIEdESSBzdXJmYWNlcy4gSWYgYSAzRERFVklDRSBzdXJmYWNlCiAgICAgICAgICogd2FzIGNyZWF0ZWQsIGFsd2F5cyB1c2UgT3BlbkdMIHN1cmZhY2VzLgogICAgICAgICAqCiAgICAgICAgICogKE5vdGU6IFhyZW5kZXIgc3VyZmFjZXMgYXJlIG5vdCBpbXBsZW1lbnRlZCBmb3Igbm93LCB0aGUKICAgICAgICAgKiB1bmFjY2VsZXJhdGVkIGltcGxlbWVudGF0aW9uIHVzZXMgR0RJIHRvIHJlbmRlciBpbiBTb2Z0d2FyZSkKICAgICAgICAgKi8KCiAgICAgICAgLyogU3RvcmUgdGhlIHR5cGUuIElmIGl0IG5lZWRzIHRvIGJlIGNoYW5nZWQsIGFsbCBXaW5lRDNEU3VyZmFjZXMgaGF2ZSB0bwogICAgICAgICAqIGJlIHJlLWNyZWF0ZWQuIFRoaXMgY291bGQgYmUgZG9uZSB3aXRoIElEaXJlY3REcmF3U3VyZmFjZTc6OlJlc3RvcmUKICAgICAgICAgKi8KICAgICAgICBUaGlzLT5JbXBsVHlwZSA9IEltcGxUeXBlOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgICBpZigocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU18zRERFVklDRSApICYmIAogICAgICAgICAgICAoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wgKSAmJiBEZWZhdWx0U3VyZmFjZVR5cGUgPT0gU1VSRkFDRV9VTktOT1dOKQogICAgICAgIHsKICAgICAgICAgICAgLyogV2UgaGF2ZSB0byBjaGFuZ2UgdG8gT3BlbkdMLAogICAgICAgICAgICAgKiBhbmQgcmUtY3JlYXRlIGFsbCBXaW5lRDNEU3VyZmFjZXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIEltcGxUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgICAgIFRoaXMtPkltcGxUeXBlID0gSW1wbFR5cGU7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIFJlLWNyZWF0aW5nIGFsbCBzdXJmYWNlc1xuIiwgVGhpcyk7CiAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZUFsbFN1cmZhY2VzKFRoaXMpOwogICAgICAgICAgICBUUkFDRSgiKCVwKSBEb25lIHJlY3JlYXRpbmcgYWxsIHN1cmZhY2VzXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCAmJiBwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTXzNEREVWSUNFKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiVGhlIGFwcGxpY2F0aW9uIHJlcXVlc3RzIGEgM0QgY2FwYWJsZSBzdXJmYWNlLCBidXQgYSBub24tb3BlbmdsIHN1cmZhY2Ugd2FzIHNldCBpbiB0aGUgcmVnaXN0cnlcbiIpOwogICAgICAgICAgICAvKiBEbyBub3QgZmFpbCBzdXJmYWNlIGNyZWF0aW9uLCBvbmx5IGZhaWwgM0QgZGV2aWNlIGNyZWF0aW9uICovCiAgICAgICAgfQogICAgfQoKICAgIC8qIEdldCB0aGUgY29ycmVjdCB3aW5lZDNkIHVzYWdlICovCiAgICBpZiAocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX0JBQ0tCVUZGRVIgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU18zRERFVklDRSAgICAgICApICkKICAgIHsKICAgICAgICBVc2FnZSB8PSBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUOwoKICAgICAgICBwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19WSURFT01FTU9SWSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVklTSUJMRTsKICAgIH0KICAgIGlmIChwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19PVkVSTEFZKSkKICAgIHsKICAgICAgICBVc2FnZSB8PSBXSU5FRDNEVVNBR0VfT1ZFUkxBWTsKICAgIH0KICAgIGlmKFRoaXMtPmRlcHRoc3RlbmNpbCB8fCAocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19aQlVGRkVSKSApCiAgICB7CiAgICAgICAgLyogVGhlIGRlcHRoIHN0ZW5jaWwgY3JlYXRpb24gY2FsbGJhY2sgc2V0cyB0aGlzIGZsYWcuCiAgICAgICAgICogU2V0IHRoZSBXaW5lRDNEIHVzYWdlIHRvIGxldCBpdCBrbm93IHRoYXQgaXQncyBhIGRlcHRoCiAgICAgICAgICogU3RlbmNpbCBzdXJmYWNlLgogICAgICAgICAqLwogICAgICAgIFVzYWdlIHw9IFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUw7CiAgICB9CiAgICBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1NZU1RFTU1FTU9SWSkKICAgIHsKICAgICAgICBQb29sID0gV0lORUQzRFBPT0xfU1lTVEVNTUVNOwogICAgfQogICAgZWxzZSBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfVEVYVFVSRU1BTkFHRSkKICAgIHsKICAgICAgICBQb29sID0gV0lORUQzRFBPT0xfTUFOQUdFRDsKICAgICAgICAvKiBNYW5hZ2VkIHRleHR1cmVzIGhhdmUgdGhlIHN5c3RlbSBtZW1vcnkgZmxhZyBzZXQgKi8KICAgICAgICBwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19TWVNURU1NRU1PUlk7CiAgICB9CiAgICBlbHNlIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfVklERU9NRU1PUlkpCiAgICB7CiAgICAgICAgLyogVmlkZW9tZW1vcnkgYWRkcyBsb2NhbHZpZG1lbSwgdGhpcyBpcyBtdXR1YWxseSBleGNsdXNpdmUgd2l0aCBzeXN0ZW1tZW1vcnkKICAgICAgICAgKiBhbmQgdGV4dHVyZW1hbmFnZQogICAgICAgICAqLwogICAgICAgIHBERFNELT5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX0xPQ0FMVklETUVNOwogICAgfQoKICAgIEZvcm1hdCA9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJnBERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgaWYoRm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikKICAgIHsKICAgICAgICBFUlIoIlVuc3VwcG9ydGVkIC8gVW5rbm93biBwaXhlbGZvcm1hdFxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQSVhFTEZPUk1BVDsKICAgIH0KCiAgICAvKiBDcmVhdGUgdGhlIFN1cmZhY2Ugb2JqZWN0ICovCiAgICAqcHBTdXJmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRGlyZWN0RHJhd1N1cmZhY2VJbXBsKSk7CiAgICBpZighKnBwU3VyZikKICAgIHsKICAgICAgICBFUlIoIiglcCkgRXJyb3IgYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICB9CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcsIElEaXJlY3REcmF3U3VyZmFjZTdfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTMsIElEaXJlY3REcmF3U3VyZmFjZTNfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbF9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdDNEVGV4dHVyZTIsIElEaXJlY3QzRFRleHR1cmUyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0M0RUZXh0dXJlLCBJRGlyZWN0M0RUZXh0dXJlMV9WdGJsKTsKICAgICgqcHBTdXJmKS0+cmVmID0gMTsKICAgICgqcHBTdXJmKS0+dmVyc2lvbiA9IDc7CiAgICAoKnBwU3VyZiktPmRkcmF3ID0gVGhpczsKICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3U2l6ZSA9IHNpemVvZihERFNVUkZBQ0VERVNDMik7CiAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREUElYRUxGT1JNQVQpOwogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKCYoKnBwU3VyZiktPnN1cmZhY2VfZGVzYywgcEREU0QpOwoKICAgIC8qIFN1cmZhY2UgYXR0YWNobWVudHMgKi8KICAgICgqcHBTdXJmKS0+bmV4dF9hdHRhY2hlZCA9IE5VTEw7CiAgICAoKnBwU3VyZiktPmZpcnN0X2F0dGFjaGVkID0gKnBwU3VyZjsKCiAgICAvKiBOZWVkZWQgdG8gcmUtY3JlYXRlIHRoZSBzdXJmYWNlIG9uIGFuIGltcGxlbWVudGF0aW9uIGNoYW5nZSAqLwogICAgKCpwcFN1cmYpLT5JbXBsVHlwZSA9IEltcGxUeXBlOwoKICAgIC8qIEZvciBEM0REZXZpY2UgY3JlYXRpb24gKi8KICAgICgqcHBTdXJmKS0+aXNSZW5kZXJUYXJnZXQgPSBGQUxTRTsKCiAgICAvKiBBIHRyYWNlIG1lc3NhZ2UgZm9yIGRlYnVnZ2luZyAqLwogICAgVFJBQ0UoIiglcCkgQ3JlYXRlZCBJRGlyZWN0RHJhd1N1cmZhY2UgaW1wbGVtZW50YXRpb24gc3RydWN0dXJlIGF0ICVwXG4iLCBUaGlzLCAqcHBTdXJmKTsKCiAgICBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTX1RFWFRVUkUgfCBERFNDQVBTXzNEREVWSUNFKSApCiAgICB7CiAgICAgICAgLyogUmVuZGVyIHRhcmdldHMgYW5kIHRleHR1cmVzIG5lZWQgYSBJUGFyZW50IGludGVyZmFjZSwKICAgICAgICAgKiBiZWNhdXNlIFdpbmVEM0Qgd2lsbCBkZXN0cm95IHRoZW0gd2hlbiB0aGUgc3dhcGNoYWluCiAgICAgICAgICogaXMgcmVsZWFzZWQKICAgICAgICAgKi8KICAgICAgICBwYXJJbXBsID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJUGFyZW50SW1wbCkpOwogICAgICAgIGlmKCFwYXJJbXBsKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgSVBhcmVudCBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgcGFySW1wbC0+cmVmID0gMTsKICAgICAgICBJQ09NX0lOSVRfSU5URVJGQUNFKHBhckltcGwsIElQYXJlbnQsIElQYXJlbnRfVnRibCk7CiAgICAgICAgUGFyZW50ID0gKElVbmtub3duICopIElDT01fSU5URVJGQUNFKHBhckltcGwsIElQYXJlbnQpOwogICAgICAgIFRSQUNFKCJVc2luZyBJUGFyZW50IGludGVyZmFjZSAlcCBhcyBwYXJlbnRcbiIsIHBhckltcGwpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIFVzZSB0aGUgc3VyZmFjZSBhcyBwYXJlbnQgKi8KICAgICAgICBQYXJlbnQgPSAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyk7CiAgICAgICAgVFJBQ0UoIlVzaW5nIFN1cmZhY2UgaW50ZXJmYWNlICVwIGFzIHBhcmVudFxuIiwgKnBwU3VyZik7CiAgICB9CgogICAgLyogTm93IGNyZWF0ZSB0aGUgV2luZUQzRCBTdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRERTRC0+ZHdXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRERTRC0+ZHdIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFMU0UgLyogRGlzY2FyZCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXNUeXBlLCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9OT05FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogTXVsdGlTYW1wbGVRdWFsaXR5ICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogU2hhcmVkSGFuZGxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEltcGxUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhcmVudCk7CgogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0REZXZpY2U6OkNyZWF0ZVN1cmZhY2UgZmFpbGVkLiBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogU2V0IHRoZSBjaGlsZCBvZiB0aGUgcGFyZW50IGltcGxlbWVudGF0aW9uIGlmIGl0IGV4aXN0cyAqLwogICAgaWYocGFySW1wbCkKICAgIHsKICAgICAgICBwYXJJbXBsLT5jaGlsZCA9IChJVW5rbm93biAqKSAoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlOwogICAgICAgIC8qIFRoZSBJUGFyZW50IHJlbGVhc2VzIHRoZSBXaW5lRDNEU3VyZmFjZSwgYW5kCiAgICAgICAgICogdGhlIGRkcmF3IHN1cmZhY2UgZG9lcyB0aGF0IHRvby4gSG9sZCBhIHJlZmVyZW5jZQogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSk7CiAgICB9CgogICAgLyogSW5jcmVhc2UgdGhlIHN1cmZhY2UgY291bnRlciwgYW5kIGF0dGFjaCB0aGUgc3VyZmFjZSAqLwogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnN1cmZhY2VzKTsKICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnN1cmZhY2VfbGlzdCwgJigqcHBTdXJmKS0+c3VyZmFjZV9saXN0X2VudHJ5KTsKCiAgICAvKiBIZXJlIHdlIGNvdWxkIHN0b3JlIGFsbCBjcmVhdGVkIHN1cmZhY2VzIGluIHRoZSBEaXJlY3REcmF3SW1wbCBzdHJ1Y3R1cmUsCiAgICAgKiBCdXQgdGhpcyBjb3VsZCBhbHNvIGJlIGRlbGVnYXRlZCB0byBXaW5lRERyYXcsIGFzIGl0IGtlZXBzIHRyYWNrIG9mIGFsbCBpdHMKICAgICAqIHJlc291cmNlcy4gTm90IGltcGxlbWVudGVkIGZvciBub3csIGFzIHRoZXJlIGFyZSBtb3JlIGltcG9ydGFudCB0aGluZ3MgOykKICAgICAqLwoKICAgIC8qIEdldCB0aGUgcGl4ZWwgZm9ybWF0IG9mIHRoZSBXaW5lRDNEU3VyZmFjZSBhbmQgc3RvcmUgaXQuCiAgICAgKiBEb24ndCB1c2UgdGhlIEZvcm1hdCBjaG9vc2VuIGFib3ZlLCBXaW5lRDNEIG1pZ2h0IGhhdmUKICAgICAqIGNoYW5nZWQgaXQKICAgICAqLwogICAgRGVzYy5Gb3JtYXQgPSAmRm9ybWF0OwogICAgRGVzYy5UeXBlID0gJlJlc1R5cGU7CiAgICBEZXNjLlVzYWdlID0gJlVzYWdlOwogICAgRGVzYy5Qb29sID0gJmR1bW15X2QzZHBvb2w7CiAgICBEZXNjLlNpemUgPSAmZHVtbXlfdWludDsKICAgIERlc2MuTXVsdGlTYW1wbGVUeXBlID0gJmR1bW15X21zdDsKICAgIERlc2MuTXVsdGlTYW1wbGVRdWFsaXR5ID0gJmR1bW15X2R3b3JkOwogICAgRGVzYy5XaWR0aCA9ICZXaWR0aDsKICAgIERlc2MuSGVpZ2h0ID0gJkhlaWdodDsKCiAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy5kd0ZsYWdzIHw9IEREU0RfUElYRUxGT1JNQVQ7CiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsICZEZXNjKTsKICAgIGlmKGhyICE9IEQzRF9PSykKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZTo6R2V0RGVzYyBmYWlsZWRcbiIpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZSggKElEaXJlY3REcmF3U3VyZmFjZTcgKikgKnBwU3VyZik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pCiAgICB7CiAgICAgICAgRklYTUUoIklXaW5lRDNEU3VyZmFjZTo6R2V0RGVzYyByZXR1cm5lZCBXSU5FRDNERk1UX1VOS05PV05cbiIpOwogICAgfQogICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoICYoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQsIEZvcm1hdCk7CgogICAgLyogQW5ubyAxNjAyIHN0b3JlcyB0aGUgcGl0Y2ggcmlnaHQgYWZ0ZXIgc3VyZmFjZSBjcmVhdGlvbiwgc28gbWFrZSBzdXJlIGl0J3MgdGhlcmUuCiAgICAgKiBJIGNhbid0IExvY2tSZWN0KCkgdGhlIHN1cmZhY2UgaGVyZSBiZWNhdXNlIGlmIE9wZW5HTCBzdXJmYWNlcyBhcmUgaW4gdXNlLCB0aGUKICAgICAqIFdpbmVEM0REZXZpY2UgbWlnaHQgbm90IGJlIHVzZWFibGUgZm9yIDNEIHlldCwgc28gYW4gZXh0cmEgbWV0aG9kIHdhcyBjcmVhdGVkLgogICAgICogVE9ETzogVGVzdCBvdGhlciBmb3VyY2MgZm9ybWF0cwogICAgICovCiAgICBpZihGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KQogICAgewogICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9MSU5FQVJTSVpFOwogICAgICAgIGlmKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51MS5kd0xpbmVhclNpemUgPSBtYXgoNCwgV2lkdGgpICogbWF4KDQsIEhlaWdodCkgLyAyOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51MS5kd0xpbmVhclNpemUgPSBtYXgoNCwgV2lkdGgpICogbWF4KDQsIEhlaWdodCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9QSVRDSDsKICAgICAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51MS5sUGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSk7CiAgICB9CgogICAgLyogQXBwbGljYXRpb24gcGFzc2VkIGEgY29sb3Iga2V5PyBTZXQgaXQhICovCiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tERVNUT1ZFUkxBWSkKICAgIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERDS0VZX0RFU1RPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUREQ09MT1JLRVkgKikgJnBERFNELT51My5kZGNrQ0tEZXN0T3ZlcmxheSk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tERVNUQkxUKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVEJMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZwRERTRC0+ZGRja0NLRGVzdEJsdCk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tTUkNPVkVSTEFZKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfU1JDT1ZFUkxBWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVERENPTE9SS0VZICopICZwRERTRC0+ZGRja0NLU3JjT3ZlcmxheSk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tTUkNCTFQpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNCTFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRERDT0xPUktFWSAqKSAmcEREU0QtPmRkY2tDS1NyY0JsdCk7CiAgICB9CiAgICBpZiAoIHBERFNELT5kd0ZsYWdzICYgRERTRF9MUFNVUkZBQ0UpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsIHBERFNELT5scFN1cmZhY2UpOwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBuZWVkIGZvciBhIHRyYWNlIGhlcmUsIHdpbmVkM2QgZG9lcyB0aGF0IGZvciB1cyAqLwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoKCpwcFN1cmYpLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9Ci8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMKICoKICogQ3JlYXRlcyBhIG5ldyBtaXBtYXAgY2hhaW4uCiAqCiAqIFBhcmFtczoKICogIHJvb3Q6IFJvb3Qgc3VyZmFjZSB0byBhdHRhY2ggdGhlIG5ld2x5IGNyZWF0ZWQgY2hhaW4gdG8KICogIGNvdW50OiBudW1iZXIgb2Ygc3VyZmFjZXMgdG8gY3JlYXRlCiAqICBERFNEOiBEZXNjcmlwdGlvbiBvZiB0aGUgc3VyZmFjZS4gSW50ZW50aW9uYWxseSBub3QgYSBwb2ludGVyIHRvIGF2b2lkIHNpZGUKICogICAgICAgIGVmZmVjdHMgb24gdGhlIGNhbGxlcgogKiAgQ3ViZUZhY2VSb290OiBXaGV0aGVyIHRoZSBuZXcgc3VyZmFjZSBpcyBhIHJvb3Qgb2YgYSBjdWJlIG1hcCBmYWNlLiBUaGlzCiAqICAgICAgICAgICAgICAgIGNyZWF0ZXMgYW4gYWRkaXRpb25hbCBzdXJmYWNlIHdpdGhvdXQgdGhlIG1pcG1hcHBpbmcgZmxhZ3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcm9vdCwKICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgY291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiBERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBDdWJlRmFjZVJvb3QpCnsKICAgIFVJTlQgaSwgaiwgbGV2ZWwgPSAwOwogICAgSFJFU1VMVCBocjsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmxhc3QgPSByb290OwoKICAgIGZvcihpID0gMDsgaSA8IGNvdW50OyBpKyspCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqb2JqZWN0MiA9IE5VTEw7CgogICAgICAgIC8qIGluY3JlYXNlIHRoZSBtaXBtYXAgbGV2ZWwsIGJ1dCBvbmx5IGlmIGEgbWlwbWFwIGlzIGNyZWF0ZWQKICAgICAgICAgKiBJbiB0aGlzIGNhc2UsIGFsc28gaGFsdmUgdGhlIHNpemUKICAgICAgICAgKi8KICAgICAgICBpZihERFNELmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVAgJiYgIUN1YmVGYWNlUm9vdCkKICAgICAgICB7CiAgICAgICAgICAgIGxldmVsKys7CiAgICAgICAgICAgIGlmKEREU0QuZHdXaWR0aCA+IDEpIEREU0QuZHdXaWR0aCAvPSAyOwogICAgICAgICAgICBpZihERFNELmR3SGVpZ2h0ID4gMSkgRERTRC5kd0hlaWdodCAvPSAyOwogICAgICAgICAgICAvKiBTZXQgdGhlIG1pcG1hcCBzdWJsZXZlbCBmbGFnIGFjY29yZGluZyB0byBtc2RuICovCiAgICAgICAgICAgIEREU0QuZGRzQ2Fwcy5kd0NhcHMyIHw9IEREU0NBUFMyX01JUE1BUFNVQkxFVkVMOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBERFNELmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfTUlQTUFQU1VCTEVWRUw7CiAgICAgICAgfQogICAgICAgIEN1YmVGYWNlUm9vdCA9IEZBTFNFOwoKICAgICAgICBociA9IElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlKFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvYmplY3QyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWwpOwogICAgICAgIGlmKGhyICE9IEREX09LKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgLyogQWRkIHRoZSBuZXcgc3VyZmFjZSB0byB0aGUgY29tcGxleCBhdHRhY2htZW50IGFycmF5ICovCiAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX0NPTVBMRVhfQVRUQUNIRUQ7IGorKykKICAgICAgICB7CiAgICAgICAgICAgIGlmKGxhc3QtPmNvbXBsZXhfYXJyYXlbal0pIGNvbnRpbnVlOwogICAgICAgICAgICBsYXN0LT5jb21wbGV4X2FycmF5W2pdID0gb2JqZWN0MjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxhc3QgPSBvYmplY3QyOwoKICAgICAgICAvKiBSZW1vdmUgdGhlIChwb3NzaWJsZSkgYmFjayBidWZmZXIgY2FwIGZyb20gdGhlIG5ldyBzdXJmYWNlIGRlc2NyaXB0aW9uLAogICAgICAgICAqIGJlY2F1c2Ugb25seSBvbmUgc3VyZmFjZSBpbiB0aGUgZmxpcHBpbmcgY2hhaW4gaXMgYSBiYWNrIGJ1ZmZlciwgb25lCiAgICAgICAgICogaXMgYSBmcm9udCBidWZmZXIsIHRoZSBvdGhlcnMgYXJlIGp1c3QgcHJpbWFyeSBzdXJmYWNlcy4KICAgICAgICAgKi8KICAgICAgICBERFNELmRkc0NhcHMuZHdDYXBzICY9IH5ERFNDQVBTX0JBQ0tCVUZGRVI7CiAgICB9CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICoKICogQ3JlYXRlcyBhIG5ldyBJRGlyZWN0RHJhd1N1cmZhY2Ugb2JqZWN0IGFuZCByZXR1cm5zIGl0cyBpbnRlcmZhY2UuCiAqCiAqIFRoZSBzdXJmYWNlIGNvbm5lY3Rpb25zIHdpdGggd2luZWQzZCBhcmUgYSBiaXQgdHJpY2t5LiBCYXNpY2FsbHkgaXQgd29ya3MKICogbGlrZSB0aGlzOgogKgogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwKICogfCBERHJhdyBzdXJmYWNlICAgICAgICAgIHwgICAgICAgICAgICAgICB8IFdpbmVEM0RTdXJmYWNlICB8CiAqIHwgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfAogKiB8ICAgICAgICBXaW5lRDNEU3VyZmFjZSAgfC0tLS0tLS0tLS0tLS0tPnwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgQ2hpbGQgICAgICAgICAgIHw8LS0tLS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8CiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfAogKgogKiBUaGUgRERyYXcgc3VyZmFjZSBpcyB0aGUgcGFyZW50IG9mIHRoZSB3aW5lZDNkIHN1cmZhY2UsIGFuZCBpdCByZWxlYXNlcwogKiB0aGUgV2luZUQzRFN1cmZhY2Ugd2hlbiB0aGUgZGRyYXcgc3VyZmFjZSBpcyBkZXN0cm95ZWQuCiAqCiAqIEhvd2V2ZXIsIGZvciBhbGwgc3VyZmFjZXMgd2hpY2ggY2FuIGJlIGluIGEgY29udGFpbmVyIGluIFdpbmVEM0QsCiAqIHdlIGhhdmUgdG8gZG8gdGhpcy4gVGhlc2Ugc3VyZmFjZXMgYXJlIHVzdXNhbGx5IGNvbXBsZXggc3VyZmFjZXMsCiAqIHNvIHRoaXMgY29uY2VybnMgcHJpbWFyeSBzdXJmYWNlcyB3aXRoIGEgZnJvbnQgYW5kIGEgYmFjayBidWZmZXIsCiAqIGFuZCB0ZXh0dXJlcy4KICoKICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18CiAqIHwgRERyYXcgc3VyZmFjZSAgICAgICAgICB8ICAgICAgICAgICAgICAgfCBDb250YWludGVyICAgICAgfAogKiB8ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgICAgICAgICAgIENoaWxkIHw8LS0tLS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8CiAqIHwgICAgICAgICAgICAgICAgVGV4dHVyZSB8PC0tLS0tLS0tLS0tLS0+fCAgICAgICAgICAgICAgICAgfAogKiB8ICAgICAgICAgV2luZUQzRFN1cmZhY2UgfDwtLS0tfCAgICAgICAgIHwgICAgICAgICAgTGV2ZWxzIHw8LS18CiAqIHwgQ29tcGxleCBjb25uZWN0aW9uICAgICB8ICAgICB8ICAgICAgICAgfCAgICAgICAgICAgICAgICAgfCAgIHwKICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgXiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICB8LS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgfCAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICB8ICAgIHwgSVBhcmVudCAgICAgICAgICB8ICAgICB8LS0tLS0tLS0+fCBXaW5lRDNEU3VyZmFjZSAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgQ2hpbGQgfDwtLS0tLS0tLS0tLS0tPnwgUGFyZW50ICAgICAgICAgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICBDb250YWluZXIgfDwtLXwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8IEREcmF3IHN1cmZhY2UgMiAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8PC0+fCBDb21wbGV4IHJvb3QgICBDaGlsZCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8ICAgICAgICAgICAgICBUZXh0dXJlIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwgICAgICAgV2luZUQzRFN1cmZhY2UgfDwtLS0tfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgfCAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwgICB8CiAqICB8ICAgIHwgSVBhcmVudCAgICAgICAgICAgICB8ICAgICB8LS0tLS0+fCBXaW5lRDNEU3VyZmFjZSAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgQ2hpbGQgfDwtLS0tLS0tLS0tPnwgUGFyZW50ICAgICAgICAgIHwgICB8CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgfCAgICAgICBDb250YWluZXIgfDwtLXwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgICAgICAgICAgIC0tLU1vcmUgc3VyZmFjZXMgY2FuIGZvbGxvdy0tLSAgICAgICAgICAgICAgICAgIHwKICoKICogVGhlIHJlYXNvbiBpcyB0aGF0IHRoZSBJV2luZUQzRFN3YXBjaGFpbihyZW5kZXIgdGFyZ2V0IGNvbnRhaW5lcikKICogYW5kIHRoZSBJV2luZUQzRFRleHVyZShUZXh0dXJlIGNvbnRhaW5lcikgcmVsZWFzZSB0aGUgcGFyZW50cwogKiBvZiB0aGVpciBzdXJmYWNlJ3MgY2hpbGRyZW4sIGJ1dCBieSByZWxlYXNpbmcgdGhlIGNvbXBsZXggcm9vdAogKiB0aGUgc3VyZmFjZXMgd2hpY2ggYXJlIGNvbXBsZXhseSBhdHRhY2hlZCB0byBpdCBhcmUgZGVzdHJveWVkCiAqIHRvby4gU2VlIElEaXJlY3REcmF3U3VyZmFjZTo6UmVsZWFzZSBmb3IgYSBtb3JlIGRldGFpbGVkCiAqIGV4cGxhbmF0aW9uLgogKgogKiBQYXJhbXM6CiAqICBERFNEOiBEZXNjcmlwdGlvbiBvZiB0aGUgc3VyZmFjZSB0byBjcmVhdGUKICogIFN1cmY6IEFkZHJlc3MgdG8gc3RvcmUgdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqICBVbmtPdXRlcjogQmFzaWNhbGx5IGZvciBhZ2dyZWdhdGlvbiBzdXBwb3J0LCBidXQgZGRyYXcgZG9lc24ndCBzdXBwb3J0CiAqICAgICAgICAgICAgYWdncmVnYXRpb24sIHNvIGl0IGhhcyB0byBiZSBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRERFUlJfKiBpZiBhbiBlcnJvciBvY2N1cnMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZVN1cmZhY2UoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipTdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpvYmplY3QgPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIExPTkcgZXh0cmFfc3VyZmFjZXMgPSAwOwogICAgRERTVVJGQUNFREVTQzIgZGVzYzI7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwKVxuIiwgVGhpcywgRERTRCwgU3VyZiwgVW5rT3V0ZXIpOwoKICAgIC8qIFNvbWUgY2hlY2tzIGJlZm9yZSB3ZSBzdGFydCAqLwogICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiICglcCkgUmVxdWVzdGluZyBzdXJmYWNlIGRlc2MgOlxuIiwgVGhpcyk7CiAgICAgICAgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MoRERTRCk7CiAgICB9CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIGlmIChVbmtPdXRlciAhPSBOVUxMKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIDogb3V0ZXIgIT0gTlVMTD9cbiIsIFRoaXMpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsgLyogdW5jaGVja2VkICovCiAgICB9CgogICAgaWYgKFN1cmYgPT0gTlVMTCkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBZb3Ugd2FudCB0byBnZXQgYmFjayBhIHN1cmZhY2U/IERvbid0IGdpdmUgTlVMTCBwdHJzIVxuIiwgVGhpcyk7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gRV9QT0lOVEVSOyAvKiB1bmNoZWNrZWQgKi8KICAgIH0KCiAgICBpZiAoIShERFNELT5kd0ZsYWdzICYgRERTRF9DQVBTKSkKICAgIHsKICAgICAgICAvKiBEVklERU8uRExMIGRvZXMgZm9yZ2V0IHRoZSBERFNEX0NBUFMgZmxhZyAuLi4gKnNpZ2gqICovCiAgICAgICAgRERTRC0+ZHdGbGFncyB8PSBERFNEX0NBUFM7CiAgICB9CiAgICBpZiAoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgPT0gMCkKICAgIHsKICAgICAgICAvKiBUaGlzIGhhcyBiZWVuIGNoZWNrZWQgb24gcmVhbCBXaW5kb3dzICovCiAgICAgICAgRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX0xPQ0FMVklETUVNIHwgRERTQ0FQU19WSURFT01FTU9SWTsKICAgIH0KCiAgICBpZiAoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0FMTE9DT05MT0FEKQogICAgewogICAgICAgIC8qIElmIHRoZSBzdXJmYWNlIGlzIG9mIHRoZSAnYWxsb2NvbmxvYWQnIHR5cGUsIGlnbm9yZSB0aGUgTFBTVVJGQUNFIGZpZWxkICovCiAgICAgICAgRERTRC0+ZHdGbGFncyAmPSB+RERTRF9MUFNVUkZBQ0U7CiAgICB9CgogICAgaWYgKChERFNELT5kd0ZsYWdzICYgRERTRF9MUFNVUkZBQ0UpICYmIChERFNELT5scFN1cmZhY2UgPT0gTlVMTCkpCiAgICB7CiAgICAgICAgLyogRnJhbmsgSGVyYmVydCdzIER1bmUgc3BlY2lmaWVzIGEgbnVsbCBwb2ludGVyIGZvciB0aGUgc3VyZmFjZSwgaWdub3JlIHRoZSBMUFNVUkZBQ0UgZmllbGQgKi8KICAgICAgICBXQVJOKCIoJXApIE51bGwgc3VyZmFjZSBwb2ludGVyIHNwZWNpZmllZCwgaWdub3JlIGl0IVxuIiwgVGhpcyk7CiAgICAgICAgRERTRC0+ZHdGbGFncyAmPSB+RERTRF9MUFNVUkZBQ0U7CiAgICB9CgogICAgaWYoKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfRkxJUCB8IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpKSA9PSAoRERTQ0FQU19GTElQIHwgRERTQ0FQU19QUklNQVJZU1VSRkFDRSkgJiYKICAgICAgICEoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApOiBBdHRlbXB0IHRvIGNyZWF0ZSBhIGZsaXBhYmxlIHByaW1hcnkgc3VyZmFjZSB3aXRob3V0IEREU0NMX0VYQ0xVU0lWRSBzZXRcbiIsIFRoaXMpOwogICAgICAgICpTdXJmID0gTlVMTDsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREU7CiAgICB9CgogICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19GUk9OVEJVRkZFUiB8IEREU0NBUFNfQkFDS0JVRkZFUikpIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiB0cmllZCB0byBjcmVhdGUgYW4gZXhwbGljaXQgZnJvbnQgb3IgYmFjayBidWZmZXJcbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURDQVBTOwogICAgfQogICAgLyogQ2hlY2sgY3ViZSBtYXBzIGJ1dCBvbmx5IGlmIHRoZSBzaXplIGluY2x1ZGVzIHRoZW0gKi8KICAgIGlmIChERFNELT5kd1NpemUgPj0gc2l6ZW9mKEREU1VSRkFDRURFU0MyKSkKICAgIHsKICAgICAgICBpZihERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQX0FMTEZBQ0VTICYmCiAgICAgICAgICAgIShERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQKSkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkN1YmUgbWFwIGZhY2VzIHJlcXVlc3RlZCB3aXRob3V0IGN1YmUgbWFwIGZsYWdcbiIpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRENBUFM7CiAgICAgICAgfQogICAgICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVAgJiYKICAgICAgICAgICAoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUF9BTExGQUNFUykgPT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oIkN1YmUgbWFwIHdpdGhvdXQgZmFjZXMgcmVxdWVzdGVkXG4iKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQoKICAgICAgICAvKiBRdWljayB0ZXN0cyBjb25maXJtIHRob3NlIGNhbiBiZSBjcmVhdGVkLCBidXQgd2UgZG9uJ3QgZG8gdGhhdCB5ZXQgKi8KICAgICAgICBpZihERFNELT5kZHNDYXBzLmR3Q2FwczIgJiBERFNDQVBTMl9DVUJFTUFQICYmCiAgICAgICAgICAgKEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVBfQUxMRkFDRVMpICE9IEREU0NBUFMyX0NVQkVNQVBfQUxMRkFDRVMpCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSgiUGFydGlhbCBjdWJlIG1hcHMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBBY2NvcmRpbmcgdG8gdGhlIG1zZG4gdGhpcyBmbGFnIGlzIGlnbm9yZWQgYnkgQ3JlYXRlU3VyZmFjZSAqLwogICAgaWYgKEREU0QtPmR3U2l6ZSA+PSBzaXplb2YoRERTVVJGQUNFREVTQzIpKQogICAgICAgIEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfTUlQTUFQU1VCTEVWRUw7CgogICAgLyogTW9kaWZ5IHNvbWUgZmxhZ3MgKi8KICAgIG1lbXNldCgmZGVzYzIsIDAsIHNpemVvZihkZXNjMikpOwogICAgZGVzYzIuZHdTaXplID0gc2l6ZW9mKGRlc2MyKTsgICAvKiBGb3IgdGhlIHN0cnVjdCBjb3B5ICovCiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoJmRlc2MyLCBERFNEKTsKICAgIGRlc2MyLmR3U2l6ZSA9IHNpemVvZihkZXNjMik7ICAgLyogVG8gb3ZlcnJpZGUgYSBwb3NzaWJseSBzbWFsbGVyIHNpemUgKi8KICAgIGRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemU9c2l6ZW9mKEREUElYRUxGT1JNQVQpOyAvKiBKdXN0IHRvIGJlIHN1cmUgKi8KCiAgICAvKiBHZXQgdGhlIHZpZGVvIG1vZGUgZnJvbSBXaW5lRDNEIC0gd2Ugd2lsbCBuZWVkIGl0ICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIFN3YXBjaGFpbiAwICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNb2RlKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gcmVhZCBkaXNwbGF5IG1vZGUgZnJvbSB3aW5lZDNkXG4iKTsKICAgICAgICBzd2l0Y2goVGhpcy0+b3JpZ19icHApCiAgICAgICAgewogICAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUDg7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDFSNUc1QjU7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMTY6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUjVHNkI1OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDI0OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I4RzhCODsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9YOFI4RzhCODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBNb2RlLldpZHRoID0gVGhpcy0+b3JpZ193aWR0aDsKICAgICAgICBNb2RlLkhlaWdodCA9IFRoaXMtPm9yaWdfaGVpZ2h0OwogICAgfQoKICAgIC8qIE5vIHBpeGVsZm9ybWF0IGdpdmVuPyBVc2UgdGhlIGN1cnJlbnQgc2NyZWVuIGZvcm1hdCAqLwogICAgaWYoIShkZXNjMi5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkpCiAgICB7CiAgICAgICAgZGVzYzIuZHdGbGFncyB8PSBERFNEX1BJWEVMRk9STUFUOwogICAgICAgIGRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemU9c2l6ZW9mKEREUElYRUxGT1JNQVQpOwoKICAgICAgICAvKiBXYWl0OiBJdCBjb3VsZCBiZSBhIFogYnVmZmVyICovCiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1pCVUZGRVIpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2goZGVzYzIudTIuZHdNaXBNYXBDb3VudCkgLyogV2hvIGhhZCB0aGlzIGdsb3Jpb3VzIGlkZWE/ICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgV0lORUQzREZNVF9EMTVTMSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDE2KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgV0lORUQzREZNVF9EMjRYOCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDMyOgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDMyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIFogYnVmZmVyIGJpdCBkZXB0aFxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgTW9kZS5Gb3JtYXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBObyBXaWR0aCBvciBubyBIZWlnaHQ/IFVzZSB0aGUgb3JpZ2luYWwgc2NyZWVuIHNpemUKICAgICAqLwogICAgaWYoIShkZXNjMi5kd0ZsYWdzICYgRERTRF9XSURUSCkgfHwKICAgICAgICEoZGVzYzIuZHdGbGFncyAmIEREU0RfSEVJR0hUKSApCiAgICB7CiAgICAgICAgLyogSW52YWxpZCBmb3Igbm9uLXJlbmRlciB0YXJnZXRzICovCiAgICAgICAgaWYoIShkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigiQ3JlYXRpbmcgYSBub24tUHJpbWFyeSBzdXJmYWNlIHdpdGhvdXQgV2lkdGggb3IgSGVpZ2h0IGluZm8sIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iKTsKICAgICAgICAgICAgKlN1cmYgPSBOVUxMOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CgogICAgICAgIGRlc2MyLmR3RmxhZ3MgfD0gRERTRF9XSURUSCB8IEREU0RfSEVJR0hUOwogICAgICAgIGRlc2MyLmR3V2lkdGggPSBNb2RlLldpZHRoOwogICAgICAgIGRlc2MyLmR3SGVpZ2h0ID0gTW9kZS5IZWlnaHQ7CiAgICB9CgogICAgLyogTWlwbWFwIGNvdW50IGZpeGVzICovCiAgICBpZihkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQKQogICAgewogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19DT01QTEVYKQogICAgICAgIHsKICAgICAgICAgICAgaWYoZGVzYzIuZHdGbGFncyAmIEREU0RfTUlQTUFQQ09VTlQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIE1pcG1hcCBjb3VudCBpcyBnaXZlbiwgc2hvdWxkIG5vdCBiZSAwICovCiAgICAgICAgICAgICAgICBpZiggZGVzYzIudTIuZHdNaXBNYXBDb3VudCA9PSAwICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogVW5kb2N1bWVudGVkIGZlYXR1cmU6IENyZWF0ZSBzdWJsZXZlbHMgdW50aWwKICAgICAgICAgICAgICAgICAqIGVpdGhlciB0aGUgd2lkdGggb3IgdGhlIGhlaWdodCBpcyAxCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERXT1JEIG1pbiA9IGRlc2MyLmR3V2lkdGggPCBkZXNjMi5kd0hlaWdodCA/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjMi5kd1dpZHRoIDogZGVzYzIuZHdIZWlnaHQ7CiAgICAgICAgICAgICAgICBkZXNjMi51Mi5kd01pcE1hcENvdW50ID0gMDsKICAgICAgICAgICAgICAgIHdoaWxlKCBtaW4gKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgKz0gMTsKICAgICAgICAgICAgICAgICAgICBtaW4gPj49IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogTm90LWNvbXBsZXggbWlwbWFwIC0+IE1pcG1hcGNvdW50ID0gMSAqLwogICAgICAgICAgICBkZXNjMi51Mi5kd01pcE1hcENvdW50ID0gMTsKICAgICAgICB9CiAgICAgICAgZXh0cmFfc3VyZmFjZXMgPSBkZXNjMi51Mi5kd01pcE1hcENvdW50IC0gMTsKCiAgICAgICAgLyogVGhlcmUncyBhIG1pcG1hcCBjb3VudCBpbiB0aGUgY3JlYXRlZCBzdXJmYWNlIGluIGFueSBjYXNlICovCiAgICAgICAgZGVzYzIuZHdGbGFncyB8PSBERFNEX01JUE1BUENPVU5UOwogICAgfQogICAgLyogSWYgbm8gbWlwbWFwIGlzIGdpdmVuLCB0aGUgdGV4dHVyZSBoYXMgb25seSBvbmUgbGV2ZWwgKi8KCiAgICAvKiBUaGUgZmlyc3Qgc3VyZmFjZSBpcyBhIGZyb250IGJ1ZmZlciwgdGhlIGJhY2sgYnVmZmVyIGlzIGNyZWF0ZWQgYWZ0ZXJ3YXJkcyAqLwogICAgaWYoIChkZXNjMi5kd0ZsYWdzICYgRERTRF9DQVBTKSAmJiAoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSApCiAgICB7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19GUk9OVEJVRkZFUjsKICAgIH0KCiAgICAvKiBUaGUgcm9vdCBzdXJmYWNlIGluIGEgY3ViZSBtYXAgaXMgcG9zaXRpdmUgeCAqLwogICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCkKICAgIHsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfQUxMRkFDRVM7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWDsKICAgIH0KCiAgICAvKiBDcmVhdGUgdGhlIGZpcnN0IHN1cmZhY2UgKi8KICAgIGhyID0gSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UoVGhpcywgJmRlc2MyLCAmb2JqZWN0LCAwKTsKICAgIGlmKCBociAhPSBERF9PSykKICAgIHsKICAgICAgICBFUlIoIklEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlIGZhaWxlZCB3aXRoICUwOHhcbiIsIGhyKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KICAgIG9iamVjdC0+aXNfY29tcGxleF9yb290ID0gVFJVRTsKCiAgICAqU3VyZiA9IElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdTdXJmYWNlNyk7CgogICAgLyogQ3JlYXRlIEFkZGl0aW9uYWwgc3VyZmFjZXMgaWYgbmVjZXNzYXJ5CiAgICAgKiBUaGlzIGFwcGxpZXMgdG8gUHJpbWFyeSBzdXJmYWNlcyB3aGljaCBoYXZlIGEgYmFjayBidWZmZXIgY291bnQKICAgICAqIHNldCwgYnV0IG5vdCB0byBtaXBtYXAgdGV4dHVyZXMuIEluIGNhc2Ugb2YgTWlwbWFwIHRleHR1cmVzLAogICAgICogd2luZUQzRCB0YWtlcyBjYXJlIG9mIHRoZSBjcmVhdGlvbiBvZiBhZGRpdGlvbmFsIHN1cmZhY2VzCiAgICAgKi8KICAgIGlmKEREU0QtPmR3RmxhZ3MgJiBERFNEX0JBQ0tCVUZGRVJDT1VOVCkKICAgIHsKICAgICAgICBleHRyYV9zdXJmYWNlcyA9IEREU0QtPmR3QmFja0J1ZmZlckNvdW50OwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzICY9IH5ERFNDQVBTX0ZST05UQlVGRkVSOyAvKiBJdCdzIG5vdCBhIGZyb250IGJ1ZmZlciAqLwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfQkFDS0JVRkZFUjsKICAgIH0KCiAgICBociA9IEREX09LOwogICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICYgRERTQ0FQUzJfQ1VCRU1BUCkKICAgIHsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfQUxMRkFDRVM7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWjsKICAgICAgICBociB8PSBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoVGhpcywgb2JqZWN0LCBleHRyYV9zdXJmYWNlcyArIDEsIGRlc2MyLCBUUlVFKTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVaOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9QT1NJVElWRVo7CiAgICAgICAgaHIgfD0gQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKFRoaXMsIG9iamVjdCwgZXh0cmFfc3VyZmFjZXMgKyAxLCBkZXNjMiwgVFJVRSk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWjsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfTkVHQVRJVkVZOwogICAgICAgIGhyIHw9IENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcyhUaGlzLCBvYmplY3QsIGV4dHJhX3N1cmZhY2VzICsgMSwgZGVzYzIsIFRSVUUpOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyIHw9ICBERFNDQVBTMl9DVUJFTUFQX1BPU0lUSVZFWTsKICAgICAgICBociB8PSBDcmVhdGVBZGRpdGlvbmFsU3VyZmFjZXMoVGhpcywgb2JqZWN0LCBleHRyYV9zdXJmYWNlcyArIDEsIGRlc2MyLCBUUlVFKTsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgJj0gfkREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVZOwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzMiB8PSAgRERTQ0FQUzJfQ1VCRU1BUF9ORUdBVElWRVg7CiAgICAgICAgaHIgfD0gQ3JlYXRlQWRkaXRpb25hbFN1cmZhY2VzKFRoaXMsIG9iamVjdCwgZXh0cmFfc3VyZmFjZXMgKyAxLCBkZXNjMiwgVFJVRSk7CiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMyICY9IH5ERFNDQVBTMl9DVUJFTUFQX05FR0FUSVZFWDsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gIEREU0NBUFMyX0NVQkVNQVBfUE9TSVRJVkVYOwogICAgfQoKICAgIGhyIHw9IENyZWF0ZUFkZGl0aW9uYWxTdXJmYWNlcyhUaGlzLCBvYmplY3QsIGV4dHJhX3N1cmZhY2VzLCBkZXNjMiwgRkFMU0UpOwogICAgaWYoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgLyogVGhpcyBkZXN0cm95cyBhbmQgcG9zc2libHkgY3JlYXRlZCBzdXJmYWNlcyB0b28gKi8KICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VfUmVsZWFzZSggSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSApOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIEFkZHJlZiB0aGUgZGRyYXcgaW50ZXJmYWNlIHRvIGtlZXAgYW4gcmVmZXJlbmNlIGZvciBlYWNoIHN1cmZhY2UgKi8KICAgIElEaXJlY3REcmF3N19BZGRSZWYoaWZhY2UpOwogICAgb2JqZWN0LT5pZmFjZVRvUmVsZWFzZSA9IChJVW5rbm93biAqKSBpZmFjZTsKCiAgICAvKiBJZiB0aGUgaW1wbGVtZW50YXRpb24gaXMgT3BlbkdMIGFuZCB0aGVyZSdzIG5vIGQzZGRldmljZSwgYXR0YWNoIGEgZDNkZGV2aWNlCiAgICAgKiBCdXQgYXR0YWNoIHRoZSBkM2RkZXZpY2Ugb25seSBpZiB0aGUgY3VycmVudGx5IGNyZWF0ZWQgc3VyZmFjZSB3YXMKICAgICAqIGEgcHJpbWFyeSBzdXJmYWNlICgyRCBhcHAgaW4gM0QgbW9kZSkgb3IgYSAzRERFVklDRSBzdXJmYWNlICgzRCBhcHApCiAgICAgKiBUaGUgb25seSBjYXNlIEkgY2FuIHRoaW5rIG9mIHdoZXJlIHRoaXMgZG9lc24ndCBhcHBseSBpcyB3aGVuIGEKICAgICAqIDJEIGFwcCB3YXMgY29uZmlndXJlZCBieSB0aGUgdXNlciB0byBydW4gd2l0aCBPcGVuR0wgYW5kIGl0IGRpZG4ndCBjcmVhdGUKICAgICAqIHRoZSByZW5kZXIgdGFyZ2V0IGFzIGZpcnN0IHN1cmZhY2UuIEluIHRoaXMgY2FzZSB0aGUgcmVuZGVyIHRhcmdldCBjcmVhdGlvbgogICAgICogd2lsbCBjYXVzZSB0aGUgM0QgaW5pdC4KICAgICAqLwogICAgaWYoIChUaGlzLT5JbXBsVHlwZSA9PSBTVVJGQUNFX09QRU5HTCkgJiYgIShUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpICYmCiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfM0RERVZJQ0UpICkKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICp0YXJnZXQgPSBvYmplY3QsICpzdXJmYWNlOwogICAgICAgIHN0cnVjdCBsaXN0ICplbnRyeTsKCiAgICAgICAgLyogU2VhcmNoIGZvciB0aGUgcHJpbWFyeSB0byB1c2UgYXMgcmVuZGVyIHRhcmdldCAqLwogICAgICAgIExJU1RfRk9SX0VBQ0goZW50cnksICZUaGlzLT5zdXJmYWNlX2xpc3QpCiAgICAgICAgewogICAgICAgICAgICBzdXJmYWNlID0gTElTVF9FTlRSWShlbnRyeSwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgc3VyZmFjZV9saXN0X2VudHJ5KTsKICAgICAgICAgICAgaWYoKHN1cmZhY2UtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU19GUk9OVEJVRkZFUikpID09CiAgICAgICAgICAgICAgIChERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU19GUk9OVEJVRkZFUikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGZvdW5kICovCiAgICAgICAgICAgICAgICB0YXJnZXQgPSBzdXJmYWNlOwogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHByaW1hcnkgJXAgYXMgcmVuZGVyIHRhcmdldFxuIiwgdGFyZ2V0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiKCVwKSBBdHRhY2hpbmcgYSBEM0REZXZpY2UsIHJlbmRlcnRhcmdldCA9ICVwXG4iLCBUaGlzLCB0YXJnZXQpOwogICAgICAgIGhyID0gSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZShUaGlzLCB0YXJnZXQpOwogICAgICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZSBmYWlsZWQsIGhyID0gJXhcbiIsIGhyKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQ3JlYXRlIGEgV2luZUQzRFRleHR1cmUgaWYgYSB0ZXh0dXJlIHdhcyByZXF1ZXN0ZWQgKi8KICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19URVhUVVJFKQogICAgewogICAgICAgIFVJTlQgbGV2ZWxzOwogICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0OwogICAgICAgIFdJTkVEM0RQT09MIFBvb2wgPSBXSU5FRDNEUE9PTF9ERUZBVUxUOwoKICAgICAgICBUaGlzLT50ZXhfcm9vdCA9IG9iamVjdDsKCiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGEgbWlwbWFwIGlzIGNyZWF0ZWQsIGNyZWF0ZSBlbm91Z2ggbGV2ZWxzICovCiAgICAgICAgICAgIGxldmVscyA9IGRlc2MyLnUyLmR3TWlwTWFwQ291bnQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIG1pcG1hcCBpcyBjcmVhdGVkLCBjcmVhdGUgb25lIGxldmVsICovCiAgICAgICAgICAgIGxldmVscyA9IDE7CiAgICAgICAgfQoKICAgICAgICAvKiBERFNDQVBTX1NZU1RFTU1FTU9SWSB0ZXh0dXJlcyBhcmUgaW4gV0lORUQzRFBPT0xfU1lTVEVNTUVNICovCiAgICAgICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1NZU1RFTU1FTU9SWSkKICAgICAgICB7CiAgICAgICAgICAgIFBvb2wgPSBXSU5FRDNEUE9PTF9TWVNURU1NRU07CiAgICAgICAgfQogICAgICAgIC8qIFNob3VsZCBJIGZvcndhcmQgdGhlIE1BTkVHRUQgY2FwIHRvIHRoZSBtYW5hZ2VkIHBvb2wgPyAqLwoKICAgICAgICAvKiBHZXQgdGhlIGZvcm1hdC4gSXQncyBzZXQgYWxyZWFkeSBieSBDcmVhdGVOZXdTdXJmYWNlICovCiAgICAgICAgRm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmb2JqZWN0LT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICAgICAgLyogVGhlIHN1cmZhY2VzIGFyZSBhbHJlYWR5IGNyZWF0ZWQsIHRoZSBjYWxsYmFjayBvbmx5CiAgICAgICAgICogcGFzc2VzIHRoZSBJV2luZUQzRFN1cmZhY2UgdG8gV2luZUQzRAogICAgICAgICAqLwogICAgICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzMiAmIEREU0NBUFMyX0NVQkVNQVApCiAgICAgICAgewogICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZUN1YmVUZXh0dXJlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTRC0+ZHdXaWR0aCwgLyogRWRnZWxlbmd0aCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiB1c2FnZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzREN1YmVUZXh0dXJlICoqKSAmb2JqZWN0LT53aW5lRDNEVGV4dHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBTaGFyZWRIYW5kbGUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlU3VyZmFjZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVGV4dHVyZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTRC0+ZHdXaWR0aCwgRERTRC0+ZHdIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbHMsIC8qIE1pcE1hcENvdW50ID0gTGV2ZWxzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiB1c2FnZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzRFRleHR1cmUgKiopICZvYmplY3QtPndpbmVEM0RUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogU2hhcmVkSGFuZGxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVTdXJmYWNlICk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnRleF9yb290ID0gTlVMTDsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgojZGVmaW5lIERERU5VTVNVUkZBQ0VTX1NFQVJDSFRZUEUgKERERU5VTVNVUkZBQ0VTX0NBTkJFQ1JFQVRFRHxEREVOVU1TVVJGQUNFU19ET0VTRVhJU1QpCiNkZWZpbmUgRERFTlVNU1VSRkFDRVNfTUFUQ0hUWVBFIChEREVOVU1TVVJGQUNFU19BTEx8RERFTlVNU1VSRkFDRVNfTUFUQ0h8RERFTlVNU1VSRkFDRVNfTk9NQVRDSCkKCnN0YXRpYyBCT09MCk1haW5fRGlyZWN0RHJhd19ERFBJWEVMRk9STUFUX01hdGNoKGNvbnN0IEREUElYRUxGT1JNQVQgKnJlcXVlc3RlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRERQSVhFTEZPUk1BVCAqcHJvdmlkZWQpCnsKICAgIC8qIFNvbWUgZmxhZ3MgbXVzdCBiZSBwcmVzZW50IGluIGJvdGggb3IgbmVpdGhlciBmb3IgYSBtYXRjaC4gKi8KICAgIHN0YXRpYyBjb25zdCBEV09SRCBtdXN0X21hdGNoID0gRERQRl9QQUxFVFRFSU5ERVhFRDEgfCBERFBGX1BBTEVUVEVJTkRFWEVEMgogICAgICAgIHwgRERQRl9QQUxFVFRFSU5ERVhFRDQgfCBERFBGX1BBTEVUVEVJTkRFWEVEOCB8IEREUEZfRk9VUkNDCiAgICAgICAgfCBERFBGX1pCVUZGRVIgfCBERFBGX1NURU5DSUxCVUZGRVI7CgogICAgaWYgKChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBwcm92aWRlZC0+ZHdGbGFncykgIT0gcmVxdWVzdGVkLT5kd0ZsYWdzKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoKHJlcXVlc3RlZC0+ZHdGbGFncyAmIG11c3RfbWF0Y2gpICE9IChwcm92aWRlZC0+ZHdGbGFncyAmIG11c3RfbWF0Y2gpKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgRERQRl9GT1VSQ0MpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+ZHdGb3VyQ0MgIT0gcHJvdmlkZWQtPmR3Rm91ckNDKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1pCVUZGRVJ8RERQRl9BTFBIQQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8RERQRl9MVU1JTkFOQ0V8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTEuZHdSR0JCaXRDb3VudCAhPSBwcm92aWRlZC0+dTEuZHdSR0JCaXRDb3VudCkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9SR0J8RERQRl9ZVVZ8RERQRl9TVEVOQ0lMQlVGRkVSCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxERFBGX0xVTUlOQU5DRXxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51Mi5kd1JCaXRNYXNrICE9IHByb3ZpZGVkLT51Mi5kd1JCaXRNYXNrKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1pCVUZGRVJ8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTMuZHdHQml0TWFzayAhPSBwcm92aWRlZC0+dTMuZHdHQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIC8qIEkgY291bGQgYmUgd3JvbmcgYWJvdXQgdGhlIGJ1bXBtYXBwaW5nLiBNU0ROIGRvY3MgYXJlIHZhZ3VlLiAqLwogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1NURU5DSUxCVUZGRVIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfEREUEZfQlVNUERVRFYpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnU0LmR3QkJpdE1hc2sgIT0gcHJvdmlkZWQtPnU0LmR3QkJpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfQUxQSEFQSVhFTFN8RERQRl9aUElYRUxTKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51NS5kd1JHQkFscGhhQml0TWFzayAhPSBwcm92aWRlZC0+dTUuZHdSR0JBbHBoYUJpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIEJPT0wKSURpcmVjdERyYXdJbXBsX0REU0RfTWF0Y2goY29uc3QgRERTVVJGQUNFREVTQzIqIHJlcXVlc3RlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgRERTVVJGQUNFREVTQzIqIHByb3ZpZGVkKQp7CiAgICBzdHJ1Y3QgY29tcGFyZV9pbmZvCiAgICB7CiAgICAgICAgRFdPUkQgZmxhZzsKICAgICAgICBwdHJkaWZmX3Qgb2Zmc2V0OwogICAgICAgIHNpemVfdCBzaXplOwogICAgfTsKCiNkZWZpbmUgQ01QKEZMQUcsIEZJRUxEKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgICAgIHsgRERTRF8jI0ZMQUcsIG9mZnNldG9mKEREU1VSRkFDRURFU0MyLCBGSUVMRCksIFwKICAgICAgICAgIHNpemVvZigoKEREU1VSRkFDRURFU0MyICopKE5VTEwpKS0+RklFTEQpIH0KCiAgICBzdGF0aWMgY29uc3Qgc3RydWN0IGNvbXBhcmVfaW5mbyBjb21wYXJlW10gPQogICAgewogICAgICAgIENNUChBTFBIQUJJVERFUFRILCBkd0FscGhhQml0RGVwdGgpLAogICAgICAgIENNUChCQUNLQlVGRkVSQ09VTlQsIGR3QmFja0J1ZmZlckNvdW50KSwKICAgICAgICBDTVAoQ0FQUywgZGRzQ2FwcyksCiAgICAgICAgQ01QKENLREVTVEJMVCwgZGRja0NLRGVzdEJsdCksCiAgICAgICAgQ01QKENLREVTVE9WRVJMQVksIHUzIC8qIGRkY2tDS0Rlc3RPdmVybGF5ICovKSwKICAgICAgICBDTVAoQ0tTUkNCTFQsIGRkY2tDS1NyY0JsdCksCiAgICAgICAgQ01QKENLU1JDT1ZFUkxBWSwgZGRja0NLU3JjT3ZlcmxheSksCiAgICAgICAgQ01QKEhFSUdIVCwgZHdIZWlnaHQpLAogICAgICAgIENNUChMSU5FQVJTSVpFLCB1MSAvKiBkd0xpbmVhclNpemUgKi8pLAogICAgICAgIENNUChMUFNVUkZBQ0UsIGxwU3VyZmFjZSksCiAgICAgICAgQ01QKE1JUE1BUENPVU5ULCB1MiAvKiBkd01pcE1hcENvdW50ICovKSwKICAgICAgICBDTVAoUElUQ0gsIHUxIC8qIGxQaXRjaCAqLyksCiAgICAgICAgLyogUElYRUxGT1JNQVQ6IG1hbnVhbCAqLwogICAgICAgIENNUChSRUZSRVNIUkFURSwgdTIgLyogZHdSZWZyZXNoUmF0ZSAqLyksCiAgICAgICAgQ01QKFRFWFRVUkVTVEFHRSwgZHdUZXh0dXJlU3RhZ2UpLAogICAgICAgIENNUChXSURUSCwgZHdXaWR0aCksCiAgICAgICAgLyogWkJVRkZFUkJJVERFUFRIOiAib2Jzb2xldGUiICovCiAgICB9OwoKI3VuZGVmIENNUAoKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmICgocmVxdWVzdGVkLT5kd0ZsYWdzICYgcHJvdmlkZWQtPmR3RmxhZ3MpICE9IHJlcXVlc3RlZC0+ZHdGbGFncykKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgZm9yIChpPTA7IGkgPCBzaXplb2YoY29tcGFyZSkvc2l6ZW9mKGNvbXBhcmVbMF0pOyBpKyspCiAgICB7CiAgICAgICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIGNvbXBhcmVbaV0uZmxhZwogICAgICAgICAgICAmJiBtZW1jbXAoKGNvbnN0IGNoYXIgKilwcm92aWRlZCArIGNvbXBhcmVbaV0ub2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKilyZXF1ZXN0ZWQgKyBjb21wYXJlW2ldLm9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgIGNvbXBhcmVbaV0uc2l6ZSkgIT0gMCkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBERFNEX1BJWEVMRk9STUFUKQogICAgewogICAgICAgIGlmICghTWFpbl9EaXJlY3REcmF3X0REUElYRUxGT1JNQVRfTWF0Y2goJnJlcXVlc3RlZC0+dTQuZGRwZlBpeGVsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJvdmlkZWQtPnU0LmRkcGZQaXhlbEZvcm1hdCkpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKI3VuZGVmIERERU5VTVNVUkZBQ0VTX1NFQVJDSFRZUEUKI3VuZGVmIERERU5VTVNVUkZBQ0VTX01BVENIVFlQRQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RW51bVN1cmZhY2VzCiAqCiAqIExvb3BzIHRocm91Z2ggYWxsIHN1cmZhY2VzIGF0dGFjaGVkIHRvIHRoaXMgZGV2aWNlIGFuZCBjYWxscyB0aGUKICogYXBwbGljYXRpb24gY2FsbGJhY2suIFRoaXMgY2FuJ3QgYmUgcmVsYXllZCB0byBXaW5lRDNERGV2aWNlLAogKiBiZWNhdXNlIHNvbWUgV2luZUQzRFN1cmZhY2VzJyBwYXJlbnRzIGFyZSBJUGFyZW50IG9iamVjdHMKICoKICogUGFyYW1zOgogKiAgRmxhZ3M6IFNvbWUgZmlsdGVyaW5nIGZsYWdzLiBTZWUgSURpcmVjdERyYXdJbXBsX0VudW1TdXJmYWNlc0NhbGxiYWNrCiAqICBERFNEOiBEZXNjcmlwdGlvbiB0byBmaWx0ZXIgZm9yCiAqICBDb250ZXh0OiBBcHBsaWNhdGlvbi1wcm92aWRlZCBwb2ludGVyLCBpdCdzIHBhc3NlZCB1bm1vZGlmaWVkIHRvIHRoZQogKiAgICAgICAgICAgQ2FsbGJhY2sgZnVuY3Rpb24KICogIENhbGxiYWNrOiBBZGRyZXNzIHRvIGNhbGwgZm9yIGVhY2ggc3VyZmFjZQogKgogKiBSZXR1cm5zOgogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgY2FsbGJhY2sgaXMgTlVMTAogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERERU5VTVNVUkZBQ0VTQ0FMTEJBQ0s3IENhbGxiYWNrKQp7CiAgICAvKiBUaGUgc3VyZmFjZSBlbnVtZXJhdGlvbiBpcyBoYW5kbGVkIGJ5IFdpbmVERHJhdywKICAgICAqIGJlY2F1c2UgaXQga2VlcHMgdHJhY2sgb2YgYWxsIHN1cmZhY2VzIGF0dGFjaGVkIHRvCiAgICAgKiBpdC4gVGhlIGZpbHRlcmluZyBpcyBkb25lIGJ5IG91ciBjYWxsYmFjayBmdW5jdGlvbiwKICAgICAqIGJlY2F1c2UgV2luZUREcmF3IGRvZXNuJ3QgaGFuZGxlIGRkcmF3LWxpa2Ugc3VyZmFjZQogICAgICogY2FwcyBzdHJ1Y3R1cmVzCiAgICAgKi8KICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmOwogICAgQk9PTCBhbGwsIG5vbWF0Y2g7CiAgICBERFNVUkZBQ0VERVNDMiBkZXNjOwogICAgc3RydWN0IGxpc3QgKmVudHJ5LCAqZW50cnkyOwoKICAgIGFsbCA9IEZsYWdzICYgRERFTlVNU1VSRkFDRVNfQUxMOwogICAgbm9tYXRjaCA9IEZsYWdzICYgRERFTlVNU1VSRkFDRVNfTk9NQVRDSDsKCiAgICBUUkFDRSgiKCVwKS0+KCV4LCVwLCVwLCVwKVxuIiwgVGhpcywgRmxhZ3MsIEREU0QsIENvbnRleHQsIENhbGxiYWNrKTsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgaWYoIUNhbGxiYWNrKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogVXNlIHRoZSBfU0FGRSBlbnVtZXJhdGlvbiwgdGhlIGFwcCBtYXkgZGVzdHJveSBlbnVtZXJhdGVkIHN1cmZhY2VzICovCiAgICBMSVNUX0ZPUl9FQUNIX1NBRkUoZW50cnksIGVudHJ5MiwgJlRoaXMtPnN1cmZhY2VfbGlzdCkKICAgIHsKICAgICAgICBzdXJmID0gTElTVF9FTlRSWShlbnRyeSwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgc3VyZmFjZV9saXN0X2VudHJ5KTsKICAgICAgICBpZiAoYWxsIHx8IChub21hdGNoICE9IElEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKEREU0QsICZzdXJmLT5zdXJmYWNlX2Rlc2MpKSkKICAgICAgICB7CiAgICAgICAgICAgIGRlc2MgPSBzdXJmLT5zdXJmYWNlX2Rlc2M7CiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKICAgICAgICAgICAgaWYoQ2FsbGJhY2soIElDT01fSU5URVJGQUNFKHN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcpLCAmZGVzYywgQ29udGV4dCkgIT0gRERFTlVNUkVUX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIEREX09LOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBERF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJCmZpbmRSZW5kZXJUYXJnZXQoSURpcmVjdERyYXdTdXJmYWNlNyAqc3VyZmFjZSwKICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqZGVzYywKICAgICAgICAgICAgICAgICB2b2lkICpjdHgpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBzdXJmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKip0YXJnZXQgPSAoSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKikgY3R4OwoKICAgIGlmKCFzdXJmLT5pc1JlbmRlclRhcmdldCkgewogICAgICAgICp0YXJnZXQgPSBzdXJmOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmYWNlKTsKICAgICAgICByZXR1cm4gRERFTlVNUkVUX0NBTkNFTDsKICAgIH0KCiAgICAvKiBSZWN1cnNlIGludG8gdGhlIHN1cmZhY2UgdHJlZSAqLwogICAgSURpcmVjdERyYXdTdXJmYWNlN19FbnVtQXR0YWNoZWRTdXJmYWNlcyhzdXJmYWNlLCBjdHgsIGZpbmRSZW5kZXJUYXJnZXQpOwoKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmYWNlKTsKICAgIGlmKCp0YXJnZXQpIHJldHVybiBEREVOVU1SRVRfQ0FOQ0VMOwogICAgZWxzZSByZXR1cm4gRERFTlVNUkVUX09LOyAvKiBDb250aW51ZSB3aXRoIHRoZSBuZXh0IG5laWdoYm9yIHN1cmZhY2UgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEQzRDdDQl9DcmVhdGVSZW5kZXJUYXJnZXQKICoKICogQ2FsbGJhY2sgY2FsbGVkIGJ5IFdpbmVEM0QgdG8gY3JlYXRlIFN1cmZhY2VzIGZvciByZW5kZXIgdGFyZ2V0IHVzYWdlCiAqIFRoaXMgZnVuY3Rpb24gdGFrZXMgdGhlIEQzRCB0YXJnZXQgZnJvbSB0aGUgSURpcmVjdERyYXdJbXBsIHN0cnVjdHVyZSwKICogYW5kIHJldHVybnMgdGhlIFdpbmVEM0RTdXJmYWNlLiBUbyBhdm9pZCBkb3VibGUgdXNhZ2UsIHRoZSBzdXJmYWNlCiAqIGlzIG1hcmtlZCBhcyByZW5kZXIgdGFyZ2V0IGFmdGVyd2FyZHMKICoKICogUGFyYW1zCiAqICBkZXZpY2U6IFRoZSBXaW5lRDNERGV2aWNlJ3MgcGFyZW50CiAqICBXaWR0aCwgSGVpZ2h0LCBGb3JtYXQ6IERpbWVuc2lvbnMgYW5kIHBpeGVsZm9ybWF0IG9mIHRoZSByZW5kZXIgdGFyZ2V0CiAqICAgICAgICAgICAgICAgICAgICAgICAgIElnbm9yZWQsIGJlY2F1c2UgdGhlIHN1cmZhY2UgYWxyZWFkeSBleGlzdHMKICogIE11bHRpU2FtcGxlLCBNdWx0aXNhbXBsZVF1YWxpdHksIExvY2thYmxlOiBJZ25vcmVkIGZvciB0aGUgc2FtZSByZWFzb24KICogIExvY2thYmxlOiBpZ25vcmVkCiAqICBwcFN1cmZhY2U6IEFkZHJlc3MgdG8gcGFzcyB0aGUgc3VyZmFjZSBwb2ludGVyIGJhY2sgYXQKICogIHBTaGFyZWRIYW5kbGU6IElnbm9yZWQKICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEQzRF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEM0Q3Q0JfQ3JlYXRlUmVuZGVyVGFyZ2V0KElVbmtub3duICpkZXZpY2UsIElVbmtub3duICpwU3VwZXJpb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTXVsdGlzYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgTG9ja2FibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlKiogcHBTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSogcFNoYXJlZEhhbmRsZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGRldmljZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpkM2RTdXJmYWNlID0gVGhpcy0+ZDNkX3RhcmdldCwgKnRhcmdldCA9IE5VTEw7CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIGRldmljZSk7CgogICAgaWYoZDNkU3VyZmFjZS0+aXNSZW5kZXJUYXJnZXQpCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19FbnVtQXR0YWNoZWRTdXJmYWNlcyhJQ09NX0lOVEVSRkFDRShkM2RTdXJmYWNlLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0YXJnZXQsIGZpbmRSZW5kZXJUYXJnZXQpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHRhcmdldCA9IGQzZFN1cmZhY2U7CiAgICB9CgogICAgaWYoIXRhcmdldCkKICAgIHsKICAgICAgICB0YXJnZXQgPSBUaGlzLT5kM2RfdGFyZ2V0OwogICAgICAgIEVSUigiICglcCkgOiBObyBEaXJlY3REcmF3U3VyZmFjZSBmb3VuZCB0byBjcmVhdGUgdGhlIGJhY2sgYnVmZmVyLiBVc2luZyB0aGUgZnJvbnQgYnVmZmVyIGFzIGJhY2sgYnVmZmVyLiBVbmNlcnRhaW4gY29uc2VxdWVuY2VzXG4iLCBUaGlzKTsKICAgIH0KCiAgICAvKiBUT0RPOiBSZXR1cm4gZmFpbHVyZSBpZiB0aGUgZGltZW5zaW9ucyBkbyBub3QgbWF0Y2gsIGJ1dCB0aGlzIHNob3VsZG4ndCBoYXBwZW4gKi8KCiAgICAqcHBTdXJmYWNlID0gdGFyZ2V0LT5XaW5lRDNEU3VyZmFjZTsKICAgIHRhcmdldC0+aXNSZW5kZXJUYXJnZXQgPSBUUlVFOwogICAgVFJBQ0UoIlJldHVybmluZyB3aW5lRDNEU3VyZmFjZSAlcCwgaXQgYmVsb25ncyB0byBzdXJmYWNlICVwXG4iLCAqcHBTdXJmYWNlLCBkM2RTdXJmYWNlKTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEM0Q3Q0JfQ3JlYXRlRGVwdGhTdGVuY2lsU3VyZmFjZShJVW5rbm93biAqZGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqcFN1cGVyaW9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBNdWx0aXNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJPT0wgRGlzY2FyZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlKiogcHBTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUqIHBTaGFyZWRIYW5kbGUpCnsKICAgIC8qIENyZWF0ZSBhIERlcHRoIFN0ZW5jaWwgc3VyZmFjZSB0byBtYWtlIFdpbmVEM0QgaGFwcHkgKi8KICAgIEhSRVNVTFQgaHIgPSBEM0RfT0s7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIEREU1VSRkFDRURFU0MyIGRkc2Q7CgogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBkZXZpY2UpOwoKICAgICpwcFN1cmZhY2UgPSBOVUxMOwoKICAgIC8qIENyZWF0ZSBhIERpcmVjdERyYXcgc3VyZmFjZSAqLwogICAgbWVtc2V0KCZkZHNkLCAwLCBzaXplb2YoZGRzZCkpOwogICAgZGRzZC5kd1NpemUgPSBzaXplb2YoZGRzZCk7CiAgICBkZHNkLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERQSVhFTEZPUk1BVCk7CiAgICBkZHNkLmR3RmxhZ3MgPSBERFNEX1BJWEVMRk9STUFUIHwgRERTRF9XSURUSCB8IEREU0RfSEVJR0hUIHwgRERTRF9DQVBTOwogICAgZGRzZC5kZHNDYXBzLmR3Q2FwcyA9IEREU0NBUFNfT0ZGU0NSRUVOUExBSU47CiAgICBkZHNkLmR3SGVpZ2h0ID0gSGVpZ2h0OwogICAgZGRzZC5kd1dpZHRoID0gV2lkdGg7CiAgICBpZihGb3JtYXQgIT0gMCkKICAgIHsKICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRkc2QudTQuZGRwZlBpeGVsRm9ybWF0LCBGb3JtYXQpOwogICAgfQogICAgZWxzZQogICAgewogICAgICBkZHNkLmR3RmxhZ3MgXj0gRERTRF9QSVhFTEZPUk1BVDsKICAgIH0KCiAgICBUaGlzLT5kZXB0aHN0ZW5jaWwgPSBUUlVFOwogICAgaHIgPSBJRGlyZWN0RHJhdzdfQ3JlYXRlU3VyZmFjZSgoSURpcmVjdERyYXc3ICopIFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZHNkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSURpcmVjdERyYXdTdXJmYWNlNyAqKikgJlRoaXMtPkRlcHRoU3RlbmNpbEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICBUaGlzLT5kZXB0aHN0ZW5jaWwgPSBGQUxTRTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCIgKCVwKSBDcmVhdGluZyBhIERlcHRoU3RlbmNpbCBTdXJmYWNlIGZhaWxlZCwgcmVzdWx0ID0gJXhcbiIsIFRoaXMsIGhyKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CiAgICAqcHBTdXJmYWNlID0gVGhpcy0+RGVwdGhTdGVuY2lsQnVmZmVyLT5XaW5lRDNEU3VyZmFjZTsKICAgIHJldHVybiBEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEM0Q3Q0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbgogKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgV2luZUQzRCB3aGljaCBjcmVhdGVzIGEgbmV3IFdpbmVEM0RTd2FwY2hhaW4KICogaW50ZXJmYWNlLiBJdCBhbHNvIGNyZWF0ZXMgYW4gSVBhcmVudCBpbnRlcmZhY2UgdG8gc3RvcmUgdGhhdCBwb2ludGVyLAogKiBzbyB0aGUgV2luZUQzRFN3YXBjaGFpbiBoYXMgYSBwYXJlbnQgYW5kIGNhbiBiZSByZWxlYXNlZCB3aGVuIHRoZSBEM0QKICogZGV2aWNlIGlzIGRlc3Ryb3llZAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEM0Q3Q0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbihJVW5rbm93biAqZGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW4gKiogcHBTd2FwQ2hhaW4pCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBkZXZpY2UpOwogICAgSVBhcmVudEltcGwgKm9iamVjdCA9IE5VTEw7CiAgICBIUkVTVUxUIHJlcyA9IEQzRF9PSzsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIGRldmljZSk7CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksICBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVBhcmVudEltcGwpKTsKICAgIGlmIChOVUxMID09IG9iamVjdCkKICAgIHsKICAgICAgICBGSVhNRSgiQWxsb2NhdGlvbiBvZiBtZW1vcnkgZmFpbGVkXG4iKTsKICAgICAgICAqcHBTd2FwQ2hhaW4gPSBOVUxMOwogICAgICAgIHJldHVybiBEREVSUl9PVVRPRlZJREVPTUVNT1JZOwogICAgfQoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0Uob2JqZWN0LCBJUGFyZW50LCBJUGFyZW50X1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwoKICAgIHJlcyA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3dhcGNoYWluLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJUGFyZW50KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UpOwogICAgaWYgKHJlcyAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgY2FsbCB0byBJV2luZUQzRERldmljZV9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluIGZhaWxlZFxuIiwgVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCAsIG9iamVjdCk7CiAgICAgICAgKnBwU3dhcENoYWluID0gTlVMTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAqcHBTd2FwQ2hhaW4gPSBzd2FwY2hhaW47CiAgICAgICAgb2JqZWN0LT5jaGlsZCA9IChJVW5rbm93biAqKSBzd2FwY2hhaW47CiAgICB9CgogICAgcmV0dXJuIHJlczsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UKICoKICogSW5pdGlhbGl6ZXMgdGhlIEQzRCBjYXBhYmlsaXRpZXMgb2YgV2luZUQzRAogKgogKiBQYXJhbXM6CiAqICBwcmltYXJ5OiBUaGUgcHJpbWFyeSBzdXJmYWNlIGZvciBEM0QKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcywKICogIERERVJSXyogb3RoZXJ3aXNlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9BdHRhY2hEM0REZXZpY2UoSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnByaW1hcnkpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBIV05EICAgICAgICAgICAgICAgICAgd2luZG93OwoKICAgIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMgbG9jYWxQYXJhbWV0ZXJzOwoKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBwcmltYXJ5KTsKCiAgICAvKiBHZXQgdGhlIHdpbmRvdyAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRIV05EKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndpbmRvdyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6R2V0SFdORCBmYWlsZWRcbiIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBJZiB0aGVyZSdzIG5vIHdpbmRvdywgY3JlYXRlIGEgaGlkZGVuIHdpbmRvdy4gV2luZUQzRCBuZWVkcyBpdCAqLwogICAgaWYod2luZG93ID09IDApCiAgICB7CiAgICAgICAgd2luZG93ID0gQ3JlYXRlV2luZG93RXhBKDAsIFRoaXMtPmNsYXNzbmFtZSwgIkhpZGRlbiBEM0QgV2luZG93IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfRElTQUJMRUQsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgR2V0TW9kdWxlSGFuZGxlQSgwKSwgTlVMTCk7CgogICAgICAgIFNob3dXaW5kb3cod2luZG93LCBTV19ISURFKTsgICAvKiBKdXN0IHRvIGJlIHN1cmUgKi8KICAgICAgICBXQVJOKCIoJXApIE5vIHdpbmRvdyBmb3IgdGhlIERpcmVjdDNERGV2aWNlLCBjcmVhdGVkIGEgaGlkZGVuIHdpbmRvdy4gSFdORD0lcFxuIiwgVGhpcywgd2luZG93KTsKICAgICAgICBUaGlzLT5kM2Rfd2luZG93ID0gd2luZG93OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIFRSQUNFKCIoJXApIFVzaW5nIGV4aXN0aW5nIHdpbmRvdyAlcCBmb3IgRGlyZWN0M0QgcmVuZGVyaW5nXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgfQoKICAgIC8qIFN0b3JlIHRoZSBmdXR1cmUgUmVuZGVyIFRhcmdldCBzdXJmYWNlICovCiAgICBUaGlzLT5kM2RfdGFyZ2V0ID0gcHJpbWFyeTsKCiAgICAvKiBVc2UgdGhlIHN1cmZhY2UgZGVzY3JpcHRpb24gZm9yIHRoZSBkZXZpY2UgcGFyYW1ldGVycywgbm90IHRoZQogICAgICogRGV2aWNlIHNldHRpbmdzLiBUaGUgYXBwIG1pZ2h0IHJlbmRlciB0byBhbiBvZmZzY3JlZW4gc3VyZmFjZQogICAgICovCiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlcldpZHRoICAgICAgICAgICAgICAgICA9IHByaW1hcnktPnN1cmZhY2VfZGVzYy5kd1dpZHRoOwogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJIZWlnaHQgICAgICAgICAgICAgICAgPSBwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdIZWlnaHQ7CiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckZvcm1hdCAgICAgICAgICAgICAgICA9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJnByaW1hcnktPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJDb3VudCAgICAgICAgICAgICAgICAgPSAocHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJiBERFNEX0JBQ0tCVUZGRVJDT1VOVCkgPyBwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdCYWNrQnVmZmVyQ291bnQgOiAwOwogICAgbG9jYWxQYXJhbWV0ZXJzLk11bHRpU2FtcGxlVHlwZSAgICAgICAgICAgICAgICAgPSBXSU5FRDNETVVMVElTQU1QTEVfTk9ORTsKICAgIGxvY2FsUGFyYW1ldGVycy5NdWx0aVNhbXBsZVF1YWxpdHkgICAgICAgICAgICAgID0gMDsKICAgIGxvY2FsUGFyYW1ldGVycy5Td2FwRWZmZWN0ICAgICAgICAgICAgICAgICAgICAgID0gV0lORUQzRFNXQVBFRkZFQ1RfQ09QWTsKICAgIGxvY2FsUGFyYW1ldGVycy5oRGV2aWNlV2luZG93ICAgICAgICAgICAgICAgICAgID0gd2luZG93OwogICAgbG9jYWxQYXJhbWV0ZXJzLldpbmRvd2VkICAgICAgICAgICAgICAgICAgICAgICAgPSAhKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRlVMTFNDUkVFTik7CiAgICBsb2NhbFBhcmFtZXRlcnMuRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCAgICAgICAgICA9IEZBTFNFOwogICAgbG9jYWxQYXJhbWV0ZXJzLkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgICAgICAgICAgPSBXSU5FRDNERk1UX0QxNjsKICAgIGxvY2FsUGFyYW1ldGVycy5GbGFncyAgICAgICAgICAgICAgICAgICAgICAgICAgID0gMDsKICAgIGxvY2FsUGFyYW1ldGVycy5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiAgICAgID0gV0lORUQzRFBSRVNFTlRfUkFURV9ERUZBVUxUOyAvKiBEZWZhdWx0IHJhdGU6IEl0J3MgYWxyZWFkeSBzZXQgKi8KICAgIGxvY2FsUGFyYW1ldGVycy5QcmVzZW50YXRpb25JbnRlcnZhbCAgICAgICAgICAgID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfREVGQVVMVDsKCiAgICBUUkFDRSgiUGFzc2luZyBtb2RlICVkXG4iLCBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckZvcm1hdCk7CgogICAgLyogU2V0IHRoaXMgTk9XLCBvdGhlcndpc2UgY3JlYXRpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZSB3aWxsIGNhdXNlIGEKICAgICAqIHJlY3Vyc2l2ZSBsb29wIHVudGlsIHJhbSBvciBlbXVsYXRlZCB2aWRlbyBtZW1vcnkgaXMgZnVsbAogICAgICovCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBUUlVFOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfSW5pdDNEKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbG9jYWxQYXJhbWV0ZXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4pOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBUaGlzLT53aW5lRDNERGV2aWNlID0gTlVMTDsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSA9IDI7CiAgICBUaGlzLT5kZWNscyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqVGhpcy0+ZGVjbHMpICogVGhpcy0+ZGVjbEFycmF5U2l6ZSk7CiAgICBpZighVGhpcy0+ZGVjbHMpCiAgICB7CiAgICAgICAgRVJSKCJFcnJvciBhbGxvY2F0aW5nIGFuIGFycmF5IGZvciB0aGUgY29udmVydGVkIHZlcnRleCBkZWNsc1xuIik7CiAgICAgICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSA9IDA7CiAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9VbmluaXQzRChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4pOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIC8qIENyZWF0ZSBhbiBJbmRleCBCdWZmZXIgcGFyZW50ICovCiAgICBUUkFDRSgiKCVwKSBTdWNjZXNzZnVsbHkgaW5pdGlhbGl6ZWQgM0RcbiIsIFRoaXMpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIgKEREUkFXLkApCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURpcmVjdERyYXdDbGlwcGVyIG9iamVjdC4KICoKICogUGFyYW1zOgogKiAgQ2xpcHBlcjogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgd2hpY2ggZGRyYXcgZG9lc24ndCBoYXZlLiBIYXMgdG8gYmUKICogICAgICAgICAgICBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBhbGxvY2F0aW5nIHRoZSBvYmplY3QgZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIoRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgIExQRElSRUNURFJBV0NMSVBQRVIgKkNsaXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSURpcmVjdERyYXdDbGlwcGVySW1wbCogb2JqZWN0OwogICAgVFJBQ0UoIiglMDh4LCVwLCVwKVxuIiwgRmxhZ3MsIENsaXBwZXIsIFVua091dGVyKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYgKFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwogICAgfQoKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoSURpcmVjdERyYXdDbGlwcGVySW1wbCkpOwogICAgaWYgKG9iamVjdCA9PSBOVUxMKQogICAgewogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3Q2xpcHBlciwgSURpcmVjdERyYXdDbGlwcGVyX1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT53aW5lRDNEQ2xpcHBlciA9IHBXaW5lRGlyZWN0M0RDcmVhdGVDbGlwcGVyKChJVW5rbm93biAqKSBvYmplY3QpOwogICAgaWYoIW9iamVjdC0+d2luZUQzRENsaXBwZXIpCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgICpDbGlwcGVyID0gKElEaXJlY3REcmF3Q2xpcHBlciAqKSBvYmplY3Q7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDcmVhdGVDbGlwcGVyCiAqCiAqIENyZWF0ZXMgYSBERHJhdyBjbGlwcGVyLiBTZWUgRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIgZm9yIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZUNsaXBwZXIoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Q2xpcHBlciAqKkNsaXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgQ2xpcHBlciwgVW5rT3V0ZXIpOwogICAgcmV0dXJuIERpcmVjdERyYXdDcmVhdGVDbGlwcGVyKEZsYWdzLCBDbGlwcGVyLCBVbmtPdXRlcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNyZWF0ZVBhbGV0dGUKICoKICogQ3JlYXRlcyBhIG5ldyBJRGlyZWN0RHJhd1BhbGV0dGUgb2JqZWN0CiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBUaGUgZmxhZ3MgZm9yIHRoZSBuZXcgY2xpcHBlcgogKiAgQ29sb3JUYWJsZTogQ29sb3IgdGFibGUgdG8gYXNzaWduIHRvIHRoZSBuZXcgY2xpcHBlcgogKiAgUGFsZXR0ZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgd2hpY2ggZGRyYXcgZG9lc24ndCBoYXZlLiBIYXMgdG8gYmUKICogICAgICAgICAgICBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBhbGxvY2F0aW5nIHRoZSBvYmplY3QgZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVQYWxldHRlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUxFVFRFRU5UUlkgKkNvbG9yVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqKlBhbGV0dGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwVW5rT3V0ZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsICpvYmplY3Q7CiAgICBIUkVTVUxUIGhyID0gRERFUlJfR0VORVJJQzsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgQ29sb3JUYWJsZSwgUGFsZXR0ZSwgcFVua091dGVyKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYocFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgV0FSTigicFVua091dGVyIGlzICVwLCByZXR1cm5pbmcgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OXG4iLCBwVW5rT3V0ZXIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKICAgIH0KCiAgICAvKiBUaGUgcmVmY291bnQgdGVzdCBzaG93cyB0aGF0IGEgY29vcGxldmVsIGlzIHJlcXVpcmVkIGZvciB0aGlzICovCiAgICBpZighVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwpCiAgICB7CiAgICAgICAgV0FSTigiTm8gY29vcGVyYXRpdmUgbGV2ZWwgc2V0LCByZXR1cm5pbmcgRERFUlJfTk9DT09QRVJBVElWRUxFVkVMU0VUXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBEREVSUl9OT0NPT1BFUkFUSVZFTEVWRUxTRVQ7CiAgICB9CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJRGlyZWN0RHJhd1BhbGV0dGVJbXBsKSk7CiAgICBpZighb2JqZWN0KQogICAgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIHBhbGV0dGUgaW1wbGVtZW50YXRpb25cbiIpOwogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3UGFsZXR0ZSwgSURpcmVjdERyYXdQYWxldHRlX1Z0YmwpOwogICAgb2JqZWN0LT5yZWYgPSAxOwogICAgb2JqZWN0LT5kZHJhd19vd25lciA9IFRoaXM7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVQYWxldHRlKFRoaXMtPndpbmVEM0REZXZpY2UsIEZsYWdzLCBDb2xvclRhYmxlLCAmb2JqZWN0LT53aW5lRDNEUGFsZXR0ZSwgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlKSApOwogICAgaWYoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBJRGlyZWN0RHJhdzdfQWRkUmVmKGlmYWNlKTsKICAgIG9iamVjdC0+aWZhY2VUb1JlbGVhc2UgPSAoSVVua25vd24gKikgaWZhY2U7CiAgICAqUGFsZXR0ZSA9IElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkR1cGxpY2F0ZVN1cmZhY2UKICoKICogRHVwbGljYXRlcyBhIHN1cmZhY2UuIFRoZSBzdXJmYWNlIG1lbW9yeSBwb2ludHMgdG8gdGhlIHNhbWUgbWVtb3J5IGFzCiAqIHRoZSBvcmlnaW5hbCBzdXJmYWNlLCBhbmQgaXQncyByZWxlYXNlZCB3aGVuIHRoZSBsYXN0IHN1cmZhY2UgcmVmZXJlbmNpbmcKICogaXQgaXMgcmVsZWFzZWQuIEkgZ3Vlc3MgdGhhdCdzIGJleW9uZCBXaW5lJ3Mgc3VyZmFjZSBtYW5hZ2VtZW50IHJpZ2h0IG5vdwogKiAoSWRlYTogY3JlYXRlIGEgbmV3IEREcmF3IHN1cmZhY2Ugd2l0aCB0aGUgc2FtZSBXaW5lRDNEU3VyZmFjZS4gSSBuZWVkIGEKICogdGVzdCBhcHBsaWNhdGlvbiB0byBpbXBsZW1lbnQgdGhpcykKICoKICogUGFyYW1zOgogKiAgU3JjOiBBZGRyZXNzIG9mIHRoZSBzb3VyY2Ugc3VyZmFjZQogKiAgRGVzdDogQWRkcmVzcyB0byB3cml0ZSB0aGUgbmV3IHN1cmZhY2UgcG9pbnRlciB0bwogKgogKiBSZXR1cm5zOgogKiAgU2VlIElEaXJlY3REcmF3Nzo6Q3JlYXRlU3VyZmFjZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRHVwbGljYXRlU3VyZmFjZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICpTcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipEZXN0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqU3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIFNyYyk7CgogICAgRklYTUUoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIFN1cmYsIERlc3QpOwoKICAgIC8qIEZvciBub3csIHNpbXBseSBjcmVhdGUgYSBuZXcsIGluZGVwZW5kZW50IHN1cmZhY2UgKi8KICAgIHJldHVybiBJRGlyZWN0RHJhdzdfQ3JlYXRlU3VyZmFjZShpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3VyZi0+c3VyZmFjZV9kZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzcgVlRhYmxlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KY29uc3QgSURpcmVjdERyYXc3VnRibCBJRGlyZWN0RHJhdzdfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gKioqLwogICAgSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3SW1wbF9SZWxlYXNlLAogICAgLyoqKiBJRGlyZWN0RHJhdyAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfQ29tcGFjdCwKICAgIElEaXJlY3REcmF3SW1wbF9DcmVhdGVDbGlwcGVyLAogICAgSURpcmVjdERyYXdJbXBsX0NyZWF0ZVBhbGV0dGUsCiAgICBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlU3VyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9EdXBsaWNhdGVTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0VudW1EaXNwbGF5TW9kZXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzLAogICAgSURpcmVjdERyYXdJbXBsX0ZsaXBUb0dESVN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0Q2FwcywKICAgIElEaXJlY3REcmF3SW1wbF9HZXREaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRGb3VyQ0NDb2RlcywKICAgIElEaXJlY3REcmF3SW1wbF9HZXRHRElTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0dldE1vbml0b3JGcmVxdWVuY3ksCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0U2NhbkxpbmUsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0VmVydGljYWxCbGFua1N0YXR1cywKICAgIElEaXJlY3REcmF3SW1wbF9Jbml0aWFsaXplLAogICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVEaXNwbGF5TW9kZSwKICAgIElEaXJlY3REcmF3SW1wbF9TZXRDb29wZXJhdGl2ZUxldmVsLAogICAgSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlLAogICAgSURpcmVjdERyYXdJbXBsX1dhaXRGb3JWZXJ0aWNhbEJsYW5rLAogICAgLyoqKiBJRGlyZWN0RHJhdzIgKioqLwogICAgSURpcmVjdERyYXdJbXBsX0dldEF2YWlsYWJsZVZpZE1lbSwKICAgIC8qKiogSURpcmVjdERyYXc3ICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9HZXRTdXJmYWNlRnJvbURDLAogICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVBbGxTdXJmYWNlcywKICAgIElEaXJlY3REcmF3SW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbCwKICAgIElEaXJlY3REcmF3SW1wbF9HZXREZXZpY2VJZGVudGlmaWVyLAogICAgLyoqKiBJRGlyZWN0RHJhdzcgKioqLwogICAgSURpcmVjdERyYXdJbXBsX1N0YXJ0TW9kZVRlc3QsCiAgICBJRGlyZWN0RHJhd0ltcGxfRXZhbHVhdGVNb2RlCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX0ZpbmREZWNsCiAqCiAqIEZpbmRzIHRoZSBXaW5lRDNEIHZlcnRleCBkZWNsYXJhdGlvbiBmb3IgYSBzcGVjaWZpYyBmdmYsIGFuZCBjcmVhdGVzIG9uZQogKiBpZiBub25lIHdhcyBmb3VuZC4KICoKICogVGhpcyBmdW5jdGlvbiBpcyBpbiBkZHJhdy5jIGFuZCB0aGUgRERyYXcgb2JqZWN0IHNwYWNlIGJlY2F1c2UgRDNENwogKiB2ZXJ0ZXggYnVmZmVycyBhcmUgY3JlYXRlZCB1c2luZyB0aGUgSURpcmVjdDNEIGludGVyZmFjZSB0byB0aGUgZGRyYXcKICogb2JqZWN0LCBzbyB0aGV5IGNhbiBiZSB2YWxpZCBhY3Jvc3MgRDNEIGRldmljZXModGhlb3JldGljYWxseS4gVGhlIGRkcmF3CiAqIG9iamVjdCBhbHNvIG93bnMgdGhlIHdpbmVkM2QgZGV2aWNlCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBUaGlzOiBEZXZpY2UKICogIGZ2ZjogRnZmIHRvIGZpbmQgdGhlIGRlY2wgZm9yCiAqCiAqIFJldHVybnM6CiAqICBOVUxMIGluIGNhc2Ugb2YgYW4gZXJyb3IsIHRoZSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uIGludGVyZmFjZSBmb3IgdGhlCiAqICBmdmYgb3RoZXJ3aXNlLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCklXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKgpJRGlyZWN0RHJhd0ltcGxfRmluZERlY2woSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZnZmKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiogcERlY2wgPSBOVUxMOwogICAgaW50IHAsIGxvdywgaGlnaDsgLyogZGVsaWJlcmF0ZWx5IHNpZ25lZCAqLwogICAgc3RydWN0IEZ2ZlRvRGVjbCAqY29udmVydGVkRGVjbHMgPSBUaGlzLT5kZWNsczsKCiAgICBUUkFDRSgiU2VhcmNoaW5nIGZvciBkZWNsYXJhdGlvbiBmb3IgZnZmICUwOHguLi4gIiwgZnZmKTsKCiAgICBsb3cgPSAwOwogICAgaGlnaCA9IFRoaXMtPm51bUNvbnZlcnRlZERlY2xzIC0gMTsKICAgIHdoaWxlKGxvdyA8PSBoaWdoKSB7CiAgICAgICAgcCA9IChsb3cgKyBoaWdoKSA+PiAxOwogICAgICAgIFRSQUNFKCIlZCAiLCBwKTsKICAgICAgICBpZihjb252ZXJ0ZWREZWNsc1twXS5mdmYgPT0gZnZmKSB7CiAgICAgICAgICAgIFRSQUNFKCJmb3VuZCAlcFxuIiwgY29udmVydGVkRGVjbHNbcF0uZGVjbCk7CiAgICAgICAgICAgIHJldHVybiBjb252ZXJ0ZWREZWNsc1twXS5kZWNsOwogICAgICAgIH0gZWxzZSBpZihjb252ZXJ0ZWREZWNsc1twXS5mdmYgPCBmdmYpIHsKICAgICAgICAgICAgbG93ID0gcCArIDE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaGlnaCA9IHAgLSAxOwogICAgICAgIH0KICAgIH0KICAgIFRSQUNFKCJub3QgZm91bmQuIENyZWF0aW5nIGFuZCBpbnNlcnRpbmcgYXQgcG9zaXRpb24gJWQuXG4iLCBsb3cpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb25Gcm9tRlZGKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcERlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ2Zik7CiAgICBpZiAoaHIgIT0gU19PSykgcmV0dXJuIE5VTEw7CgogICAgaWYoVGhpcy0+ZGVjbEFycmF5U2l6ZSA9PSBUaGlzLT5udW1Db252ZXJ0ZWREZWNscykgewogICAgICAgIGludCBncm93ID0gbWF4KFRoaXMtPmRlY2xBcnJheVNpemUgLyAyLCA4KTsKICAgICAgICBjb252ZXJ0ZWREZWNscyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvbnZlcnRlZERlY2xzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGNvbnZlcnRlZERlY2xzWzBdKSAqIChUaGlzLT5udW1Db252ZXJ0ZWREZWNscyArIGdyb3cpKTsKICAgICAgICBpZighY29udmVydGVkRGVjbHMpIHsKICAgICAgICAgICAgLyogVGhpcyB3aWxsIGRlc3Ryb3kgaXQgKi8KICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9SZWxlYXNlKHBEZWNsKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmRlY2xzID0gY29udmVydGVkRGVjbHM7CiAgICAgICAgVGhpcy0+ZGVjbEFycmF5U2l6ZSArPSBncm93OwogICAgfQoKICAgIG1lbW1vdmUoY29udmVydGVkRGVjbHMgKyBsb3cgKyAxLCBjb252ZXJ0ZWREZWNscyArIGxvdywgc2l6ZW9mKGNvbnZlcnRlZERlY2xzWzBdKSAqIChUaGlzLT5udW1Db252ZXJ0ZWREZWNscyAtIGxvdykpOwogICAgY29udmVydGVkRGVjbHNbbG93XS5kZWNsID0gcERlY2w7CiAgICBjb252ZXJ0ZWREZWNsc1tsb3ddLmZ2ZiA9IGZ2ZjsKICAgIFRoaXMtPm51bUNvbnZlcnRlZERlY2xzKys7CgogICAgVFJBQ0UoIlJldHVybmluZyAlcC4gJWQgZGVjbHMgaW4gYXJyYXlcbiIsIHBEZWNsLCBUaGlzLT5udW1Db252ZXJ0ZWREZWNscyk7CiAgICByZXR1cm4gcERlY2w7Cn0K