LyoKICogQ29weXJpZ2h0IDE5OTctMjAwMCBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTgtMjAwMCBMaW9uZWwgVWxtZXIKICogQ29weXJpZ2h0IDIwMDAtMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgImV4Y3B0LmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCnN0YXRpYyBCT09MIElEaXJlY3REcmF3SW1wbF9ERFNEX01hdGNoKGNvbnN0IEREU1VSRkFDRURFU0MyKiByZXF1ZXN0ZWQsIGNvbnN0IEREU1VSRkFDRURFU0MyKiBwcm92aWRlZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqcHJpbWFyeSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsIEREU1VSRkFDRURFU0MyICpwRERTRCwgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnBwU3VyZiwgVUlOVCBsZXZlbCk7CgovKiBEZXZpY2UgaWRlbnRpZmllci4gRG9uJ3QgcmVsYXkgaXQgdG8gV2luZUQzRCAqLwpzdGF0aWMgY29uc3QgRERERVZJQ0VJREVOVElGSUVSMiBkZXZpY2VpZGVudGlmaWVyID0KewogICAgImRpc3BsYXkiLAogICAgIkRpcmVjdERyYXcgSEFMIiwKICAgIHsgeyAweDAwMDEwMDAxLCAweDAwMDEwMDAxIH0gfSwKICAgIDAsIDAsIDAsIDAsCiAgICAvKiBhODM3M2MxMC03YWM0LTRkZWItODQ5YS0wMDk4NDRkMDhiMmQgKi8KICAgIHsweGE4MzczYzEwLDB4N2FjNCwweDRkZWIsIHsweDg0LDB4OWEsMHgwMCwweDk4LDB4NDQsMHhkMCwweDhiLDB4MmR9fSwKICAgIDAKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBNZXRob2RzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJpZXMgZGlmZmVyZW50IGludGVyZmFjZXMgb2YgdGhlIERpcmVjdERyYXcgb2JqZWN0LiBJdCBjYW4gcmV0dXJuCiAqIElEaXJlY3REcmF3IGludGVyZmFjZXMgaW4gdmVyc2lvbiAxLCAyLCA0IGFuZCA3LCBhbmQgSURpcmVjdDNEIGludGVyZmFjZXMKICogaW4gdmVyc2lvbiAxLCAyLCAzIGFuZCA3LiBBbiBJRGlyZWN0M0REZXZpY2UgY2FuIGJlIGNyZWF0ZWQgd2l0aCB0aGlzCiAqIG1ldGhvZC4KICogVGhlIHJldHVybmVkIGludGVyZmFjZSBpcyBBZGRSZWYoKS1lZCBiZWZvcmUgaXQncyByZXR1cm5lZAogKgogKiBSdWxlcyBmb3IgUXVlcnlJbnRlcmZhY2U6CiAqICBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/IFwKICogICAgdXJsPS9saWJyYXJ5L2VuLXVzL2NvbS9odG1sLzZkYjE3ZWQ4LTA2ZTQtNGJhZS1iYzI2LTExMzE3NmNjN2UwZS5hc3AKICoKICogVXNlZCBmb3IgdmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIHJlZmlpZDogSW50ZXJmYWNlIElEIGFza2VkIGZvcgogKiAgb2JqOiBVc2VkIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUmV0dXJuczoKICogIFNfT0sgaWYgYW4gaW50ZXJmYWNlIHdhcyBmb3VuZAogKiAgRV9OT0lOVEVSRkFDRSBpZiB0aGUgcmVxdWVzdGVkIGludGVyZmFjZSB3YXNuJ3QgZm91bmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmVmaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICAgIC8qIEFjY29yZGluZyB0byBDT00gZG9jcywgaWYgdGhlIFF1ZXJ5SW50ZXJmYWNlIGZhaWxzLCBvYmogc2hvdWxkIGJlIHNldCB0byBOVUxMICovCiAgICAqb2JqID0gTlVMTDsKCiAgICBpZighcmVmaWlkKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIC8qIENoZWNrIERpcmVjdERyYXcgSW50ZXJmYWNlcyAqLwogICAgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JVW5rbm93biwgcmVmaWlkICkgfHwKICAgICAgICAgSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXc3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3Nyk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3NCwgcmVmaWlkICkgKQogICAgewogICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzQpOwogICAgICAgIFRSQUNFKCIoJXApIFJldHVybmluZyBJRGlyZWN0RHJhdzQgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0RHJhdzMsIHJlZmlpZCApICkKICAgIHsKICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXczKTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXczIGludGVyZmFjZSBhdCAlcFxuIiwgVGhpcywgKm9iaik7CiAgICB9CiAgICBlbHNlIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdERyYXcyLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3Mik7CiAgICAgICAgVFJBQ0UoIiglcCkgUmV0dXJuaW5nIElEaXJlY3REcmF3MiBpbnRlcmZhY2UgYXQgJXBcbiIsIFRoaXMsICpvYmopOwogICAgfQogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3REcmF3LCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3KTsKICAgICAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgSURpcmVjdERyYXcgaW50ZXJmYWNlIGF0ICVwXG4iLCBUaGlzLCAqb2JqKTsKICAgIH0KCiAgICAvKiBEaXJlY3QzRAogICAgICogVGhlIHJlZmNvdW50IHVuaXQgdGVzdCByZXZlYWxlZCB0aGF0IGFuIElEaXJlY3QzRDcgaW50ZXJmYWNlIGNhbiBvbmx5IGJlIHF1ZXJpZWQKICAgICAqIGZyb20gYSBEaXJlY3REcmF3IG9iamVjdCB0aGF0IHdhcyBjcmVhdGVkIGFzIGFuIElEaXJlY3REcmF3NyBpbnRlcmZhY2UuIE5vIGlkZWEKICAgICAqIHdobyBoYWQgdGhpcyBpZGVhIGFuZCB3aHkuIFRoZSBvbGRlciBpbnRlcmZhY2VzIGNhbiBxdWVyeSBhbmQgSURpcmVjdDNEIHZlcnNpb24KICAgICAqIGJlY2F1c2UgdGhleSBhcmUgYWxsIGNyZWF0ZWQgYXMgSURpcmVjdERyYXcoMSkuIFRoaXMgaXNuJ3QgcmVhbGx5IGNydWNpYWwgYmVoYXZpb3IsCiAgICAgKiBhbmQgbWVzc3kgdG8gaW1wbGVtZW50IHdpdGggdGhlIGNvbW1vbiBjcmVhdGlvbiBmdW5jdGlvbiwgc28gaXQgaGFzIGJlZW4gbGVmdCBvdXQgaGVyZS4KICAgICAqLwogICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRCAgLCByZWZpaWQgKSB8fAogICAgICAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDIgLCByZWZpaWQgKSB8fAogICAgICAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDMgLCByZWZpaWQgKSB8fAogICAgICAgICAgICAgIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDcgLCByZWZpaWQgKSApCiAgICB7CiAgICAgICAgLyogQ2hlY2sgdGhlIHN1cmZhY2UgaW1wbGVtZW50YXRpb24gKi8KICAgICAgICBpZihUaGlzLT5JbXBsVHlwZSA9PSBTVVJGQUNFX1VOS05PV04pCiAgICAgICAgewogICAgICAgICAgICAvKiBBcHBzIG1heSBjcmVhdGUgdGhlIElEaXJlY3QzRCBJbnRlcmZhY2UgYmVmb3JlIHRoZSBwcmltYXJ5IHN1cmZhY2UuCiAgICAgICAgICAgICAqIHNldCB0aGUgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICBUUkFDRSgiKCVwKSBDaG9vc2luZyBPcGVuR0wgc3VyZmFjZXMgYmVjYXVzZSBhIERpcmVjdDNEIGludGVyZmFjZSB3YXMgcmVxdWVzdGVkXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZihUaGlzLT5JbXBsVHlwZSAhPSBTVVJGQUNFX09QRU5HTCAmJiBEZWZhdWx0U3VyZmFjZVR5cGUgPT0gU1VSRkFDRV9VTktOT1dOKQogICAgICAgIHsKICAgICAgICAgICAgRVJSKCIoJXApIFRoZSBBcHAgaXMgcmVxdWVzdGluZyBhIEQzRCBkZXZpY2UsIGJ1dCBhIG5vbi1PcGVuR0wgc3VyZmFjZSB0eXBlIHdhcyBjaG9vc2VuLiBQcmVwYXJlIGZvciB0cm91YmxlIVxuIiwgVGhpcyk7CiAgICAgICAgICAgIEVSUigiICglcCkgWW91IG1heSB3YW50IHRvIGNvbnRhY3Qgd2luZS1kZXZlbCBmb3IgaGVscFxuIiwgVGhpcyk7CiAgICAgICAgICAgIC8qIFNob3VsZCBJIGFzc2VydCgwKSBoZXJlPz8/ICovCiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJUaGUgYXBwIHJlcXVlc3RzIGEgRGlyZWN0M0QgaW50ZXJmYWNlLCBidXQgbm9uLW9wZW5nbCBzdXJmYWNlcyB3aGVyZSBzZXQgaW4gd2luZWNmZ1xuIik7CiAgICAgICAgICAgIC8qIERvIG5vdCBhYm9ydCBoZXJlLCBvbmx5IHJlamVjdCAzRCBEZXZpY2UgY3JlYXRpb24gKi8KICAgICAgICB9CgogICAgICAgIGlmICggSXNFcXVhbEdVSUQoICZJSURfSURpcmVjdDNEICAsIHJlZmlpZCApICkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSAxOwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0QgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKCBJc0VxdWFsR1VJRCggJklJRF9JRGlyZWN0M0QyICAsIHJlZmlpZCApICkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmQzZHZlcnNpb24gPSAyOwogICAgICAgICAgICAqb2JqID0gSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEMik7CiAgICAgICAgICAgIFRSQUNFKCIgcmV0dXJuaW5nIERpcmVjdDNEMiBpbnRlcmZhY2UgYXQgJXAuXG4iLCAqb2JqKTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDMgICwgcmVmaWlkICkgKQogICAgICAgIHsKICAgICAgICAgICAgVGhpcy0+ZDNkdmVyc2lvbiA9IDM7CiAgICAgICAgICAgICpvYmogPSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QzKTsKICAgICAgICAgICAgVFJBQ0UoIiByZXR1cm5pbmcgRGlyZWN0M0QzIGludGVyZmFjZSBhdCAlcC5cbiIsICpvYmopOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmKElzRXF1YWxHVUlEKCAmSUlEX0lEaXJlY3QzRDcgICwgcmVmaWlkICkpCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5kM2R2ZXJzaW9uID0gNzsKICAgICAgICAgICAgKm9iaiA9IElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDcpOwogICAgICAgICAgICBUUkFDRSgiIHJldHVybmluZyBEaXJlY3QzRDcgaW50ZXJmYWNlIGF0ICVwLlxuIiwgKm9iaik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFVua25vd24gaW50ZXJmYWNlICovCiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCIoJXApLT4oJXMsICVwKTogTm8gaW50ZXJmYWNlIGZvdW5kXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CiAgICAgICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CgogICAgSVVua25vd25fQWRkUmVmKCAoSVVua25vd24gKikgKm9iaiApOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkFkZFJlZgogKgogKiBJbmNyZWFzZXMgdGhlIGludGVyZmFjZXMgcmVmY291bnQsIGJhc2ljYWxseQogKgogKiBERHJhdyByZWZjb3VudGluZyBpcyBhIGJpdCB0cmlja3kuIFRoZSBkaWZmZXJlbnQgRGlyZWN0RHJhdyBpbnRlcmZhY2UKICogdmVyc2lvbnMgaGF2ZSBpbmRpdmlkdWFsIHJlZmNvdW50cywgYnV0IHRoZSBJRGlyZWN0M0QgaW50ZXJmYWNlcyBkbyBub3QuCiAqIEFsbCBpbnRlcmZhY2VzIGFyZSBmcm9tIG9uZSBvYmplY3QsIHRoYXQgbWVhbnMgY2FsbGluZyBRdWVyeUludGVyZmFjZSBvbiBhbgogKiBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlIGZvciBhbiBJRGlyZWN0RHJhdzQgaW50ZXJmYWNlIGRvZXMgbm90IGNyZWF0ZSBhIG5ldwogKiBJRGlyZWN0RHJhd0ltcGwgb2JqZWN0LgogKgogKiBUaGF0IG1lYW5zIGFsbCBBZGRSZWYgYW5kIFJlbGVhc2UgaW1wbGVtZW50YXRpb25zIG9mIElEaXJlY3REcmF3WCB3b3JrCiAqIHdpdGggdGhlaXIgb3duIGNvdW50ZXIsIGFuZCBJRGlyZWN0M0RYOjpBZGRSZWYgdGh1bmsgdG8gSURpcmVjdERyYXcgKDEpLAogKiBleGNlcHQgb2YgSURpcmVjdDNENyB3aGljaCB0aHVua3MgdG8gSURpcmVjdERyYXc3CiAqCiAqIFJldHVybnM6IFRoZSBuZXcgcmVmY291bnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9BZGRSZWYoSURpcmVjdERyYXc3ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWY3KTsKCiAgICBUUkFDRSgiKCVwKSA6IGluY3JlbWVudGluZyBJRGlyZWN0RHJhdzcgcmVmY291bnQgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiAtMSk7CgogICAgaWYocmVmID09IDEpIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5udW1JZmFjZXMpOwoKICAgIHJldHVybiByZWY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfRGVzdHJveQogKgogKiBEZXN0cm95cyBhIGRkcmF3IG9iamVjdCBpZiBhbGwgcmVmY291bnRzIGFyZSAwLiBUaGlzIGlzIHRvIHNoYXJlIGNvZGUKICogYmV0d2VlbiB0aGUgSURpcmVjdERyYXdYOjpSZWxlYXNlIGZ1bmN0aW9ucwogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEaXJlY3REcmF3IG9iamVjdCB0byBkZXN0cm95CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZApJRGlyZWN0RHJhd0ltcGxfRGVzdHJveShJRGlyZWN0RHJhd0ltcGwgKlRoaXMpCnsKICAgIC8qIENsZWFyIHRoZSBjb29wbGV2ZWwgdG8gcmVzdG9yZSB3aW5kb3cgYW5kIGRpc3BsYXkgbW9kZSAqLwogICAgSURpcmVjdERyYXc3X1NldENvb3BlcmF0aXZlTGV2ZWwoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9OT1JNQUwpOwoKICAgIC8qIERlc3Ryb3kgdGhlIGRldmljZSB3aW5kb3cgaWYgd2UgY3JlYXRlZCBvbmUgKi8KICAgIGlmKFRoaXMtPmRldmljZXdpbmRvdyAhPSAwKQogICAgewogICAgICAgIFRSQUNFKCIgKCVwKSBEZXN0cm95aW5nIHRoZSBkZXZpY2Ugd2luZG93ICVwXG4iLCBUaGlzLCBUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgIERlc3Ryb3lXaW5kb3coVGhpcy0+ZGV2aWNld2luZG93KTsKICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSAwOwogICAgfQoKICAgIC8qIFVucmVnaXN0ZXIgdGhlIHdpbmRvdyBjbGFzcyAqLwogICAgVW5yZWdpc3RlckNsYXNzQShUaGlzLT5jbGFzc25hbWUsIDApOwoKICAgIHJlbW92ZV9kZHJhd19vYmplY3QoVGhpcyk7CgogICAgLyogUmVsZWFzZSB0aGUgYXR0YWNoZWQgV2luZUQzRCBzdHVmZiAqLwogICAgSVdpbmVEM0REZXZpY2VfUmVsZWFzZShUaGlzLT53aW5lRDNERGV2aWNlKTsKICAgIElXaW5lRDNEX1JlbGVhc2UoVGhpcy0+d2luZUQzRCk7CgogICAgLyogTm93IGZyZWUgdGhlIG9iamVjdCAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlJlbGVhc2UKICoKICogRGVjcmVhc2VzIHRoZSByZWZjb3VudC4gSWYgdGhlIHJlZmNvdW50IGZhbGxzIHRvIDAsIHRoZSBvYmplY3QgaXMgZGVzdHJveWVkCiAqCiAqIFJldHVybnM6IFRoZSBuZXcgcmVmY291bnQKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9SZWxlYXNlKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmNyk7CgogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBJRGlyZWN0RHJhdzcgcmVmY291bnQgZnJvbSAldS5cbiIsIFRoaXMsIHJlZiArMSk7CgogICAgaWYocmVmID09IDApCiAgICB7CiAgICAgICAgVUxPTkcgaWZhY2Vjb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5udW1JZmFjZXMpOwogICAgICAgIGlmKGlmYWNlY291bnQgPT0gMCkgSURpcmVjdERyYXdJbXBsX0Rlc3Ryb3koVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3IG1ldGhvZHMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9TZXR1cEV4Y2x1c2l2ZVdpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtb2RpZmllcyBhIEhXTkQncyBTdHlsZSBhbmQgRXhTdHlsZSBmb3IgcHJvcGVyCiAqIGZ1bGxzY3JlZW4gdXNlLgogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBQb2ludGVyIHRvIHRoZSBEaXJlY3REcmF3IGltcGxlbWVudGF0aW9uCiAqICBIV05EOiBXaW5kb3cgdG8gc2V0dXAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZApJRGlyZWN0RHJhd0ltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KElEaXJlY3REcmF3SW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIHdpbmRvdykKewogICAgTE9ORyBzdHlsZSwgZXhTdHlsZTsKICAgIC8qIERvbid0IGRvIGFueXRoaW5nIGlmIGFuIG9yaWdpbmFsIHN0eWxlIGlzIHN0b3JlZC4KICAgICAqIFRoYXQgc2hvdWxkbid0IGhhcHBlbgogICAgICovCiAgICBUUkFDRSgiKCVwKTogU2V0dGluZyB1cCB3aW5kb3cgJXAgZm9yIGV4Y2x1c2l2ZSBtb2RlXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgaWYoIChUaGlzLT5zdHlsZSAhPSAwKSAmJiAoVGhpcy0+ZXhTdHlsZSAhPSAwKSApCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFdhbnQgdG8gY2hhbmdlIHRoZSB3aW5kb3cgcGFyYW1ldGVycyBvZiBIV05EICVwLCBidXQgXAogICAgICAgICAgICAgYW5vdGhlciBzdHlsZSBpcyBzdG9yZWQgZm9yIHJlc3RhdXJhdGlvbiBhZnRlcndhcmRzXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgfQoKICAgIC8qIEdldCB0aGUgcGFyYW1ldGVycyBhbmQgc2F2ZSB0aGVtICovCiAgICBzdHlsZSA9IEdldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFKTsKICAgIGV4U3R5bGUgPSBHZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFKTsKICAgIFRoaXMtPnN0eWxlID0gc3R5bGU7CiAgICBUaGlzLT5leFN0eWxlID0gZXhTdHlsZTsKCiAgICAvKiBGaWx0ZXIgb3V0IHdpbmRvdyBkZWNvcmF0aW9ucyAqLwogICAgc3R5bGUgJj0gfldTX0NBUFRJT047CiAgICBzdHlsZSAmPSB+V1NfVEhJQ0tGUkFNRTsKICAgIGV4U3R5bGUgJj0gfldTX0VYX1dJTkRPV0VER0U7CiAgICBleFN0eWxlICY9IH5XU19FWF9DTElFTlRFREdFOwoKICAgIC8qIE1ha2Ugc3VyZSB0aGUgd2luZG93IGlzIG1hbmFnZWQsIG90aGVyd2lzZSB3ZSB3b24ndCBnZXQga2V5Ym9hcmQgaW5wdXQgKi8KICAgIHN0eWxlIHw9IFdTX1BPUFVQIHwgV1NfU1lTTUVOVTsKCiAgICBUUkFDRSgiT2xkIHN0eWxlIHdhcyAlMDh4LCUwOHgsIHNldHRpbmcgdG8gJTA4eCwlMDh4XG4iLAogICAgICAgICAgVGhpcy0+c3R5bGUsIFRoaXMtPmV4U3R5bGUsIHN0eWxlLCBleFN0eWxlKTsKCiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9TVFlMRSwgc3R5bGUpOwogICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSwgZXhTdHlsZSk7CgogICAgLyogSW5mb3JtIHRoZSB3aW5kb3cgYWJvdXQgdGhlIHVwZGF0ZS4KICAgICAqIFRPRE86IFNob3VsZCBJIG1vdmUgaXQgdG8gMC8wIHRvbz8KICAgICAqLwogICAgU2V0V2luZG93UG9zKHdpbmRvdywgMCAvKiBJbnNlcnRBZnRlciwgaWdub3JlZCAqLywKICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLCAvKiBQb3MsIFNpemUsIGlnbm9yZWQgKi8KICAgICAgICAgICAgICAgICBTV1BfRlJBTUVDSEFOR0VEIHwgU1dQX05PU0laRSB8IFNXUF9OT01PVkUgfCBTV1BfTk9aT1JERVIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVXaW5kb3cKICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgcmVzdG9yZXMgYSB3aW5kb3dzJyBwcm9wZXJ0aWVzIHdoZW4gdGFraW5nIGl0IG91dAogKiBvZiBmdWxsc2NyZWVuIG1vZGUKICoKICogUGFyYW1zOgogKiAgVGhpczogUG9pbnRlciB0byB0aGUgRGlyZWN0RHJhdyBpbXBsZW1lbnRhdGlvbgogKiAgSFdORDogV2luZG93IHRvIHNldHVwCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQKSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVXaW5kb3coSURpcmVjdERyYXdJbXBsICpUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIHdpbmRvdykKewogICAgaWYoIChUaGlzLT5zdHlsZSA9PSAwKSAmJiAoVGhpcy0+ZXhTdHlsZSA9PSAwKSApCiAgICB7CiAgICAgICAgLyogVGhpcyBjb3VsZCBiZSBhIEREU0NMX05PUk1BTCAtPiBERFNDTF9OT1JNQUwKICAgICAgICAgKiBzd2l0Y2gsIGRvIG5vdGhpbmcKICAgICAgICAgKi8KICAgICAgICByZXR1cm47CiAgICB9CiAgICBUUkFDRSgiKCVwKTogUmVzdG9yaW5nIHdpbmRvdyBzZXR0aW5ncyBvZiB3aW5kb3cgJXAgdG8gJTA4eCwgJTA4eFxuIiwKICAgICAgICAgIFRoaXMsIHdpbmRvdywgVGhpcy0+c3R5bGUsIFRoaXMtPmV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBUaGlzLT5zdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBUaGlzLT5leFN0eWxlKTsKCiAgICAvKiBEZWxldGUgdGhlIG9sZCB2YWx1ZXMgKi8KICAgIFRoaXMtPnN0eWxlID0gMDsKICAgIFRoaXMtPmV4U3R5bGUgPSAwOwoKICAgIC8qIEluZm9ybSB0aGUgd2luZG93IGFib3V0IHRoZSB1cGRhdGUgKi8KICAgIFNldFdpbmRvd1Bvcyh3aW5kb3csIDAgLyogSW5zZXJ0QWZ0ZXIsIGlnbm9yZWQgKi8sCiAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgLyogUG9zLCBTaXplLCBpZ25vcmVkICovCiAgICAgICAgICAgICAgICAgU1dQX0ZSQU1FQ0hBTkdFRCB8IFNXUF9OT01PVkUgfCBTV1BfTk9TSVpFIHwgU1dQX05PWk9SREVSKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6U2V0Q29vcGVyYXRpdmVMZXZlbAogKgogKiBTZXRzIHRoZSBjb29wZXJhdGl2ZSBsZXZlbCBmb3IgdGhlIERpcmVjdERyYXcgb2JqZWN0LCBhbmQgdGhlIHdpbmRvdwogKiBhc3NpZ25lZCB0byBpdC4gVGhlIGNvb3BlcmF0aXZlIGxldmVsIGRldGVybWluZXMgdGhlIGdlbmVyYWwgYmVoYXZpb3IKICogb2YgdGhlIERpcmVjdERyYXcgYXBwbGljYXRpb24KICoKICogV2FybmluZzogVGhpcyBpcyBxdWl0ZSB0cmlja3ksIGFzIGl0J3Mgbm90IHJlYWxseSBkb2N1bWVudGVkIHdoaWNoCiAqIGNvb3BlcmF0aXZlIGxldmVscyBjYW4gYmUgY29tYmluZWQgd2l0aCBlYWNoIG90aGVyLiBJZiBhIGdhbWUgZmFpbHMKICogYWZ0ZXIgdGhpcyBmdW5jdGlvbiwgdHJ5IHRvIGNoZWNrIHRoZSBjb29wZXJhdGl2ZSBsZXZlbHMgcGFzc2VkIG9uCiAqIFdpbmRvd3MsIGFuZCBpZiBpdCByZXR1cm5zIHNvbWV0aGluZyBkaWZmZXJlbnQuCiAqCiAqIElmIHlvdSB0aGluayB0aGF0IHRoaXMgZnVuY3Rpb24gY2F1c2VkIHRoZSBmYWlsdXJlIGJlY2F1c2UgaXQgd3JpdGVzIGEKICogZml4bWUsIGJlIHN1cmUgdG8gcnVuIGFnYWluIHdpdGggYSArZGRyYXcgdHJhY2UuCiAqCiAqIFdoYXQgaXMga25vd24gYWJvdXQgY29vcGVyYXRpdmUgbGV2ZWxzIChTZWUgdGhlIGRkcmF3IG1vZGVzIHRlc3QpOgogKiBERFNDTF9FWENMVVNJVkUgYW5kIEREU0NMX0ZVTExTQ1JFRU4gbXVzdCBiZSB1c2VkIHdpdGggZWFjaCBvdGhlcgogKiBERFNDTF9OT1JNQUwgaXMgbm90IGNvbXBhdGlibGUgd2l0aCBERFNDTF9FWENMVVNJVkUgb3IgRERTQ0xfRlVMTFNDUkVFTgogKiBERFNDTF9TRVRGT0NVU1dJTkRPVyBjYW4gYmUgcGFzc2VkIG9ubHkgaW4gRERTQ0xfTk9STUFMIG1vZGUsIGJ1dCBhZnRlciB0aGF0CiAqIEREU0NMX0ZVTExTQ1JFRU4gY2FuIGJlIGFjdGl2YXRlZAogKiBERFNDTF9TRVRGT0NVU1dJTkRPVyBtYXkgb25seSBiZSB1c2VkIHdpdGggRERTQ0xfTk9XSU5ET1dDSEFOR0VTCiAqCiAqIEhhbmRsZWQgZmxhZ3M6IEREU0NMX05PUk1BTCwgRERTQ0xfRlVMTFNDUkVFTiwgRERTQ0xfRVhDTFVTSVZFLAogKiAgICAgICAgICAgICAgICBERFNDTF9TRVRGT0NVU1dJTkRPVyAocGFydGlhbGx5KQogKgogKiBVbmhhbmRsZWQgZmxhZ3MsIHdoaWNoIHNob3VsZCBiZSBpbXBsZW1lbnRlZAogKiAgRERTQ0xfU0VUREVWSUNFV0lORE9XOiBTZXRzIGEgd2luZG93IHNwZWNpYWxseSB1c2VkIGZvciByZW5kZXJpbmcgKEkgZG9uJ3QKICogIGV4cGVjdCBhbnkgZGlmZmVyZW5jZSB0byBhIG5vcm1hbCB3aW5kb3cgZm9yIHdpbmUpCiAqICBERFNDTF9DUkVBVEVERVZJQ0VXSU5ET1c6IFRlbGxzIGRkcmF3IHRvIGNyZWF0ZSBpdHMgb3duIHdpbmRvdyBmb3IKICogIHJlbmRlcmluZyAoUG9zc2libGUgdGVzdCBjYXNlOiBIYWxmLWxpZmUpCiAqCiAqIFVuc3VyZSBhYm91dCB0aGVzZTogRERTQ0xfRlBVU0VUVVAgRERTQ0xfRlBVUkVTRVJWRQogKgogKiBUaGVzZSBzZWVtIG5vdCByZWFsbHkgaW1wb3JhbnQgZm9yIHdpbmUKICogIEREU0NMX0FMTE9XUkVCT09ULCBERFNDTF9OT1dJTkRPV0NIQU5HRVMsIEREU0NMX0FMTE9XTU9ERVgsCiAqICBERFNDTF9NVUxUSVRIUkVERUQKICoKICogUmV0dXJuczoKICogIEREX09LIGlmIHRoZSBjb29wZXJhdGl2ZSBsZXZlbCB3YXMgc2V0IHN1Y2Nlc3NmdWxseQogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiB0aGUgcGFzc2VkIGNvb3BlcmF0aXZlIGxldmVsIGNvbWJpbmF0aW9uIGlzIGludmFsaWQKICogIERERVJSX0hXTkRBTFJFQURZU0VUIGlmIEREU0NMX1NFVEZPQ1VTV0lORE9XIGlzIHBhc3NlZCBpbiBleGNsdXNpdmUgbW9kZQogKiAgIChQcm9iYWJseSBvdGhlcnMgdG9vLCBoYXZlIHRvIGludmVzdGlnYXRlKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfU2V0Q29vcGVyYXRpdmVMZXZlbChJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIGh3bmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNvb3BsZXZlbCkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIEhXTkQgd2luZG93OwogICAgSFJFU1VMVCBocjsKCiAgICBGSVhNRSgiKCVwKS0+KCVwLCUwOHgpXG4iLFRoaXMsaHduZCxjb29wbGV2ZWwpOwogICAgRERSQVdfZHVtcF9jb29wZXJhdGl2ZWxldmVsKGNvb3BsZXZlbCk7CgogICAgLyogR2V0IHRoZSBvbGQgd2luZG93ICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwgJndpbmRvdyk7CiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6R2V0SFdORCBmYWlsZWQsIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBUZXN0cyBzdWdnZXN0IHRoYXQgd2UgbmVlZCBvbmUgb2YgdGhlbTogKi8KICAgIGlmKCEoY29vcGxldmVsICYgKEREU0NMX1NFVEZPQ1VTV0lORE9XIHwKICAgICAgICAgICAgICAgICAgICAgIEREU0NMX05PUk1BTCAgICAgICAgIHwKICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0VYQ0xVU0lWRSAgICAgICkpKQogICAgewogICAgICAgIFRSQUNFKCJJbmNvcnJlY3QgY29vcGxldmVsIGZsYWdzLCByZXR1cm5pbmcgRERFUlJfSU5WQUxJRFBBUkFNU1xuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogSGFuZGxlIHRob3NlIGxldmVscyBmaXJzdCB3aGljaCBzZXQgdmFyaW91cyBod25kcyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfU0VURk9DVVNXSU5ET1cpCiAgICB7CiAgICAgICAgLyogVGhpcyBpc24ndCBjb21wYXRpYmxlIHdpdGggYSBsb3Qgb2YgZmxhZ3MgKi8KICAgICAgICBpZihjb29wbGV2ZWwgJiAoIEREU0NMX01VTFRJVEhSRUFERUQgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9GUFVTRVRVUCAgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlBVUFJFU0VSVkUgICAgIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX0FMTE9XUkVCT09UICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9BTExPV01PREVYICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfU0VUREVWSUNFV0lORE9XIHwKICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NMX05PUk1BTCAgICAgICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICBERFNDTF9FWENMVVNJVkUgICAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0xfRlVMTFNDUkVFTiAgICAgICkgKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIkNhbGxlZCB3aXRoIGluY29tcGF0aWJsZSBmbGFncywgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiggKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRlVMTFNDUkVFTikgJiYgd2luZG93KQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIlNldHRpbmcgRERTQ0xfU0VURk9DVVNXSU5ET1cgd2l0aCBhbiBhbHJlYWR5IHNldCB3aW5kb3csIHJldHVybmluZyBEREVSUl9IV05EQUxSRUFEWVNFVFxuIik7CiAgICAgICAgICAgIHJldHVybiBEREVSUl9IV05EQUxSRUFEWVNFVDsKICAgICAgICB9CgogICAgICAgIFRoaXMtPmZvY3Vzd2luZG93ID0gaHduZDsKICAgICAgICAvKiBXb24ndCB1c2UgdGhlIGh3bmQgcGFyYW0gZm9yIGFueXRoaW5nIGVsc2UgKi8KICAgICAgICBod25kID0gTlVMTDsKCiAgICAgICAgLyogVXNlIHRoZSBmb2N1cyB3aW5kb3cgZm9yIGRyYXdpbmcgdG9vICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBUaGlzLT5mb2N1c3dpbmRvdyk7CgogICAgICAgIC8qIERlc3Ryb3kgdGhlIGRldmljZSB3aW5kb3csIGlmIHdlIGhhdmUgb25lICovCiAgICAgICAgaWYoVGhpcy0+ZGV2aWNld2luZG93KQogICAgICAgIHsKICAgICAgICAgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5kZXZpY2V3aW5kb3cpOwogICAgICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIC8qIEREU0NMX05PUk1BTCBvciBERFNDTF9GVUxMU0NSRUVOIHwgRERTQ0xfRVhDTFVTSVZFICovCiAgICBpZihjb29wbGV2ZWwgJiBERFNDTF9OT1JNQUwpCiAgICB7CiAgICAgICAgLyogQ2FuJ3QgY29leGlzdCB3aXRoIGZ1bGxzY3JlZW4gb3IgZXhjbHVzaXZlICovCiAgICAgICAgaWYoY29vcGxldmVsICYgKEREU0NMX0ZVTExTQ1JFRU4gfCBERFNDTF9FWENMVVNJVkUpICkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIEREU0NMX05PUk1BTCBpcyBub3QgY29tcGF0aXZlIHdpdGggRERTQ0xfRlVMTFNDUkVFTiBvciBERFNDTF9FWENMVVNJVkVcbiIsIFRoaXMpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CgogICAgICAgIC8qIFN3aXRjaGluZyBmcm9tIGZ1bGxzY3JlZW4/ICovCiAgICAgICAgaWYoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9GVUxMU0NSRUVOKQogICAgICAgIHsKICAgICAgICAgICAgLyogUmVzdG9yZSB0aGUgZGlzcGxheSBtb2RlICovCiAgICAgICAgICAgIElEaXJlY3REcmF3N19SZXN0b3JlRGlzcGxheU1vZGUoaWZhY2UpOwoKICAgICAgICAgICAgaWYod2luZG93KQogICAgICAgICAgICAgICAgSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVXaW5kb3coVGhpcywgd2luZG93KTsKCiAgICAgICAgICAgIFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICY9IH5ERFNDTF9GVUxMU0NSRUVOOwogICAgICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfRVhDTFVTSVZFOwogICAgICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfQUxMT1dNT0RFWDsKICAgICAgICB9CgogICAgICAgIC8qIERvbid0IG92ZXJyaWRlIGZvY3VzIHdpbmRvd3Mgb3IgcHJpdmF0ZSBkZXZpY2Ugd2luZG93cyAqLwogICAgICAgIGlmKCBod25kICYmCiAgICAgICAgICAgICEoVGhpcy0+Zm9jdXN3aW5kb3cpICYmCiAgICAgICAgICAgICEoVGhpcy0+ZGV2aWNld2luZG93KSAmJgogICAgICAgICAgICAoaHduZCAhPSB3aW5kb3cpICkKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwgaHduZCk7CiAgICAgICAgfQoKICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSk7CiAgICB9CiAgICBlbHNlIGlmKGNvb3BsZXZlbCAmIEREU0NMX0ZVTExTQ1JFRU4pCiAgICB7CiAgICAgICAgLyogTmVlZHMgRERTQ0xfRVhDTFVTSVZFICovCiAgICAgICAgaWYoIShjb29wbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpICkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIEREU0NMX0ZVTExTQ1JFRU4gbmVlZHMgRERTQ0xfRVhDTFVTSVZFXG4iLCBUaGlzKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICAgICAgfQogICAgICAgIC8qIE5lZWQgYSBIV05ECiAgICAgICAgaWYoaHduZCA9PSAwKQogICAgICAgIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfRlVMTFNDUkVFTiBuZWVkcyBhIEhXTkRcbiIsIFRoaXMpOwogICAgICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgICAgICB9CiAgICAgICAgKi8KCiAgICAgICAgLyogU3dpdGNoIGZyb20gbm9ybWFsIHRvIGZ1bGwgc2NyZWVuIG1vZGU/ICovCiAgICAgICAgaWYoVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgJiBERFNDTF9OT1JNQUwpCiAgICAgICAgewogICAgICAgICAgICBUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmPSB+RERTQ0xfTk9STUFMOwogICAgICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSk7CiAgICAgICAgfQoKICAgICAgICAvKiBEb24ndCBvdmVycmlkZSBmb2N1cyB3aW5kb3dzIG9yIHByaXZhdGUgZGV2aWNlIHdpbmRvd3MgKi8KICAgICAgICBpZiggaHduZCAmJgogICAgICAgICAgICAhKFRoaXMtPmZvY3Vzd2luZG93KSAmJgogICAgICAgICAgICAhKFRoaXMtPmRldmljZXdpbmRvdykgJiYKICAgICAgICAgICAgKGh3bmQgIT0gd2luZG93KSApCiAgICAgICAgewogICAgICAgICAgICAvKiBPbiBhIHdpbmRvdyBjaGFuZ2UsIHJlc3RvcmUgdGhlIG9sZCB3aW5kb3cgYW5kIHNldCB0aGUgbmV3IG9uZSAqLwogICAgICAgICAgICBpZih3aW5kb3cgIT0gaHduZCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYod2luZG93KQogICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9SZXN0b3JlV2luZG93KFRoaXMsIHdpbmRvdyk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KFRoaXMsIGh3bmQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEhXTkQoVGhpcy0+d2luZUQzRERldmljZSwgaHduZCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZihjb29wbGV2ZWwgJiBERFNDTF9FWENMVVNJVkUpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCkgRERTQ0xfRVhDTFVTSVZFIG5lZWRzIEREU0NMX0ZVTExTQ1JFRU5cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX0NSRUFURURFVklDRVdJTkRPVykKICAgIHsKICAgICAgICAvKiBEb24ndCBjcmVhdGUgYSBkZXZpY2Ugd2luZG93IGlmIGEgZm9jdXMgd2luZG93IGlzIHNldCAqLwogICAgICAgIGlmKCAhKFRoaXMtPmZvY3Vzd2luZG93KSApCiAgICAgICAgewogICAgICAgICAgICBIV05EIGRldmljZXdpbmRvdyA9IENyZWF0ZVdpbmRvd0V4QSgwLCBUaGlzLT5jbGFzc25hbWUsICJERHJhdyBkZXZpY2Ugd2luZG93IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV1NfUE9QVVAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCwgR2V0TW9kdWxlSGFuZGxlQSgwKSwgTlVMTCk7CgogICAgICAgICAgICBTaG93V2luZG93KGRldmljZXdpbmRvdywgU1dfU0hPVyk7ICAgLyogSnVzdCB0byBiZSBzdXJlICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIENyZWF0ZWQgYSBERHJhdyBkZXZpY2Ugd2luZG93LiBIV05EPSVwXG4iLCBUaGlzLCBkZXZpY2V3aW5kb3cpOwoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLCBkZXZpY2V3aW5kb3cpOwogICAgICAgICAgICBUaGlzLT5kZXZpY2V3aW5kb3cgPSBkZXZpY2V3aW5kb3c7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFVuaGFuZGxlZCBmbGFncyAqLwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dSRUJPT1QpCiAgICAgICAgV0FSTigiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9BTExPV1JFQk9PVCwgaGFybWxlc3NcbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfQUxMT1dNT0RFWCkKICAgICAgICBXQVJOKCIoJXApIFVuaGFuZGxlZCBmbGFnIEREU0NMX0FMTE9XTU9ERVgsIGhhcm1sZXNzXG4iLCBUaGlzKTsKICAgIGlmKGNvb3BsZXZlbCAmIEREU0NMX01VTFRJVEhSRUFERUQpCiAgICAgICAgRklYTUUoIiglcCkgVW5oYW5kbGVkIGZsYWcgRERTQ0xfTVVMVElUSFJFQURFRCwgVWggT2guLi5cbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfRlBVU0VUVVApCiAgICAgICAgV0FSTigiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9GUFVTRVRVUCwgaGFybWxlc3NcbiIsIFRoaXMpOwogICAgaWYoY29vcGxldmVsICYgRERTQ0xfRlBVUFJFU0VSVkUpCiAgICAgICAgV0FSTigiKCVwKSBVbmhhbmRsZWQgZmxhZyBERFNDTF9GUFVQUkVTRVJWRSwgaGFybWxlc3NcbiIsIFRoaXMpOwoKICAgIC8qIFN0b3JlIHRoZSBjb29wZXJhdGl2ZV9sZXZlbCAqLwogICAgVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwgfD0gY29vcGxldmVsOwogICAgVFJBQ0UoIlNldENvb3BlcmF0aXZlTGV2ZWwgcmV0dW5pbmcgRERfT0tcbiIpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpTZXREaXNwbGF5TW9kZQogKgogKiBTZXRzIHRoZSBkaXNwbGF5IHNjcmVlbiByZXNvbHV0aW9uLCBjb2xvciBkZXB0aCBhbmQgcmVmcmVzaCBmcmVxdWVuY3kKICogd2hlbiBpbiBmdWxsc2NyZWVuIG1vZGUgKGluIHRoZW9yeSkuCiAqIFBvc3NpYmxlIHJldHVybiB2YWx1ZXMgbGlzdGVkIGluIHRoZSBTREsgc3VnZ2VzdCB0aGF0IHRoaXMgbWV0aG9kIGZhaWxzCiAqIHdoZW4gbm90IGluIGZ1bGxzY3JlZW4gbW9kZSwgYnV0IHRoaXMgaXMgd3JvbmcuIFdpbmRvd3MgMjAwMCBoYXBwaWx5IHNldHMKICogdGhlIGRpc3BsYXkgbW9kZSBpbiBERFNDTF9OT1JNQUwgbW9kZSB3aXRob3V0IGFuIGh3bmQgc3BlY2lmaWVkLgogKiBJdCBzZWVtcyB0byBiZSB2YWxpZCB0byBwYXNzIDAgZm9yIFdpdGggYW5kIEhlaWdodCwgdGhpcyBoYXMgdG8gYmUgdGVzdGVkCiAqIEl0IGNvdWxkIG1lYW4gdGhhdCB0aGUgY3VycmVudCB2aWRlbyBtb2RlIHNob3VsZCBiZSBsZWZ0IGFzLWlzLiAoQnV0IHdoeQogKiBjYWxsIGl0IHRoZW4/KQogKgogKiBQYXJhbXM6CiAqICBIZWlnaHQsIFdpZHRoOiBTY3JlZW4gZGltZW5zaW9uCiAqICBCUFA6IENvbG9yIGRlcHRoIGluIEJpdHMgcGVyIHBpeGVsCiAqICBSZWZyZXNocmF0ZTogU2NyZWVuIHJlZnJlc2ggcmF0ZQogKiAgRmxhZ3M6IE90aGVyIHN0dWZmCiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1NldERpc3BsYXlNb2RlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEJQUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFJlZnJlc2hSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJWQsJWQsJXg6IFJlbGF5IVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgQlBQLCBSZWZyZXNoUmF0ZSwgRmxhZ3MpOwoKICAgIGlmKCAhV2lkdGggfHwgIUhlaWdodCApCiAgICB7CiAgICAgICAgRVJSKCJXaWR0aD0lZCwgSGVpZ2h0PSVkLCB3aGF0IHRvIGRvP1xuIiwgV2lkdGgsIEhlaWdodCk7CiAgICAgICAgLyogSXQgbG9va3MgbGlrZSBOZWVkIGZvciBTcGVlZCBQb3JzY2hlIFVubGVhc2hlZCBleHBlY3RzIEREX09LIGhlcmUgKi8KICAgICAgICByZXR1cm4gRERfT0s7CiAgICB9CgogICAgLyogQ2hlY2sgdGhlIGV4Y2x1c2l2ZSBtb2RlCiAgICBpZighKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRVhDTFVTSVZFKSkKICAgICAgICByZXR1cm4gRERFUlJfTk9FWENMVVNJVkVNT0RFOwogICAgICogVGhpcyBpcyBXUk9ORy4gRG9uJ3Qga25vdyBpZiB0aGUgU0RLIGlzIGNvbXBsZXRlbHkKICAgICAqIHdyb25nIGFuZCBpZiB0aGVyZSBhcmUgYW55IGNvbmRpdGlvbnMgd2hlbiBEREVSUl9OT0VYQ0xVU0lWRQogICAgICogaXMgcmV0dXJuZWQsIGJ1dCBIYWxmLUxpZmUgMS4xLjEuMSAoU3RlYW0gdmVyc2lvbikKICAgICAqIGRlcGVuZHMgb24gdGhpcwogICAgICovCgogICAgTW9kZS5XaWR0aCA9IFdpZHRoOwogICAgTW9kZS5IZWlnaHQgPSBIZWlnaHQ7CiAgICBNb2RlLlJlZnJlc2hSYXRlID0gUmVmcmVzaFJhdGU7CiAgICBzd2l0Y2goQlBQKQogICAgewogICAgICAgIGNhc2UgODogIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9QODsgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxNTogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1gxUjVHNUI1OyBicmVhazsKICAgICAgICBjYXNlIDE2OiBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUjVHNkI1OyAgIGJyZWFrOwogICAgICAgIGNhc2UgMjQ6IE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9SOEc4Qjg7ICAgYnJlYWs7CiAgICAgICAgY2FzZSAzMjogTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX0E4UjhHOEI4OyBicmVhazsKICAgIH0KCiAgICAvKiBUT0RPOiBUaGUgcG9zc2libGUgcmV0dXJuIHZhbHVlcyBmcm9tIG1zZG4gc3VnZ2VzdCB0aGF0CiAgICAgKiB0aGUgc2NyZWVuIG1vZGUgY2FuJ3QgYmUgY2hhbmdlZCBpZiBhIHN1cmZhY2UgaXMgbG9ja2VkCiAgICAgKiBvciBzb21lIGRyYXdpbmcgaXMgaW4gcHJvZ3Jlc3MKICAgICAqLwoKICAgIC8qIFRPRE86IExvc2UgdGhlIHByaW1hcnkgc3VyZmFjZSAqLwogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlX1NldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogRmlyc3Qgc3dhcGNoYWluICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6UmVzdG9yZURpc3BsYXlNb2RlCiAqCiAqIFJlc3RvcmVzIHRoZSBkaXNwbGF5IG1vZGUgdG8gd2hhdCBpdCB3YXMgYXQgY3JlYXRpb24gdGltZS4gQmFzaWNhbGx5LgogKgogKiBBIHByb2JsZW0gYXJpc2VzIHdoZW4gdGhlcmUgYXJlIDIgRGlyZWN0RHJhdyBvYmplY3RzIHVzaW5nIHRoZSBzYW1lIGh3bmQ6CiAqICAtPiBERF8xIGZpbmRzIHRoZSBzY3JlZW4gYXQgMTQwMHgxMDUweDMyIHdoZW4gY3JlYXRlZCwgc2V0cyBpdCB0byA2NDB4NDgweDE2CiAqICAtPiBERF8yIGlzIGNyZWF0ZWQsIGZpbmRzIHRoZSBzY3JlZW4gYXQgNjQweDQ4MHgxNiwgc2V0cyBpdCB0byAxMDI0eDc2OHgzMgogKiAgLT4gRERfMSBpcyByZWxlYXNlZC4gVGhlIHNjcmVlbiBzaG91bGQgYmUgbGVmdCBhdCAxMDI0eDc2OHgzMi4KICogIC0+IEREXzIgaXMgcmVsZWFzZWQuIFRoZSBzY3JlZW4gc2hvdWxkIGJlIHNldCB0byAxNDAweDEwNTB4MzIKICogVGhpcyBjYXNlIGlzIHVuaGFuZGxlZCByaWdodCBub3csIGJ1dCBFbXBpcmUgRWFydGggZG9lcyBpdCB0aGlzIHdheS4KICogKEJ1dCBwZXJoYXBzIHRoZXJlIGlzIHNvbWV0aGluZyBpbiBTZXRDb29wZXJhdGl2ZUxldmVsIHRvIHByZXZlbnQgdGhpcykKICoKICogVGhlIG1zZG4gc2F5cyB0aGF0IHRoaXMgbWV0aG9kIHJlc2V0cyB0aGUgZGlzcGxheSBtb2RlIHRvIHdoYXQgaXQgd2FzIGJlZm9yZQogKiBTZXREaXNwbGF5TW9kZSB3YXMgY2FsbGVkLiBXaGF0IGlmIFNldERpc3BsYXlNb2RlcyBpcyBjYWxsZWQgMiB0aW1lcz8/CiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX05PRVhDTFVTSVZFIG1vZGUgaWYgdGhlIGRldmljZSBpc24ndCBpbiBmdWxsc2NyZWVuIG1vZGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVEaXNwbGF5TW9kZShJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBJRGlyZWN0RHJhdzdfU2V0RGlzcGxheU1vZGUoSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ193aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+b3JpZ19oZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPm9yaWdfYnBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0Q2FwcwogKgogKiBSZXR1cm5zIHRoZSBkcml2ZXMgY2FwYWJpbGl0aWVzCiAqCiAqIFVzZWQgZm9yIHZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBEcml2ZXJDYXBzOiBTdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIEhhcmR3YXJlIGFjY2VsZXJhdGVkIGNhcHMgdG8KICogIEhlbENhcHM6IFN0cnVjdHVyZSB0byB3cml0ZSB0aGUgZW11bGF0aW9uIGNhcHMgdG8KICoKICogUmV0dXJucwogKiAgVGhpcyBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIEREX09LIG9ubHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldENhcHMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTICpEcml2ZXJDYXBzLAogICAgICAgICAgICAgICAgICAgICAgICBERENBUFMgKkhFTENhcHMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgRHJpdmVyQ2FwcywgSEVMQ2Fwcyk7CgogICAgLyogT25lIHN0cnVjdHVyZSBtdXN0IGJlICE9IE5VTEwgKi8KICAgIGlmKCAoIURyaXZlckNhcHMpICYmICghSEVMQ2FwcykgKQogICAgewogICAgICAgIEVSUigiKCVwKSBJbnZhbGlkIHBhcmFtcyB0byBJRGlyZWN0RHJhd0ltcGxfR2V0Q2Fwc1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgaWYoRHJpdmVyQ2FwcykKICAgIHsKICAgICAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoRHJpdmVyQ2FwcywgJlRoaXMtPmNhcHMpOwogICAgICAgIGlmIChUUkFDRV9PTihkZHJhdykpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiRHJpdmVyIENhcHMgOlxuIik7CiAgICAgICAgICAgIEREUkFXX2R1bXBfRERDQVBTKERyaXZlckNhcHMpOwogICAgICAgIH0KCiAgICB9CiAgICBpZihIRUxDYXBzKQogICAgewogICAgICAgIEREX1NUUlVDVF9DT1BZX0JZU0laRShIRUxDYXBzLCAmVGhpcy0+Y2Fwcyk7CiAgICAgICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJIRUwgQ2FwcyA6XG4iKTsKICAgICAgICAgICAgRERSQVdfZHVtcF9ERENBUFMoSEVMQ2Fwcyk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6Q29tcGFjdAogKgogKiBObyBpZGVhIHdoYXQgaXQgZG9lcywgTVNETiBzYXlzIGl0J3Mgbm90IGltcGxlbWVudGVkLgogKgogKiBSZXR1cm5zCiAqICBERF9PSywgYnV0IHRoaXMgaXMgdW5jaGVja2VkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9Db21wYWN0KElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpHZXREaXNwbGF5TW9kZQogKgogKiBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjdXJyZW50IGRpc3BsYXkgbW9kZQogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIEREU0Q6IEFkZHJlc3Mgb2YgYSBzdXJmYWNlIGRlc2NyaXB0aW9uIHN0cnVjdHVyZSB0byB3cml0ZSB0aGUgaW5mbyB0bwogKgogKiBSZXR1cm5zCiAqICBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0RGlzcGxheU1vZGUoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNEKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwogICAgRFdPUkQgU2l6ZTsKICAgIFRSQUNFKCIoJXApLT4oJXApOiBSZWxheVxuIiwgVGhpcywgRERTRCk7CgogICAgLyogVGhpcyBzZWVtcyBzYW5lICovCiAgICBpZighRERTRCkgCiAgICB7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CiAgICB9CgogICAgLyogVGhlIG5lY2Vzc2FyeSBtZW1iZXJzIG9mIExQRERTVVJGQUNFREVTQyBhbmQgTFBERFNVUkZBQ0VERVNDMiBhcmUgZXF1YWwsCiAgICAgKiBzbyBvbmUgbWV0aG9kIGNhbiBiZSB1c2VkIGZvciBhbGwgdmVyc2lvbnMgKEhvcGVmdWxseSkKICAgICAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXREaXNwbGF5TW9kZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogc3dhcGNoYWluIDAgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk1vZGUpOwogICAgaWYoIGhyICE9IEQzRF9PSyApCiAgICB7CiAgICAgICAgRVJSKCIgKCVwKSBJV2luZUQzRERldmljZTo6R2V0RGlzcGxheU1vZGUgcmV0dXJuZWQgJTA4eFxuIiwgVGhpcywgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBTaXplID0gRERTRC0+ZHdTaXplOwogICAgbWVtc2V0KEREU0QsIDAsIFNpemUpOwoKICAgIEREU0QtPmR3U2l6ZSA9IFNpemU7CiAgICBERFNELT5kd0ZsYWdzIHw9IEREU0RfSEVJR0hUIHwgRERTRF9XSURUSCB8IEREU0RfUElYRUxGT1JNQVQgfCBERFNEX1BJVENIIHwgRERTRF9SRUZSRVNIUkFURTsKICAgIEREU0QtPmR3V2lkdGggPSBNb2RlLldpZHRoOwogICAgRERTRC0+ZHdIZWlnaHQgPSBNb2RlLkhlaWdodDsgCiAgICBERFNELT51Mi5kd1JlZnJlc2hSYXRlID0gNjA7CiAgICBERFNELT5kZHNDYXBzLmR3Q2FwcyA9IDA7CiAgICBERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREU0QtPnU0LmRkcGZQaXhlbEZvcm1hdCk7CiAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCgmRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0LCBNb2RlLkZvcm1hdCk7CiAgICBERFNELT51MS5sUGl0Y2ggPSBNb2RlLldpZHRoICogRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0LnUxLmR3UkdCQml0Q291bnQgLyA4OwoKICAgIGlmKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiUmV0dXJuaW5nIHN1cmZhY2UgZGVzYyA6XG4iKTsKICAgICAgICBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhERFNEKTsKICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldEZvdXJDQ0NvZGVzCiAqCiAqIFJldHVybnMgYW4gYXJyYXkgb2Ygc3VwcG9ydGVkIEZvdXJDQyBjb2Rlcy4KICoKICogRXhpc3RzIGluIFZlcnNpb24gMSwgMiwgNCBhbmQgNwogKgogKiBQYXJhbXM6CiAqICBOdW1Db2RlczogQ29udGFpbnMgdGhlIG51bWJlciBvZiBDb2RlcyB0aGF0IENvZGVzIGNhbiBjYXJyeS4gUmV0dXJucyB0aGUgbnVtYmVyCiAqICAgICAgICAgICAgb2YgZW51bWVyYXRlZCBjb2RlcwogKiAgQ29kZXM6IFBvaW50ZXIgdG8gYW4gYXJyYXkgb2YgRFdPUkRzIHdoZXJlIHRoZSBzdXBwb3J0ZWQgY29kZXMgYXJlIHdyaXR0ZW4KICogICAgICAgICB0bwogKgogKiBSZXR1cm5zCiAqICBBbHdheXMgcmV0dXJucyBERF9PSywgYXMgaXQncyBhIHN0dWIgZm9yIG5vdwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0Rm91ckNDQ29kZXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpOdW1Db2RlcywgRFdPUkQgKkNvZGVzKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglcCwgJXApOiBTdHViIVxuIiwgVGhpcywgTnVtQ29kZXMsIENvZGVzKTsKCiAgICBpZihOdW1Db2RlcykgKk51bUNvZGVzID0gMDsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldE1vbml0b3JGcmVxdWVuY3kKICoKICogUmV0dXJucyB0aGUgbW9uaXRvcidzIGZyZXF1ZW5jeQogKgogKiBFeGlzdHMgaW4gVmVyc2lvbiAxLCAyLCA0IGFuZCA3CiAqCiAqIFBhcmFtczoKICogIEZyZXE6IFBvaW50ZXIgdG8gYSBEV09SRCB0byB3cml0ZSB0aGUgZnJlcXVlbmN5IHRvCiAqCiAqIFJldHVybnMKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRNb25pdG9yRnJlcXVlbmN5KElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpGcmVxKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIEZyZXEpOwoKICAgIC8qIElkZWFsbHkgdGhpcyBzaG91bGQgYmUgaW4gV2luZUQzRCwgYXMgaXQgY29uY2VybnMgdGhlIHNjcmVlbiBzZXR1cCwKICAgICAqIGJ1dCBmb3Igbm93IHRoaXMgc2hvdWxkIG1ha2UgdGhlIGdhbWVzIGhhcHB5CiAgICAgKi8KICAgICpGcmVxID0gNjA7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldFZlcnRpY2FsQmxhbmtTdGF0dXMKICoKICogUmV0dXJucyB0aGUgVmVydGljYWwgYmxhbmsgc3RhdHVzIG9mIHRoZSBtb25pdG9yLiBUaGlzIHNob3VsZCBiZSBpbiBXaW5lRDNECiAqIHRvbyBiYXNpY2FsbHksIGJ1dCBhcyBpdCdzIGEgc2VtaSBzdHViLCBJIGRpZG4ndCBjcmVhdGUgYSBmdW5jdGlvbiB0aGVyZQogKgogKiBQYXJhbXM6CiAqICBzdGF0dXM6IFBvaW50ZXIgdG8gYSBCT09MIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSB2ZXJ0aWNhbCBibGFuayBzdGF0dXMKICoKICogUmV0dXJucwogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBzdGF0dXMgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfR2V0VmVydGljYWxCbGFua1N0YXR1cyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MICpzdGF0dXMpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgc3RhdHVzKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUsIHRoZSBNU0ROIHN1Z2dlc3RzIGl0IHRvbyAqLwogICAgaWYoIXN0YXR1cykgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgKnN0YXR1cyA9IFRoaXMtPmZha2VfdmJsYW5rOwogICAgVGhpcy0+ZmFrZV92YmxhbmsgPSAhVGhpcy0+ZmFrZV92Ymxhbms7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldEF2YWlsYWJsZVZpZE1lbQogKgogKiBSZXR1cm5zIHRoZSB0b3RhbCBhbmQgZnJlZSB2aWRlbyBtZW1vcnkKICoKICogUGFyYW1zOgogKiAgQ2FwczogU3BlY2lmaWVzIHRoZSBtZW1vcnkgdHlwZSBhc2tlZCBmb3IKICogIHRvdGFsOiBQb2ludGVyIHRvIGEgRFdPUkQgdG8gYmUgZmlsbGVkIHdpdGggdGhlIHRvdGFsIG1lbW9yeQogKiAgZnJlZTogUG9pbnRlciB0byBhIERXT1JEIHRvIGJlIGZpbGxlZCB3aXRoIHRoZSBmcmVlIG1lbW9yeQogKgogKiBSZXR1cm5zCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIG9mIGZyZWUgYW5kIHRvdGFsIGFyZSBOVUxMCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRBdmFpbGFibGVWaWRNZW0oSURpcmVjdERyYXc3ICppZmFjZSwgRERTQ0FQUzIgKkNhcHMsIERXT1JEICp0b3RhbCwgRFdPUkQgKmZyZWUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCAlcCwgJXApXG4iLCBUaGlzLCBDYXBzLCB0b3RhbCwgZnJlZSk7CgogICAgaWYoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCIoJXApIEFza2VkIGZvciBtZW1vcnkgd2l0aCBkZXNjcmlwdGlvbjogIiwgVGhpcyk7CiAgICAgICAgRERSQVdfZHVtcF9ERFNDQVBTMihDYXBzKTsKICAgICAgICBUUkFDRSgiXG4iKTsKICAgIH0KCiAgICAvKiBUb2RvOiBTeXN0ZW0gbWVtb3J5IHZzIGxvY2FsIHZpZGVvIG1lbW9yeSB2cyBub24tbG9jYWwgdmlkZW8gbWVtb3J5CiAgICAgKiBUaGUgTVNETiBhbHNvIG1lbnRpb25zIGRpZmZlcmVuY2VzIGJldHdlZW4gdGV4dHVyZSBtZW1vcnkgYW5kIG90aGVyCiAgICAgKiByZXNvdXJjZXMsIGJ1dCB0aGF0J3Mgbm90IGltcG9ydGFudAogICAgICovCgogICAgaWYoICghdG90YWwpICYmICghZnJlZSkgKSByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICBpZih0b3RhbCkgKnRvdGFsID0gVGhpcy0+dG90YWxfdmlkbWVtOwogICAgaWYoZnJlZSkgKmZyZWUgPSBJV2luZUQzRERldmljZV9HZXRBdmFpbGFibGVUZXh0dXJlTWVtKFRoaXMtPndpbmVEM0REZXZpY2UpOwoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6SW5pdGlhbGl6ZQogKgogKiBJbml0aWFsaXplcyBhIERpcmVjdERyYXcgaW50ZXJmYWNlLgogKgogKiBQYXJhbXM6CiAqICBHVUlEOiBJbnRlcmZhY2UgaWRlbnRpZmllci4gV2VsbCwgZG9uJ3Qga25vdyB3aGF0IHRoaXMgaXMgcmVhbGx5IGdvb2QKICogICBmb3IKICoKICogUmV0dXJucwogKiAgUmV0dXJucyBERF9PSyBvbiB0aGUgZmlyc3QgY2FsbCwKICogIERERVJSX0FMUkVBRFlJTklUSUFMSVpFRCBvbiByZXBlYXRlZCBjYWxscwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfSW5pdGlhbGl6ZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBHVUlEICpHdWlkKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcyk6IE5vLW9wXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKEd1aWQpKTsKCiAgICBpZihUaGlzLT5pbml0aWFsaXplZCkKICAgIHsKICAgICAgICByZXR1cm4gRERFUlJfQUxSRUFEWUlOSVRJQUxJWkVEOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldHVybiBERF9PSzsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RmxpcFRvR0RJU3VyZmFjZQogKgogKiAiTWFrZXMgdGhlIHN1cmZhY2UgdGhhdCB0aGUgR0RJIHdyaXRlcyB0byB0aGUgcHJpbWFyeSBzdXJmYWNlIgogKiBMb29rcyBsaWtlIHNvbWUgd2luZG93cyBzcGVjaWZpYyB0aGluZyB3ZSBkb24ndCBoYXZlIHRvIGNhcmUgYWJvdXQuCiAqIEFjY29yZGluZyB0byBNU0ROIGl0IHBlcm1pdHMgR0RJIGRpYWxvZyBib3hlcyBpbiBGVUxMU0NSRUVOIG1vZGUuIEdvb2QgdG8KICogc2hvdyBlcnJvciBib3hlcyA7KQogKiBXZWxsLCBqdXN0IHJldHVybiBERF9PSy4KICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9GbGlwVG9HRElTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpXYWl0Rm9yVmVydGljYWxCbGFuawogKgogKiBUaGlzIG1ldGhvZCBhbGxvd3MgYXBwbGljYXRpb25zIHRvIGdldCBpbiBzeW5jIHdpdGggdGhlIHZlcnRpY2FsIGJsYW5rCiAqIGludGVydmFsLgogKiBUaGUgd29ybWhvbGUgZGVtbyBpbiB0aGUgRGlyZWN0WCA3IHNkayB1c2VzIHRoaXMgY2FsbCwgYW5kIGl0IGRvZXNuJ3QKICogcmVkcmF3IHRoZSBzY3JlZW4sIG1vc3QgbGlrZWx5IGJlY2F1c2Ugb2YgdGhpcyBzdHViCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBGbGFnczogb25lIG9mIEREV0FJVFZCX0JMT0NLQkVHSU4sIEREV0FJVFZCX0JMT0NLQkVHSU5FVkVOVAogKiAgICAgICAgIG9yIEREV0FJVFZCX0JMT0NLRU5ECiAqICBoOiBOb3QgdXNlZCwgYWNjb3JkaW5nIHRvIE1TRE4KICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfV2FpdEZvclZlcnRpY2FsQmxhbmsoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFIGgpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCV4LCVwKTogU3R1YlxuIiwgVGhpcywgRmxhZ3MsIGgpOwoKICAgIC8qIE1TRE4gc2F5cyBERFdBSVRWQl9CTE9DS0JFR0lORVZFTlQgaXMgbm90IHN1cHBvcnRlZCAqLwogICAgaWYoRmxhZ3MgJiBERFdBSVRWQl9CTE9DS0JFR0lORVZFTlQpCiAgICAgICAgcmV0dXJuIERERVJSX1VOU1VQUE9SVEVEOyAvKiB1bmNoZWNrZWQgKi8KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldFNjYW5MaW5lCiAqCiAqIFJldHVybnMgdGhlIHNjYW4gbGluZSB0aGF0IGlzIGJlaW5nIGRyYXduIG9uIHRoZSBtb25pdG9yCiAqCiAqIFBhcmFtZXRlcnM6CiAqICBTY2FubGluZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgc2NhbiBsaW5lIHZhbHVlIHRvCiAqCiAqIFJldHVybnM6CiAqICBBbHdheXMgcmV0dXJucyBERF9PSwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovIApzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSURpcmVjdERyYXdJbXBsX0dldFNjYW5MaW5lKElEaXJlY3REcmF3NyAqaWZhY2UsIERXT1JEICpTY2FubGluZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIHN0YXRpYyBCT09MIGhpZGUgPSBGQUxTRTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBNb2RlOwoKICAgIC8qIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9mdGVuLCBzbyBwcmludCB0aGUgZml4bWUgb25seSBvbmNlICovCiAgICBpZighaGlkZSkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKS0+KCVwKTogU2VtaS1TdHViXG4iLCBUaGlzLCBTY2FubGluZSk7CiAgICAgICAgaGlkZSA9IFRSVUU7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VfR2V0RGlzcGxheU1vZGUoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTW9kZSk7CgogICAgLyogRmFrZSB0aGUgbGluZSBzd2VlcGluZyBvZiB0aGUgbW9uaXRvciAqLwogICAgLyogRklYTUU6IFdlIHNob3VsZCBzeW5jaHJvbml6ZSB3aXRoIGEgc291cmNlIHRvIGtlZXAgdGhlIHJlZnJlc2ggcmF0ZSAqLyAKICAgICpTY2FubGluZSA9IFRoaXMtPmN1cl9zY2FubGluZSsrOwogICAgLyogQXNzdW1lIDIwIHNjYW4gbGluZXMgaW4gdGhlIHZlcnRpY2FsIGJsYW5rICovCiAgICBpZiAoVGhpcy0+Y3VyX3NjYW5saW5lID49IE1vZGUuSGVpZ2h0ICsgMjApCiAgICAgICAgVGhpcy0+Y3VyX3NjYW5saW5lID0gMDsKCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlRlc3RDb29wZXJhdGl2ZUxldmVsCiAqCiAqIEluZm9ybXMgdGhlIGFwcGxpY2F0aW9uIGFib3V0IHRoZSBzdGF0ZSBvZiB0aGUgdmlkZW8gYWRhcHRlciwgZGVwZW5kaW5nCiAqIG9uIHRoZSBjb29wZXJhdGl2ZSBsZXZlbAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIGRldmljZSBpcyBpbiBhIHNhbmUgc3RhdGUKICogIERERVJSX05PRVhDTFVTSVZFTU9ERSBvciBEREVSUl9FWENMVVNJVkVNT0RFQUxSRUFEWVNFVAogKiAgaWYgdGhlIHN0YXRlIGlzIG5vdCBjb3JyZWN0KFNlZSBiZWxvdykKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbChJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICAvKiBEZXNjcmlwdGlvbiBmcm9tIE1TRE46CiAgICAgKiBGb3IgZnVsbHNjcmVlbiBhcHBzIHJldHVybiBEREVSUl9OT0VYQ0xVU0lWRU1PREUgaWYgdGhlIHVzZXIgc3dpdGNoZWQKICAgICAqIGF3YXkgZnJvbSB0aGUgYXBwIHdpdGggZS5nLiBhbHQtdGFiLiBXaW5kb3dlZCBhcHBzIHJlY2VpdmUgCiAgICAgKiBEREVSUl9FWENMVVNJVkVNT0RFQUxSRUFEWVNFVCBpZiBhbm90aGVyIGFwcGxpY2F0aW9uIGNyZWF0ZWQgYSAKICAgICAqIERpcmVjdERyYXcgb2JqZWN0IGluIGV4Y2x1c2l2ZSBtb2RlLiBEREVSUl9XUk9OR01PREUgaXMgcmV0dXJuZWQsCiAgICAgKiB3aGVuIHRoZSB2aWRlbyBtb2RlIGhhcyBjaGFuZ2VkCiAgICAgKi8KCiAgICBociA9ICBJV2luZUQzRERldmljZV9UZXN0Q29vcGVyYXRpdmVMZXZlbChUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBGaXggdGhlIHJlc3VsdCB2YWx1ZS4gVGhlc2UgdmFsdWVzIGFyZSBtYXBwZWQgZnJvbSB0aGVpcgogICAgICogZDNkOSBjb3VudGVycGFydC4KICAgICAqLwogICAgc3dpdGNoKGhyKQogICAgewogICAgICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VMT1NUOgogICAgICAgICAgICBpZihUaGlzLT5jb29wZXJhdGl2ZV9sZXZlbCAmIEREU0NMX0VYQ0xVU0lWRSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmV0dXJuIERERVJSX05PRVhDTFVTSVZFTU9ERTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9FWENMVVNJVkVNT0RFQUxSRUFEWVNFVDsKICAgICAgICAgICAgfQoKICAgICAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTk9UUkVTRVQ6CiAgICAgICAgICAgIHJldHVybiBERF9PSzsKCiAgICAgICAgY2FzZSBXSU5FRDNEX09LOgogICAgICAgICAgICByZXR1cm4gRERfT0s7CgogICAgICAgIGNhc2UgV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiKCVwKSBVbmV4cGVjdGVkIHJldHVybiB2YWx1ZSAlMDh4IGZyb20gd2luZUQzRCwgIgogICAgICAgICAgICAgICAgIiByZXR1cm5pbmcgRERfT0tcbiIsIFRoaXMsIGhyKTsKICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldEdESVN1cmZhY2UKICoKICogUmV0dXJucyB0aGUgc3VyZmFjZSB0aGF0IEdESSBpcyB0cmVhdGluZyBhcyB0aGUgcHJpbWFyeSBzdXJmYWNlLgogKiBGb3IgV2luZSB0aGlzIGlzIHRoZSBmcm9udCBidWZmZXIKICoKICogUGFyYW1zOgogKiAgR0RJU3VyZmFjZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgc3VyZmFjZSBwb2ludGVyIHRvCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgc3VyZmFjZSB3YXMgZm91bmQKICogIERERVJSX05PVEZPVU5EIGlmIHRoZSBHREkgc3VyZmFjZSB3YXNuJ3QgZm91bmQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9HZXRHRElTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKipHRElTdXJmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSVdpbmVEM0RTdXJmYWNlICpTdXJmOwogICAgSURpcmVjdERyYXdTdXJmYWNlNyAqZGRzdXJmOwogICAgSFJFU1VMVCBocjsKICAgIEREU0NBUFMyIGRkc0NhcHM7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgR0RJU3VyZmFjZSk7CgogICAgLyogR2V0IHRoZSBiYWNrIGJ1ZmZlciBmcm9tIHRoZSB3aW5lRDNERGV2aWNlIGFuZCBzZWFyY2ggaXRzCiAgICAgKiBhdHRhY2hlZCBzdXJmYWNlcyBmb3IgdGhlIGZyb250IGJ1ZmZlcgogICAgICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldEJhY2tCdWZmZXIoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBTd2FwQ2hhaW4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBmaXJzdCBiYWNrIGJ1ZmZlciovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREJBQ0tCVUZGRVJfVFlQRV9NT05PLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdXJmKTsKCiAgICBpZiggKGhyICE9IEQzRF9PSykgfHwKICAgICAgICAoIVN1cmYpICkKICAgIHsKICAgICAgICBFUlIoIklXaW5lRDNERGV2aWNlOjpHZXRCYWNrQnVmZmVyIGZhaWxlZFxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX05PVEZPVU5EOwogICAgfQoKICAgIC8qIEdldEJhY2tCdWZmZXIgQWRkUmVmKCllZCB0aGUgc3VyZmFjZSwgcmVsZWFzZSBpdCAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoU3VyZik7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChTdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKiopICZkZHN1cmYpOwogICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKGRkc3VyZik7ICAvKiBGb3IgdGhlIEdldFBhcmVudCAqLwoKICAgIC8qIEZpbmQgdGhlIGZyb250IGJ1ZmZlciAqLwogICAgZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX0ZST05UQlVGRkVSOwogICAgaHIgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShkZHN1cmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZHNDYXBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHRElTdXJmYWNlKTsKICAgIGlmKGhyICE9IEREX09LKQogICAgewogICAgICAgIEVSUigiSURpcmVjdERyYXdTdXJmYWNlNzo6R2V0QXR0YWNoZWRTdXJmYWNlIGZhaWxlZCwgaHIgPSAleFxuIiwgaHIpOwogICAgfQoKICAgIC8qIFRoZSBBZGRSZWYgaXMgT0sgdGhpcyB0aW1lICovCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfRW51bURpc3BsYXlNb2Rlc0NCCiAqCiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciBJRGlyZWN0RHJhdzc6OkVudW1EaXNwbGF5TW9kZXMuIFRyYW5zbGF0ZXMKICogdGhlIHdpbmVEM0QgdmFsdWVzIHRvIGRkcmF3IHZhbHVlcyBhbmQgY2FsbHMgdGhlIGFwcGxpY2F0aW9uIGNhbGxiYWNrCiAqCiAqIFBhcmFtczoKICogIGRldmljZTogVGhlIElEaXJlY3REcmF3NyBpbnRlcmZhY2UgdG8gdGhlIGN1cnJlbnQgZGV2aWNlCiAqICBXaXRoLCBIZWlnaHQsIFBpeGVsZm9ybWF0LCBSZWZyZXNoOiBFbnVtZXJhdGVkIGRpc3BsYXkgbW9kZQogKiAgY29udGV4dDogdGhlIGNvbnRleHQgcG9pbnRlciBwYXNzZWQgdG8gSVdpbmVEM0REZXZpY2U6OkVudW1EaXNwbGF5TW9kZXMKICoKICogUmV0dXJuczoKICogIFRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgYXBwbGljYXRpb24gY2FsbGJhY2sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAKc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9FbnVtRGlzcGxheU1vZGVzQ0IoSVVua25vd24gKnBEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIFBpeGVsZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZMT0FUIFJlZnJlc2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY29udGV4dCkKewogICAgRERTVVJGQUNFREVTQzIgY2FsbGJhY2tfc2Q7CiAgICBFbnVtRGlzcGxheU1vZGVzQ0JTICpjYnMgPSAoRW51bURpc3BsYXlNb2Rlc0NCUyAqKSBjb250ZXh0OwoKICAgIG1lbXNldCgmY2FsbGJhY2tfc2QsIDAsIHNpemVvZihjYWxsYmFja19zZCkpOwogICAgY2FsbGJhY2tfc2QuZHdTaXplID0gc2l6ZW9mKGNhbGxiYWNrX3NkKTsKICAgIGNhbGxiYWNrX3NkLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemUgPSBzaXplb2YoRERQSVhFTEZPUk1BVCk7CgogICAgY2FsbGJhY2tfc2QuZHdGbGFncyA9IEREU0RfSEVJR0hUfEREU0RfV0lEVEh8RERTRF9QSVhFTEZPUk1BVHxERFNEX1BJVENIOwogICAgaWYoUmVmcmVzaCA+IDAuMCkKICAgIHsKICAgICAgICBjYWxsYmFja19zZC5kd0ZsYWdzIHw9IEREU0RfUkVGUkVTSFJBVEU7CiAgICAgICAgY2FsbGJhY2tfc2QudTIuZHdSZWZyZXNoUmF0ZSA9IDYwLjA7CiAgICB9CgogICAgY2FsbGJhY2tfc2QuZHdIZWlnaHQgPSBIZWlnaHQ7CiAgICBjYWxsYmFja19zZC5kd1dpZHRoID0gV2lkdGg7CgogICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmNhbGxiYWNrX3NkLnU0LmRkcGZQaXhlbEZvcm1hdCwgUGl4ZWxmb3JtYXQpOwogICAgcmV0dXJuIGNicy0+Y2FsbGJhY2soJmNhbGxiYWNrX3NkLCBjYnMtPmNvbnRleHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFbnVtRGlzcGxheU1vZGVzCiAqCiAqIEVudW1lcmF0ZXMgdGhlIHN1cHBvcnRlZCBEaXNwbGF5IG1vZGVzLiBUaGUgbW9kZXMgY2FuIGJlIGZpbHRlcmVkIHdpdGgKICogdGhlIEREU0QgcGFyYW1ldGVyLgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogY2FuIGJlIERERURNX1JFRlJFU0hSQVRFUyBhbmQgRERFRE1fU1RBTkRBUkRWR0FNT0RFUwogKiAgRERTRDogU3VyZmFjZSBkZXNjcmlwdGlvbiB0byBmaWx0ZXIgdGhlIG1vZGVzCiAqICBDb250ZXh0OiBQb2ludGVyIHBhc3NlZCBiYWNrIHRvIHRoZSBjYWxsYmFjayBmdW5jdGlvbgogKiAgY2I6IEFwcGxpY2F0aW9uLXByb3ZpZGVkIGNhbGxiYWNrIGZ1bmN0aW9uCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBjYWxsYmFjayB3YXNuJ3Qgc2V0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8gCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfRW51bURpc3BsYXlNb2RlcyhJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKkREU0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNTU9ERVNDQUxMQkFDSzIgY2IpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBVSU5UIFdpZHRoID0gMCwgSGVpZ2h0ID0gMDsKICAgIFdJTkVEM0RGT1JNQVQgcGl4ZWxmb3JtYXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICBFbnVtRGlzcGxheU1vZGVzQ0JTIGNiczsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwKTogUmVsYXlcbiIsIFRoaXMsIEREU0QsIENvbnRleHQsIGNiKTsKCiAgICAvKiBUaGlzIGxvb2tzIHNhbmUgKi8KICAgIGlmKCFjYikgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogVGhlIHByaXZhdGUgY2FsbGJhY2sgc3RydWN0dXJlICovCiAgICBjYnMuY2FsbGJhY2sgPSBjYjsKICAgIGNicy5jb250ZXh0ID0gQ29udGV4dDsKCiAgICBpZihERFNEKQogICAgewogICAgICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9XSURUSCkKICAgICAgICAgICAgV2lkdGggPSBERFNELT5kd1dpZHRoOwogICAgICAgIGlmIChERFNELT5kd0ZsYWdzICYgRERTRF9IRUlHSFQpCiAgICAgICAgICAgIEhlaWdodCA9IEREU0QtPmR3SGVpZ2h0OwogICAgICAgIGlmICgoRERTRC0+ZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpICYmIChERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQuZHdGbGFncyAmIEREUEZfUkdCKSApCiAgICAgICAgICAgIHBpeGVsZm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmRERTRC0+dTQuZGRwZlBpeGVsRm9ybWF0KTsKICAgIH0KCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VfRW51bURpc3BsYXlNb2RlcyhUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaWR0aCwgSGVpZ2h0LCBwaXhlbGZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGxfRW51bURpc3BsYXlNb2Rlc0NCKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RXZhbHVhdGVNb2RlCiAqCiAqIFVzZWQgd2l0aCBJRGlyZWN0RHJhdzc6OlN0YXJ0TW9kZVRlc3QgdG8gdGVzdCB2aWRlbyBtb2Rlcy4KICogRXZhbHVhdGVNb2RlIGlzIHVzZWQgdG8gcGFzcyBvciBmYWlsIGEgbW9kZSwgYW5kIGNvbnRpbnVlIHdpdGggdGhlIG5leHQKICogbW9kZQogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRERFTV9NT0RFUEFTU0VEIG9yIERERU1fTU9ERUZBSUxFRAogKiAgVGltZW91dDogUmV0dXJucyB0aGUgYW1vdW50IG9mIHNlY29uZHMgbGVmdCBiZWZvcmUgdGhlIG1vZGUgd291bGQgaGF2ZQogKiAgICAgICAgICAgYmVlbiBmYWlsZWQgYXV0b21hdGljYWxseQogKgogKiBSZXR1cm5zOgogKiAgVGhpcyBpbXBsZW1lbnRhdGlvbiBhbHdheXMgRERfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0V2YWx1YXRlTW9kZShJRGlyZWN0RHJhdzcgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEICpUaW1lb3V0KQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglZCwlcCk6IFN0dWIhXG4iLCBUaGlzLCBGbGFncywgVGltZW91dCk7CgogICAgLyogV2hlbiBpbXBsZW1lbnRpbmcgdGhpcywgaW1wbGVtZW50IGl0IGluIFdpbmVEM0QgKi8KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkdldERldmljZUlkZW50aWZpZXIKICoKICogUmV0dXJucyB0aGUgZGV2aWNlIGlkZW50aWZpZXIsIHdoaWNoIGdpdmVzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkcml2ZXIKICogT3VyIGRldmljZSBpZGVudGlmaWVyIGlzIGRlZmluZWQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGlzIGZpbGUuCiAqCiAqIFBhcmFtczoKICogIEREREk6IEFkZHJlc3MgZm9yIHRoZSByZXR1cm5lZCBzdHJ1Y3R1cmUKICogIEZsYWdzOiBDYW4gYmUgRERHRElfR0VUSE9TVElERU5USUZJRVIKICoKICogUmV0dXJuczoKICogIE9uIHN1Y2Nlc3MgaXQgcmV0dXJucyBERF9PSwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBERERJIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldERldmljZUlkZW50aWZpZXIoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERERVZJQ0VJREVOVElGSUVSMiAqRERESSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCUwOHgpXG4iLCBUaGlzLCBERERJLCBGbGFncyk7CgogICAgaWYoIUREREkpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogVGhlIERER0RJX0dFVEhPU1RJREVOVElGSUVSIHJldHVybnMgdGhlIGluZm9ybWF0aW9uIGFib3V0IHRoZSAyRAogICAgICogaG9zdCBhZGFwdGVyLCBpZiB0aGVyZSdzIGEgc2Vjb25kYXJ5IDNEIGFkYXB0ZXIuIFRoaXMgZG9lc24ndCBhcHBseQogICAgICogdG8gYW55IG1vZGVybiBoYXJkd2FyZSwgbm9yIGlzIGl0IGludGVyZXN0aW5nIGZvciBXaW5lLCBzbyBpZ25vcmUgaXQKICAgICAqLwoKICAgICpERERJID0gZGV2aWNlaWRlbnRpZmllcjsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6R2V0U3VyZmFjZUZyb21EQwogKgogKiBSZXR1cm5zIHRoZSBTdXJmYWNlIGZvciBhIEdESSBkZXZpY2UgY29udGV4dCBoYW5kbGUuCiAqIElzIHRoaXMgcmVsYXRlZCB0byBJRGlyZWN0RHJhd1N1cmZhY2U6OkdldERDID8/PwogKgogKiBQYXJhbXM6CiAqICBoZGM6IGhkYyB0byByZXR1cm4gdGhlIHN1cmZhY2UgZm9yCiAqICBTdXJmYWNlOiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBzdXJmYWNlIHBvaW50ZXIgdG8KICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0dldFN1cmZhY2VGcm9tREMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSERDIGhkYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqKlN1cmZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVwLCVwKTogU3R1YiFcbiIsIFRoaXMsIGhkYywgU3VyZmFjZSk7CgogICAgLyogSW1wbGVtZW50YXRpb24gaWRlYSBpZiBuZWVkZWQ6IExvb3AgdGhyb3VnaCBhbGwgc3VyZmFjZXMgYW5kIGNvbXBhcmUKICAgICAqIHRoZWlyIGhkYyB3aXRoIGhkYy4gSW1wbGVtZW50IGl0IGluIFdpbmVEM0QhICovCiAgICByZXR1cm4gRERFUlJfTk9URk9VTkQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OlJlc3RvcmVBbGxTdXJmYWNlcwogKgogKiBDYWxscyB0aGUgcmVzdG9yZSBtZXRob2Qgb2YgYWxsIHN1cmZhY2VzCiAqCiAqIFBhcmFtczoKICoKICogUmV0dXJuczoKICogIEFsd2F5cyByZXR1cm5zIEREX09LIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1Jlc3RvcmVBbGxTdXJmYWNlcyhJRGlyZWN0RHJhdzcgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgRklYTUUoIiglcCk6IFN0dWJcbiIsIFRoaXMpOwoKICAgIC8qIFRoaXMgaXNuJ3QgaGFyZCB0byBpbXBsZW1lbnQ6IEVudW1lcmF0ZSBhbGwgV2luZUQzRCBzdXJmYWNlcywKICAgICAqIGdldCB0aGVpciBwYXJlbnQgYW5kIGNhbGwgdGhlaXIgcmVzdG9yZSBtZXRob2QuIERvIG5vdCBpbXBsZW1lbnQKICAgICAqIGl0IGluIFdpbmVEM0QsIGFzIHJlc3RvcmluZyBhIHN1cmZhY2UgbWVhbnMgcmUtY3JlYXRpbmcgdGhlCiAgICAgKiBXaW5lRDNERFN1cmZhY2UKICAgICAqLwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpTdGFydE1vZGVUZXN0CiAqCiAqIFRlc3RzIHRoZSBzcGVjaWZpZWQgdmlkZW8gbW9kZXMgdG8gdXBkYXRlIHRoZSBzeXN0ZW0gcmVnaXN0cnkgd2l0aAogKiByZWZyZXNoIHJhdGUgaW5mb3JtYXRpb24uIFN0YXJ0TW9kZVRlc3Qgc3RhcnRzIHRoZSBtb2RlIHRlc3QsCiAqIEV2YWx1YXRlTW9kZSBpcyB1c2VkIHRvIGZhaWwgb3IgcGFzcyBhIG1vZGUuIElmIEV2YWx1YXRlTW9kZQogKiBpc24ndCBjYWxsZWQgd2l0aGluIDE1IHNlY29uZHMsIHRoZSBtb2RlIGlzIGZhaWxlZCBhdXRvbWF0aWNhbGx5CiAqCiAqIEFzIHJlZnJlc2ggcmF0ZXMgYXJlIGhhbmRsZWQgYnkgdGhlIFggc2VydmVyLCBJIGRvbid0IHRoaW5rIHRoaXMKICogTWV0aG9kIGlzIGltcG9ydGFudAogKgogKiBQYXJhbXM6CiAqICBNb2RlczogQW4gYXJyYXkgb2YgbW9kZSBzcGVjaWZpY2F0aW9ucwogKiAgTnVtTW9kZXM6IFRoZSBudW1iZXIgb2YgbW9kZXMgaW4gTW9kZXMKICogIEZsYWdzOiBTb21lIGZsYWdzLi4uCiAqCiAqIFJldHVybnM6CiAqICBSZXR1cm5zIERERVJSX1RFU1RGSU5JU0hFRCBpZiBmbGFncyBjb250YWlucyBERFNNVF9JU1RFU1RSRVFVSVJFRCwKICogIGlmIG5vIG1vZGVzIGFyZSBwYXNzZWQsIERERVJSX0lOVkFMSURQQVJBTVMgaXMgcmV0dXJuZWQsCiAqICBvdGhlcndpc2UgRERfT0sKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1N0YXJ0TW9kZVRlc3QoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0laRSAqTW9kZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIE51bU1vZGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFdBUk4oIiglcCktPiglcCwgJWQsICV4KTogU2VtaS1TdHViLCBtb3N0IGxpa2VseSBoYXJtbGVzc1xuIiwgVGhpcywgTW9kZXMsIE51bU1vZGVzLCBGbGFncyk7CgogICAgLyogVGhpcyBsb29rcyBzYW5lICovCiAgICBpZiggKCFNb2RlcykgfHwgKE51bU1vZGVzID09IDApICkgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgLyogRERTTVRfSVNURVNUUkVRVUlSRUQgYXNrcyBpZiBhIG1vZGUgdGVzdCBpcyBuZWNlc3NhcnkuCiAgICAgKiBBcyBpdCBpcyBub3QsIERERVJSX1RFU1RGSU5JU0hFRCBpcyByZXR1cm5lZAogICAgICogKGhvcGVmdWxseSB0aGF0J3MgY29ycmVjdAogICAgICoKICAgIGlmKEZsYWdzICYgRERTTVRfSVNURVNUUkVRVUlSRUQpIHJldHVybiBEREVSUl9URVNURklOSVNIRUQ7CiAgICAgKiB3ZWxsLCB0aGF0IHZhbHVlIGRvZXNuJ3QgKHlldCkgZXhpc3QgaW4gdGhlIHdpbmUgaGVhZGVycywgc28gaWdub3JlIGl0CiAgICAgKi8KCiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVTdXJmYWNlc0NhbGxiYWNrCiAqCiAqIEVudW1lcmF0aW9uIGNhbGxiYWNrIGZvciBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcy4KICogSXQgcmUtcmVjcmVhdGVzIHRoZSBXaW5lRDNEU3VyZmFjZS4gSXQncyBwcmV0dHkgc3RyYWlnaHRmb3J3YXJkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX1JlY3JlYXRlU3VyZmFjZXNDYWxsYmFjayhJRGlyZWN0RHJhd1N1cmZhY2U3ICpzdXJmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpkZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkNvbnRleHQpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmZJbXBsID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VyZik7CiAgICBJRGlyZWN0RHJhd0ltcGwgKlRoaXMgPSBzdXJmSW1wbC0+ZGRyYXc7CiAgICBJVW5rbm93biAqUGFyZW50OwogICAgSVBhcmVudEltcGwgKnBhckltcGwgPSBOVUxMOwogICAgSVdpbmVEM0RTdXJmYWNlICp3aW5lRDNEU3VyZmFjZTsKICAgIEhSRVNVTFQgaHI7CiAgICB2b2lkICp0bXA7CgogICAgV0lORUQzRFNVUkZBQ0VfREVTQyAgICAgRGVzYzsKICAgIFdJTkVEM0RGT1JNQVQgICAgICAgICAgIEZvcm1hdDsKICAgIFdJTkVEM0RSRVNPVVJDRVRZUEUgICAgIFR5cGU7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICBVc2FnZTsKICAgIFdJTkVEM0RQT09MICAgICAgICAgICAgIFBvb2w7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICBTaXplOwoKICAgIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlVHlwZTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgIE11bHRpU2FtcGxlUXVhbGl0eTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgIFdpZHRoOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgSGVpZ2h0OwoKICAgIFRSQUNFKCIoJXApOiBFbnVtZXJhdGVkIFN1cmZhY2UgJXBcbiIsIFRoaXMsIHN1cmZJbXBsKTsKCiAgICAvKiBGb3IgdGhlIGVudW1lcmF0aW9uICovCiAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7CgogICAgaWYoc3VyZkltcGwtPkltcGxUeXBlID09IFRoaXMtPkltcGxUeXBlKSByZXR1cm4gRERFTlVNUkVUX09LOyAvKiBDb250aW51ZSAqLwoKICAgIC8qIEdldCB0aGUgb2JqZWN0cyAqLwogICAgd2luZUQzRFN1cmZhY2UgPSBzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KHdpbmVEM0RTdXJmYWNlLCAmUGFyZW50KTsKICAgIElVbmtub3duX1JlbGVhc2UoUGFyZW50KTsgLyogRm9yIHRoZSBnZXRQYXJlbnQgKi8KCiAgICAvKiBJcyB0aGUgcGFyZW50IGFuIElQYXJlbnQgaW50ZXJmYWNlPyAqLwogICAgaWYoSVVua25vd25fUXVlcnlJbnRlcmZhY2UoUGFyZW50LCAmSUlEX0lQYXJlbnQsICZ0bXApID09IFNfT0spCiAgICB7CiAgICAgICAgLyogSXQgaXMgYSBJUGFyZW50IGludGVyZmFjZSEgKi8KICAgICAgICBJVW5rbm93bl9SZWxlYXNlKFBhcmVudCk7IC8qIEZvciB0aGUgUXVlcnlJbnRlcmZhY2UgKi8KICAgICAgICBwYXJJbXBsID0gSUNPTV9PQkpFQ1QoSVBhcmVudEltcGwsIElQYXJlbnQsIFBhcmVudCk7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgcmVmZXJlbmNlIHRoZSBwYXJlbnQgaW50ZXJmYWNlIGlzIGhvbGRpbmcgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSh3aW5lRDNEU3VyZmFjZSk7CiAgICB9CgoKICAgIC8qIEdldCB0aGUgc3VyZmFjZSBwcm9wZXJ0aWVzICovCiAgICBEZXNjLkZvcm1hdCA9ICZGb3JtYXQ7CiAgICBEZXNjLlR5cGUgPSAmVHlwZTsKICAgIERlc2MuVXNhZ2UgPSAmVXNhZ2U7CiAgICBEZXNjLlBvb2wgPSAmUG9vbDsKICAgIERlc2MuU2l6ZSA9ICZTaXplOwogICAgRGVzYy5NdWx0aVNhbXBsZVR5cGUgPSAmTXVsdGlTYW1wbGVUeXBlOwogICAgRGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSAmTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgRGVzYy5XaWR0aCA9ICZXaWR0aDsKICAgIERlc2MuSGVpZ2h0ID0gJkhlaWdodDsKCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHdpbmVEM0RTdXJmYWNlLCAmRGVzYyk7CiAgICBpZihociAhPSBEM0RfT0spIHJldHVybiBocjsKCiAgICAvKiBDcmVhdGUgdGhlIG5ldyBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXaWR0aCwgSGVpZ2h0LCBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBEaXNjYXJkICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cmZJbXBsLT5taXBtYXBfbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN1cmZJbXBsLT5XaW5lRDNEU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTXVsdGlTYW1wbGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE11bHRpU2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFNoYXJlZEhhbmRsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQYXJlbnQpOwoKICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICByZXR1cm4gaHI7CgogICAgLyogVXBkYXRlIHRoZSBJUGFyZW50IGlmIGl0IGV4aXN0cyAqLwogICAgaWYocGFySW1wbCkKICAgIHsKICAgICAgICBwYXJJbXBsLT5jaGlsZCA9IChJVW5rbm93biAqKSBzdXJmSW1wbC0+V2luZUQzRFN1cmZhY2U7CiAgICAgICAgLyogQWRkIGEgcmVmZXJlbmNlIGZvciB0aGUgSVBhcmVudCAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoc3VyZkltcGwtPldpbmVEM0RTdXJmYWNlKTsKICAgIH0KICAgIC8qIFRPRE86IENvcHkgdGhlIHN1cmZhY2UgY29udGVudCwgZXhjZXB0IGZvciByZW5kZXIgdGFyZ2V0cyAqLwoKICAgIGlmKElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHdpbmVEM0RTdXJmYWNlKSA9PSAwKQogICAgICAgIFRSQUNFKCJTdXJmYWNlIHJlbGVhc2VkIHN1Y2Nlc3NmdWwsIG5leHQgc3VyZmFjZVxuIik7CiAgICBlbHNlCiAgICAgICAgRVJSKCJTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBvbGQgV2luZUQzRFN1cmZhY2VcbiIpOwoKICAgIHN1cmZJbXBsLT5JbXBsVHlwZSA9IFRoaXMtPkltcGxUeXBlOwoKICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcwogKgogKiBBIGZ1bmN0aW9uLCB0aGF0IGNvbnZlcnRzIGFsbCB3aW5lRDNEU3VyZmFjZXMgdG8gdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiB0eXBlCiAqIEl0IGVudW1lcmF0ZXMgYWxsIHN1cmZhY2VzIHdpdGggSVdpbmVEM0REZXZpY2U6OkVudW1TdXJmYWNlcywgY3JlYXRlcyBhCiAqIG5ldyBXaW5lRDNEU3VyZmFjZSwgY29waWVzIHRoZSBjb250ZW50IGFuZCByZWxlYXNlcyB0aGUgb2xkIHN1cmZhY2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcyhJRGlyZWN0RHJhd0ltcGwgKlRoaXMpCnsKICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICBUUkFDRSgiKCVwKTogU3dpdGNoIHRvIGltcGxlbWVudGF0aW9uICVkXG4iLCBUaGlzLCBUaGlzLT5JbXBsVHlwZSk7CgogICAgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wgJiYgVGhpcy0+ZDNkX2luaXRpYWxpemVkKQogICAgewogICAgICAgIC8qIFNob3VsZCBoYXBwZW4gYWxtb3N0IG5ldmVyICovCiAgICAgICAgRklYTUUoIiglcCkgU3dpdGNoaW5nIHRvIG5vbi1vcGVuZ2wgc3VyZmFjZXMgd2l0aCBkM2Qgc3RhcnRlZC4gSXMgdGhpcyBhIGJ1Zz9cbiIsIFRoaXMpOwogICAgICAgIC8qIFNodXRkb3duIGQzZCAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX1VuaW5pdDNEKFRoaXMtPndpbmVEM0REZXZpY2UsIEQzRDdDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZSwgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4pOwogICAgfQogICAgLyogQ29udHJhcnk6IEQzRCBzdGFydGluZyBpcyBoYW5kbGVkIGJ5IHRoZSBjYWxsZXIsIGJlY2F1c2UgaXQga25vd3MgdGhlIHJlbmRlciB0YXJnZXQgKi8KCiAgICBtZW1zZXQoJmRlc2MsIDAsIHNpemVvZihkZXNjKSk7CiAgICBkZXNjLmR3U2l6ZSA9IHNpemVvZihkZXNjKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXc3X0VudW1TdXJmYWNlcyhJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbF9SZWNyZWF0ZVN1cmZhY2VzQ2FsbGJhY2spOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZVN1cmZhY2UKICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIElEaXJlY3QzRERldmljZV9DcmVhdGVUZXh0dXJlLiBJdCBzZWFyY2hlcyBmb3IgdGhlCiAqIGNvcnJlY3QgbWlwbWFwIHN1YmxldmVsLCBhbmQgcmV0dXJucyBpdCB0byBXaW5lRDNELgogKiBUaGUgc3VyZmFjZXMgYXJlIGNyZWF0ZWQgYWxyZWFkeSBieSBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgV2l0aCwgSGVpZ2h0OiBXaXRoIGFuZCBoZWlnaHQgb2YgdGhlIHN1cmZhY2UKICogIEZvcm1hdDogVGhlIHJlcXVlc3RlZCBmb3JtYXQKICogIFVzYWdlLCBQb29sOiBEM0RVU0FHRSBhbmQgRDNEUE9PTCBvZiB0aGUgc3VyZmFjZQogKiAgbGV2ZWw6IFRoZSBtaXBtYXAgbGV2ZWwKICogIFN1cmZhY2U6IFBvaW50ZXIgdG8gcGFzcyB0aGUgY3JlYXRlZCBzdXJmYWNlIGJhY2sgYXQKICogIFNoYXJlZEhhbmRsZTogTlVMTAogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVTdXJmYWNlKElVbmtub3duICpkZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwU3VwZXJpb3IsCiAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RQT09MIFBvb2wsIFVJTlQgbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqKlN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSAqU2hhcmVkSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmYgPSBUaGlzLT50ZXhfcm9vdDsKICAgIGludCBpOwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrLiBzdXJmPSVwXG4iLCBkZXZpY2UsIHN1cmYpOwoKICAgIC8qIEZpbmQgdGhlIHdhbnRlZCBtaXBtYXAuIFRoZXJlIGFyZSBlbm91Z2ggbWlwbWFwcyBpbiB0aGUgY2hhaW4gKi8KICAgIGZvcihpID0gMDsgaSA8IGxldmVsOyBpKyspCiAgICAgICAgc3VyZiA9IHN1cmYtPm5leHRfY29tcGxleDsKCiAgICAvKiBSZXR1cm4gdGhlIHN1cmZhY2UgKi8KICAgICpTdXJmYWNlID0gc3VyZi0+V2luZUQzRFN1cmZhY2U7CgogICAgVFJBQ0UoIlJldHVybmluZyB3aW5lRDNEU3VyZmFjZSAlcCwgaXQgYmVsb25ncyB0byBzdXJmYWNlICVwXG4iLCAqU3VyZmFjZSwgc3VyZik7CiAgICByZXR1cm4gRDNEX09LOwp9CgpVTE9ORyBXSU5BUEkgRDNEN0NCX0Rlc3Ryb3lTd2FwQ2hhaW4oSVdpbmVEM0RTd2FwQ2hhaW4gKnBTd2FwQ2hhaW4pIHsKICAgIElVbmtub3duKiBzd2FwQ2hhaW5QYXJlbnQ7CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIHBTd2FwQ2hhaW4pOwoKICAgIElXaW5lRDNEU3dhcENoYWluX0dldFBhcmVudChwU3dhcENoYWluLCAmc3dhcENoYWluUGFyZW50KTsKICAgIElVbmtub3duX1JlbGVhc2Uoc3dhcENoYWluUGFyZW50KTsKICAgIHJldHVybiBJVW5rbm93bl9SZWxlYXNlKHN3YXBDaGFpblBhcmVudCk7Cn0KClVMT05HIFdJTkFQSSBEM0Q3Q0JfRGVzdHJveURlcHRoU3RlbmNpbFN1cmZhY2UoSVdpbmVEM0RTdXJmYWNlICpwU3VyZmFjZSkgewogICAgSVVua25vd24qIHN1cmZhY2VQYXJlbnQ7CiAgICBUUkFDRSgiKCVwKSBjYWxsIGJhY2tcbiIsIHBTdXJmYWNlKTsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KHBTdXJmYWNlLCAoSVVua25vd24gKiopICZzdXJmYWNlUGFyZW50KTsKICAgIElVbmtub3duX1JlbGVhc2Uoc3VyZmFjZVBhcmVudCk7CiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZShzdXJmYWNlUGFyZW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlCiAqCiAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciBJRGlyZWN0RHJhdzc6OkNyZWF0ZVN1cmZhY2UuIEl0IGNyZWF0ZXMgYSBuZXcgc3VyZmFjZQogKiB3aXRoIHRoZSBwYXNzZWQgcGFyYW1ldGVycy4KICoKICogUGFyYW1zOgogKiAgRERTRDogRGVzY3JpcHRpb24gb2YgdGhlIHN1cmZhY2UgdG8gY3JlYXRlCiAqICBTdXJmOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBhdAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShJRGlyZWN0RHJhd0ltcGwgKlRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpwRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKnBwU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBsZXZlbCkKewogICAgSFJFU1VMVCBocjsKICAgIFVJTlQgV2lkdGggPSAwLCBIZWlnaHQgPSAwOwogICAgV0lORUQzREZPUk1BVCBGb3JtYXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICBXSU5FRDNEUkVTT1VSQ0VUWVBFIFJlc1R5cGUgPSBXSU5FRDNEUlRZUEVfU1VSRkFDRTsKICAgIERXT1JEIFVzYWdlID0gMDsKICAgIFdJTkVEM0RTVVJGVFlQRSBJbXBsVHlwZSA9IFRoaXMtPkltcGxUeXBlOwogICAgV0lORUQzRFNVUkZBQ0VfREVTQyBEZXNjOwogICAgSVVua25vd24gKlBhcmVudDsKICAgIElQYXJlbnRJbXBsICpwYXJJbXBsID0gTlVMTDsKICAgIFdJTkVEM0RQT09MIFBvb2wgPSBXSU5FRDNEUE9PTF9ERUZBVUxUOwoKICAgIC8qIER1bW1pZXMgZm9yIEdldERlc2MgKi8KICAgIFdJTkVEM0RQT09MIGR1bW15X2QzZHBvb2w7CiAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBkdW1teV9tc3Q7CiAgICBVSU5UIGR1bW15X3VpbnQ7CiAgICBEV09SRCBkdW1teV9kd29yZDsKCiAgICBpZiAoVFJBQ0VfT04oZGRyYXcpKQogICAgewogICAgICAgIFRSQUNFKCIgKCVwKSBSZXF1ZXN0aW5nIHN1cmZhY2UgZGVzYyA6XG4iLCBUaGlzKTsKICAgICAgICBERFJBV19kdW1wX3N1cmZhY2VfZGVzYyhwRERTRCk7CiAgICB9CgogICAgLyogU2VsZWN0IHRoZSBzdXJmYWNlIHR5cGUsIGlmIGl0IHdhc24ndCBjaG9vc2VuIHlldCAqLwogICAgaWYoSW1wbFR5cGUgPT0gU1VSRkFDRV9VTktOT1dOKQogICAgewogICAgICAgIC8qIFVzZSBHTCBTdXJmYWNlcyBpZiBhIEQzRERFVklDRSBTdXJmYWNlIGlzIHJlcXVlc3RlZCAqLwogICAgICAgIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfM0RERVZJQ0UpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBDaG9vc2luZyBHTCBzdXJmYWNlcyBiZWNhdXNlIGEgM0RERVZJQ0UgU3VyZmFjZSB3YXMgcmVxdWVzdGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgSW1wbFR5cGUgPSBTVVJGQUNFX09QRU5HTDsKICAgICAgICB9CgogICAgICAgIC8qIE90aGVyd2lzZSB1c2UgR0RJIHN1cmZhY2VzIGZvciBub3cgKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBDaG9vc2luZyBHREkgc3VyZmFjZXMgZm9yIDJEIHJlbmRlcmluZ1xuIiwgVGhpcyk7CiAgICAgICAgICAgIEltcGxUeXBlID0gU1VSRkFDRV9HREk7CiAgICAgICAgfQoKICAgICAgICAvKiBQb2xpY3kgaWYgYWxsIHN1cmZhY2UgaW1wbGVtZW50YXRpb25zIGFyZSBhdmFpbGFibGU6CiAgICAgICAgICogRmlyc3QsIGNoZWNrIGlmIGEgZGVmYXVsdCB0eXBlIHdhcyBzZXQgd2l0aCB3aW5lY2ZnLiBJZiBub3QsCiAgICAgICAgICogdHJ5IFhyZW5kZXIgc3VyZmFjZXMsIGFuZCB1c2UgdGhlbSBpZiB0aGV5IHdvcmsuIE5leHQsIGNoZWNrIGlmCiAgICAgICAgICogYWNjZWxlcmF0ZWQgT3BlbkdMIGlzIGF2YWlsYWJsZSwgYW5kIHVzZSBHTCBzdXJmYWNlcyBpbiB0aGlzCiAgICAgICAgICogY2FzZS4gSWYgYWxsIGVsc2UgZmFpbHMsIHVzZSBHREkgc3VyZmFjZXMuIElmIGEgM0RERVZJQ0Ugc3VyZmFjZQogICAgICAgICAqIHdhcyBjcmVhdGVkLCBhbHdheXMgdXNlIE9wZW5HTCBzdXJmYWNlcy4KICAgICAgICAgKgogICAgICAgICAqIChOb3RlOiBYcmVuZGVyIHN1cmZhY2VzIGFyZSBub3QgaW1wbGVtZW50ZWQgZm9yIG5vdywgdGhlCiAgICAgICAgICogdW5hY2NlbGVyYXRlZCBpbXBsZW1lbnRhdGlvbiB1c2VzIEdESSB0byByZW5kZXIgaW4gU29mdHdhcmUpCiAgICAgICAgICovCgogICAgICAgIC8qIFN0b3JlIHRoZSB0eXBlLiBJZiBpdCBuZWVkcyB0byBiZSBjaGFuZ2VkLCBhbGwgV2luZUQzRFN1cmZhY2VzIGhhdmUgdG8KICAgICAgICAgKiBiZSByZS1jcmVhdGVkLiBUaGlzIGNvdWxkIGJlIGRvbmUgd2l0aCBJRGlyZWN0RHJhd1N1cmZhY2U3OjpSZXN0b3JlCiAgICAgICAgICovCiAgICAgICAgVGhpcy0+SW1wbFR5cGUgPSBJbXBsVHlwZTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAgaWYoKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfM0RERVZJQ0UgKSAmJiAKICAgICAgICAgICAgKFRoaXMtPkltcGxUeXBlICE9IFNVUkZBQ0VfT1BFTkdMICkgJiYgRGVmYXVsdFN1cmZhY2VUeXBlID09IFNVUkZBQ0VfVU5LTk9XTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIFdlIGhhdmUgdG8gY2hhbmdlIHRvIE9wZW5HTCwKICAgICAgICAgICAgICogYW5kIHJlLWNyZWF0ZSBhbGwgV2luZUQzRFN1cmZhY2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJbXBsVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICBUaGlzLT5JbXBsVHlwZSA9IEltcGxUeXBlOwogICAgICAgICAgICBUUkFDRSgiKCVwKSBSZS1jcmVhdGluZyBhbGwgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGxfUmVjcmVhdGVBbGxTdXJmYWNlcyhUaGlzKTsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgRG9uZSByZWNyZWF0aW5nIGFsbCBzdXJmYWNlc1xuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoVGhpcy0+SW1wbFR5cGUgIT0gU1VSRkFDRV9PUEVOR0wpCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJUaGUgYXBwbGljYXRpb24gcmVxdWVzdHMgYSAzRCBjYXBhYmxlIHN1cmZhY2UsIGJ1dCBhIG5vbi1vcGVuZ2wgc3VyZmFjZSB3YXMgc2V0IGluIHRoZSByZWdpc3RyeVxuIik7CiAgICAgICAgICAgIC8qIERvIG5vdCBmYWlsIHN1cmZhY2UgY3JlYXRpb24sIG9ubHkgZmFpbCAzRCBkZXZpY2UgY3JlYXRpb24gKi8KICAgICAgICB9CiAgICB9CgogICAgLyogR2V0IHRoZSBjb3JyZWN0IHdpbmVkM2QgdXNhZ2UgKi8KICAgIGlmIChwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiAoRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfQkFDS0JVRkZFUiAgICAgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTXzNEREVWSUNFICAgICAgICkgKQogICAgewogICAgICAgIFVzYWdlIHw9IFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQ7CgogICAgICAgIHBERFNELT5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX1ZJREVPTUVNT1JZIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19WSVNJQkxFICAgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfTE9DQUxWSURNRU07CiAgICB9CiAgICBpZiAocEREU0QtPmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVXNhZ2UgfD0gV0lORUQzRFVTQUdFX09WRVJMQVk7CiAgICB9CiAgICBpZihUaGlzLT5kZXB0aHN0ZW5jaWwpCiAgICB7CiAgICAgICAgLyogVGhlIGRlcHRoIHN0ZW5jaWwgY3JlYXRpb24gY2FsbGJhY2sgc2V0cyB0aGlzIGZsYWcuCiAgICAgICAgICogU2V0IHRoZSBXaW5lRDNEIHVzYWdlIHRvIGxldCBpdCBrbm93IHRoYXQgaXQncyBhIGRlcHRoCiAgICAgICAgICogU3RlbmNpbCBzdXJmYWNlLgogICAgICAgICAqLwogICAgICAgIFVzYWdlIHw9IFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUw7CiAgICB9CiAgICBpZihwRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1NZU1RFTU1FTU9SWSkKICAgIHsKICAgICAgICBQb29sID0gV0lORUQzRFBPT0xfU1lTVEVNTUVNOwogICAgfQoKICAgIEZvcm1hdCA9IFBpeGVsRm9ybWF0X0REMldpbmVEM0QoJnBERFNELT51NC5kZHBmUGl4ZWxGb3JtYXQpOwogICAgaWYoRm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikKICAgIHsKICAgICAgICBFUlIoIlVuc3VwcG9ydGVkIC8gVW5rbm93biBwaXhlbGZvcm1hdFxuIik7CiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQSVhFTEZPUk1BVDsKICAgIH0KCiAgICAvKiBDcmVhdGUgdGhlIFN1cmZhY2Ugb2JqZWN0ICovCiAgICAqcHBTdXJmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRGlyZWN0RHJhd1N1cmZhY2VJbXBsKSk7CiAgICBpZighKnBwU3VyZikKICAgIHsKICAgICAgICBFUlIoIiglcCkgRXJyb3IgYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIERERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICB9CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTcsIElEaXJlY3REcmF3U3VyZmFjZTdfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3U3VyZmFjZTMsIElEaXJlY3REcmF3U3VyZmFjZTNfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKCpwcFN1cmYsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbF9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoKnBwU3VyZiwgSURpcmVjdDNEVGV4dHVyZTIsIElEaXJlY3QzRFRleHR1cmUyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0M0RUZXh0dXJlLCBJRGlyZWN0M0RUZXh0dXJlMV9WdGJsKTsKICAgICgqcHBTdXJmKS0+cmVmID0gMTsKICAgICgqcHBTdXJmKS0+dmVyc2lvbiA9IDc7CiAgICAoKnBwU3VyZiktPmRkcmF3ID0gVGhpczsKICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3U2l6ZSA9IHNpemVvZihERFNVUkZBQ0VERVNDMik7CiAgICAoKnBwU3VyZiktPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREUElYRUxGT1JNQVQpOwogICAgRERfU1RSVUNUX0NPUFlfQllTSVpFKCYoKnBwU3VyZiktPnN1cmZhY2VfZGVzYywgcEREU0QpOwoKICAgIC8qIFN1cmZhY2UgYXR0YWNobWVudHMgKi8KICAgICgqcHBTdXJmKS0+bmV4dF9hdHRhY2hlZCA9IE5VTEw7CiAgICAoKnBwU3VyZiktPmZpcnN0X2F0dGFjaGVkID0gKnBwU3VyZjsKCiAgICAoKnBwU3VyZiktPm5leHRfY29tcGxleCA9IE5VTEw7CiAgICAoKnBwU3VyZiktPmZpcnN0X2NvbXBsZXggPSAqcHBTdXJmOwoKICAgIC8qIE5lZWRlZCB0byByZS1jcmVhdGUgdGhlIHN1cmZhY2Ugb24gYW4gaW1wbGVtZW50YXRpb24gY2hhbmdlICovCiAgICAoKnBwU3VyZiktPkltcGxUeXBlID0gSW1wbFR5cGU7CgogICAgLyogRm9yIEQzRERldmljZSBjcmVhdGlvbiAqLwogICAgKCpwcFN1cmYpLT5pc1JlbmRlclRhcmdldCA9IEZBTFNFOwoKICAgIC8qIEEgdHJhY2UgbWVzc2FnZSBmb3IgZGVidWdnaW5nICovCiAgICBUUkFDRSgiKCVwKSBDcmVhdGVkIElEaXJlY3REcmF3U3VyZmFjZSBpbXBsZW1lbnRhdGlvbiBzdHJ1Y3R1cmUgYXQgJXBcbiIsIFRoaXMsICpwcFN1cmYpOwoKICAgIGlmKHBERFNELT5kZHNDYXBzLmR3Q2FwcyAmICggRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfVEVYVFVSRSB8IEREU0NBUFNfM0RERVZJQ0UpICkKICAgIHsKICAgICAgICAvKiBSZW5kZXIgdGFyZ2V0cyBhbmQgdGV4dHVyZXMgbmVlZCBhIElQYXJlbnQgaW50ZXJmYWNlLAogICAgICAgICAqIGJlY2F1c2UgV2luZUQzRCB3aWxsIGRlc3Ryb3kgdGhlbSB3aGVuIHRoZSBzd2FwY2hhaW4KICAgICAgICAgKiBpcyByZWxlYXNlZAogICAgICAgICAqLwogICAgICAgIHBhckltcGwgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKElQYXJlbnRJbXBsKSk7CiAgICAgICAgaWYoIXBhckltcGwpCiAgICAgICAgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBhbGxvY2F0aW5nIG1lbW9yeSBmb3IgYSBJUGFyZW50IGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICAgICAgcmV0dXJuIERERVJSX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgICAgICBwYXJJbXBsLT5yZWYgPSAxOwogICAgICAgIElDT01fSU5JVF9JTlRFUkZBQ0UocGFySW1wbCwgSVBhcmVudCwgSVBhcmVudF9WdGJsKTsKICAgICAgICBQYXJlbnQgPSAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UocGFySW1wbCwgSVBhcmVudCk7CiAgICAgICAgVFJBQ0UoIlVzaW5nIElQYXJlbnQgaW50ZXJmYWNlICVwIGFzIHBhcmVudFxuIiwgcGFySW1wbCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogVXNlIHRoZSBzdXJmYWNlIGFzIHBhcmVudCAqLwogICAgICAgIFBhcmVudCA9IChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRSgqcHBTdXJmLCBJRGlyZWN0RHJhd1N1cmZhY2U3KTsKICAgICAgICBUUkFDRSgiVXNpbmcgU3VyZmFjZSBpbnRlcmZhY2UgJXAgYXMgcGFyZW50XG4iLCAqcHBTdXJmKTsKICAgIH0KCiAgICAvKiBOb3cgY3JlYXRlIHRoZSBXaW5lRDNEIFN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlU3VyZmFjZShUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBERFNELT5kd1dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBERFNELT5kd0hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBEaXNjYXJkICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlc1R5cGUsIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRE1VTFRJU0FNUExFX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBNdWx0aVNhbXBsZVF1YWxpdHkgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBTaGFyZWRIYW5kbGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW1wbFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUGFyZW50KTsKCiAgICBpZihociAhPSBEM0RfT0spCiAgICB7CiAgICAgICAgRVJSKCJJV2luZUQzRERldmljZTo6Q3JlYXRlU3VyZmFjZSBmYWlsZWQuIGhyID0gJTA4eFxuIiwgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBTZXQgdGhlIGNoaWxkIG9mIHRoZSBwYXJlbnQgaW1wbGVtZW50YXRpb24gaWYgaXQgZXhpc3RzICovCiAgICBpZihwYXJJbXBsKQogICAgewogICAgICAgIHBhckltcGwtPmNoaWxkID0gKElVbmtub3duICopICgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2U7CiAgICAgICAgLyogVGhlIElQYXJlbnQgcmVsZWFzZXMgdGhlIFdpbmVEM0RTdXJmYWNlLCBhbmQKICAgICAgICAgKiB0aGUgZGRyYXcgc3VyZmFjZSBkb2VzIHRoYXQgdG9vLiBIb2xkIGEgcmVmZXJlbmNlCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZigoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlKTsKICAgIH0KCiAgICAvKiBJbmNyZWFzZSB0aGUgc3VyZmFjZSBjb3VudGVyLCBhbmQgYXR0YWNoIHRoZSBzdXJmYWNlICovCiAgICBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+c3VyZmFjZXMpOwogICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+c3VyZmFjZV9saXN0LCAmKCpwcFN1cmYpLT5zdXJmYWNlX2xpc3RfZW50cnkpOwoKICAgIC8qIEhlcmUgd2UgY291bGQgc3RvcmUgYWxsIGNyZWF0ZWQgc3VyZmFjZXMgaW4gdGhlIERpcmVjdERyYXdJbXBsIHN0cnVjdHVyZSwKICAgICAqIEJ1dCB0aGlzIGNvdWxkIGFsc28gYmUgZGVsZWdhdGVkIHRvIFdpbmVERHJhdywgYXMgaXQga2VlcHMgdHJhY2sgb2YgYWxsIGl0cwogICAgICogcmVzb3VyY2VzLiBOb3QgaW1wbGVtZW50ZWQgZm9yIG5vdywgYXMgdGhlcmUgYXJlIG1vcmUgaW1wb3J0YW50IHRoaW5ncyA7KQogICAgICovCgogICAgLyogR2V0IHRoZSBwaXhlbCBmb3JtYXQgb2YgdGhlIFdpbmVEM0RTdXJmYWNlIGFuZCBzdG9yZSBpdC4KICAgICAqIERvbid0IHVzZSB0aGUgRm9ybWF0IGNob29zZW4gYWJvdmUsIFdpbmVEM0QgbWlnaHQgaGF2ZQogICAgICogY2hhbmdlZCBpdAogICAgICovCiAgICBEZXNjLkZvcm1hdCA9ICZGb3JtYXQ7CiAgICBEZXNjLlR5cGUgPSAmUmVzVHlwZTsKICAgIERlc2MuVXNhZ2UgPSAmVXNhZ2U7CiAgICBEZXNjLlBvb2wgPSAmZHVtbXlfZDNkcG9vbDsKICAgIERlc2MuU2l6ZSA9ICZkdW1teV91aW50OwogICAgRGVzYy5NdWx0aVNhbXBsZVR5cGUgPSAmZHVtbXlfbXN0OwogICAgRGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSAmZHVtbXlfZHdvcmQ7CiAgICBEZXNjLldpZHRoID0gJldpZHRoOwogICAgRGVzYy5IZWlnaHQgPSAmSGVpZ2h0OwoKICAgICgqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgfD0gRERTRF9QSVhFTEZPUk1BVDsKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERlc2MoKCpwcFN1cmYpLT5XaW5lRDNEU3VyZmFjZSwgJkRlc2MpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0RTdXJmYWNlOjpHZXREZXNjIGZhaWxlZFxuIik7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKCAoSURpcmVjdERyYXdTdXJmYWNlNyAqKSAqcHBTdXJmKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoRm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikKICAgIHsKICAgICAgICBGSVhNRSgiSVdpbmVEM0RTdXJmYWNlOjpHZXREZXNjIHJldHVybmVkIFdJTkVEM0RGTVRfVU5LTk9XTlxuIik7CiAgICB9CiAgICBQaXhlbEZvcm1hdF9XaW5lRDNEdG9ERCggJigqcHBTdXJmKS0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdCwgRm9ybWF0KTsKCiAgICAvKiBBbm5vIDE2MDIgc3RvcmVzIHRoZSBwaXRjaCByaWdodCBhZnRlciBzdXJmYWNlIGNyZWF0aW9uLCBzbyBtYWtlIHN1cmUgaXQncyB0aGVyZS4KICAgICAqIEkgY2FuJ3QgTG9ja1JlY3QoKSB0aGUgc3VyZmFjZSBoZXJlIGJlY2F1c2UgaWYgT3BlbkdMIHN1cmZhY2VzIGFyZSBpbiB1c2UsIHRoZQogICAgICogV2luZUQzRERldmljZSBtaWdodCBub3QgYmUgdXNlYWJsZSBmb3IgM0QgeWV0LCBzbyBhbiBleHRyYSBtZXRob2Qgd2FzIGNyZWF0ZWQKICAgICAqLwogICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MuZHdGbGFncyB8PSBERFNEX1BJVENIOwogICAgKCpwcFN1cmYpLT5zdXJmYWNlX2Rlc2MudTEubFBpdGNoID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UpOwoKICAgIC8qIEFwcGxpY2F0aW9uIHBhc3NlZCBhIGNvbG9yIGtleT8gU2V0IGl0ISAqLwogICAgaWYocEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLREVTVE9WRVJMQVkpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9ERVNUT1ZFUkxBWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBERFNELT51My5kZGNrQ0tEZXN0T3ZlcmxheSk7CiAgICB9CiAgICBpZihwRERTRC0+ZHdGbGFncyAmIEREU0RfQ0tERVNUQkxUKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfREVTVEJMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBERFNELT5kZGNrQ0tEZXN0Qmx0KTsKICAgIH0KICAgIGlmKHBERFNELT5kd0ZsYWdzICYgRERTRF9DS1NSQ09WRVJMQVkpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbG9yS2V5KCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0tFWV9TUkNPVkVSTEFZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcEREU0QtPmRkY2tDS1NyY092ZXJsYXkpOwogICAgfQogICAgaWYocEREU0QtPmR3RmxhZ3MgJiBERFNEX0NLU1JDQkxUKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleSgoKnBwU3VyZiktPldpbmVEM0RTdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERENLRVlfU1JDQkxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcEREU0QtPmRkY2tDS1NyY0JsdCk7CiAgICB9CiAgICBpZiAoIHBERFNELT5kd0ZsYWdzICYgRERTRF9MUFNVUkZBQ0UpCiAgICB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKCgqcHBTdXJmKS0+V2luZUQzRFN1cmZhY2UsIHBERFNELT5scFN1cmZhY2UpOwogICAgICAgIGlmKGhyICE9IFdJTkVEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICAvKiBObyBuZWVkIGZvciBhIHRyYWNlIGhlcmUsIHdpbmVkM2QgZG9lcyB0aGF0IGZvciB1cyAqLwogICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoKCpwcFN1cmYpLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDcmVhdGVTdXJmYWNlCiAqCiAqIENyZWF0ZXMgYSBuZXcgSURpcmVjdERyYXdTdXJmYWNlIG9iamVjdCBhbmQgcmV0dXJucyBpdHMgaW50ZXJmYWNlLgogKgogKiBUaGUgc3VyZmFjZSBjb25uZWN0aW9ucyB3aXRoIHdpbmVkM2QgYXJlIGEgYml0IHRyaWNreS4gQmFzaWNhbGx5IGl0IHdvcmtzCiAqIGxpa2UgdGhpczoKICoKICogfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgICAgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18CiAqIHwgRERyYXcgc3VyZmFjZSAgICAgICAgICB8ICAgICAgICAgICAgICAgfCBXaW5lRDNEU3VyZmFjZSAgfAogKiB8ICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgV2luZUQzRFN1cmZhY2UgIHwtLS0tLS0tLS0tLS0tLT58ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgIENoaWxkICAgICAgICAgICB8PC0tLS0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfAogKiB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgIHwtLS0tLS0tLS0tLS0tLS0tLXwKICoKICogVGhlIEREcmF3IHN1cmZhY2UgaXMgdGhlIHBhcmVudCBvZiB0aGUgd2luZWQzZCBzdXJmYWNlLCBhbmQgaXQgcmVsZWFzZXMKICogdGhlIFdpbmVEM0RTdXJmYWNlIHdoZW4gdGhlIGRkcmF3IHN1cmZhY2UgaXMgZGVzdHJveWVkLgogKgogKiBIb3dldmVyLCBmb3IgYWxsIHN1cmZhY2VzIHdoaWNoIGNhbiBiZSBpbiBhIGNvbnRhaW5lciBpbiBXaW5lRDNELAogKiB3ZSBoYXZlIHRvIGRvIHRoaXMuIFRoZXNlIHN1cmZhY2VzIGFyZSB1c3VzYWxseSBjb21wbGV4IHN1cmZhY2VzLAogKiBzbyB0aGlzIGNvbmNlcm5zIHByaW1hcnkgc3VyZmFjZXMgd2l0aCBhIGZyb250IGFuZCBhIGJhY2sgYnVmZmVyLAogKiBhbmQgdGV4dHVyZXMuCiAqCiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfAogKiB8IEREcmF3IHN1cmZhY2UgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgQ29udGFpbnRlciAgICAgIHwKICogfCAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICB8CiAqIHwgICAgICAgICAgICAgICAgICBDaGlsZCB8PC0tLS0tLS0tLS0tLS0+fCBQYXJlbnQgICAgICAgICAgfAogKiB8ICAgICAgICAgICAgICAgIFRleHR1cmUgfDwtLS0tLS0tLS0tLS0tPnwgICAgICAgICAgICAgICAgIHwKICogfCAgICAgICAgIFdpbmVEM0RTdXJmYWNlIHw8LS0tLXwgICAgICAgICB8ICAgICAgICAgIExldmVscyB8PC0tfAogKiB8IENvbXBsZXggY29ubmVjdGlvbiAgICAgfCAgICAgfCAgICAgICAgIHwgICAgICAgICAgICAgICAgIHwgICB8CiAqIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18ICAgICB8ICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIF4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgfCAgICB8IElQYXJlbnQgICAgICAgICAgfCAgICAgfC0tLS0tLS0tPnwgV2luZUQzRFN1cmZhY2UgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgIENoaWxkIHw8LS0tLS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8ICAgfAogKiAgfCAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgIHwgICAgICAgQ29udGFpbmVyIHw8LS18CiAqICB8ICAgIHwtLS0tLS0tLS0tLS0tLS0tLS18ICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCBERHJhdyBzdXJmYWNlIDIgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8ICAgICAgICAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfDwtPnwgQ29tcGxleCByb290ICAgQ2hpbGQgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgfCAgICAgICAgICAgICAgVGV4dHVyZSB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICB8ICAgICAgIFdpbmVEM0RTdXJmYWNlIHw8LS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICB8CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKICogIHwgICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgICAgIHwgICAgICB8LS0tLS0tLS0tLS0tLS0tLS18ICAgfAogKiAgfCAgICB8IElQYXJlbnQgICAgICAgICAgICAgfCAgICAgfC0tLS0tPnwgV2luZUQzRFN1cmZhY2UgIHwgICB8CiAqICB8ICAgIHwgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgfCAgIHwKICogIHwgICAgfCAgICAgICAgICAgICAgIENoaWxkIHw8LS0tLS0tLS0tLT58IFBhcmVudCAgICAgICAgICB8ICAgfAogKiAgfCAgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgICAgICAgICAgIHwgICAgICAgQ29udGFpbmVyIHw8LS18CiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tfCAgIHwKICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAogKiAgfCAgICAgICAgICAgICAtLS1Nb3JlIHN1cmZhY2VzIGNhbiBmb2xsb3ctLS0gICAgICAgICAgICAgICAgICB8CiAqCiAqIFRoZSByZWFzb24gaXMgdGhhdCB0aGUgSVdpbmVEM0RTd2FwY2hhaW4ocmVuZGVyIHRhcmdldCBjb250YWluZXIpCiAqIGFuZCB0aGUgSVdpbmVEM0RUZXh1cmUoVGV4dHVyZSBjb250YWluZXIpIHJlbGVhc2UgdGhlIHBhcmVudHMKICogb2YgdGhlaXIgc3VyZmFjZSdzIGNoaWxkcmVuLCBidXQgYnkgcmVsZWFzaW5nIHRoZSBjb21wbGV4IHJvb3QKICogdGhlIHN1cmZhY2VzIHdoaWNoIGFyZSBjb21wbGV4bHkgYXR0YWNoZWQgdG8gaXQgYXJlIGRlc3Ryb3llZAogKiB0b28uIFNlZSBJRGlyZWN0RHJhd1N1cmZhY2U6OlJlbGVhc2UgZm9yIGEgbW9yZSBkZXRhaWxlZAogKiBleHBsYW5hdGlvbi4KICoKICogUGFyYW1zOgogKiAgRERTRDogRGVzY3JpcHRpb24gb2YgdGhlIHN1cmZhY2UgdG8gY3JlYXRlCiAqICBTdXJmOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBhdAogKiAgVW5rT3V0ZXI6IEJhc2ljYWxseSBmb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgYnV0IGRkcmF3IGRvZXNuJ3Qgc3VwcG9ydAogKiAgICAgICAgICAgIGFnZ3JlZ2F0aW9uLCBzbyBpdCBoYXMgdG8gYmUgTlVMTAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyICE9IE5VTEwKICogIERERVJSXyogaWYgYW4gZXJyb3Igb2NjdXJzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpERFNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2U3ICoqU3VyZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqb2JqZWN0ID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBMT05HIGV4dHJhX3N1cmZhY2VzID0gMCwgaTsKICAgIEREU1VSRkFDRURFU0MyIGRlc2MyOwogICAgVUlOVCBsZXZlbCA9IDA7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwKVxuIiwgVGhpcywgRERTRCwgU3VyZiwgVW5rT3V0ZXIpOwoKICAgIC8qIFNvbWUgY2hlY2tzIGJlZm9yZSB3ZSBzdGFydCAqLwogICAgaWYgKFRSQUNFX09OKGRkcmF3KSkKICAgIHsKICAgICAgICBUUkFDRSgiICglcCkgUmVxdWVzdGluZyBzdXJmYWNlIGRlc2MgOlxuIiwgVGhpcyk7CiAgICAgICAgRERSQVdfZHVtcF9zdXJmYWNlX2Rlc2MoRERTRCk7CiAgICB9CgogICAgaWYgKFVua091dGVyICE9IE5VTEwpCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgOiBvdXRlciAhPSBOVUxMP1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsgLyogdW5jaGVja2VkICovCiAgICB9CgogICAgaWYgKCEoRERTRC0+ZHdGbGFncyAmIEREU0RfQ0FQUykpCiAgICB7CiAgICAgICAgLyogRFZJREVPLkRMTCBkb2VzIGZvcmdldCB0aGUgRERTRF9DQVBTIGZsYWcgLi4uICpzaWdoKiAqLwogICAgICAgIEREU0QtPmR3RmxhZ3MgfD0gRERTRF9DQVBTOwogICAgfQogICAgaWYgKEREU0QtPmRkc0NhcHMuZHdDYXBzID09IDApCiAgICB7CiAgICAgICAgLyogVGhpcyBoYXMgYmVlbiBjaGVja2VkIG9uIHJlYWwgV2luZG93cyAqLwogICAgICAgIEREU0QtPmRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19MT0NBTFZJRE1FTSB8IEREU0NBUFNfVklERU9NRU1PUlk7CiAgICB9CgogICAgaWYgKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19BTExPQ09OTE9BRCkKICAgIHsKICAgICAgICAvKiBJZiB0aGUgc3VyZmFjZSBpcyBvZiB0aGUgJ2FsbG9jb25sb2FkJyB0eXBlLCBpZ25vcmUgdGhlIExQU1VSRkFDRSBmaWVsZCAqLwogICAgICAgIEREU0QtPmR3RmxhZ3MgJj0gfkREU0RfTFBTVVJGQUNFOwogICAgfQoKICAgIGlmICgoRERTRC0+ZHdGbGFncyAmIEREU0RfTFBTVVJGQUNFKSAmJiAoRERTRC0+bHBTdXJmYWNlID09IE5VTEwpKQogICAgewogICAgICAgIC8qIEZyYW5rIEhlcmJlcnQncyBEdW5lIHNwZWNpZmllcyBhIG51bGwgcG9pbnRlciBmb3IgdGhlIHN1cmZhY2UsIGlnbm9yZSB0aGUgTFBTVVJGQUNFIGZpZWxkICovCiAgICAgICAgV0FSTigiKCVwKSBOdWxsIHN1cmZhY2UgcG9pbnRlciBzcGVjaWZpZWQsIGlnbm9yZSBpdCFcbiIsIFRoaXMpOwogICAgICAgIEREU0QtPmR3RmxhZ3MgJj0gfkREU0RfTFBTVVJGQUNFOwogICAgfQoKICAgIGlmKChERFNELT5kZHNDYXBzLmR3Q2FwcyAmIChERFNDQVBTX0ZMSVAgfCBERFNDQVBTX1BSSU1BUllTVVJGQUNFKSkgPT0gKEREU0NBUFNfRkxJUCB8IEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpICYmCiAgICAgICAhKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRVhDTFVTSVZFKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogQXR0ZW1wdCB0byBjcmVhdGUgYSBmbGlwYWJsZSBwcmltYXJ5IHN1cmZhY2Ugd2l0aG91dCBERFNDTF9FWENMVVNJVkUgc2V0XG4iLCBUaGlzKTsKICAgICAgICAqU3VyZiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIERERVJSX05PRVhDTFVTSVZFTU9ERTsKICAgIH0KCiAgICBpZiAoU3VyZiA9PSBOVUxMKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIFlvdSB3YW50IHRvIGdldCBiYWNrIGEgc3VyZmFjZT8gRG9uJ3QgZ2l2ZSBOVUxMIHB0cnMhXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRV9QT0lOVEVSOyAvKiB1bmNoZWNrZWQgKi8KICAgIH0KCiAgICAvKiBBY2NvcmRpbmcgdG8gdGhlIG1zZG4gdGhpcyBmbGFnIGlzIGlnbm9yZWQgYnkgQ3JlYXRlU3VyZmFjZSAqLwogICAgaWYgKEREU0QtPmR3U2l6ZSA+PSBzaXplb2YoRERTVVJGQUNFREVTQzIpKQogICAgICAgIEREU0QtPmRkc0NhcHMuZHdDYXBzMiAmPSB+RERTQ0FQUzJfTUlQTUFQU1VCTEVWRUw7CgogICAgLyogTW9kaWZ5IHNvbWUgZmxhZ3MgKi8KICAgIG1lbXNldCgmZGVzYzIsIDAsIHNpemVvZihkZXNjMikpOwogICAgZGVzYzIuZHdTaXplID0gc2l6ZW9mKGRlc2MyKTsgICAvKiBGb3IgdGhlIHN0cnVjdCBjb3B5ICovCiAgICBERF9TVFJVQ1RfQ09QWV9CWVNJWkUoJmRlc2MyLCBERFNEKTsKICAgIGRlc2MyLmR3U2l6ZSA9IHNpemVvZihkZXNjMik7ICAgLyogVG8gb3ZlcnJpZGUgYSBwb3NzaWJseSBzbWFsbGVyIHNpemUgKi8KICAgIGRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemU9c2l6ZW9mKEREUElYRUxGT1JNQVQpOyAvKiBKdXN0IHRvIGJlIHN1cmUgKi8KCiAgICAvKiBHZXQgdGhlIHZpZGVvIG1vZGUgZnJvbSBXaW5lRDNEIC0gd2Ugd2lsbCBuZWVkIGl0ICovCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldERpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIFN3YXBjaGFpbiAwICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZNb2RlKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gcmVhZCBkaXNwbGF5IG1vZGUgZnJvbSB3aW5lZDNkXG4iKTsKICAgICAgICBzd2l0Y2goVGhpcy0+b3JpZ19icHApCiAgICAgICAgewogICAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUDg7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfWDFSNUc1QjU7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgMTY6CiAgICAgICAgICAgICAgICBNb2RlLkZvcm1hdCA9IFdJTkVEM0RGTVRfUjVHNkI1OwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIDI0OgogICAgICAgICAgICAgICAgTW9kZS5Gb3JtYXQgPSBXSU5FRDNERk1UX1I4RzhCODsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAzMjoKICAgICAgICAgICAgICAgIE1vZGUuRm9ybWF0ID0gV0lORUQzREZNVF9YOFI4RzhCODsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBNb2RlLldpZHRoID0gVGhpcy0+b3JpZ193aWR0aDsKICAgICAgICBNb2RlLkhlaWdodCA9IFRoaXMtPm9yaWdfaGVpZ2h0OwogICAgfQoKICAgIC8qIE5vIHBpeGVsZm9ybWF0IGdpdmVuPyBVc2UgdGhlIGN1cnJlbnQgc2NyZWVuIGZvcm1hdCAqLwogICAgaWYoIShkZXNjMi5kd0ZsYWdzICYgRERTRF9QSVhFTEZPUk1BVCkpCiAgICB7CiAgICAgICAgZGVzYzIuZHdGbGFncyB8PSBERFNEX1BJWEVMRk9STUFUOwogICAgICAgIGRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdC5kd1NpemU9c2l6ZW9mKEREUElYRUxGT1JNQVQpOwoKICAgICAgICAvKiBXYWl0OiBJdCBjb3VsZCBiZSBhIFogYnVmZmVyICovCiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1pCVUZGRVIpCiAgICAgICAgewogICAgICAgICAgICBzd2l0Y2goZGVzYzIudTIuZHdNaXBNYXBDb3VudCkgLyogV2hvIGhhZCB0aGlzIGdsb3Jpb3VzIGlkZWE/ICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNhc2UgMTU6CiAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgV0lORUQzREZNVF9EMTVTMSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDE2KTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMjQ6CiAgICAgICAgICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgV0lORUQzREZNVF9EMjRYOCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDMyOgogICAgICAgICAgICAgICAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZXNjMi51NC5kZHBmUGl4ZWxGb3JtYXQsIFdJTkVEM0RGTVRfRDMyKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIFogYnVmZmVyIGJpdCBkZXB0aFxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgUGl4ZWxGb3JtYXRfV2luZUQzRHRvREQoJmRlc2MyLnU0LmRkcGZQaXhlbEZvcm1hdCwgTW9kZS5Gb3JtYXQpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBObyBXaWR0aCBvciBubyBIZWlnaHQ/IFVzZSB0aGUgY3VycmVudCB3aW5kb3cgc2l6ZSBvcgogICAgICogdGhlIG9yaWdpbmFsIHNjcmVlbiBzaXplCiAgICAgKi8KICAgIGlmKCEoZGVzYzIuZHdGbGFncyAmIEREU0RfV0lEVEgpIHx8CiAgICAgICAhKGRlc2MyLmR3RmxhZ3MgJiBERFNEX0hFSUdIVCkgKQogICAgewogICAgICAgIEhXTkQgd2luZG93OwoKICAgICAgICAvKiBGYWxsYmFjazogRnJvbSBXaW5lRDNEIC8gb3JpZ2luYWwgbW9kZSAqLwogICAgICAgIGRlc2MyLmR3RmxhZ3MgfD0gRERTRF9XSURUSCB8IEREU0RfSEVJR0hUOwogICAgICAgIGRlc2MyLmR3V2lkdGggPSBNb2RlLldpZHRoOwogICAgICAgIGRlc2MyLmR3SGVpZ2h0ID0gTW9kZS5IZWlnaHQ7CgogICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd2luZG93KTsKICAgICAgICBpZiggKGhyID09IEQzRF9PSykgJiYgKHdpbmRvdyAhPSAwKSApCiAgICAgICAgewogICAgICAgICAgICBSRUNUIHJlY3Q7CiAgICAgICAgICAgIGlmKEdldFdpbmRvd1JlY3Qod2luZG93LCAmcmVjdCkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBUaGlzIGlzIGEgaGFjayB1bnRpbCBJIGZpbmQgYSBiZXR0ZXIgc29sdXRpb24gKi8KICAgICAgICAgICAgICAgIGlmKCAocmVjdC5yaWdodCAtIHJlY3QubGVmdCkgPD0gMSB8fAogICAgICAgICAgICAgICAgICAgIChyZWN0LmJvdHRvbSAtIHJlY3QudG9wKSA8PSAxICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiV2FudGVkIHRvIGdldCBzdXJmYWNlIGRpbWVuc2lvbnMgZnJvbSB3aW5kb3cgJXAsIGJ1dCBpdCBoYXMgb25seSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGEgc2l6ZSBvZiAlZHglZC4gVXNpbmcgZnVsbCBzY3JlZW4gZGltZW5zaW9uc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LCByZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0LCByZWN0LmJvdHRvbSAtIHJlY3QudG9wKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBOb3Qgc3VyZSBpZiB0aGlzIGlzIGNvcnJlY3QgKi8KICAgICAgICAgICAgICAgICAgICBkZXNjMi5kd1dpZHRoID0gcmVjdC5yaWdodCAtIHJlY3QubGVmdDsKICAgICAgICAgICAgICAgICAgICBkZXNjMi5kd0hlaWdodCA9IHJlY3QuYm90dG9tIC0gcmVjdC50b3A7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHdpbmRvdyAlcCdzIGRpbWVuc2lvbnM6ICVkeCVkXG4iLCB3aW5kb3csIGRlc2MyLmR3V2lkdGgsIGRlc2MyLmR3SGVpZ2h0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBNaXBtYXAgY291bnQgZml4ZXMgKi8KICAgIGlmKGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVApCiAgICB7CiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX0NPTVBMRVgpCiAgICAgICAgewogICAgICAgICAgICBpZihkZXNjMi5kd0ZsYWdzICYgRERTRF9NSVBNQVBDT1VOVCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTWlwbWFwIGNvdW50IGlzIGdpdmVuLCBub3RoaW5nIHRvIGRvICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBVbmRvY3VtZW50ZWQgZmVhdHVyZTogQ3JlYXRlIHN1YmxldmVscyB1bnRpbAogICAgICAgICAgICAgICAgICogZWl0aGVyIHRoZSB3aWR0aCBvciB0aGUgaGVpZ2h0IGlzIDEKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgRFdPUkQgbWluID0gZGVzYzIuZHdXaWR0aCA8IGRlc2MyLmR3SGVpZ2h0ID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2MyLmR3V2lkdGggOiBkZXNjMi5kd0hlaWdodDsKICAgICAgICAgICAgICAgIGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgPSAwOwogICAgICAgICAgICAgICAgd2hpbGUoIG1pbiApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGVzYzIudTIuZHdNaXBNYXBDb3VudCArPSAxOwogICAgICAgICAgICAgICAgICAgIG1pbiA+Pj0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBOb3QtY29tcGxleCBtaXBtYXAgLT4gTWlwbWFwY291bnQgPSAxICovCiAgICAgICAgICAgIGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgPSAxOwogICAgICAgIH0KICAgICAgICBleHRyYV9zdXJmYWNlcyA9IGRlc2MyLnUyLmR3TWlwTWFwQ291bnQgLSAxOwoKICAgICAgICAvKiBUaGVyZSdzIGEgbWlwbWFwIGNvdW50IGluIHRoZSBjcmVhdGVkIHN1cmZhY2UgaW4gYW55IGNhc2UgKi8KICAgICAgICBkZXNjMi5kd0ZsYWdzIHw9IEREU0RfTUlQTUFQQ09VTlQ7CiAgICB9CiAgICAvKiBJZiBubyBtaXBtYXAgaXMgZ2l2ZW4sIHRoZSB0ZXh0dXJlIGhhcyBvbmx5IG9uZSBsZXZlbCAqLwoKICAgIC8qIFRoZSBmaXJzdCBzdXJmYWNlIGlzIGEgZnJvbnQgYnVmZmVyLCB0aGUgYmFjayBidWZmZXIgaXMgY3JlYXRlZCBhZnRlcndhcmRzICovCiAgICBpZiggKGRlc2MyLmR3RmxhZ3MgJiBERFNEX0NBUFMpICYmIChkZXNjMi5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpICkKICAgIHsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX0ZST05UQlVGRkVSOwogICAgfQoKICAgIC8qIENyZWF0ZSB0aGUgZmlyc3Qgc3VyZmFjZSAqLwogICAgaHIgPSBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZShUaGlzLCAmZGVzYzIsICZvYmplY3QsIDApOwogICAgaWYoIGhyICE9IEREX09LKQogICAgewogICAgICAgIEVSUigiSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UgZmFpbGVkIHdpdGggJTA4eFxuIiwgaHIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAqU3VyZiA9IElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdTdXJmYWNlNyk7CgogICAgLyogQ3JlYXRlIEFkZGl0aW9uYWwgc3VyZmFjZXMgaWYgbmVjZXNzYXJ5CiAgICAgKiBUaGlzIGFwcGxpZXMgdG8gUHJpbWFyeSBzdXJmYWNlcyB3aGljaCBoYXZlIGEgYmFjayBidWZmZXIgY291bnQKICAgICAqIHNldCwgYnV0IG5vdCB0byBtaXBtYXAgdGV4dHVyZXMuIEluIGNhc2Ugb2YgTWlwbWFwIHRleHR1cmVzLAogICAgICogd2luZUQzRCB0YWtlcyBjYXJlIG9mIHRoZSBjcmVhdGlvbiBvZiBhZGRpdGlvbmFsIHN1cmZhY2VzCiAgICAgKi8KICAgIGlmKEREU0QtPmR3RmxhZ3MgJiBERFNEX0JBQ0tCVUZGRVJDT1VOVCkKICAgIHsKICAgICAgICBleHRyYV9zdXJmYWNlcyA9IEREU0QtPmR3QmFja0J1ZmZlckNvdW50OwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzICY9IH5ERFNDQVBTX0ZST05UQlVGRkVSOyAvKiBJdCdzIG5vdCBhIGZyb250IGJ1ZmZlciAqLwogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfQkFDS0JVRkZFUjsKICAgIH0KICAgIC8qIFNldCB0aGUgRERTQ0FQUzJfTUlQTUFQU1VCTEVWRUwgZmxhZyBvbiBtaXBtYXAgc3VibGV2ZWxzIGFjY29yZGluZyB0byB0aGUgbXNkbiAqLwogICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgIHsKICAgICAgICBkZXNjMi5kZHNDYXBzLmR3Q2FwczIgfD0gRERTQ0FQUzJfTUlQTUFQU1VCTEVWRUw7CiAgICB9CgogICAgZm9yKGkgPSAwOyBpIDwgZXh0cmFfc3VyZmFjZXM7IGkrKykKICAgIHsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpvYmplY3QyID0gTlVMTDsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICppdGVyYXRvcjsKCiAgICAgICAgLyogaW5jcmVhc2UgdGhlIG1pcG1hcCBsZXZlbCwgYnV0IG9ubHkgaWYgYSBtaXBtYXAgaXMgY3JlYXRlZAogICAgICAgICAqIEluIHRoaXMgY2FzZSwgYWxzbyBoYWx2ZSB0aGUgc2l6ZQogICAgICAgICAqLwogICAgICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19NSVBNQVApCiAgICAgICAgewogICAgICAgICAgICBsZXZlbCsrOwogICAgICAgICAgICBpZihkZXNjMi5kd1dpZHRoID4gMSkgZGVzYzIuZHdXaWR0aCAvPSAyOwogICAgICAgICAgICBpZihkZXNjMi5kd0hlaWdodCA+IDEpIGRlc2MyLmR3SGVpZ2h0IC89IDI7CiAgICAgICAgfQoKICAgICAgICBociA9IElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlKFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGVzYzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsKTsKICAgICAgICBpZihociAhPSBERF9PSykKICAgICAgICB7CiAgICAgICAgICAgIC8qIFRoaXMgZGVzdHJveXMgYW5kIHBvc3NpYmx5IGNyZWF0ZWQgc3VyZmFjZXMgdG9vICovCiAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9SZWxlYXNlKCBJQ09NX0lOVEVSRkFDRShvYmplY3QsIElEaXJlY3REcmF3U3VyZmFjZTcpICk7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CgogICAgICAgIC8qIEFkZCB0aGUgbmV3IHN1cmZhY2UgdG8gdGhlIGNvbXBsZXggYXR0YWNobWVudCBsaXN0ICovCiAgICAgICAgb2JqZWN0Mi0+Zmlyc3RfY29tcGxleCA9IG9iamVjdDsKICAgICAgICBvYmplY3QyLT5uZXh0X2NvbXBsZXggPSBOVUxMOwogICAgICAgIGl0ZXJhdG9yID0gb2JqZWN0OwogICAgICAgIHdoaWxlKGl0ZXJhdG9yLT5uZXh0X2NvbXBsZXgpIGl0ZXJhdG9yID0gaXRlcmF0b3ItPm5leHRfY29tcGxleDsKICAgICAgICBpdGVyYXRvci0+bmV4dF9jb21wbGV4ID0gb2JqZWN0MjsKCiAgICAgICAgLyogUmVtb3ZlIHRoZSAocG9zc2libGUpIGJhY2sgYnVmZmVyIGNhcCBmcm9tIHRoZSBuZXcgc3VyZmFjZSBkZXNjcmlwdGlvbiwKICAgICAgICAgKiBiZWNhdXNlIG9ubHkgb25lIHN1cmZhY2UgaW4gdGhlIGZsaXBwaW5nIGNoYWluIGlzIGEgYmFjayBidWZmZXIsIG9uZQogICAgICAgICAqIGlzIGEgZnJvbnQgYnVmZmVyLCB0aGUgb3RoZXJzIGFyZSBqdXN0IHByaW1hcnkgc3VyZmFjZXMuCiAgICAgICAgICovCiAgICAgICAgZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJj0gfkREU0NBUFNfQkFDS0JVRkZFUjsKICAgIH0KCiAgICAvKiBBZGRyZWYgdGhlIGRkcmF3IGludGVyZmFjZSB0byBrZWVwIGFuIHJlZmVyZW5jZSBmb3IgZWFjaCBzdXJmYWNlICovCiAgICBJRGlyZWN0RHJhdzdfQWRkUmVmKGlmYWNlKTsKICAgIG9iamVjdC0+aWZhY2VUb1JlbGVhc2UgPSAoSVVua25vd24gKikgaWZhY2U7CgogICAgLyogSWYgdGhlIGltcGxlbWVudGF0aW9uIGlzIE9wZW5HTCBhbmQgdGhlcmUncyBubyBkM2RkZXZpY2UsIGF0dGFjaCBhIGQzZGRldmljZQogICAgICogQnV0IGF0dGFjaCB0aGUgZDNkZGV2aWNlIG9ubHkgaWYgdGhlIGN1cnJlbnRseSBjcmVhdGVkIHN1cmZhY2Ugd2FzCiAgICAgKiBhIHByaW1hcnkgc3VyZmFjZSAoMkQgYXBwIGluIDNEIG1vZGUpIG9yIGEgM0RERVZJQ0Ugc3VyZmFjZSAoM0QgYXBwKQogICAgICogVGhlIG9ubHkgY2FzZSBJIGNhbiB0aGluayBvZiB3aGVyZSB0aGlzIGRvZXNuJ3QgYXBwbHkgaXMgd2hlbiBhCiAgICAgKiAyRCBhcHAgd2FzIGNvbmZpZ3VyZWQgYnkgdGhlIHVzZXIgdG8gcnVuIHdpdGggT3BlbkdMIGFuZCBpdCBkaWRuJ3QgY3JlYXRlCiAgICAgKiB0aGUgcmVuZGVyIHRhcmdldCBhcyBmaXJzdCBzdXJmYWNlLiBJbiB0aGlzIGNhc2UgdGhlIHJlbmRlciB0YXJnZXQgY3JlYXRpb24KICAgICAqIHdpbGwgY2F1c2UgdGhlIDNEIGluaXQuCiAgICAgKi8KICAgIGlmKCAoVGhpcy0+SW1wbFR5cGUgPT0gU1VSRkFDRV9PUEVOR0wpICYmICEoVGhpcy0+ZDNkX2luaXRpYWxpemVkKSAmJgogICAgICAgIGRlc2MyLmRkc0NhcHMuZHdDYXBzICYgKEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTXzNEREVWSUNFKSApCiAgICB7CiAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqdGFyZ2V0ID0gb2JqZWN0LCAqc3VyZmFjZTsKICAgICAgICBzdHJ1Y3QgbGlzdCAqZW50cnk7CgogICAgICAgIC8qIFNlYXJjaCBmb3IgdGhlIHByaW1hcnkgdG8gdXNlIGFzIHJlbmRlciB0YXJnZXQgKi8KICAgICAgICBMSVNUX0ZPUl9FQUNIKGVudHJ5LCAmVGhpcy0+c3VyZmFjZV9saXN0KQogICAgICAgIHsKICAgICAgICAgICAgc3VyZmFjZSA9IExJU1RfRU5UUlkoZW50cnksIElEaXJlY3REcmF3U3VyZmFjZUltcGwsIHN1cmZhY2VfbGlzdF9lbnRyeSk7CiAgICAgICAgICAgIGlmKHN1cmZhY2UtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGZvdW5kICovCiAgICAgICAgICAgICAgICB0YXJnZXQgPSBzdXJmYWNlOwogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIHByaW1hcnkgJXAgYXMgcmVuZGVyIHRhcmdldFxuIiwgdGFyZ2V0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiKCVwKSBBdHRhY2hpbmcgYSBEM0REZXZpY2UsIHJlbmRlcnRhcmdldCA9ICVwXG4iLCBUaGlzLCB0YXJnZXQpOwogICAgICAgIGhyID0gSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZShUaGlzLCB0YXJnZXQtPmZpcnN0X2NvbXBsZXgpOwogICAgICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiSURpcmVjdERyYXdJbXBsX0F0dGFjaEQzRERldmljZSBmYWlsZWQsIGhyID0gJXhcbiIsIGhyKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQ3JlYXRlIGEgV2luZUQzRFRleHR1cmUgaWYgYSB0ZXh0dXJlIHdhcyByZXF1ZXN0ZWQgKi8KICAgIGlmKEREU0QtPmRkc0NhcHMuZHdDYXBzICYgRERTQ0FQU19URVhUVVJFKQogICAgewogICAgICAgIFVJTlQgbGV2ZWxzOwogICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0OwogICAgICAgIFdJTkVEM0RQT09MIFBvb2wgPSBXSU5FRDNEUE9PTF9ERUZBVUxUOwoKICAgICAgICBUaGlzLT50ZXhfcm9vdCA9IG9iamVjdDsKCiAgICAgICAgaWYoZGVzYzIuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGEgbWlwbWFwIGlzIGNyZWF0ZWQsIGNyZWF0ZSBlbm91Z2ggbGV2ZWxzICovCiAgICAgICAgICAgIGxldmVscyA9IGRlc2MyLnUyLmR3TWlwTWFwQ291bnQ7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vIG1pcG1hcCBpcyBjcmVhdGVkLCBjcmVhdGUgb25lIGxldmVsICovCiAgICAgICAgICAgIGxldmVscyA9IDE7CiAgICAgICAgfQoKICAgICAgICAvKiBERFNDQVBTX1NZU1RFTU1FTU9SWSB0ZXh0dXJlcyBhcmUgaW4gV0lORUQzRFBPT0xfU1lTVEVNTUVNICovCiAgICAgICAgaWYoRERTRC0+ZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1NZU1RFTU1FTU9SWSkKICAgICAgICB7CiAgICAgICAgICAgIFBvb2wgPSBXSU5FRDNEUE9PTF9TWVNURU1NRU07CiAgICAgICAgfQogICAgICAgIC8qIFNob3VsZCBJIGZvcndhcmQgdGhlIE1BTkVHRUQgY2FwIHRvIHRoZSBtYW5hZ2VkIHBvb2wgPyAqLwoKICAgICAgICAvKiBHZXQgdGhlIGZvcm1hdC4gSXQncyBzZXQgYWxyZWFkeSBieSBDcmVhdGVOZXdTdXJmYWNlICovCiAgICAgICAgRm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmb2JqZWN0LT5zdXJmYWNlX2Rlc2MudTQuZGRwZlBpeGVsRm9ybWF0KTsKCiAgICAgICAgLyogVGhlIHN1cmZhY2VzIGFyZSBhbHJlYWR5IGNyZWF0ZWQsIHRoZSBjYWxsYmFjayBvbmx5CiAgICAgICAgICogcGFzc2VzIHRoZSBJV2luZUQzRFN1cmZhY2UgdG8gV2luZUQzRAogICAgICAgICAqLwogICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVGV4dHVyZSggVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0QtPmR3V2lkdGgsIEREU0QtPmR3SGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzLCAvKiBNaXBNYXBDb3VudCA9IExldmVscyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogdXNhZ2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT53aW5lRDNEVGV4dHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIFNoYXJlZEhhbmRsZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdTdXJmYWNlNyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlU3VyZmFjZSApOwogICAgICAgIFRoaXMtPnRleF9yb290ID0gTlVMTDsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCiNkZWZpbmUgRERFTlVNU1VSRkFDRVNfU0VBUkNIVFlQRSAoRERFTlVNU1VSRkFDRVNfQ0FOQkVDUkVBVEVEfERERU5VTVNVUkZBQ0VTX0RPRVNFWElTVCkKI2RlZmluZSBEREVOVU1TVVJGQUNFU19NQVRDSFRZUEUgKERERU5VTVNVUkZBQ0VTX0FMTHxEREVOVU1TVVJGQUNFU19NQVRDSHxEREVOVU1TVVJGQUNFU19OT01BVENIKQoKc3RhdGljIEJPT0wKTWFpbl9EaXJlY3REcmF3X0REUElYRUxGT1JNQVRfTWF0Y2goY29uc3QgRERQSVhFTEZPUk1BVCAqcmVxdWVzdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBERFBJWEVMRk9STUFUICpwcm92aWRlZCkKewogICAgLyogU29tZSBmbGFncyBtdXN0IGJlIHByZXNlbnQgaW4gYm90aCBvciBuZWl0aGVyIGZvciBhIG1hdGNoLiAqLwogICAgc3RhdGljIGNvbnN0IERXT1JEIG11c3RfbWF0Y2ggPSBERFBGX1BBTEVUVEVJTkRFWEVEMSB8IEREUEZfUEFMRVRURUlOREVYRUQyCiAgICAgICAgfCBERFBGX1BBTEVUVEVJTkRFWEVENCB8IEREUEZfUEFMRVRURUlOREVYRUQ4IHwgRERQRl9GT1VSQ0MKICAgICAgICB8IEREUEZfWkJVRkZFUiB8IEREUEZfU1RFTkNJTEJVRkZFUjsKCiAgICBpZiAoKHJlcXVlc3RlZC0+ZHdGbGFncyAmIHByb3ZpZGVkLT5kd0ZsYWdzKSAhPSByZXF1ZXN0ZWQtPmR3RmxhZ3MpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmICgocmVxdWVzdGVkLT5kd0ZsYWdzICYgbXVzdF9tYXRjaCkgIT0gKHByb3ZpZGVkLT5kd0ZsYWdzICYgbXVzdF9tYXRjaCkpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBERFBGX0ZPVVJDQykKICAgICAgICBpZiAocmVxdWVzdGVkLT5kd0ZvdXJDQyAhPSBwcm92aWRlZC0+ZHdGb3VyQ0MpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfWkJVRkZFUnxERFBGX0FMUEhBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxERFBGX0xVTUlOQU5DRXxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51MS5kd1JHQkJpdENvdW50ICE9IHByb3ZpZGVkLT51MS5kd1JHQkJpdENvdW50KQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIChERFBGX1JHQnxERFBGX1lVVnxERFBGX1NURU5DSUxCVUZGRVIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfEREUEZfTFVNSU5BTkNFfEREUEZfQlVNUERVRFYpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnUyLmR3UkJpdE1hc2sgIT0gcHJvdmlkZWQtPnUyLmR3UkJpdE1hc2spCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfWkJVRkZFUnxERFBGX0JVTVBEVURWKSkKICAgICAgICBpZiAocmVxdWVzdGVkLT51My5kd0dCaXRNYXNrICE9IHByb3ZpZGVkLT51My5kd0dCaXRNYXNrKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgLyogSSBjb3VsZCBiZSB3cm9uZyBhYm91dCB0aGUgYnVtcG1hcHBpbmcuIE1TRE4gZG9jcyBhcmUgdmFndWUuICovCiAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgKEREUEZfUkdCfEREUEZfWVVWfEREUEZfU1RFTkNJTEJVRkZFUgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8RERQRl9CVU1QRFVEVikpCiAgICAgICAgaWYgKHJlcXVlc3RlZC0+dTQuZHdCQml0TWFzayAhPSBwcm92aWRlZC0+dTQuZHdCQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiAoRERQRl9BTFBIQVBJWEVMU3xERFBGX1pQSVhFTFMpKQogICAgICAgIGlmIChyZXF1ZXN0ZWQtPnU1LmR3UkdCQWxwaGFCaXRNYXNrICE9IHByb3ZpZGVkLT51NS5kd1JHQkFscGhhQml0TWFzaykKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgQk9PTApJRGlyZWN0RHJhd0ltcGxfRERTRF9NYXRjaChjb25zdCBERFNVUkZBQ0VERVNDMiogcmVxdWVzdGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBERFNVUkZBQ0VERVNDMiogcHJvdmlkZWQpCnsKICAgIHN0cnVjdCBjb21wYXJlX2luZm8KICAgIHsKICAgICAgICBEV09SRCBmbGFnOwogICAgICAgIHB0cmRpZmZfdCBvZmZzZXQ7CiAgICAgICAgc2l6ZV90IHNpemU7CiAgICB9OwoKI2RlZmluZSBDTVAoRkxBRywgRklFTEQpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICAgICAgeyBERFNEXyMjRkxBRywgb2Zmc2V0b2YoRERTVVJGQUNFREVTQzIsIEZJRUxEKSwgXAogICAgICAgICAgc2l6ZW9mKCgoRERTVVJGQUNFREVTQzIgKikoTlVMTCkpLT5GSUVMRCkgfQoKICAgIHN0YXRpYyBjb25zdCBzdHJ1Y3QgY29tcGFyZV9pbmZvIGNvbXBhcmVbXSA9CiAgICB7CiAgICAgICAgQ01QKEFMUEhBQklUREVQVEgsIGR3QWxwaGFCaXREZXB0aCksCiAgICAgICAgQ01QKEJBQ0tCVUZGRVJDT1VOVCwgZHdCYWNrQnVmZmVyQ291bnQpLAogICAgICAgIENNUChDQVBTLCBkZHNDYXBzKSwKICAgICAgICBDTVAoQ0tERVNUQkxULCBkZGNrQ0tEZXN0Qmx0KSwKICAgICAgICBDTVAoQ0tERVNUT1ZFUkxBWSwgdTMgLyogZGRja0NLRGVzdE92ZXJsYXkgKi8pLAogICAgICAgIENNUChDS1NSQ0JMVCwgZGRja0NLU3JjQmx0KSwKICAgICAgICBDTVAoQ0tTUkNPVkVSTEFZLCBkZGNrQ0tTcmNPdmVybGF5KSwKICAgICAgICBDTVAoSEVJR0hULCBkd0hlaWdodCksCiAgICAgICAgQ01QKExJTkVBUlNJWkUsIHUxIC8qIGR3TGluZWFyU2l6ZSAqLyksCiAgICAgICAgQ01QKExQU1VSRkFDRSwgbHBTdXJmYWNlKSwKICAgICAgICBDTVAoTUlQTUFQQ09VTlQsIHUyIC8qIGR3TWlwTWFwQ291bnQgKi8pLAogICAgICAgIENNUChQSVRDSCwgdTEgLyogbFBpdGNoICovKSwKICAgICAgICAvKiBQSVhFTEZPUk1BVDogbWFudWFsICovCiAgICAgICAgQ01QKFJFRlJFU0hSQVRFLCB1MiAvKiBkd1JlZnJlc2hSYXRlICovKSwKICAgICAgICBDTVAoVEVYVFVSRVNUQUdFLCBkd1RleHR1cmVTdGFnZSksCiAgICAgICAgQ01QKFdJRFRILCBkd1dpZHRoKSwKICAgICAgICAvKiBaQlVGRkVSQklUREVQVEg6ICJvYnNvbGV0ZSIgKi8KICAgIH07CgojdW5kZWYgQ01QCgogICAgdW5zaWduZWQgaW50IGk7CgogICAgaWYgKChyZXF1ZXN0ZWQtPmR3RmxhZ3MgJiBwcm92aWRlZC0+ZHdGbGFncykgIT0gcmVxdWVzdGVkLT5kd0ZsYWdzKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBmb3IgKGk9MDsgaSA8IHNpemVvZihjb21wYXJlKS9zaXplb2YoY29tcGFyZVswXSk7IGkrKykKICAgIHsKICAgICAgICBpZiAocmVxdWVzdGVkLT5kd0ZsYWdzICYgY29tcGFyZVtpXS5mbGFnCiAgICAgICAgICAgICYmIG1lbWNtcCgoY29uc3QgY2hhciAqKXByb3ZpZGVkICsgY29tcGFyZVtpXS5vZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgY2hhciAqKXJlcXVlc3RlZCArIGNvbXBhcmVbaV0ub2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgY29tcGFyZVtpXS5zaXplKSAhPSAwKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKHJlcXVlc3RlZC0+ZHdGbGFncyAmIEREU0RfUElYRUxGT1JNQVQpCiAgICB7CiAgICAgICAgaWYgKCFNYWluX0RpcmVjdERyYXdfRERQSVhFTEZPUk1BVF9NYXRjaCgmcmVxdWVzdGVkLT51NC5kZHBmUGl4ZWxGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwcm92aWRlZC0+dTQuZGRwZlBpeGVsRm9ybWF0KSkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgojdW5kZWYgRERFTlVNU1VSRkFDRVNfU0VBUkNIVFlQRQojdW5kZWYgRERFTlVNU1VSRkFDRVNfTUFUQ0hUWVBFCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpFbnVtU3VyZmFjZXMKICoKICogTG9vcHMgdGhyb3VnaCBhbGwgc3VyZmFjZXMgYXR0YWNoZWQgdG8gdGhpcyBkZXZpY2UgYW5kIGNhbGxzIHRoZQogKiBhcHBsaWNhdGlvbiBjYWxsYmFjay4gVGhpcyBjYW4ndCBiZSByZWxheWVkIHRvIFdpbmVEM0REZXZpY2UsCiAqIGJlY2F1c2Ugc29tZSBXaW5lRDNEU3VyZmFjZXMnIHBhcmVudHMgYXJlIElQYXJlbnQgb2JqZWN0cwogKgogKiBQYXJhbXM6CiAqICBGbGFnczogU29tZSBmaWx0ZXJpbmcgZmxhZ3MuIFNlZSBJRGlyZWN0RHJhd0ltcGxfRW51bVN1cmZhY2VzQ2FsbGJhY2sKICogIEREU0Q6IERlc2NyaXB0aW9uIHRvIGZpbHRlciBmb3IKICogIENvbnRleHQ6IEFwcGxpY2F0aW9uLXByb3ZpZGVkIHBvaW50ZXIsIGl0J3MgcGFzc2VkIHVubW9kaWZpZWQgdG8gdGhlCiAqICAgICAgICAgICBDYWxsYmFjayBmdW5jdGlvbgogKiAgQ2FsbGJhY2s6IEFkZHJlc3MgdG8gY2FsbCBmb3IgZWFjaCBzdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIHRoZSBjYWxsYmFjayBpcyBOVUxMCiAqICBERF9PSyBvbiBzdWNjZXNzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9FbnVtU3VyZmFjZXMoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqRERTRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRERFTlVNU1VSRkFDRVNDQUxMQkFDSzcgQ2FsbGJhY2spCnsKICAgIC8qIFRoZSBzdXJmYWNlIGVudW1lcmF0aW9uIGlzIGhhbmRsZWQgYnkgV2luZUREcmF3LAogICAgICogYmVjYXVzZSBpdCBrZWVwcyB0cmFjayBvZiBhbGwgc3VyZmFjZXMgYXR0YWNoZWQgdG8KICAgICAqIGl0LiBUaGUgZmlsdGVyaW5nIGlzIGRvbmUgYnkgb3VyIGNhbGxiYWNrIGZ1bmN0aW9uLAogICAgICogYmVjYXVzZSBXaW5lRERyYXcgZG9lc24ndCBoYW5kbGUgZGRyYXctbGlrZSBzdXJmYWNlCiAgICAgKiBjYXBzIHN0cnVjdHVyZXMKICAgICAqLwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKnN1cmY7CiAgICBCT09MIGFsbCwgbm9tYXRjaDsKICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICBzdHJ1Y3QgbGlzdCAqZW50cnksICplbnRyeTI7CgogICAgYWxsID0gRmxhZ3MgJiBEREVOVU1TVVJGQUNFU19BTEw7CiAgICBub21hdGNoID0gRmxhZ3MgJiBEREVOVU1TVVJGQUNFU19OT01BVENIOwoKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgRERTRCwgQ29udGV4dCwgQ2FsbGJhY2spOwoKICAgIGlmKCFDYWxsYmFjaykKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKCiAgICAvKiBVc2UgdGhlIF9TQUZFIGVudW1lcmF0aW9uLCB0aGUgYXBwIG1heSBkZXN0cm95IGVudW1lcmF0ZWQgc3VyZmFjZXMgKi8KICAgIExJU1RfRk9SX0VBQ0hfU0FGRShlbnRyeSwgZW50cnkyLCAmVGhpcy0+c3VyZmFjZV9saXN0KQogICAgewogICAgICAgIHN1cmYgPSBMSVNUX0VOVFJZKGVudHJ5LCBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBzdXJmYWNlX2xpc3RfZW50cnkpOwogICAgICAgIGlmIChhbGwgfHwgKG5vbWF0Y2ggIT0gSURpcmVjdERyYXdJbXBsX0REU0RfTWF0Y2goRERTRCwgJnN1cmYtPnN1cmZhY2VfZGVzYykpKQogICAgICAgIHsKICAgICAgICAgICAgZGVzYyA9IHN1cmYtPnN1cmZhY2VfZGVzYzsKICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlN19BZGRSZWYoSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNykpOwogICAgICAgICAgICBpZihDYWxsYmFjayggSUNPTV9JTlRFUkZBQ0Uoc3VyZiwgSURpcmVjdERyYXdTdXJmYWNlNyksICZkZXNjLCBDb250ZXh0KSAhPSBEREVOVU1SRVRfT0spCiAgICAgICAgICAgICAgICByZXR1cm4gRERfT0s7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZVJlbmRlclRhcmdldAogKgogKiBDYWxsYmFjayBjYWxsZWQgYnkgV2luZUQzRCB0byBjcmVhdGUgU3VyZmFjZXMgZm9yIHJlbmRlciB0YXJnZXQgdXNhZ2UKICogVGhpcyBmdW5jdGlvbiB0YWtlcyB0aGUgRDNEIHRhcmdldCBmcm9tIHRoZSBJRGlyZWN0RHJhd0ltcGwgc3RydWN0dXJlLAogKiBhbmQgcmV0dXJucyB0aGUgV2luZUQzRFN1cmZhY2UuIFRvIGF2b2lkIGRvdWJsZSB1c2FnZSwgdGhlIHN1cmZhY2UKICogaXMgbWFya2VkIGFzIHJlbmRlciB0YXJnZXQgYWZ0ZXJ3YXJkcwogKgogKiBQYXJhbXMKICogIGRldmljZTogVGhlIFdpbmVEM0REZXZpY2UncyBwYXJlbnQKICogIFdpZHRoLCBIZWlnaHQsIEZvcm1hdDogRGltZW5zaW9ucyBhbmQgcGl4ZWxmb3JtYXQgb2YgdGhlIHJlbmRlciB0YXJnZXQKICogICAgICAgICAgICAgICAgICAgICAgICAgSWdub3JlZCwgYmVjYXVzZSB0aGUgc3VyZmFjZSBhbHJlYWR5IGV4aXN0cwogKiAgTXVsdGlTYW1wbGUsIE11bHRpc2FtcGxlUXVhbGl0eSwgTG9ja2FibGU6IElnbm9yZWQgZm9yIHRoZSBzYW1lIHJlYXNvbgogKiAgTG9ja2FibGU6IGlnbm9yZWQKICogIHBwU3VyZmFjZTogQWRkcmVzcyB0byBwYXNzIHRoZSBzdXJmYWNlIHBvaW50ZXIgYmFjayBhdAogKiAgcFNoYXJlZEhhbmRsZTogSWdub3JlZAogKgogKiBSZXR1cm5zOgogKiAgQWx3YXlzIHJldHVybnMgRDNEX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkQzRDdDQl9DcmVhdGVSZW5kZXJUYXJnZXQoSVVua25vd24gKmRldmljZSwgSVVua25vd24gKnBTdXBlcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBNdWx0aXNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgQk9PTCBMb2NrYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UqKiBwcFN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFKiBwU2hhcmVkSGFuZGxlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKmQzZFN1cmZhY2UgPSAoSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqKSBUaGlzLT5kM2RfdGFyZ2V0LT5maXJzdF9jb21wbGV4OwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBkZXZpY2UpOwoKICAgIC8qIExvb3AgdGhyb3VnaCB0aGUgY29tcGxleCBjaGFpbiBhbmQgdHJ5IHRvIGZpbmQgdW51c2VkIHByaW1hcnkgc3VyZmFjZXMgKi8KICAgIHdoaWxlKGQzZFN1cmZhY2UtPmlzUmVuZGVyVGFyZ2V0KQogICAgewogICAgICAgIGQzZFN1cmZhY2UgPSBkM2RTdXJmYWNlLT5uZXh0X2NvbXBsZXg7CiAgICAgICAgaWYoIWQzZFN1cmZhY2UpIGJyZWFrOwogICAgfQogICAgaWYoIWQzZFN1cmZhY2UpCiAgICB7CiAgICAgICAgZDNkU3VyZmFjZSA9IFRoaXMtPmQzZF90YXJnZXQ7CiAgICAgICAgRVJSKCIgKCVwKSA6IE5vIERpcmVjdERyYXdTdXJmYWNlIGZvdW5kIHRvIGNyZWF0ZSB0aGUgYmFjayBidWZmZXIuIFVzaW5nIHRoZSBmcm9udCBidWZmZXIgYXMgYmFjayBidWZmZXIuIFVuY2VydGFpbiBjb25zZXF1ZW5jZXNcbiIsIFRoaXMpOwogICAgfQoKICAgIC8qIFRPRE86IFJldHVybiBmYWlsdXJlIGlmIHRoZSBkaW1lbnNpb25zIGRvIG5vdCBtYXRjaCwgYnV0IHRoaXMgc2hvdWxkbid0IGhhcHBlbiAqLwoKICAgICpwcFN1cmZhY2UgPSBkM2RTdXJmYWNlLT5XaW5lRDNEU3VyZmFjZTsKICAgIGQzZFN1cmZhY2UtPmlzUmVuZGVyVGFyZ2V0ID0gVFJVRTsKICAgIFRSQUNFKCJSZXR1cm5pbmcgd2luZUQzRFN1cmZhY2UgJXAsIGl0IGJlbG9uZ3MgdG8gc3VyZmFjZSAlcFxuIiwgKnBwU3VyZmFjZSwgZDNkU3VyZmFjZSk7CiAgICByZXR1cm4gRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZURlcHRoU3RlbmNpbFN1cmZhY2UoSVVua25vd24gKmRldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKnBTdXBlcmlvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgTXVsdGlzYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCT09MIERpc2NhcmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSoqIHBwU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFKiBwU2hhcmVkSGFuZGxlKQp7CiAgICAvKiBDcmVhdGUgYSBEZXB0aCBTdGVuY2lsIHN1cmZhY2UgdG8gbWFrZSBXaW5lRDNEIGhhcHB5ICovCiAgICBIUkVTVUxUIGhyID0gRDNEX09LOwogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGRldmljZSk7CiAgICBERFNVUkZBQ0VERVNDMiBkZHNkOwoKICAgIFRSQUNFKCIoJXApIGNhbGwgYmFja1xuIiwgZGV2aWNlKTsKCiAgICAqcHBTdXJmYWNlID0gTlVMTDsKCiAgICAvKiBDcmVhdGUgYSBEaXJlY3REcmF3IHN1cmZhY2UgKi8KICAgIG1lbXNldCgmZGRzZCwgMCwgc2l6ZW9mKGRkc2QpKTsKICAgIGRkc2QuZHdTaXplID0gc2l6ZW9mKGRkc2QpOwogICAgZGRzZC51NC5kZHBmUGl4ZWxGb3JtYXQuZHdTaXplID0gc2l6ZW9mKEREUElYRUxGT1JNQVQpOwogICAgZGRzZC5kd0ZsYWdzID0gRERTRF9QSVhFTEZPUk1BVCB8IEREU0RfV0lEVEggfCBERFNEX0hFSUdIVCB8IEREU0RfQ0FQUzsKICAgIGRkc2QuZGRzQ2Fwcy5kd0NhcHMgPSBERFNDQVBTX09GRlNDUkVFTlBMQUlOOwogICAgZGRzZC5kd0hlaWdodCA9IEhlaWdodDsKICAgIGRkc2QuZHdXaWR0aCA9IFdpZHRoOwogICAgaWYoRm9ybWF0ICE9IDApCiAgICB7CiAgICAgIFBpeGVsRm9ybWF0X1dpbmVEM0R0b0REKCZkZHNkLnU0LmRkcGZQaXhlbEZvcm1hdCwgRm9ybWF0KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgZGRzZC5kd0ZsYWdzIF49IEREU0RfUElYRUxGT1JNQVQ7CiAgICB9CgogICAgVGhpcy0+ZGVwdGhzdGVuY2lsID0gVFJVRTsKICAgIGhyID0gSURpcmVjdERyYXc3X0NyZWF0ZVN1cmZhY2UoKElEaXJlY3REcmF3NyAqKSBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGRzZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElEaXJlY3REcmF3U3VyZmFjZTcgKiopICZUaGlzLT5EZXB0aFN0ZW5jaWxCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgVGhpcy0+ZGVwdGhzdGVuY2lsID0gRkFMU0U7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiICglcCkgQ3JlYXRpbmcgYSBEZXB0aFN0ZW5jaWwgU3VyZmFjZSBmYWlsZWQsIHJlc3VsdCA9ICV4XG4iLCBUaGlzLCBocik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQogICAgKnBwU3VyZmFjZSA9IFRoaXMtPkRlcHRoU3RlbmNpbEJ1ZmZlci0+V2luZUQzRFN1cmZhY2U7CiAgICByZXR1cm4gRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRDNEN0NCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4KICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIFdpbmVEM0Qgd2hpY2ggY3JlYXRlcyBhIG5ldyBXaW5lRDNEU3dhcGNoYWluCiAqIGludGVyZmFjZS4gSXQgYWxzbyBjcmVhdGVzIGFuIElQYXJlbnQgaW50ZXJmYWNlIHRvIHN0b3JlIHRoYXQgcG9pbnRlciwKICogc28gdGhlIFdpbmVEM0RTd2FwY2hhaW4gaGFzIGEgcGFyZW50IGFuZCBjYW4gYmUgcmVsZWFzZWQgd2hlbiB0aGUgRDNECiAqIGRldmljZSBpcyBkZXN0cm95ZWQKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRDNEN0NCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVVua25vd24gKmRldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluICoqIHBwU3dhcENoYWluKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd0ltcGwsIElEaXJlY3REcmF3NywgZGV2aWNlKTsKICAgIElQYXJlbnRJbXBsICpvYmplY3QgPSBOVUxMOwogICAgSFJFU1VMVCByZXMgPSBEM0RfT0s7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwogICAgVFJBQ0UoIiglcCkgY2FsbCBiYWNrXG4iLCBkZXZpY2UpOwoKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElQYXJlbnRJbXBsKSk7CiAgICBpZiAoTlVMTCA9PSBvYmplY3QpCiAgICB7CiAgICAgICAgRklYTUUoIkFsbG9jYXRpb24gb2YgbWVtb3J5IGZhaWxlZFxuIik7CiAgICAgICAgKnBwU3dhcENoYWluID0gTlVMTDsKICAgICAgICByZXR1cm4gRERFUlJfT1VUT0ZWSURFT01FTU9SWTsKICAgIH0KCiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKG9iamVjdCwgSVBhcmVudCwgSVBhcmVudF9WdGJsKTsKICAgIG9iamVjdC0+cmVmID0gMTsKCiAgICByZXMgPSBJV2luZUQzRERldmljZV9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKFRoaXMtPndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN3YXBjaGFpbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biopIElDT01fSU5URVJGQUNFKG9iamVjdCwgSVBhcmVudCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRDdDQl9DcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlKTsKICAgIGlmIChyZXMgIT0gRDNEX09LKQogICAgewogICAgICAgIEZJWE1FKCIoJXApIGNhbGwgdG8gSVdpbmVEM0REZXZpY2VfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbiBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAgLCBvYmplY3QpOwogICAgICAgICpwcFN3YXBDaGFpbiA9IE5VTEw7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgKnBwU3dhcENoYWluID0gc3dhcGNoYWluOwogICAgICAgIG9iamVjdC0+Y2hpbGQgPSAoSVVua25vd24gKikgc3dhcGNoYWluOwogICAgfQoKICAgIHJldHVybiByZXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlCiAqCiAqIEluaXRpYWxpemVzIHRoZSBEM0QgY2FwYWJpbGl0aWVzIG9mIFdpbmVEM0QKICoKICogUGFyYW1zOgogKiAgcHJpbWFyeTogVGhlIHByaW1hcnkgc3VyZmFjZSBmb3IgRDNECiAqCiAqIFJldHVybnMKICogIEREX09LIG9uIHN1Y2Nlc3MsCiAqICBEREVSUl8qIG90aGVyd2lzZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0ltcGxfQXR0YWNoRDNERGV2aWNlKElEaXJlY3REcmF3SW1wbCAqVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpwcmltYXJ5KQp7CiAgICBIUkVTVUxUIGhyOwogICAgVUlOVCAgICAgICAgICAgICAgICAgIEJhY2tCdWZmZXJDb3VudCA9IDA7CiAgICBIV05EICAgICAgICAgICAgICAgICAgd2luZG93OwoKICAgIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMgbG9jYWxQYXJhbWV0ZXJzOwogICAgQk9PTCBpc1dpbmRvd2VkLCBFbmFibGVBdXRvRGVwdGhTdGVuY2lsOwogICAgV0lORUQzREZPUk1BVCBBdXRvRGVwdGhTdGVuY2lsRm9ybWF0OwogICAgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGVUeXBlOwogICAgV0lORUQzRFNXQVBFRkZFQ1QgIFN3YXBFZmZlY3Q7CiAgICBEV09SRCBGbGFncywgTXVsdGlTYW1wbGVRdWFsaXR5OwogICAgVUlOVCBGdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiwgUHJlc2VudGF0aW9uSW50ZXJ2YWw7CiAgICBXSU5FRDNERElTUExBWU1PREUgTW9kZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgcHJpbWFyeSk7CgogICAgLyogR2V0IHRoZSB3aW5kb3cgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0SFdORChUaGlzLT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ3aW5kb3cpOwogICAgaWYoaHIgIT0gRDNEX09LKQogICAgewogICAgICAgIEVSUigiSVdpbmVEM0REZXZpY2U6OkdldEhXTkQgZmFpbGVkXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogSWYgdGhlcmUncyBubyB3aW5kb3csIGNyZWF0ZSBhIGhpZGRlbiB3aW5kb3cuIFdpbmVEM0QgbmVlZHMgaXQgKi8KICAgIGlmKHdpbmRvdyA9PSAwKQogICAgewogICAgICAgIHdpbmRvdyA9IENyZWF0ZVdpbmRvd0V4QSgwLCBUaGlzLT5jbGFzc25hbWUsICJIaWRkZW4gRDNEIFdpbmRvdyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdTX0RJU0FCTEVELCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwsIEdldE1vZHVsZUhhbmRsZUEoMCksIE5VTEwpOwoKICAgICAgICBTaG93V2luZG93KHdpbmRvdywgU1dfSElERSk7ICAgLyogSnVzdCB0byBiZSBzdXJlICovCiAgICAgICAgV0FSTigiKCVwKSBObyB3aW5kb3cgZm9yIHRoZSBEaXJlY3QzRERldmljZSwgY3JlYXRlZCBhIGhpZGRlbiB3aW5kb3cuIEhXTkQ9JXBcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICAgICAgVGhpcy0+ZDNkX3dpbmRvdyA9IHdpbmRvdzsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKSBVc2luZyBleGlzdGluZyB3aW5kb3cgJXAgZm9yIERpcmVjdDNEIHJlbmRlcmluZ1xuIiwgVGhpcywgd2luZG93KTsKICAgIH0KCiAgICAvKiB1c2UgdGhlIHN1cmZhY2UgZGVzY3JpcHRpb24gZm9yIHRoZSBkZXZpY2UgcGFyYW1ldGVycywgbm90IHRoZQogICAgICogRGV2aWNlIHNldHRpbmdzLiBUaGUgYXBwIG1pZ2h0IHJlbmRlciB0byBhbiBvZmZzY3JlZW4gc3VyZmFjZQogICAgICovCiAgICBNb2RlLldpZHRoID0gcHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3V2lkdGg7CiAgICBNb2RlLkhlaWdodCA9IHByaW1hcnktPnN1cmZhY2VfZGVzYy5kd0hlaWdodDsKICAgIE1vZGUuRm9ybWF0ID0gUGl4ZWxGb3JtYXRfREQyV2luZUQzRCgmcHJpbWFyeS0+c3VyZmFjZV9kZXNjLnU0LmRkcGZQaXhlbEZvcm1hdCk7CgogICAgaWYocHJpbWFyeS0+c3VyZmFjZV9kZXNjLmR3RmxhZ3MgJiBERFNEX0JBQ0tCVUZGRVJDT1VOVCkKICAgIHsKICAgICAgICBCYWNrQnVmZmVyQ291bnQgPSBwcmltYXJ5LT5zdXJmYWNlX2Rlc2MuZHdCYWNrQnVmZmVyQ291bnQ7CiAgICB9CgogICAgLyogU3RvcmUgdGhlIGZ1dHVyZSBSZW5kZXIgVGFyZ2V0IHN1cmZhY2UgKi8KICAgIFRoaXMtPmQzZF90YXJnZXQgPSBwcmltYXJ5OwoKICAgIGlzV2luZG93ZWQgPSAhKFRoaXMtPmNvb3BlcmF0aXZlX2xldmVsICYgRERTQ0xfRlVMTFNDUkVFTik7CiAgICBFbmFibGVBdXRvRGVwdGhTdGVuY2lsID0gRkFMU0U7CiAgICBBdXRvRGVwdGhTdGVuY2lsRm9ybWF0ID0gV0lORUQzREZNVF9EMTY7CiAgICBNdWx0aVNhbXBsZVR5cGUgPSBXSU5FRDNETVVMVElTQU1QTEVfTk9ORTsKICAgIFN3YXBFZmZlY3QgPSBXSU5FRDNEU1dBUEVGRkVDVF9DT1BZOwogICAgRmxhZ3MgPSAwOwogICAgTXVsdGlTYW1wbGVRdWFsaXR5ID0gMDsKICAgIEZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6ID0gV0lORUQzRFBSRVNFTlRfUkFURV9ERUZBVUxUOyAvKiBEZWZhdWx0IHJhdGU6IEl0J3MgYWxyZWFkeSBzZXQgKi8KICAgIFByZXNlbnRhdGlvbkludGVydmFsID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfREVGQVVMVDsKCiAgICBUUkFDRSgiUGFzc2luZyBtb2RlICVkXG4iLCBNb2RlLkZvcm1hdCk7CgogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJXaWR0aCAgICAgICAgICAgICAgICA9ICZNb2RlLldpZHRoOwogICAgbG9jYWxQYXJhbWV0ZXJzLkJhY2tCdWZmZXJIZWlnaHQgICAgICAgICAgICAgICA9ICZNb2RlLkhlaWdodDsKICAgIGxvY2FsUGFyYW1ldGVycy5CYWNrQnVmZmVyRm9ybWF0ICAgICAgICAgICAgICAgPSAoV0lORUQzREZPUk1BVCAqKSAmTW9kZS5Gb3JtYXQ7CiAgICBsb2NhbFBhcmFtZXRlcnMuQmFja0J1ZmZlckNvdW50ICAgICAgICAgICAgICAgID0gKFVJTlQgKikgJkJhY2tCdWZmZXJDb3VudDsKICAgIGxvY2FsUGFyYW1ldGVycy5NdWx0aVNhbXBsZVR5cGUgICAgICAgICAgICAgICAgPSAmTXVsdGlTYW1wbGVUeXBlOwogICAgbG9jYWxQYXJhbWV0ZXJzLk11bHRpU2FtcGxlUXVhbGl0eSAgICAgICAgICAgICA9ICZNdWx0aVNhbXBsZVF1YWxpdHk7CiAgICBsb2NhbFBhcmFtZXRlcnMuU3dhcEVmZmVjdCAgICAgICAgICAgICAgICAgICAgID0gJlN3YXBFZmZlY3Q7CiAgICBsb2NhbFBhcmFtZXRlcnMuaERldmljZVdpbmRvdyAgICAgICAgICAgICAgICAgID0gJndpbmRvdzsKICAgIGxvY2FsUGFyYW1ldGVycy5XaW5kb3dlZCAgICAgICAgICAgICAgICAgICAgICAgPSAmaXNXaW5kb3dlZDsKICAgIGxvY2FsUGFyYW1ldGVycy5FbmFibGVBdXRvRGVwdGhTdGVuY2lsICAgICAgICAgPSAmRW5hYmxlQXV0b0RlcHRoU3RlbmNpbDsKICAgIGxvY2FsUGFyYW1ldGVycy5BdXRvRGVwdGhTdGVuY2lsRm9ybWF0ICAgICAgICAgPSAmQXV0b0RlcHRoU3RlbmNpbEZvcm1hdDsKICAgIGxvY2FsUGFyYW1ldGVycy5GbGFncyAgICAgICAgICAgICAgICAgICAgICAgICAgPSAmRmxhZ3M7CiAgICBsb2NhbFBhcmFtZXRlcnMuRnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHogICAgID0gJkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6OwogICAgbG9jYWxQYXJhbWV0ZXJzLlByZXNlbnRhdGlvbkludGVydmFsICAgICAgICAgICA9ICZQcmVzZW50YXRpb25JbnRlcnZhbDsKCiAgICAvKiBTZXQgdGhpcyBOT1csIG90aGVyd2lzZSBjcmVhdGluZyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIHdpbGwgY2F1c2UgYQogICAgICogcmVjdXJzaXZlIGxvb3AgdW50aWwgcmFtIG9yIGVtdWxhdGVkIHZpZGVvIG1lbW9yeSBpcyBmdWxsCiAgICAgKi8KICAgIFRoaXMtPmQzZF9pbml0aWFsaXplZCA9IFRSVUU7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9Jbml0M0QoVGhpcy0+d2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsb2NhbFBhcmFtZXRlcnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0Q3Q0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbik7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIFRoaXMtPndpbmVEM0REZXZpY2UgPSBOVUxMOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBDcmVhdGUgYW4gSW5kZXggQnVmZmVyIHBhcmVudCAqLwogICAgVFJBQ0UoIiglcCkgU3VjY2Vzc2Z1bGx5IGluaXRpYWxpemVkIDNEXG4iLCBUaGlzKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdDcmVhdGVDbGlwcGVyIChERFJBVy5AKQogKgogKiBDcmVhdGVzIGEgbmV3IElEaXJlY3REcmF3Q2xpcHBlciBvYmplY3QuCiAqCiAqIFBhcmFtczoKICogIENsaXBwZXI6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIGludGVyZmFjZSBwb2ludGVyIHRvCiAqICBVbmtPdXRlcjogRm9yIGFnZ3JlZ2F0aW9uIHN1cHBvcnQsIHdoaWNoIGRkcmF3IGRvZXNuJ3QgaGF2ZS4gSGFzIHRvIGJlCiAqICAgICAgICAgICAgTlVMTAogKgogKiBSZXR1cm5zOgogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyICE9IE5VTEwKICogIEVfT1VUT0ZNRU1PUlkgaWYgYWxsb2NhdGluZyB0aGUgb2JqZWN0IGZhaWxlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdDcmVhdGVDbGlwcGVyKERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKipDbGlwcGVyLAogICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIElEaXJlY3REcmF3Q2xpcHBlckltcGwqIG9iamVjdDsKICAgIFRSQUNFKCIoJTA4eCwlcCwlcClcbiIsIEZsYWdzLCBDbGlwcGVyLCBVbmtPdXRlcik7CgogICAgaWYgKFVua091dGVyICE9IE5VTEwpIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAgICAgIHNpemVvZihJRGlyZWN0RHJhd0NsaXBwZXJJbXBsKSk7CiAgICBpZiAob2JqZWN0ID09IE5VTEwpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd0NsaXBwZXIsIElEaXJlY3REcmF3Q2xpcHBlcl9WdGJsKTsKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+aFduZCA9IDA7CiAgICBvYmplY3QtPmRkcmF3X293bmVyID0gTlVMTDsKCiAgICAqQ2xpcHBlciA9IChJRGlyZWN0RHJhd0NsaXBwZXIgKikgb2JqZWN0OwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXc3OjpDcmVhdGVDbGlwcGVyCiAqCiAqIENyZWF0ZXMgYSBERHJhdyBjbGlwcGVyLiBTZWUgRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIgZm9yIGRldGFpbHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdJbXBsX0NyZWF0ZUNsaXBwZXIoSURpcmVjdERyYXc3ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Q2xpcHBlciAqKkNsaXBwZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdJbXBsLCBJRGlyZWN0RHJhdzcsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgQ2xpcHBlciwgVW5rT3V0ZXIpOwogICAgcmV0dXJuIERpcmVjdERyYXdDcmVhdGVDbGlwcGVyKEZsYWdzLCBDbGlwcGVyLCBVbmtPdXRlcik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhdzc6OkNyZWF0ZVBhbGV0dGUKICoKICogQ3JlYXRlcyBhIG5ldyBJRGlyZWN0RHJhd1BhbGV0dGUgb2JqZWN0CiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBUaGUgZmxhZ3MgZm9yIHRoZSBuZXcgY2xpcHBlcgogKiAgQ29sb3JUYWJsZTogQ29sb3IgdGFibGUgdG8gYXNzaWduIHRvIHRoZSBuZXcgY2xpcHBlcgogKiAgUGFsZXR0ZTogQWRkcmVzcyB0byB3cml0ZSB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgdG8KICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24gc3VwcG9ydCwgd2hpY2ggZGRyYXcgZG9lc24ndCBoYXZlLiBIYXMgdG8gYmUKICogICAgICAgICAgICBOVUxMCiAqCiAqIFJldHVybnM6CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgIT0gTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBhbGxvY2F0aW5nIHRoZSBvYmplY3QgZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9DcmVhdGVQYWxldHRlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUxFVFRFRU5UUlkgKkNvbG9yVGFibGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqKlBhbGV0dGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwVW5rT3V0ZXIpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsICpvYmplY3Q7CiAgICBIUkVTVUxUIGhyID0gRERFUlJfR0VORVJJQzsKICAgIFRSQUNFKCIoJXApLT4oJXgsJXAsJXAsJXApXG4iLCBUaGlzLCBGbGFncywgQ29sb3JUYWJsZSwgUGFsZXR0ZSwgcFVua091dGVyKTsKCiAgICBpZihwVW5rT3V0ZXIgIT0gTlVMTCkKICAgIHsKICAgICAgICBXQVJOKCJwVW5rT3V0ZXIgaXMgJXAsIHJldHVybmluZyBDTEFTU19FX05PQUdHUkVHQVRJT05cbiIsIHBVbmtPdXRlcik7CiAgICAgICAgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKICAgIH0KCiAgICAvKiBUaGUgcmVmY291bnQgdGVzdCBzaG93cyB0aGF0IGEgY29vcGxldmVsIGlzIHJlcXVpcmVkIGZvciB0aGlzICovCiAgICBpZighVGhpcy0+Y29vcGVyYXRpdmVfbGV2ZWwpCiAgICB7CiAgICAgICAgV0FSTigiTm8gY29vcGVyYXRpdmUgbGV2ZWwgc2V0LCByZXR1cm5pbmcgRERFUlJfTk9DT09QRVJBVElWRUxFVkVMU0VUXG4iKTsKICAgICAgICByZXR1cm4gRERFUlJfTk9DT09QRVJBVElWRUxFVkVMU0VUOwogICAgfQoKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoSURpcmVjdERyYXdQYWxldHRlSW1wbCkpOwogICAgaWYoIW9iamVjdCkKICAgIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBhbGxvY2F0aW5nIG1lbW9yeSBmb3IgYSBwYWxldHRlIGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlLCBJRGlyZWN0RHJhd1BhbGV0dGVfVnRibCk7CiAgICBvYmplY3QtPnJlZiA9IDE7CiAgICBvYmplY3QtPmRkcmF3X293bmVyID0gVGhpczsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVBhbGV0dGUoVGhpcy0+d2luZUQzRERldmljZSwgRmxhZ3MsIENvbG9yVGFibGUsICZvYmplY3QtPndpbmVEM0RQYWxldHRlLCAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0Uob2JqZWN0LCBJRGlyZWN0RHJhd1BhbGV0dGUpICk7CiAgICBpZihociAhPSBERF9PSykKICAgIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBJRGlyZWN0RHJhdzdfQWRkUmVmKGlmYWNlKTsKICAgIG9iamVjdC0+aWZhY2VUb1JlbGVhc2UgPSAoSVVua25vd24gKikgaWZhY2U7CiAgICAqUGFsZXR0ZSA9IElDT01fSU5URVJGQUNFKG9iamVjdCwgSURpcmVjdERyYXdQYWxldHRlKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Nzo6RHVwbGljYXRlU3VyZmFjZQogKgogKiBEdXBsaWNhdGVzIGEgc3VyZmFjZS4gVGhlIHN1cmZhY2UgbWVtb3J5IHBvaW50cyB0byB0aGUgc2FtZSBtZW1vcnkgYXMKICogdGhlIG9yaWdpbmFsIHN1cmZhY2UsIGFuZCBpdCdzIHJlbGVhc2VkIHdoZW4gdGhlIGxhc3Qgc3VyZmFjZSByZWZlcmVuY2luZwogKiBpdCBpcyByZWxlYXNlZC4gSSBndWVzcyB0aGF0J3MgYmV5b25kIFdpbmUncyBzdXJmYWNlIG1hbmFnZW1lbnQgcmlnaHQgbm93CiAqIChJZGVhOiBjcmVhdGUgYSBuZXcgRERyYXcgc3VyZmFjZSB3aXRoIHRoZSBzYW1lIFdpbmVEM0RTdXJmYWNlLiBJIG5lZWQgYQogKiB0ZXN0IGFwcGxpY2F0aW9uIHRvIGltcGxlbWVudCB0aGlzKQogKgogKiBQYXJhbXM6CiAqICBTcmM6IEFkZHJlc3Mgb2YgdGhlIHNvdXJjZSBzdXJmYWNlCiAqICBEZXN0OiBBZGRyZXNzIHRvIHdyaXRlIHRoZSBuZXcgc3VyZmFjZSBwb2ludGVyIHRvCiAqCiAqIFJldHVybnM6CiAqICBTZWUgSURpcmVjdERyYXc3OjpDcmVhdGVTdXJmYWNlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3SW1wbF9EdXBsaWNhdGVTdXJmYWNlKElEaXJlY3REcmF3NyAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3REcmF3U3VyZmFjZTcgKlNyYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlNyAqKkRlc3QpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3SW1wbCwgSURpcmVjdERyYXc3LCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpTdXJmID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgU3JjKTsKCiAgICBGSVhNRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgU3VyZiwgRGVzdCk7CgogICAgLyogRm9yIG5vdywgc2ltcGx5IGNyZWF0ZSBhIG5ldywgaW5kZXBlbmRlbnQgc3VyZmFjZSAqLwogICAgcmV0dXJuIElEaXJlY3REcmF3N19DcmVhdGVTdXJmYWNlKGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdXJmLT5zdXJmYWNlX2Rlc2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3NyBWVGFibGUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpjb25zdCBJRGlyZWN0RHJhdzdWdGJsIElEaXJlY3REcmF3N19WdGJsID0KewogICAgLyoqKiBJVW5rbm93biAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfQWRkUmVmLAogICAgSURpcmVjdERyYXdJbXBsX1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3REcmF3ICoqKi8KICAgIElEaXJlY3REcmF3SW1wbF9Db21wYWN0LAogICAgSURpcmVjdERyYXdJbXBsX0NyZWF0ZUNsaXBwZXIsCiAgICBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlUGFsZXR0ZSwKICAgIElEaXJlY3REcmF3SW1wbF9DcmVhdGVTdXJmYWNlLAogICAgSURpcmVjdERyYXdJbXBsX0R1cGxpY2F0ZVN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfRW51bURpc3BsYXlNb2RlcywKICAgIElEaXJlY3REcmF3SW1wbF9FbnVtU3VyZmFjZXMsCiAgICBJRGlyZWN0RHJhd0ltcGxfRmxpcFRvR0RJU3VyZmFjZSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRDYXBzLAogICAgSURpcmVjdERyYXdJbXBsX0dldERpc3BsYXlNb2RlLAogICAgSURpcmVjdERyYXdJbXBsX0dldEZvdXJDQ0NvZGVzLAogICAgSURpcmVjdERyYXdJbXBsX0dldEdESVN1cmZhY2UsCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0TW9uaXRvckZyZXF1ZW5jeSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRTY2FuTGluZSwKICAgIElEaXJlY3REcmF3SW1wbF9HZXRWZXJ0aWNhbEJsYW5rU3RhdHVzLAogICAgSURpcmVjdERyYXdJbXBsX0luaXRpYWxpemUsCiAgICBJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZURpc3BsYXlNb2RlLAogICAgSURpcmVjdERyYXdJbXBsX1NldENvb3BlcmF0aXZlTGV2ZWwsCiAgICBJRGlyZWN0RHJhd0ltcGxfU2V0RGlzcGxheU1vZGUsCiAgICBJRGlyZWN0RHJhd0ltcGxfV2FpdEZvclZlcnRpY2FsQmxhbmssCiAgICAvKioqIElEaXJlY3REcmF3MiAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfR2V0QXZhaWxhYmxlVmlkTWVtLAogICAgLyoqKiBJRGlyZWN0RHJhdzcgKioqLwogICAgSURpcmVjdERyYXdJbXBsX0dldFN1cmZhY2VGcm9tREMsCiAgICBJRGlyZWN0RHJhd0ltcGxfUmVzdG9yZUFsbFN1cmZhY2VzLAogICAgSURpcmVjdERyYXdJbXBsX1Rlc3RDb29wZXJhdGl2ZUxldmVsLAogICAgSURpcmVjdERyYXdJbXBsX0dldERldmljZUlkZW50aWZpZXIsCiAgICAvKioqIElEaXJlY3REcmF3NyAqKiovCiAgICBJRGlyZWN0RHJhd0ltcGxfU3RhcnRNb2RlVGVzdCwKICAgIElEaXJlY3REcmF3SW1wbF9FdmFsdWF0ZU1vZGUKfTsK