LyoKICogQ29udGV4dCBhbmQgcmVuZGVyIHRhcmdldCBtYW5hZ2VtZW50IGluIHdpbmVkM2QKICoKICogQ29weXJpZ2h0IDIwMDctMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpZmRlZiBIQVZFX0ZMT0FUX0gKIyBpbmNsdWRlIDxmbG9hdC5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkKTsKCiNkZWZpbmUgR0xJTkZPX0xPQ0FUSU9OIFRoaXMtPmFkYXB0ZXItPmdsX2luZm8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb250ZXh0X01hcmtTdGF0ZURpcnR5CiAqCiAqIE1hcmtzIGEgc3RhdGUgaW4gYSBjb250ZXh0IGRpcnR5LiBPbmx5IG9uZSBjb250ZXh0LCBvcHBvc2VkIHRvCiAqIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eSwgd2hpY2ggbWFya3MgdGhlIHN0YXRlIGRpcnR5IGluIGFsbAogKiBjb250ZXh0cwogKgogKiBQYXJhbXM6CiAqICBjb250ZXh0OiBDb250ZXh0IHRvIG1hcmsgdGhlIHN0YXRlIGRpcnR5IGluCiAqICBzdGF0ZTogU3RhdGUgdG8gbWFyayBkaXJ0eQogKiAgU3RhdGVUYWJsZTogUG9pbnRlciB0byB0aGUgc3RhdGUgdGFibGUgaW4gdXNlKGZvciBzdGF0ZSBncm91cGluZykKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBDb250ZXh0X01hcmtTdGF0ZURpcnR5KFdpbmVEM0RDb250ZXh0ICpjb250ZXh0LCBEV09SRCBzdGF0ZSwgY29uc3Qgc3RydWN0IFN0YXRlRW50cnkgKlN0YXRlVGFibGUpIHsKICAgIERXT1JEIHJlcCA9IFN0YXRlVGFibGVbc3RhdGVdLnJlcHJlc2VudGF0aXZlOwogICAgRFdPUkQgaWR4OwogICAgQllURSBzaGlmdDsKCiAgICBpZighcmVwIHx8IGlzU3RhdGVEaXJ0eShjb250ZXh0LCByZXApKSByZXR1cm47CgogICAgY29udGV4dC0+ZGlydHlBcnJheVtjb250ZXh0LT5udW1EaXJ0eUVudHJpZXMrK10gPSByZXA7CiAgICBpZHggPSByZXAgPj4gNTsKICAgIHNoaWZ0ID0gcmVwICYgMHgxZjsKICAgIGNvbnRleHQtPmlzU3RhdGVEaXJ0eVtpZHhdIHw9ICgxIDw8IHNoaWZ0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFkZENvbnRleHRUb0FycmF5CiAqCiAqIEFkZHMgYSBjb250ZXh0IHRvIHRoZSBjb250ZXh0IGFycmF5LiBIZWxwZXIgZnVuY3Rpb24gZm9yIENyZWF0ZUNvbnRleHQKICoKICogVGhpcyBtZXRob2QgaXMgbm90IGNhbGxlZCBpbiBwZXJmb3JtYW5jZS1jcml0aWNhbCBjb2RlIHBhdGhzLCBvbmx5IHdoZW4gYQogKiBuZXcgcmVuZGVyIHRhcmdldCBvciBzd2FwY2hhaW4gaXMgY3JlYXRlZC4gVGh1cyBwZXJmb3JtYW5jZSBpcyBub3QgYW4gaXNzdWUKICogaGVyZS4KICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFkZCB0aGUgY29udGV4dCBmb3IKICogIGhkYzogZGV2aWNlIGNvbnRleHQKICogIGdsQ3R4OiBXR0wgY29udGV4dCB0byBhZGQKICogIHBidWZmZXI6IG9wdGlvbmFsIHBidWZmZXIgdXNlZCB3aXRoIHRoaXMgY29udGV4dAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBXaW5lRDNEQ29udGV4dCAqQWRkQ29udGV4dFRvQXJyYXkoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBIV05EIHdpbl9oYW5kbGUsIEhEQyBoZGMsIEhHTFJDIGdsQ3R4LCBIUEJVRkZFUkFSQiBwYnVmZmVyKSB7CiAgICBXaW5lRDNEQ29udGV4dCAqKm9sZEFycmF5ID0gVGhpcy0+Y29udGV4dHM7CiAgICBEV09SRCBzdGF0ZTsKCiAgICBUaGlzLT5jb250ZXh0cyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMtPmNvbnRleHRzKSAqIChUaGlzLT5udW1Db250ZXh0cyArIDEpKTsKICAgIGlmKFRoaXMtPmNvbnRleHRzID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBncm93IHRoZSBjb250ZXh0IGFycmF5XG4iKTsKICAgICAgICBUaGlzLT5jb250ZXh0cyA9IG9sZEFycmF5OwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgaWYob2xkQXJyYXkpIHsKICAgICAgICBtZW1jcHkoVGhpcy0+Y29udGV4dHMsIG9sZEFycmF5LCBzaXplb2YoKlRoaXMtPmNvbnRleHRzKSAqIFRoaXMtPm51bUNvbnRleHRzKTsKICAgIH0KCiAgICBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0c10gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFdpbmVEM0RDb250ZXh0KSk7CiAgICBpZihUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0c10gPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGFsbG9jYXRlIGEgbmV3IGNvbnRleHRcbiIpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmNvbnRleHRzKTsKICAgICAgICBUaGlzLT5jb250ZXh0cyA9IG9sZEFycmF5OwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXS0+aGRjID0gaGRjOwogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT5nbEN0eCA9IGdsQ3R4OwogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT5wYnVmZmVyID0gcGJ1ZmZlcjsKICAgIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXS0+d2luX2hhbmRsZSA9IHdpbl9oYW5kbGU7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvbGRBcnJheSk7CgogICAgLyogTWFyayBhbGwgc3RhdGVzIGRpcnR5IHRvIGZvcmNlIGEgcHJvcGVyIGluaXRpYWxpemF0aW9uIG9mIHRoZSBzdGF0ZXMgb24gdGhlIGZpcnN0IHVzZSBvZiB0aGUgY29udGV4dAogICAgICovCiAgICBmb3Ioc3RhdGUgPSAwOyBzdGF0ZSA8PSBTVEFURV9ISUdIRVNUOyBzdGF0ZSsrKSB7CiAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0c10sIHN0YXRlLCBUaGlzLT5zaGFkZXJfYmFja2VuZC0+U3RhdGVUYWJsZSk7CiAgICB9CgogICAgVGhpcy0+bnVtQ29udGV4dHMrKzsKICAgIFRSQUNFKCJDcmVhdGVkIGNvbnRleHQgJXBcbiIsIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzIC0gMV0pOwogICAgcmV0dXJuIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzIC0gMV07Cn0KCi8qIFRoaXMgZnVuY3Rpb24gdGFrZXMgY2FyZSBvZiBXaW5lRDNEIHBpeGVsIGZvcm1hdCBzZWxlY3Rpb24uICovCnN0YXRpYyBpbnQgV2luZUQzRF9DaG9vc2VQaXhlbEZvcm1hdChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIEhEQyBoZGMsIFdJTkVEM0RGT1JNQVQgQ29sb3JGb3JtYXQsIFdJTkVEM0RGT1JNQVQgRGVwdGhTdGVuY2lsRm9ybWF0LCBCT09MIGF1eEJ1ZmZlcnMsIGludCBudW1TYW1wbGVzLCBCT09MIHBidWZmZXIsIEJPT0wgZmluZENvbXBhdGlibGUpCnsKICAgIGludCBpUGl4ZWxGb3JtYXQ9MDsKICAgIHNob3J0IHJlZEJpdHMsIGdyZWVuQml0cywgYmx1ZUJpdHMsIGFscGhhQml0cywgY29sb3JCaXRzOwogICAgc2hvcnQgZGVwdGhCaXRzPTAsIHN0ZW5jaWxCaXRzPTA7CgogICAgaW50IGkgPSAwOwogICAgaW50IG5DZmdzID0gVGhpcy0+YWRhcHRlci0+bkNmZ3M7CiAgICBXaW5lRDNEX1BpeGVsRm9ybWF0ICpjZmdzID0gVGhpcy0+YWRhcHRlci0+Y2ZnczsKCiAgICBpZighZ2V0Q29sb3JCaXRzKENvbG9yRm9ybWF0LCAmcmVkQml0cywgJmdyZWVuQml0cywgJmJsdWVCaXRzLCAmYWxwaGFCaXRzLCAmY29sb3JCaXRzKSkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGdldCBjb2xvciBiaXRzIGZvciBmb3JtYXQgJXMgKCUjeCkhXG4iLCBkZWJ1Z19kM2Rmb3JtYXQoQ29sb3JGb3JtYXQpLCBDb2xvckZvcm1hdCk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYoRGVwdGhTdGVuY2lsRm9ybWF0KSB7CiAgICAgICAgZ2V0RGVwdGhTdGVuY2lsQml0cyhEZXB0aFN0ZW5jaWxGb3JtYXQsICZkZXB0aEJpdHMsICZzdGVuY2lsQml0cyk7CiAgICB9CgogICAgLyogRmluZCBhIHBpeGVsIGZvcm1hdCB3aGljaCBFWEFDVExZIG1hdGNoZXMgb3VyIHJlcXVpcmVtZW50cyAoZXhjZXB0IGZvciBkZXB0aCkgKi8KICAgIGZvcihpPTA7IGk8bkNmZ3M7IGkrKykgewogICAgICAgIEJPT0wgZXhhY3REZXB0aE1hdGNoID0gVFJVRTsKICAgICAgICBjZmdzID0gJlRoaXMtPmFkYXB0ZXItPmNmZ3NbaV07CgogICAgICAgIC8qIEZvciBub3cgb25seSBhY2NlcHQgUkdCQSBmb3JtYXRzLiBQZXJoYXBzIHNvbWUgZGF5IHdlIHdpbGwKICAgICAgICAgKiBhbGxvdyBmbG9hdGluZyBwb2ludCBmb3JtYXRzIGZvciBwYnVmZmVycy4gKi8KICAgICAgICBpZihjZmdzLT5pUGl4ZWxUeXBlICE9IFdHTF9UWVBFX1JHQkFfQVJCKQogICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgLyogSW4gd2luZG93IG1vZGUgKCFwYnVmZmVyKSB3ZSBuZWVkIGEgd2luZG93IGRyYXdhYmxlIGZvcm1hdCBhbmQgZG91YmxlIGJ1ZmZlcmluZy4gKi8KICAgICAgICBpZighcGJ1ZmZlciAmJiAhKGNmZ3MtPndpbmRvd0RyYXdhYmxlICYmIGNmZ3MtPmRvdWJsZUJ1ZmZlcikpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAvKiBXZSBsaWtlIHRvIGhhdmUgYXV4IGJ1ZmZlcnMgaW4gYmFja2J1ZmZlciBtb2RlICovCiAgICAgICAgaWYoYXV4QnVmZmVycyAmJiAhY2Zncy0+YXV4QnVmZmVycykKICAgICAgICAgICAgY29udGludWU7CgogICAgICAgIC8qIEluIHBidWZmZXItbW9kZSB3ZSBuZWVkIGEgcGJ1ZmZlci1jYXBhYmxlIGZvcm1hdCBidXQgd2UgZG9uJ3Qgd2FudCBkb3VibGUgYnVmZmVyaW5nICovCiAgICAgICAgaWYocGJ1ZmZlciAmJiAoIWNmZ3MtPnBidWZmZXJEcmF3YWJsZSB8fCBjZmdzLT5kb3VibGVCdWZmZXIpKQogICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgaWYoY2Zncy0+cmVkU2l6ZSAhPSByZWRCaXRzKQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICBpZihjZmdzLT5ncmVlblNpemUgIT0gZ3JlZW5CaXRzKQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICBpZihjZmdzLT5ibHVlU2l6ZSAhPSBibHVlQml0cykKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgaWYoY2Zncy0+YWxwaGFTaXplICE9IGFscGhhQml0cykKICAgICAgICAgICAgY29udGludWU7CgogICAgICAgIC8qIFdlIHRyeSB0byBsb2NhdGUgYSBmb3JtYXQgd2hpY2ggbWF0Y2hlcyBvdXIgcmVxdWlyZW1lbnRzIGV4YWN0bHkuIEluIGNhc2Ugb2YKICAgICAgICAgKiBkZXB0aCBpdCBpcyBubyBwcm9ibGVtIHRvIGVtdWxhdGUgMTYtYml0IHVzaW5nIGUuZy4gMjQtYml0LCBzbyBhY2NlcHQgdGhhdC4gKi8KICAgICAgICBpZihjZmdzLT5kZXB0aFNpemUgPCBkZXB0aEJpdHMpCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIGVsc2UgaWYoY2Zncy0+ZGVwdGhTaXplID4gZGVwdGhCaXRzKQogICAgICAgICAgICBleGFjdERlcHRoTWF0Y2ggPSBGQUxTRTsKCiAgICAgICAgLyogSW4gYWxsIGNhc2VzIG1ha2Ugc3VyZSB0aGUgbnVtYmVyIG9mIHN0ZW5jaWwgYml0cyBtYXRjaGVzIG91ciByZXF1aXJlbWVudHMKICAgICAgICAgKiBldmVuIHdoZW4gd2UgZG9uJ3QgbmVlZCBzdGVuY2lsIGJlY2F1c2UgaXQgY291bGQgYWZmZWN0IHBlcmZvcm1hbmNlICovCiAgICAgICAgaWYoIShjZmdzLT5zdGVuY2lsU2l6ZSA9PSBzdGVuY2lsQml0cykpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAvKiBDaGVjayBtdWx0aXNhbXBsaW5nIHN1cHBvcnQgKi8KICAgICAgICBpZihjZmdzLT5udW1TYW1wbGVzICE9IG51bVNhbXBsZXMpCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAvKiBXaGVuIHdlIGhhdmUgcGFzc2VkIGFsbCB0aGUgY2hlY2tzIHRoZW4gd2UgaGF2ZSBmb3VuZCBhIGZvcm1hdCB3aGljaCBtYXRjaGVzIG91cgogICAgICAgICAqIHJlcXVpcmVtZW50cy4gTm90ZSB0aGF0IHdlIG9ubHkgY2hlY2sgZm9yIGEgbGltaXQgbnVtYmVyIG9mIGNhcGFiaWxpdGllcyByaWdodCBub3csCiAgICAgICAgICogc28gdGhlcmUgY2FuIGVhc2lseSBiZSBhIGRvemVuIG9mIHBpeGVsIGZvcm1hdHMgd2hpY2ggYXBwZWFyIHRvIGJlIHRoZSAnc2FtZScgYnV0CiAgICAgICAgICogY2FuIHN0aWxsIGRpZmZlciBpbiB0aGluZ3MgbGlrZSBtdWx0aXNhbXBsaW5nLCBzdGVyZW8sIFNSR0IgYW5kIG90aGVyIGZsYWdzLgogICAgICAgICAqLwoKICAgICAgICAvKiBFeGl0IHRoZSBsb29wIGFzIHdlIGhhdmUgZm91bmQgYSBmb3JtYXQgOikgKi8KICAgICAgICBpZihleGFjdERlcHRoTWF0Y2gpIHsKICAgICAgICAgICAgaVBpeGVsRm9ybWF0ID0gY2Zncy0+aVBpeGVsRm9ybWF0OwogICAgICAgICAgICBicmVhazsKICAgICAgICB9IGVsc2UgaWYoIWlQaXhlbEZvcm1hdCkgewogICAgICAgICAgICAvKiBJbiB0aGUgZW5kIHdlIG1pZ2h0IGVuZCB1cCB3aXRoIGEgZm9ybWF0IHdoaWNoIGRvZXNuJ3QgZXhhY3RseSBtYXRjaCBvdXIgZGVwdGgKICAgICAgICAgICAgICogcmVxdWlyZW1lbnRzLiBBY2NlcHQgdGhlIGZpcnN0IGZvcm1hdCB3ZSBmb3VuZCBiZWNhdXNlIGZvcm1hdHMgd2l0aCBoaWdoZXIgaVBpeGVsRm9ybWF0CiAgICAgICAgICAgICAqIHZhbHVlcyB0ZW5kIHRvIGhhdmUgbW9yZSBleHRlbmRlZCBjYXBhYmlsaXRpZXMgKGUuZy4gbXVsdGlzYW1wbGluZykgd2hpY2ggd2UgZG9uJ3QgbmVlZC4gKi8KICAgICAgICAgICAgaVBpeGVsRm9ybWF0ID0gY2Zncy0+aVBpeGVsRm9ybWF0OwogICAgICAgIH0KICAgIH0KCiAgICAvKiBXaGVuIGZpbmRDb21wYXRpYmxlIGlzIHNldCBhbmQgbm8gc3VpdGFibGUgZm9ybWF0IHdhcyBmb3VuZCwgbGV0IENob29zZVBpeGVsRm9ybWF0IGNob29zZSBhIHBpeGVsIGZvcm1hdCBpbiBvcmRlciBub3QgdG8gY3Jhc2guICovCiAgICBpZighaVBpeGVsRm9ybWF0ICYmICFmaW5kQ29tcGF0aWJsZSkgewogICAgICAgIEVSUigiQ2FuJ3QgZmluZCBhIHN1aXRhYmxlIGlQaXhlbEZvcm1hdFxuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfSBlbHNlIGlmKCFpUGl4ZWxGb3JtYXQpIHsKICAgICAgICBQSVhFTEZPUk1BVERFU0NSSVBUT1IgcGZkOwoKICAgICAgICBUUkFDRSgiRmFsbGluZyBiYWNrIHRvIENob29zZVBpeGVsRm9ybWF0IGFzIHdlIHdlcmVuJ3QgYWJsZSB0byBmaW5kIGFuIGV4YWN0bHkgbWF0Y2hpbmcgcGl4ZWwgZm9ybWF0XG4iKTsKICAgICAgICAvKiBQaXhlbEZvcm1hdCBzZWxlY3Rpb24gKi8KICAgICAgICBaZXJvTWVtb3J5KCZwZmQsIHNpemVvZihwZmQpKTsKICAgICAgICBwZmQublNpemUgICAgICA9IHNpemVvZihwZmQpOwogICAgICAgIHBmZC5uVmVyc2lvbiAgID0gMTsKICAgICAgICBwZmQuZHdGbGFncyAgICA9IFBGRF9TVVBQT1JUX09QRU5HTCB8IFBGRF9ET1VCTEVCVUZGRVIgfCBQRkRfRFJBV19UT19XSU5ET1c7LypQRkRfR0VORVJJQ19BQ0NFTEVSQVRFRCovCiAgICAgICAgcGZkLmlQaXhlbFR5cGUgPSBQRkRfVFlQRV9SR0JBOwogICAgICAgIHBmZC5jQWxwaGFCaXRzID0gYWxwaGFCaXRzOwogICAgICAgIHBmZC5jQ29sb3JCaXRzID0gY29sb3JCaXRzOwogICAgICAgIHBmZC5jRGVwdGhCaXRzID0gZGVwdGhCaXRzOwogICAgICAgIHBmZC5jU3RlbmNpbEJpdHMgPSBzdGVuY2lsQml0czsKICAgICAgICBwZmQuaUxheWVyVHlwZSA9IFBGRF9NQUlOX1BMQU5FOwoKICAgICAgICBpUGl4ZWxGb3JtYXQgPSBDaG9vc2VQaXhlbEZvcm1hdChoZGMsICZwZmQpOwogICAgICAgIGlmKCFpUGl4ZWxGb3JtYXQpIHsKICAgICAgICAgICAgLyogSWYgdGhpcyBoYXBwZW5zIHNvbWV0aGluZyBpcyB2ZXJ5IHdyb25nIGFzIENob29zZVBpeGVsRm9ybWF0IGJhcmVseSBmYWlscyAqLwogICAgICAgICAgICBFUlIoIkNhbid0IGZpbmQgYSBzdWl0YWJsZSBpUGl4ZWxGb3JtYXRcbiIpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCJGb3VuZCBpUGl4ZWxGb3JtYXQ9JWQgZm9yIENvbG9yRm9ybWF0PSVzLCBEZXB0aFN0ZW5jaWxGb3JtYXQ9JXNcbiIsIGlQaXhlbEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KENvbG9yRm9ybWF0KSwgZGVidWdfZDNkZm9ybWF0KERlcHRoU3RlbmNpbEZvcm1hdCkpOwogICAgcmV0dXJuIGlQaXhlbEZvcm1hdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENyZWF0ZUNvbnRleHQKICoKICogQ3JlYXRlcyBhIG5ldyBjb250ZXh0IGZvciBhIHdpbmRvdywgb3IgYSBwYnVmZmVyIGNvbnRleHQuCiAqCiAqICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgdGFyZ2V0OiBTdXJmYWNlIHRoaXMgY29udGV4dCB3aWxsIHJlbmRlciB0bwogKiAgd2luX2hhbmRsZTogaGFuZGxlIHRvIHRoZSB3aW5kb3cgd2hpY2ggd2UgYXJlIGRyYXdpbmcgdG8KICogIGNyZWF0ZV9wYnVmZmVyOiB0ZWxscyB3aGV0aGVyIHRvIGNyZWF0ZSBhIHBidWZmZXIgb3Igbm90CiAqICBwUHJlc2VudFBhcmFtZXRlcnM6IGNvbnRhaW5zIHRoZSBwaXhlbGZvcm1hdHMgdG8gdXNlIGZvciBvbnNjcmVlbiByZW5kZXJpbmcKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpXaW5lRDNEQ29udGV4dCAqQ3JlYXRlQ29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCwgSFdORCB3aW5faGFuZGxlLCBCT09MIGNyZWF0ZV9wYnVmZmVyLCBjb25zdCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTICpwUHJlc2VudFBhcm1zKSB7CiAgICBIREMgb2xkRHJhd2FibGUsIGhkYzsKICAgIEhQQlVGRkVSQVJCIHBidWZmZXIgPSBOVUxMOwogICAgSEdMUkMgY3R4ID0gTlVMTCwgb2xkQ3R4OwogICAgV2luZUQzRENvbnRleHQgKnJldCA9IE5VTEw7CiAgICBpbnQgczsKCiAgICBUUkFDRSgiKCVwKTogQ3JlYXRpbmcgYSAlcyBjb250ZXh0IGZvciByZW5kZXIgdGFyZ2V0ICVwXG4iLCBUaGlzLCBjcmVhdGVfcGJ1ZmZlciA/ICJvZmZzY3JlZW4iIDogIm9uc2NyZWVuIiwgdGFyZ2V0KTsKCiAgICBpZihjcmVhdGVfcGJ1ZmZlcikgewogICAgICAgIEhEQyBoZGNfcGFyZW50ID0gR2V0REMod2luX2hhbmRsZSk7CiAgICAgICAgaW50IGlQaXhlbEZvcm1hdCA9IDA7CgogICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU3RlbmNpbFN1cmZhY2UgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgICAgIFdJTkVEM0RGT1JNQVQgU3RlbmNpbEJ1ZmZlckZvcm1hdCA9IChOVUxMICE9IFN0ZW5jaWxTdXJmYWNlKSA/ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTdGVuY2lsU3VyZmFjZSktPnJlc291cmNlLmZvcm1hdCA6IDA7CgogICAgICAgIC8qIFRyeSB0byBmaW5kIGEgcGl4ZWwgZm9ybWF0IHdpdGggcGJ1ZmZlciBzdXBwb3J0LiAqLwogICAgICAgIGlQaXhlbEZvcm1hdCA9IFdpbmVEM0RfQ2hvb3NlUGl4ZWxGb3JtYXQoVGhpcywgaGRjX3BhcmVudCwgdGFyZ2V0LT5yZXNvdXJjZS5mb3JtYXQsIFN0ZW5jaWxCdWZmZXJGb3JtYXQsIEZBTFNFIC8qIGF1eEJ1ZmZlcnMgKi8sIDAgLyogbnVtU2FtcGxlcyAqLywgVFJVRSAvKiBQQlVGRkVSICovLCBGQUxTRSAvKiBmaW5kQ29tcGF0aWJsZSAqLyk7CiAgICAgICAgaWYoIWlQaXhlbEZvcm1hdCkgewogICAgICAgICAgICBUUkFDRSgiVHJ5aW5nIHRvIGxvY2F0ZSBhIGNvbXBhdGlibGUgcGl4ZWwgZm9ybWF0IGJlY2F1c2UgYW4gZXhhY3QgbWF0Y2ggZmFpbGVkLlxuIik7CgogICAgICAgICAgICAvKiBGb3Igc29tZSByZWFzb24gd2Ugd2VyZW4ndCBhYmxlIHRvIGZpbmQgYSBmb3JtYXQsIHRyeSB0byBmaW5kIHNvbWV0aGluZyBpbnN0ZWFkIG9mIGNyYXNoaW5nLgogICAgICAgICAgICAgKiBBIHJlYXNvbiBmb3IgZmFpbHVyZSBjb3VsZCBoYXZlIGJlZW4gd2dsQ2hvb3NlUGl4ZWxGb3JtYXRBUkIgc3RyaWN0bmVzcy4gKi8KICAgICAgICAgICAgaVBpeGVsRm9ybWF0ID0gV2luZUQzRF9DaG9vc2VQaXhlbEZvcm1hdChUaGlzLCBoZGNfcGFyZW50LCB0YXJnZXQtPnJlc291cmNlLmZvcm1hdCwgU3RlbmNpbEJ1ZmZlckZvcm1hdCwgRkFMU0UgLyogYXV4QnVmZmVyICovLCAwIC8qIG51bVNhbXBsZXMgKi8sIFRSVUUgLyogUEJVRkZFUiAqLywgVFJVRSAvKiBmaW5kQ29tcGF0aWJsZSAqLyk7CiAgICAgICAgfQoKICAgICAgICAvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4gYXMgQ2hvb3NlUGl4ZWxGb3JtYXQgYWx3YXlzIHJldHVybnMgc29tZXRoaW5nICovCiAgICAgICAgaWYoIWlQaXhlbEZvcm1hdCkgewogICAgICAgICAgICBFUlIoIlVuYWJsZSB0byBsb2NhdGUgYSBwaXhlbCBmb3JtYXQgZm9yIGEgcGJ1ZmZlclxuIik7CiAgICAgICAgICAgIFJlbGVhc2VEQyh3aW5faGFuZGxlLCBoZGNfcGFyZW50KTsKICAgICAgICAgICAgZ290byBvdXQ7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgYSBwQnVmZmVyIGRyYXdhYmxlIGZvciB0aGUgbmV3IGNvbnRleHRcbiIpOwogICAgICAgIHBidWZmZXIgPSBHTF9FWFRDQUxMKHdnbENyZWF0ZVBidWZmZXJBUkIoaGRjX3BhcmVudCwgaVBpeGVsRm9ybWF0LCB0YXJnZXQtPmN1cnJlbnREZXNjLldpZHRoLCB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCwgMCkpOwogICAgICAgIGlmKCFwYnVmZmVyKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBhIHBidWZmZXJcbiIpOwogICAgICAgICAgICBSZWxlYXNlREMod2luX2hhbmRsZSwgaGRjX3BhcmVudCk7CiAgICAgICAgICAgIGdvdG8gb3V0OwogICAgICAgIH0KCiAgICAgICAgLyogSW4gV0dMIGEgcGJ1ZmZlciBpcyAnd3JhcHBlZCcgaW5zaWRlIGEgSERDIHRvICdmb29sJyB3Z2xNYWtlQ3VycmVudCAqLwogICAgICAgIGhkYyA9IEdMX0VYVENBTEwod2dsR2V0UGJ1ZmZlckRDQVJCKHBidWZmZXIpKTsKICAgICAgICBpZighaGRjKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IGdldCBhIEhEQyBmb3IgcGJ1ZmZlciAoJXApXG4iLCBwYnVmZmVyKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTCh3Z2xEZXN0cm95UGJ1ZmZlckFSQihwYnVmZmVyKSk7CiAgICAgICAgICAgIFJlbGVhc2VEQyh3aW5faGFuZGxlLCBoZGNfcGFyZW50KTsKICAgICAgICAgICAgZ290byBvdXQ7CiAgICAgICAgfQogICAgICAgIFJlbGVhc2VEQyh3aW5faGFuZGxlLCBoZGNfcGFyZW50KTsKICAgIH0gZWxzZSB7CiAgICAgICAgUElYRUxGT1JNQVRERVNDUklQVE9SIHBmZDsKICAgICAgICBpbnQgaVBpeGVsRm9ybWF0OwogICAgICAgIGludCByZXM7CiAgICAgICAgV0lORUQzREZPUk1BVCBDb2xvckZvcm1hdCA9IHRhcmdldC0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIFdJTkVEM0RGT1JNQVQgRGVwdGhTdGVuY2lsRm9ybWF0ID0gMDsKICAgICAgICBCT09MIGF1eEJ1ZmZlcnMgPSBGQUxTRTsKICAgICAgICBpbnQgbnVtU2FtcGxlcyA9IDA7CgogICAgICAgIGhkYyA9IEdldERDKHdpbl9oYW5kbGUpOwogICAgICAgIGlmKGhkYyA9PSBOVUxMKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IHJldHJpZXZlIGEgZGV2aWNlIGNvbnRleHQhXG4iKTsKICAgICAgICAgICAgZ290byBvdXQ7CiAgICAgICAgfQoKICAgICAgICAvKiBJbiBjYXNlIG9mIE9STV9CQUNLQlVGRkVSLCBtYWtlIHN1cmUgdG8gcmVxdWVzdCBhbiBhbHBoYSBjb21wb25lbnQgZm9yIFg0UjRHNEI0L1g4UjhHOEI4IGFzIHdlIG1pZ2h0IG5lZWQgaXQgZm9yIHRoZSBiYWNrYnVmZmVyLiAqLwogICAgICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9CQUNLQlVGRkVSKSB7CiAgICAgICAgICAgIGF1eEJ1ZmZlcnMgPSBUUlVFOwoKICAgICAgICAgICAgaWYodGFyZ2V0LT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9YNFI0RzRCNCkKICAgICAgICAgICAgICAgIENvbG9yRm9ybWF0ID0gV0lORUQzREZNVF9BNFI0RzRCNDsKICAgICAgICAgICAgZWxzZSBpZih0YXJnZXQtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1g4UjhHOEI4KQogICAgICAgICAgICAgICAgQ29sb3JGb3JtYXQgPSBXSU5FRDNERk1UX0E4UjhHOEI4OwogICAgICAgIH0KCiAgICAgICAgLyogRGlyZWN0RHJhdyBzdXBwb3J0cyA4Yml0IHBhbGV0dGVkIHJlbmRlciB0YXJnZXRzIGFuZCB0aGVzZSBhcmUgdXNlZCBieSBvbGQgZ2FtZXMgbGlrZSBTdGFyY3JhZnQgYW5kIEMmQy4KICAgICAgICAgKiBNb3N0IG1vZGVybiBoYXJkd2FyZSBkb2Vzbid0IHN1cHBvcnQgOGJpdCBuYXRpdmVseSBzbyB3ZSBwZXJmb3JtIHNvbWUgZm9ybSBvZiA4Yml0IC0+IDMyYml0IGNvbnZlcnNpb24uCiAgICAgICAgICogVGhlIGNvbnZlcnNpb24gKGFiKXVzZXMgdGhlIGFscGhhIGNvbXBvbmVudCBmb3Igc3RvcmluZyB0aGUgcGFsZXR0ZSBpbmRleC4gRm9yIHRoaXMgcmVhc29uIHdlIHJlcXVpcmUKICAgICAgICAgKiBhIGZvcm1hdCB3aXRoIDhiaXQgYWxwaGEsIHNvIHJlcXVlc3QgQThSOEc4QjguICovCiAgICAgICAgaWYoQ29sb3JGb3JtYXQgPT0gV0lORUQzREZNVF9QOCkKICAgICAgICAgICAgQ29sb3JGb3JtYXQgPSBXSU5FRDNERk1UX0E4UjhHOEI4OwoKICAgICAgICAvKiBSZXRyaWV2ZSB0aGUgZGVwdGggc3RlbmNpbCBmb3JtYXQgZnJvbSB0aGUgcHJlc2VudCBwYXJhbWV0ZXJzLgogICAgICAgICAqIFRoZSBjaG9pY2Ugb2YgdGhlIHByb3BlciBmb3JtYXQgY2FuIGdpdmUgYSBuaWNlIHBlcmZvcm1hbmNlIGJvb3N0CiAgICAgICAgICogaW4gY2FzZSBvZiBHUFUgbGltaXRlZCBwcm9ncmFtcy4gKi8KICAgICAgICBpZihwUHJlc2VudFBhcm1zLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsKSB7CiAgICAgICAgICAgIFRSQUNFKCJwUHJlc2VudFBhcm1zLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsPWVuYWJsZWQ7IHVzaW5nIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQ9JXNcbiIsIGRlYnVnX2QzZGZvcm1hdChwUHJlc2VudFBhcm1zLT5BdXRvRGVwdGhTdGVuY2lsRm9ybWF0KSk7CiAgICAgICAgICAgIERlcHRoU3RlbmNpbEZvcm1hdCA9IHBQcmVzZW50UGFybXMtPkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQ7CiAgICAgICAgfQoKICAgICAgICAvKiBEM0Qgb25seSBhbGxvd3MgbXVsdGlzYW1wbGluZyB3aGVuIFN3YXBFZmZlY3QgaXMgc2V0IHRvIFdJTkVEM0RTV0FQRUZGRUNUX0RJU0NBUkQgKi8KICAgICAgICBpZihwUHJlc2VudFBhcm1zLT5NdWx0aVNhbXBsZVR5cGUgJiYgKHBQcmVzZW50UGFybXMtPlN3YXBFZmZlY3QgPT0gV0lORUQzRFNXQVBFRkZFQ1RfRElTQ0FSRCkpIHsKICAgICAgICAgICAgaWYoIUdMX1NVUFBPUlQoQVJCX01VTFRJU0FNUExFKSkKICAgICAgICAgICAgICAgIEVSUigiVGhlIHByb2dyYW0gaXMgcmVxdWVzdGluZyBtdWx0aXNhbXBsaW5nIHdpdGhvdXQgc3VwcG9ydCFcbiIpOwogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIEVSUigiUmVxdWVzdGluZyBNdWx0aVNhbXBsZVR5cGU9JWRcbiIsIHBQcmVzZW50UGFybXMtPk11bHRpU2FtcGxlVHlwZSk7CiAgICAgICAgICAgICAgICBudW1TYW1wbGVzID0gcFByZXNlbnRQYXJtcy0+TXVsdGlTYW1wbGVUeXBlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBUcnkgdG8gZmluZCBhIHBpeGVsIGZvcm1hdCB3aGljaCBtYXRjaGVzIG91ciByZXF1aXJlbWVudHMgKi8KICAgICAgICBpUGl4ZWxGb3JtYXQgPSBXaW5lRDNEX0Nob29zZVBpeGVsRm9ybWF0KFRoaXMsIGhkYywgQ29sb3JGb3JtYXQsIERlcHRoU3RlbmNpbEZvcm1hdCwgYXV4QnVmZmVycywgbnVtU2FtcGxlcywgRkFMU0UgLyogUEJVRkZFUiAqLywgRkFMU0UgLyogZmluZENvbXBhdGlibGUgKi8pOwoKICAgICAgICAvKiBUcnkgdG8gbG9jYXRlIGEgY29tcGF0aWJsZSBmb3JtYXQgaWYgd2Ugd2VyZW4ndCBhYmxlIHRvIGZpbmQgYW55dGhpbmcgKi8KICAgICAgICBpZighaVBpeGVsRm9ybWF0KSB7CiAgICAgICAgICAgIFRSQUNFKCJUcnlpbmcgdG8gbG9jYXRlIGEgY29tcGF0aWJsZSBwaXhlbCBmb3JtYXQgYmVjYXVzZSBhbiBleGFjdCBtYXRjaCBmYWlsZWQuXG4iKTsKICAgICAgICAgICAgaVBpeGVsRm9ybWF0ID0gV2luZUQzRF9DaG9vc2VQaXhlbEZvcm1hdChUaGlzLCBoZGMsIENvbG9yRm9ybWF0LCBEZXB0aFN0ZW5jaWxGb3JtYXQsIGF1eEJ1ZmZlcnMsIDAgLyogbnVtU2FtcGxlcyAqLywgRkFMU0UgLyogUEJVRkZFUiAqLywgVFJVRSAvKiBmaW5kQ29tcGF0aWJsZSAqLyApOwogICAgICAgIH0KCiAgICAgICAgLyogSWYgd2Ugc3RpbGwgZG9uJ3QgaGF2ZSBhIHBpeGVsIGZvcm1hdCwgc29tZXRoaW5nIGlzIHZlcnkgd3JvbmcgYXMgQ2hvb3NlUGl4ZWxGb3JtYXQgYmFyZWx5IGZhaWxzICovCiAgICAgICAgaWYoIWlQaXhlbEZvcm1hdCkgewogICAgICAgICAgICBFUlIoIkNhbid0IGZpbmQgYSBzdWl0YWJsZSBpUGl4ZWxGb3JtYXRcbiIpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQoKICAgICAgICBEZXNjcmliZVBpeGVsRm9ybWF0KGhkYywgaVBpeGVsRm9ybWF0LCBzaXplb2YocGZkKSwgJnBmZCk7CiAgICAgICAgcmVzID0gU2V0UGl4ZWxGb3JtYXQoaGRjLCBpUGl4ZWxGb3JtYXQsIE5VTEwpOwogICAgICAgIGlmKCFyZXMpIHsKICAgICAgICAgICAgaW50IG9sZFBpeGVsRm9ybWF0ID0gR2V0UGl4ZWxGb3JtYXQoaGRjKTsKCiAgICAgICAgICAgIC8qIEJ5IGRlZmF1bHQgV0dMIGRvZXNuJ3QgYWxsb3cgcGl4ZWwgZm9ybWF0IGFkanVzdG1lbnRzIGJ1dCB3ZSBuZWVkIGl0IGhlcmUuCiAgICAgICAgICAgICAqIEZvciB0aGlzIHJlYXNvbiB0aGVyZSBpcyBhIFdJTkUtc3BlY2lmaWMgd2dsU2V0UGl4ZWxGb3JtYXQgd2hpY2ggYWxsb3dzIHlvdSB0bwogICAgICAgICAgICAgKiBzZXQgdGhlIHBpeGVsIGZvcm1hdCBtdWx0aXBsZSB0aW1lcy4gT25seSB1c2UgaXQgd2hlbiBpdCBpcyByZWFsbHkgbmVlZGVkLiAqLwoKICAgICAgICAgICAgaWYob2xkUGl4ZWxGb3JtYXQgPT0gaVBpeGVsRm9ybWF0KSB7CiAgICAgICAgICAgICAgICAvKiBXZSBkb24ndCBoYXZlIHRvIGRvIGFueXRoaW5nIGFzIHRoZSBmb3JtYXRzIGFyZSB0aGUgc2FtZSA6KSAqLwogICAgICAgICAgICB9IGVsc2UgaWYob2xkUGl4ZWxGb3JtYXQgJiYgR0xfU1VQUE9SVChXR0xfV0lORV9QSVhFTF9GT1JNQVRfUEFTU1RIUk9VR0gpKSB7CiAgICAgICAgICAgICAgICByZXMgPSBHTF9FWFRDQUxMKHdnbFNldFBpeGVsRm9ybWF0V0lORShoZGMsIGlQaXhlbEZvcm1hdCwgTlVMTCkpOwoKICAgICAgICAgICAgICAgIGlmKCFyZXMpIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIndnbFNldFBpeGVsRm9ybWF0V0lORSBmYWlsZWQgb24gSERDPSVwIGZvciBpUGl4ZWxGb3JtYXQ9JWRcbiIsIGhkYywgaVBpeGVsRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZihvbGRQaXhlbEZvcm1hdCkgewogICAgICAgICAgICAgICAgLyogT3BlbkdMIGRvZXNuJ3QgYWxsb3cgcGl4ZWwgZm9ybWF0IGFkanVzdG1lbnRzLiBQcmludCBhbiBlcnJvciBhbmQgY29udGludWUgdXNpbmcgdGhlIG9sZCBmb3JtYXQuCiAgICAgICAgICAgICAgICAgKiBUaGVyZSdzIGEgYmlnIGNoYW5jZSB0aGF0IHRoZSBvbGQgZm9ybWF0IHdvcmtzIGFsdGhvdWdoIHdpdGggYSBwZXJmb3JtYW5jZSBoaXQgYW5kIHBlcmhhcHMgcmVuZGVyaW5nIGVycm9ycy4gKi8KICAgICAgICAgICAgICAgIEVSUigiSERDPSVwIGlzIGFscmVhZHkgc2V0IHRvIGlQaXhlbEZvcm1hdD0lZCBhbmQgT3BlbkdMIGRvZXNuJ3QgYWxsb3cgY2hhbmdlcyFcbiIsIGhkYywgb2xkUGl4ZWxGb3JtYXQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJTZXRQaXhlbEZvcm1hdCBmYWlsZWQgb24gSERDPSVwIGZvciBpUGl4ZWxGb3JtYXQ9JWRcbiIsIGhkYywgaVBpeGVsRm9ybWF0KTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBjdHggPSBwd2dsQ3JlYXRlQ29udGV4dChoZGMpOwogICAgaWYoVGhpcy0+bnVtQ29udGV4dHMpIHB3Z2xTaGFyZUxpc3RzKFRoaXMtPmNvbnRleHRzWzBdLT5nbEN0eCwgY3R4KTsKCiAgICBpZighY3R4KSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgV0dMIGNvbnRleHRcbiIpOwogICAgICAgIGlmKGNyZWF0ZV9wYnVmZmVyKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwod2dsUmVsZWFzZVBidWZmZXJEQ0FSQihwYnVmZmVyLCBoZGMpKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTCh3Z2xEZXN0cm95UGJ1ZmZlckFSQihwYnVmZmVyKSk7CiAgICAgICAgfQogICAgICAgIGdvdG8gb3V0OwogICAgfQogICAgcmV0ID0gQWRkQ29udGV4dFRvQXJyYXkoVGhpcywgd2luX2hhbmRsZSwgaGRjLCBjdHgsIHBidWZmZXIpOwogICAgaWYoIXJldCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGFkZCB0aGUgbmV3bHkgY3JlYXRlZCBjb250ZXh0IHRvIHRoZSBjb250ZXh0IGxpc3RcbiIpOwogICAgICAgIHB3Z2xEZWxldGVDb250ZXh0KGN0eCk7CiAgICAgICAgaWYoY3JlYXRlX3BidWZmZXIpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTCh3Z2xSZWxlYXNlUGJ1ZmZlckRDQVJCKHBidWZmZXIsIGhkYykpOwogICAgICAgICAgICBHTF9FWFRDQUxMKHdnbERlc3Ryb3lQYnVmZmVyQVJCKHBidWZmZXIpKTsKICAgICAgICB9CiAgICAgICAgZ290byBvdXQ7CiAgICB9CiAgICByZXQtPnN1cmZhY2UgPSAoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldDsKICAgIHJldC0+aXNQQnVmZmVyID0gY3JlYXRlX3BidWZmZXI7CiAgICByZXQtPnRpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogICAgaWYoVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9kaXJ0aWZ5YWJsZV9jb25zdGFudHMoKElXaW5lRDNERGV2aWNlICopIFRoaXMpKSB7CiAgICAgICAgLyogQ3JlYXRlIHRoZSBkaXJ0eSBjb25zdGFudHMgYXJyYXkgYW5kIGluaXRpYWxpemUgdGhlbSB0byBkaXJ0eSAqLwogICAgICAgIHJldC0+dnNoYWRlcl9jb25zdF9kaXJ0eSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLAogICAgICAgICAgICAgICAgc2l6ZW9mKCpyZXQtPnZzaGFkZXJfY29uc3RfZGlydHkpICogR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikpOwogICAgICAgIHJldC0+cHNoYWRlcl9jb25zdF9kaXJ0eSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLAogICAgICAgICAgICAgICAgc2l6ZW9mKCpyZXQtPnBzaGFkZXJfY29uc3RfZGlydHkpICogR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikpOwogICAgICAgIG1lbXNldChyZXQtPnZzaGFkZXJfY29uc3RfZGlydHksIDEsCiAgICAgICAgICAgICAgIHNpemVvZigqcmV0LT52c2hhZGVyX2NvbnN0X2RpcnR5KSAqIEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpKTsKICAgICAgICBtZW1zZXQocmV0LT5wc2hhZGVyX2NvbnN0X2RpcnR5LCAxLAogICAgICAgICAgICAgICAgc2l6ZW9mKCpyZXQtPnBzaGFkZXJfY29uc3RfZGlydHkpICogR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikpOwogICAgfQoKICAgIFRSQUNFKCJTdWNjZXNzZnVsbHkgY3JlYXRlZCBuZXcgY29udGV4dCAlcFxuIiwgcmV0KTsKCiAgICAvKiBTZXQgdXAgdGhlIGNvbnRleHQgZGVmYXVsdHMgKi8KICAgIG9sZEN0eCAgPSBwd2dsR2V0Q3VycmVudENvbnRleHQoKTsKICAgIG9sZERyYXdhYmxlID0gcHdnbEdldEN1cnJlbnREQygpOwogICAgaWYob2xkQ3R4ICYmIG9sZERyYXdhYmxlKSB7CiAgICAgICAgLyogU2VlIGNvbW1lbnQgaW4gQWN0aXZhdGVDb250ZXh0IGNvbnRleHQgc3dpdGNoaW5nICovCiAgICAgICAgVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9mcmFnbWVudF9lbmFibGUoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIEZBTFNFKTsKICAgIH0KICAgIGlmKHB3Z2xNYWtlQ3VycmVudChoZGMsIGN0eCkgPT0gRkFMU0UpIHsKICAgICAgICBFUlIoIkNhbm5vdCBhY3RpdmF0ZSBjb250ZXh0IHRvIHNldCB1cCBkZWZhdWx0c1xuIik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgRU5URVJfR0woKTsKCiAgICBnbEdldEludGVnZXJ2KEdMX0FVWF9CVUZGRVJTLCAmcmV0LT5hdXhfYnVmZmVycyk7CgogICAgVFJBQ0UoIlNldHRpbmcgdXAgdGhlIHNjcmVlblxuIik7CiAgICAvKiBDbGVhciB0aGUgc2NyZWVuICovCiAgICBnbENsZWFyQ29sb3IoMS4wLCAwLjAsIDAuMCwgMC4wKTsKICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyQ29sb3IiKTsKICAgIGdsQ2xlYXJJbmRleCgwKTsKICAgIGdsQ2xlYXJEZXB0aCgxKTsKICAgIGdsQ2xlYXJTdGVuY2lsKDB4ZmZmZik7CgogICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKCiAgICBnbENvbG9yM2YoMS4wLCAxLjAsIDEuMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDb2xvcjNmIik7CgogICAgZ2xFbmFibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIik7CgogICAgZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9MT0NBTF9WSUVXRVIsIEdMX1RSVUUpOwogICAgY2hlY2tHTGNhbGwoImdsTGlnaHRNb2RlbGkoR0xfTElHSFRfTU9ERUxfTE9DQUxfVklFV0VSLCBHTF9UUlVFKTsiKTsKCiAgICBnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsiKTsKCiAgICBnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0NPTE9SX0NPTlRST0wsIEdMX1NFUEFSQVRFX1NQRUNVTEFSX0NPTE9SKTsKICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0NPTE9SX0NPTlRST0wsIEdMX1NFUEFSQVRFX1NQRUNVTEFSX0NPTE9SKTsiKTsKCiAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfQUxJR05NRU5ULCBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCk7CiAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9QQUNLX0FMSUdOTUVOVCwgVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQpOyIpOwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCk7CiAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCk7Iik7CgogICAgaWYoR0xfU1VQUE9SVChBUFBMRV9DTElFTlRfU1RPUkFHRSkpIHsKICAgICAgICAvKiBNb3N0IHRleHR1cmVzIHdpbGwgdXNlIGNsaWVudCBzdG9yYWdlIGlmIHN1cHBvcnRlZC4gRXhjZXB0aW9ucyBhcmUgbm9uLW5hdGl2ZSBwb3dlciBvZiAyIHRleHR1cmVzCiAgICAgICAgICogYW5kIHRleHR1cmVzIGluIERJQiBzZWN0aW9ucyhkdWUgdG8gdGhlIG1lbW9yeSBwcm90ZWN0aW9uKS4KICAgICAgICAgKi8KICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfVFJVRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKSIpOwogICAgfQogICAgaWYoR0xfU1VQUE9SVChBUkJfVkVSVEVYX0JMRU5EKSkgewogICAgICAgIC8qIERpcmVjdDNEIGFsd2F5cyB1c2VzIG4tMSB3ZWlnaHRzIGZvciBuIHdvcmxkIG1hdHJpY2VzIGFuZCB1c2VzIDEgLSBzdW0gZm9yIHRoZSBsYXN0IG9uZQogICAgICAgICAqIHRoaXMgaXMgZXF1YWwgdG8gR0xfV0VJR0hUX1NVTV9VTklUWV9BUkIuIEVuYWJsaW5nIGl0IGRvZXNuJ3QgZG8gYW55dGhpbmcgdW5sZXNzCiAgICAgICAgICogR0xfVkVSVEVYX0JMRU5EX0FSQiBpc24ndCBlbmFibGVkIHRvbwogICAgICAgICAqLwogICAgICAgIGdsRW5hYmxlKEdMX1dFSUdIVF9TVU1fVU5JVFlfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfV0VJR0hUX1NVTV9VTklUWV9BUkIpIik7CiAgICB9CiAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMikpIHsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfU0hBREVSX05WKSIpOwoKICAgICAgICAvKiBTZXQgdXAgdGhlIHByZXZpb3VzIHRleHR1cmUgaW5wdXQgZm9yIGFsbCBzaGFkZXIgdW5pdHMuIFRoaXMgYXBwbGllcyB0byBidW1wIG1hcHBpbmcsIGFuZCBpbiBkM2QKICAgICAgICAgKiB0aGUgcHJldmlvdXMgdGV4dHVyZSB3aGVyZSB0byBzb3VyY2UgdGhlIG9mZnNldCBmcm9tIGlzIGFsd2F5cyB1bml0IC0gMS4KICAgICAgICAgKi8KICAgICAgICBmb3IocyA9IDE7IHMgPCBHTF9MSU1JVFModGV4dHVyZXMpOyBzKyspIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCICsgcykpOwogICAgICAgICAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9TSEFERVJfTlYsIEdMX1BSRVZJT1VTX1RFWFRVUkVfSU5QVVRfTlYsIEdMX1RFWFRVUkUwX0FSQiArIHMgLSAxKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aShHTF9URVhUVVJFX1NIQURFUl9OViwgR0xfUFJFVklPVVNfVEVYVFVSRV9JTlBVVF9OViwgLi4uXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgaWYoR0xfU1VQUE9SVChBUkJfUE9JTlRfU1BSSVRFKSkgewogICAgICAgIGZvcihzID0gMDsgcyA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7IHMrKykgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyBzKSk7CiAgICAgICAgICAgIGdsVGV4RW52aShHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgR0xfVFJVRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkoR0xfUE9JTlRfU1BSSVRFX0FSQiwgR0xfQ09PUkRfUkVQTEFDRV9BUkIsIEdMX1RSVUUpXG4iKTsKICAgICAgICB9CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIE5ldmVyIGtlZXAgR0xfRlJBR01FTlRfU0hBREVSX0FUSSBlbmFibGVkIG9uIGEgY29udGV4dCB0aGF0IHdlIHN3aXRjaCBhd2F5IGZyb20sCiAgICAgKiBidXQgZW5hYmxlIGl0IGZvciB0aGUgZmlyc3QgY29udGV4dCB3ZSBjcmVhdGUsIGFuZCByZWVuYWJsZSBpdCBvbiB0aGUgb2xkIGNvbnRleHQKICAgICAqLwogICAgaWYob2xkRHJhd2FibGUgJiYgb2xkQ3R4KSB7CiAgICAgICAgcHdnbE1ha2VDdXJyZW50KG9sZERyYXdhYmxlLCBvbGRDdHgpOwogICAgfQogICAgVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9mcmFnbWVudF9lbmFibGUoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIFRSVUUpOwoKb3V0OgogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlbW92ZUNvbnRleHRGcm9tQXJyYXkKICoKICogUmVtb3ZlcyBhIGNvbnRleHQgZnJvbSB0aGUgY29udGV4dCBtYW5hZ2VyLiBUaGUgb3BlbmdsIGNvbnRleHQgaXMgbm90CiAqIGRlc3Ryb3llZCBvciB1bnNldC4gY29udGV4dCBpcyBub3QgYSB2YWxpZCBwb2ludGVyIGFmdGVyIHRoYXQgY2FsbC4KICoKICogU2ltaWxhciB0byB0aGUgZm9ybWVyIGNhbGwgdGhpcyBpc24ndCBhIHBlcmZvcm1hbmNlIGNyaXRpY2FsIGZ1bmN0aW9uLiBBCiAqIGhlbHBlciBmdW5jdGlvbiBmb3IgRGVzdHJveUNvbnRleHQuCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICogIGNvbnRleHQ6IENvbnRleHQgdG8gcmVtb3ZlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgUmVtb3ZlQ29udGV4dEZyb21BcnJheShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0KSB7CiAgICBVSU5UIHQsIHM7CiAgICBXaW5lRDNEQ29udGV4dCAqKm9sZEFycmF5ID0gVGhpcy0+Y29udGV4dHM7CgogICAgVFJBQ0UoIlJlbW92aW5nIGN0eCAlcFxuIiwgY29udGV4dCk7CgogICAgVGhpcy0+bnVtQ29udGV4dHMtLTsKCiAgICBpZihUaGlzLT5udW1Db250ZXh0cykgewogICAgICAgIFRoaXMtPmNvbnRleHRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogVGhpcy0+bnVtQ29udGV4dHMpOwogICAgICAgIGlmKCFUaGlzLT5jb250ZXh0cykgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBhbGxvY2F0ZSBhIG5ldyBjb250ZXh0IGFycmF5LCBQQU5JQyEhIVxuIik7CiAgICAgICAgfQogICAgICAgIHQgPSAwOwogICAgICAgIGZvcihzID0gMDsgcyA8IFRoaXMtPm51bUNvbnRleHRzOyBzKyspIHsKICAgICAgICAgICAgaWYob2xkQXJyYXlbc10gPT0gY29udGV4dCkgY29udGludWU7CiAgICAgICAgICAgIFRoaXMtPmNvbnRleHRzW3RdID0gb2xkQXJyYXlbc107CiAgICAgICAgICAgIHQrKzsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmNvbnRleHRzID0gTlVMTDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjb250ZXh0KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZEFycmF5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlc3Ryb3lDb250ZXh0CiAqCiAqIERlc3Ryb3lzIGEgd2luZUQzRENvbnRleHQKICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgY29udGV4dDogQ29udGV4dCB0byBkZXN0cm95CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBEZXN0cm95Q29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0KSB7CgogICAgLyogY2hlY2sgdGhhdCB3ZSBhcmUgdGhlIGN1cnJlbnQgY29udGV4dCBmaXJzdCAqLwogICAgVFJBQ0UoIkRlc3Ryb3lpbmcgY3R4ICVwXG4iLCBjb250ZXh0KTsKICAgIGlmKHB3Z2xHZXRDdXJyZW50Q29udGV4dCgpID09IGNvbnRleHQtPmdsQ3R4KXsKICAgICAgICBwd2dsTWFrZUN1cnJlbnQoTlVMTCwgTlVMTCk7CiAgICB9CgogICAgaWYoY29udGV4dC0+aXNQQnVmZmVyKSB7CiAgICAgICAgR0xfRVhUQ0FMTCh3Z2xSZWxlYXNlUGJ1ZmZlckRDQVJCKGNvbnRleHQtPnBidWZmZXIsIGNvbnRleHQtPmhkYykpOwogICAgICAgIEdMX0VYVENBTEwod2dsRGVzdHJveVBidWZmZXJBUkIoY29udGV4dC0+cGJ1ZmZlcikpOwogICAgfSBlbHNlIFJlbGVhc2VEQyhjb250ZXh0LT53aW5faGFuZGxlLCBjb250ZXh0LT5oZGMpOwogICAgcHdnbERlbGV0ZUNvbnRleHQoY29udGV4dC0+Z2xDdHgpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvbnRleHQtPnZzaGFkZXJfY29uc3RfZGlydHkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY29udGV4dC0+cHNoYWRlcl9jb25zdF9kaXJ0eSk7CiAgICBSZW1vdmVDb250ZXh0RnJvbUFycmF5KFRoaXMsIGNvbnRleHQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU2V0dXBGb3JCbGl0CiAqCiAqIFNldHMgdXAgYSBjb250ZXh0IGZvciBEaXJlY3REcmF3IGJsaXR0aW5nLgogKiBBbGwgdGV4dHVyZSB1bml0cyBhcmUgZGlzYWJsZWQsIHRleHR1cmUgdW5pdCAwIGlzIHNldCBhcyBjdXJyZW50IHVuaXQKICogZm9nLCBsaWdodGluZywgYmxlbmRpbmcsIGFscGhhIHRlc3QsIHogdGVzdCwgc2Npc3NvciB0ZXN0LCBjdWxsaW5nIGRpc2FibGVkCiAqIGNvbG9yIHdyaXRpbmcgZW5hYmxlZCBmb3IgYWxsIGNoYW5uZWxzCiAqIHJlZ2lzdGVyIGNvbWJpbmVycyBkaXNhYmxlZCwgc2hhZGVycyBkaXNhYmxlZAogKiB3b3JsZCBtYXRyaXggaXMgc2V0IHRvIGlkZW50aXR5LCB0ZXh0dXJlIG1hdHJpeCAwIHRvbwogKiBwcm9qZWN0aW9uIG1hdHJpeCBpcyBzZXR1cCBmb3IgZHJhd2luZyBzY3JlZW4gY29vcmRpbmF0ZXMKICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgY29udGV4dDogQ29udGV4dCB0byBzZXR1cAogKiAgd2lkdGg6IHJlbmRlciB0YXJnZXQgd2lkdGgKICogIGhlaWdodDogcmVuZGVyIHRhcmdldCBoZWlnaHQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIHZvaWQgU2V0dXBGb3JCbGl0KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgV2luZUQzRENvbnRleHQgKmNvbnRleHQsIFVJTlQgd2lkdGgsIFVJTlQgaGVpZ2h0KSB7CiAgICBpbnQgaTsKICAgIGNvbnN0IHN0cnVjdCBTdGF0ZUVudHJ5ICpTdGF0ZVRhYmxlID0gVGhpcy0+c2hhZGVyX2JhY2tlbmQtPlN0YXRlVGFibGU7CgogICAgVFJBQ0UoIlNldHRpbmcgdXAgY29udGV4dCAlcCBmb3IgYmxpdHRpbmdcbiIsIGNvbnRleHQpOwogICAgaWYoY29udGV4dC0+bGFzdF93YXNfYmxpdCkgewogICAgICAgIFRSQUNFKCJDb250ZXh0IGlzIGFscmVhZHkgc2V0IHVwIGZvciBibGl0dGluZywgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29udGV4dC0+bGFzdF93YXNfYmxpdCA9IFRSVUU7CgogICAgLyogVE9ETzogVXNlIGEgZGlzcGxheSBsaXN0ICovCgogICAgLyogRGlzYWJsZSBzaGFkZXJzICovCiAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2NsZWFudXAoKElXaW5lRDNERGV2aWNlICopIFRoaXMpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WU0hBREVSLCBTdGF0ZVRhYmxlKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUElYRUxTSEFERVIsIFN0YXRlVGFibGUpOwoKICAgIC8qIERpc2FibGUgYWxsIHRleHR1cmVzLiBUaGUgY2FsbGVyIGNhbiB0aGVuIGJpbmQgYSB0ZXh0dXJlIGl0IHdhbnRzIHRvIGJsaXQKICAgICAqIGZyb20KICAgICAqLwogICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1JFR0lTVEVSX0NPTUJJTkVSU19OVik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9SRUdJU1RFUl9DT01CSU5FUlNfTlYpIik7CiAgICB9CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgIC8qIFRoZSBibGl0dGluZyBjb2RlIHVzZXMgKGZvciBub3cpIHRoZSBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSwgc28gbWFrZSBzdXJlIHRvIHJlc2V0IGFsbCBmaXhlZAogICAgICAgICAqIGZ1bmN0aW9uIHRleHR1cmUgdW5pdC4gTm8gbmVlZCB0byBjYXJlIGZvciBoaWdoZXIgc2FtcGxlcnMKICAgICAgICAgKi8KICAgICAgICBmb3IoaSA9IEdMX0xJTUlUUyh0ZXh0dXJlcykgLSAxOyBpID4gMCA7IGktLSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyBpKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKCiAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfQ1VCRV9NQVApKSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFX0NVQkVfTUFQX0FSQiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzNEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzNEIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzJEIik7CgogICAgICAgICAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZpKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsiKTsKCiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVEVYVFVSRVNUQUdFKGksIFdJTkVEM0RUU1NfQ09MT1JPUCksIFN0YXRlVGFibGUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1NBTVBMRVIoaSksIFN0YXRlVGFibGUpOwogICAgICAgIH0KICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICB9CiAgICBpZihHTF9TVVBQT1JUKEFSQl9URVhUVVJFX0NVQkVfTUFQKSkgewogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFX0NVQkVfTUFQX0FSQiIpOwogICAgfQogICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfM0QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzNEIik7CiAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8yRCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfMkQiKTsKCiAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOwoKICAgIGdsTWF0cml4TW9kZShHTF9URVhUVVJFKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdHJpeE1vZGUoR0xfVEVYVFVSRSkiKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMb2FkSWRlbnRpdHkoKSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9UUkFOU0ZPUk0oV0lORUQzRFRTX1RFWFRVUkUwKSwgU3RhdGVUYWJsZSk7CgogICAgaWYgKEdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfTE9EX0JJQVMpKSB7CiAgICAgICAgZ2xUZXhFbnZmKEdMX1RFWFRVUkVfRklMVEVSX0NPTlRST0xfRVhULAogICAgICAgICAgICAgICAgICBHTF9URVhUVVJFX0xPRF9CSUFTX0VYVCwKICAgICAgICAgICAgICAgICAgMC4wKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZpIEdMX1RFWFRVUkVfTE9EX0JJQVNfRVhUIC4uLiIpOwogICAgfQogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9TQU1QTEVSKDApLCBTdGF0ZVRhYmxlKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVEVYVFVSRVNUQUdFKDAsIFdJTkVEM0RUU1NfQ09MT1JPUCksIFN0YXRlVGFibGUpOwoKICAgIC8qIE90aGVyIG1pc2Mgc3RhdGVzICovCiAgICBnbERpc2FibGUoR0xfQUxQSEFfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQUxQSEFURVNURU5BQkxFKSwgU3RhdGVUYWJsZSk7CiAgICBnbERpc2FibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9MSUdIVElORyIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0xJR0hUSU5HKSwgU3RhdGVUYWJsZSk7CiAgICBnbERpc2FibGUoR0xfREVQVEhfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0RFUFRIX1RFU1QiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aRU5BQkxFKSwgU3RhdGVUYWJsZSk7CiAgICBnbERpc2FibGUoR0xfRk9HKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfRk9HRU5BQkxFKSwgU3RhdGVUYWJsZSk7CiAgICBnbERpc2FibGUoR0xfQkxFTkQpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9CTEVORCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0FMUEhBQkxFTkRFTkFCTEUpLCBTdGF0ZVRhYmxlKTsKICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9DVUxMX0ZBQ0UiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DVUxMTU9ERSksIFN0YXRlVGFibGUpOwogICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1NURU5DSUxfVEVTVCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NURU5DSUxFTkFCTEUpLCBTdGF0ZVRhYmxlKTsKICAgIGdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9TQ0lTU09SX1RFU1QiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRSksIFN0YXRlVGFibGUpOwogICAgaWYoR0xfU1VQUE9SVChBUkJfUE9JTlRfU1BSSVRFKSkgewogICAgICAgIGdsRGlzYWJsZShHTF9QT0lOVF9TUFJJVEVfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1BPSU5UX1NQUklURV9BUkIiKTsKICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfUE9JTlRTUFJJVEVFTkFCTEUpLCBTdGF0ZVRhYmxlKTsKICAgIH0KICAgIGdsQ29sb3JNYXNrKEdMX1RSVUUsIEdMX1RSVUUsR0xfVFJVRSxHTF9UUlVFKTsKICAgIGNoZWNrR0xjYWxsKCJnbENvbG9yTWFzayIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0NMSVBQSU5HKSwgU3RhdGVUYWJsZSk7CiAgICBpZiAoR0xfU1VQUE9SVChFWFRfU0VDT05EQVJZX0NPTE9SKSkgewogICAgICAgIGdsRGlzYWJsZShHTF9DT0xPUl9TVU1fRVhUKTsKICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1BFQ1VMQVJFTkFCTEUpLCBTdGF0ZVRhYmxlKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX0NPTE9SX1NVTV9FWFQpIik7CiAgICB9CiAgICBpZiAoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZpbmFsQ29tYmluZXJJbnB1dE5WKEdMX1ZBUklBQkxFX0JfTlYsIEdMX1NQQVJFMF9OViwgR0xfVU5TSUdORURfSURFTlRJVFlfTlYsIEdMX1JHQikpOwogICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TUEVDVUxBUkVOQUJMRSksIFN0YXRlVGFibGUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEZpbmFsQ29tYmluZXJJbnB1dE5WIik7CiAgICB9CgogICAgLyogU2V0dXAgdHJhbnNmb3JtcyAqLwogICAgZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVykiKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMb2FkSWRlbnRpdHkoKSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9UUkFOU0ZPUk0oV0lORUQzRFRTX1dPUkxETUFUUklYKDApKSwgU3RhdGVUYWJsZSk7CgogICAgZ2xNYXRyaXhNb2RlKEdMX1BST0pFQ1RJT04pOwogICAgY2hlY2tHTGNhbGwoImdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKSIpOwogICAgZ2xMb2FkSWRlbnRpdHkoKTsKICAgIGNoZWNrR0xjYWxsKCJnbExvYWRJZGVudGl0eSgpIik7CiAgICBnbE9ydGhvKDAsIHdpZHRoLCBoZWlnaHQsIDAsIDAuMCwgLTEuMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xPcnRobyIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9UUkFOU0ZPUk0oV0lORUQzRFRTX1BST0pFQ1RJT04pLCBTdGF0ZVRhYmxlKTsKCiAgICBjb250ZXh0LT5sYXN0X3dhc19yaHcgPSBUUlVFOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WREVDTCwgU3RhdGVUYWJsZSk7IC8qIGJlY2F1c2Ugb2YgbGFzdF93YXNfcmh3ID0gVFJVRSAqLwoKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMCk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAwKSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUxKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDEpIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTIpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgMikiKTsKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMyk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAzKSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkU0KTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDQpIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTUpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgNSkiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DTElQUElORyksIFN0YXRlVGFibGUpOwoKICAgIGdsVmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7CiAgICBjaGVja0dMY2FsbCgiZ2xWaWV3cG9ydCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WSUVXUE9SVCwgU3RhdGVUYWJsZSk7CgogICAgVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9mcmFnbWVudF9lbmFibGUoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluCiAqCiAqIFNlYXJjaGVzIGEgc3dhcGNoYWluIGZvciBhbGwgY29udGV4dHMgYW5kIHBpY2tzIG9uZSBmb3IgdGhlIHRocmVhZCB0aWQuCiAqIElmIG5vbmUgY2FuIGJlIGZvdW5kIHRoZSBzd2FwY2hhaW4gaXMgcmVxdWVzdGVkIHRvIGNyZWF0ZSBhIG5ldyBjb250ZXh0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFdpbmVEM0RDb250ZXh0ICpmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbihJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluLCBEV09SRCB0aWQpIHsKICAgIGludCBpOwoKICAgIGZvcihpID0gMDsgaSA8ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIHN3YXBjaGFpbiktPm51bV9jb250ZXh0czsgaSsrKSB7CiAgICAgICAgaWYoKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgc3dhcGNoYWluKS0+Y29udGV4dFtpXS0+dGlkID09IHRpZCkgewogICAgICAgICAgICByZXR1cm4gKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgc3dhcGNoYWluKS0+Y29udGV4dFtpXTsKICAgICAgICB9CgogICAgfQoKICAgIC8qIENyZWF0ZSBhIG5ldyBjb250ZXh0IGZvciB0aGUgdGhyZWFkICovCiAgICByZXR1cm4gSVdpbmVEM0RTd2FwQ2hhaW5JbXBsX0NyZWF0ZUNvbnRleHRGb3JUaHJlYWQoc3dhcGNoYWluKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZpbmRDb250ZXh0CiAqCiAqIEZpbmRzIGEgY29udGV4dCBmb3IgdGhlIGN1cnJlbnQgcmVuZGVyIHRhcmdldCBhbmQgdGhyZWFkCiAqCiAqIFBhcmFtZXRlcnM6CiAqICB0YXJnZXQ6IFJlbmRlciB0YXJnZXQgdG8gZmluZCB0aGUgY29udGV4dCBmb3IKICogIHRpZDogVGhyZWFkIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKgogKiBSZXR1cm5zOiBUaGUgbmVlZGVkIGNvbnRleHQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIFdpbmVEM0RDb250ZXh0ICpGaW5kQ29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZSAqdGFyZ2V0LCBEV09SRCB0aWQsIEdMaW50ICpidWZmZXIpIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW4gPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIEJPT0wgcmVhZFRleHR1cmUgPSB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSAhPSBPUk1fRkJPICYmIFRoaXMtPnJlbmRlcl9vZmZzY3JlZW47CiAgICBXaW5lRDNEQ29udGV4dCAqY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICBCT09MIG9sZFJlbmRlck9mZnNjcmVlbiA9IFRoaXMtPnJlbmRlcl9vZmZzY3JlZW47CiAgICBjb25zdCBXSU5FRDNERk9STUFUIG9sZEZtdCA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KS0+cmVzb3VyY2UuZm9ybWF0OwogICAgY29uc3QgV0lORUQzREZPUk1BVCBuZXdGbXQgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgdGFyZ2V0KS0+cmVzb3VyY2UuZm9ybWF0OwogICAgY29uc3Qgc3RydWN0IFN0YXRlRW50cnkgKlN0YXRlVGFibGUgPSBUaGlzLT5zaGFkZXJfYmFja2VuZC0+U3RhdGVUYWJsZTsKCiAgICAvKiBUbyBjb21wZW5zYXRlIHRoZSBsYWNrIG9mIGZvcm1hdCBzd2l0Y2hpbmcgd2l0aCBzb21lIG9mZnNjcmVlbiByZW5kZXJpbmcgbWV0aG9kcyBhbmQgb24gb25zY3JlZW4gYnVmZmVycwogICAgICogdGhlIGFscGhhIGJsZW5kIHN0YXRlIGNoYW5nZXMgd2l0aCBkaWZmZXJlbnQgcmVuZGVyIHRhcmdldCBmb3JtYXRzCiAgICAgKi8KICAgIGlmKG9sZEZtdCAhPSBuZXdGbXQpIHsKICAgICAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqb2xkID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KG9sZEZtdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpuZXcgPSBnZXRGb3JtYXREZXNjRW50cnkobmV3Rm10LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICAgICAgLyogRGlzYWJsZSBibGVuZGluZyB3aGVuIHRoZSBhbHBoYU1hc2sgaGFzIGNoYW5nZWQgYW5kIHdoZW4gYSBmb3JtYXQgZG9lc24ndCBzdXBwb3J0IGJsZW5kaW5nICovCiAgICAgICAgaWYoKG9sZC0+YWxwaGFNYXNrICYmICFuZXctPmFscGhhTWFzaykgfHwgKCFvbGQtPmFscGhhTWFzayAmJiBuZXctPmFscGhhTWFzaykgfHwgIShnbERlc2MtPkZsYWdzICYgV0lORUQzREZNVF9GTEFHX1BPU1RQSVhFTFNIQURFUl9CTEVORElORykpIHsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0FMUEhBQkxFTkRFTkFCTEUpLCBTdGF0ZVRhYmxlKTsKICAgICAgICB9CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKHRhcmdldCwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopICZzd2FwY2hhaW4pOwogICAgaWYoaHIgPT0gV0lORUQzRF9PSyAmJiBzd2FwY2hhaW4pIHsKICAgICAgICBUUkFDRSgiUmVuZGVyaW5nIG9uc2NyZWVuXG4iKTsKCiAgICAgICAgY29udGV4dCA9IGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluKHN3YXBjaGFpbiwgdGlkKTsKCiAgICAgICAgVGhpcy0+cmVuZGVyX29mZnNjcmVlbiA9IEZBTFNFOwogICAgICAgIC8qIFRoZSBjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQgd2lsbCBjYXRjaCBhIE5PUCBjb250ZXh0IGNoYW5nZS4gVGhpcyBjYW4gb2NjdXIKICAgICAgICAgKiBpZiB3ZSBhcmUgc3dpdGNoaW5nIGJhY2sgdG8gc3dhcGNoYWluIHJlbmRlcmluZyBpbiBjYXNlIG9mIEZCTyBvciBCYWNrIEJ1ZmZlciBvZmZzY3JlZW4KICAgICAgICAgKiByZW5kZXJpbmcuIE5vIGNvbnRleHQgY2hhbmdlIGlzIG5lZWRlZCBpbiB0aGF0IGNhc2UKICAgICAgICAgKi8KCiAgICAgICAgaWYoKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgc3dhcGNoYWluKS0+ZnJvbnRCdWZmZXIgPT0gdGFyZ2V0KSB7CiAgICAgICAgICAgICpidWZmZXIgPSBHTF9GUk9OVDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAqYnVmZmVyID0gR0xfQkFDSzsKICAgICAgICB9CiAgICAgICAgaWYod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX1BCVUZGRVIpIHsKICAgICAgICAgICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQgJiYgdGlkID09IFRoaXMtPnBidWZmZXJDb250ZXh0LT50aWQpIHsKICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJDb250ZXh0LT50aWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcGNoYWluKTsKCiAgICAgICAgaWYob2xkUmVuZGVyT2Zmc2NyZWVuKSB7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgV0lORUQzRFRTX1BST0pFQ1RJT04sIFN0YXRlVGFibGUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZERUNMLCBTdGF0ZVRhYmxlKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WSUVXUE9SVCwgU3RhdGVUYWJsZSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0NJU1NPUlJFQ1QsIFN0YXRlVGFibGUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX0ZST05URkFDRSwgU3RhdGVUYWJsZSk7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlJlbmRlcmluZyBvZmZzY3JlZW5cbiIpOwogICAgICAgIFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gPSBUUlVFOwogICAgICAgICpidWZmZXIgPSBUaGlzLT5vZmZzY3JlZW5CdWZmZXI7CgogICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSkgewogICAgICAgICAgICBjYXNlIE9STV9GQk86CiAgICAgICAgICAgICAgICAvKiBGQk9zIGRvIG5vdCBuZWVkIGEgZGlmZmVyZW50IGNvbnRleHQuIFN0YXkgd2l0aCB3aGF0ZXZlciBjb250ZXh0IGlzIGFjdGl2ZSBhdCB0aGUgbW9tZW50ICovCiAgICAgICAgICAgICAgICBpZihUaGlzLT5hY3RpdmVDb250ZXh0ICYmIHRpZCA9PSBUaGlzLT5sYXN0VGhyZWFkKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgbWF5IGhhcHBlbiBpZiB0aGUgYXBwIGp1bXBzIHN0cmFpZ2h0IGludG8gb2Zmc2NyZWVuIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICAqIFN0YXJ0IHVzaW5nIHRoZSBjb250ZXh0IG9mIHRoZSBwcmltYXJ5IHN3YXBjaGFpbi4gdGlkID09IDAgaXMgbm8gcHJvYmxlbQogICAgICAgICAgICAgICAgICAgICAqIGZvciBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbi4KICAgICAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICAgICAqIENhbiBhbHNvIGhhcHBlbiBvbiB0aHJlYWQgc3dpdGNoZXMgLSBpbiB0aGF0IGNhc2UgZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4KICAgICAgICAgICAgICAgICAgICAgKiBpcyBwZXJmZWN0IHRvIGNhbGwuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluKFRoaXMtPnN3YXBjaGFpbnNbMF0sIHRpZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgT1JNX1BCVUZGRVI6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldGltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSB0YXJnZXQ7CiAgICAgICAgICAgICAgICBpZihUaGlzLT5wYnVmZmVyQ29udGV4dCA9PSBOVUxMIHx8CiAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVyV2lkdGggPCB0YXJnZXRpbXBsLT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckhlaWdodCA8IHRhcmdldGltcGwtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIERlc3Ryb3lDb250ZXh0KFRoaXMsIFRoaXMtPnBidWZmZXJDb250ZXh0KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIC8qIFRoZSBkaXNwbGF5IGlzIGlycmVsZXZhbnQgaGVyZSwgdGhlIHdpbmRvdyBpcyAwLiBCdXQgQ3JlYXRlQ29udGV4dCBuZWVkcyBhIHZhbGlkIFggY29ubmVjdGlvbi4KICAgICAgICAgICAgICAgICAgICAgKiBDcmVhdGUgdGhlIGNvbnRleHQgb24gdGhlIHNhbWUgc2VydmVyIGFzIHRoZSBwcmltYXJ5IHN3YXBjaGFpbi4gVGhlIHByaW1hcnkgc3dhcGNoYWluIGlzIGV4aXN0cyBhdCB0aGlzIHBvaW50LgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJDb250ZXh0ID0gQ3JlYXRlQ29udGV4dChUaGlzLCB0YXJnZXRpbXBsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgVGhpcy0+c3dhcGNoYWluc1swXSktPmNvbnRleHRbMF0tPndpbl9oYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIHBidWZmZXIgKi8sICYoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKVRoaXMtPnN3YXBjaGFpbnNbMF0pLT5wcmVzZW50UGFybXMpOwogICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJXaWR0aCA9IHRhcmdldGltcGwtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJIZWlnaHQgPSB0YXJnZXRpbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICBpZihUaGlzLT5wYnVmZmVyQ29udGV4dC0+dGlkICE9IDAgJiYgVGhpcy0+cGJ1ZmZlckNvbnRleHQtPnRpZCAhPSB0aWQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlRoZSBQQnVmZnIgY29udGV4dCBpcyBvbmx5IHN1cHBvcnRlZCBmb3Igb25lIHRocmVhZCBmb3Igbm93IVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJDb250ZXh0LT50aWQgPSB0aWQ7CiAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IFRoaXMtPnBidWZmZXJDb250ZXh0OwogICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgYSBidWZmZXIgY29udGV4dCBhbmQgZHJhd2FibGUsIGZhbGxpbmcgYmFjayB0byBiYWNrIGJ1ZmZlciBvZmZzY3JlZW4gcmVuZGVyaW5nXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9IE9STV9CQUNLQlVGRkVSOwogICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBjYXNlIE9STV9CQUNLQlVGRkVSOgogICAgICAgICAgICAgICAgLyogU3RheSB3aXRoIHRoZSBjdXJyZW50bHkgYWN0aXZlIGNvbnRleHQgZm9yIGJhY2sgYnVmZmVyIHJlbmRlcmluZyAqLwogICAgICAgICAgICAgICAgaWYoVGhpcy0+YWN0aXZlQ29udGV4dCAmJiB0aWQgPT0gVGhpcy0+bGFzdFRocmVhZCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBUaGlzLT5hY3RpdmVDb250ZXh0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBUaGlzIG1heSBoYXBwZW4gaWYgdGhlIGFwcCBqdW1wcyBzdHJhaWdodCBpbnRvIG9mZnNjcmVlbiByZW5kZXJpbmcKICAgICAgICAgICAgICAgICAgICAgKiBTdGFydCB1c2luZyB0aGUgY29udGV4dCBvZiB0aGUgcHJpbWFyeSBzd2FwY2hhaW4uIHRpZCA9PSAwIGlzIG5vIHByb2JsZW0KICAgICAgICAgICAgICAgICAgICAgKiBmb3IgZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4uCiAgICAgICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAgICAgKiBDYW4gYWxzbyBoYXBwZW4gb24gdGhyZWFkIHN3aXRjaGVzIC0gaW4gdGhhdCBjYXNlIGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluCiAgICAgICAgICAgICAgICAgICAgICogaXMgcGVyZmVjdCB0byBjYWxsLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbihUaGlzLT5zd2FwY2hhaW5zWzBdLCB0aWQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgIT0gT1JNX0ZCTykgewogICAgICAgICAgICAvKiBNYWtlIHN1cmUgd2UgaGF2ZSBhIE9wZW5HTCB0ZXh0dXJlIG5hbWUgc28gdGhlIFByZUxvYWQoKSB1c2VkIHRvIHJlYWQgdGhlIGJ1ZmZlcgogICAgICAgICAgICAgKiBiYWNrIHdoZW4gd2UgYXJlIGRvbmUgd29uJ3QgbWFyayB1cyBkaXJ0eS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHRhcmdldCk7CiAgICAgICAgfQoKICAgICAgICBpZighb2xkUmVuZGVyT2Zmc2NyZWVuKSB7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgV0lORUQzRFRTX1BST0pFQ1RJT04sIFN0YXRlVGFibGUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZERUNMLCBTdGF0ZVRhYmxlKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WSUVXUE9SVCwgU3RhdGVUYWJsZSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0NJU1NPUlJFQ1QsIFN0YXRlVGFibGUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX0ZST05URkFDRSwgU3RhdGVUYWJsZSk7CiAgICAgICAgfQogICAgfQogICAgaWYgKHJlYWRUZXh0dXJlKSB7CiAgICAgICAgQk9PTCBvbGRJbkRyYXcgPSBUaGlzLT5pc0luRHJhdzsKCiAgICAgICAgLyogUHJlTG9hZCByZXF1aXJlcyBhIGNvbnRleHQgdG8gbG9hZCB0aGUgdGV4dHVyZSwgdGh1cyBpdCB3aWxsIGNhbGwgQWN0aXZhdGVDb250ZXh0LgogICAgICAgICAqIFNldCB0aGUgaXNJbkRyYXcgdG8gdHJ1ZSB0byBzaWduYWwgUHJlTG9hZCB0aGF0IGl0IGhhcyBhIGNvbnRleHQuIFdpbGwgYmUgdHJpY2t5CiAgICAgICAgICogd2hlbiB1c2luZyBvZmZzY3JlZW4gcmVuZGVyaW5nIHdpdGggbXVsdGl0aHJlYWRpbmcKICAgICAgICAgKi8KICAgICAgICBUaGlzLT5pc0luRHJhdyA9IFRSVUU7CgogICAgICAgIC8qIERvIHRoYXQgYmVmb3JlIHN3aXRjaGluZyB0aGUgY29udGV4dDoKICAgICAgICAgKiBSZWFkIHRoZSBiYWNrIGJ1ZmZlciBvZiB0aGUgb2xkIGRyYXdhYmxlIGludG8gdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KTsKCiAgICAgICAgLyogQXNzdW1lIHRoYXQgdGhlIGRyYXdhYmxlIHdpbGwgYmUgbW9kaWZpZWQgYnkgc29tZSBvdGhlciB0aGluZ3Mgbm93ICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIEZBTFNFKTsKCiAgICAgICAgVGhpcy0+aXNJbkRyYXcgPSBvbGRJbkRyYXc7CiAgICB9CgogICAgaWYob2xkUmVuZGVyT2Zmc2NyZWVuICE9IFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gJiYgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSAhPSBXSU5FRDNEX0RDU19OT19DT1BZKSB7CiAgICAgICAgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9IFdJTkVEM0RfRENTX0NPUFk7CiAgICB9CiAgICByZXR1cm4gY29udGV4dDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFjdGl2YXRlQ29udGV4dAogKgogKiBGaW5kcyBhIHJlbmRlcmluZyBjb250ZXh0IGFuZCBkcmF3YWJsZSBtYXRjaGluZyB0aGUgZGV2aWNlIGFuZCByZW5kZXIKICogdGFyZ2V0IGZvciB0aGUgY3VycmVudCB0aHJlYWQsIGFjdGl2YXRlcyB0aGVtIGFuZCBwdXRzIHRoZW0gaW50byB0aGUKICogcmVxdWVzdGVkIHN0YXRlLgogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWN0aXZhdGUgdGhlIGNvbnRleHQgZm9yCiAqICB0YXJnZXQ6IFJlcXVlc3RlZCByZW5kZXIgdGFyZ2V0CiAqICB1c2FnZTogUHJlcGFyZXMgdGhlIGNvbnRleHQgZm9yIGJsaXR0aW5nLCBkcmF3aW5nIG9yIG90aGVyIGFjdGlvbnMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIEFjdGl2YXRlQ29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZSAqdGFyZ2V0LCBDb250ZXh0VXNhZ2UgdXNhZ2UpIHsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgIHRpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgaTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgIGRpcnR5U3RhdGUsIGlkeDsKICAgIEJZVEUgICAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0OwogICAgV2luZUQzRENvbnRleHQgICAgICAgICAgICAgICAgKmNvbnRleHQ7CiAgICBHTGludCAgICAgICAgICAgICAgICAgICAgICAgICBkcmF3QnVmZmVyPTA7CiAgICBjb25zdCBzdHJ1Y3QgU3RhdGVFbnRyeSAgICAgICAqU3RhdGVUYWJsZSA9IFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5TdGF0ZVRhYmxlOwoKICAgIFRSQUNFKCIoJXApOiBTZWxlY3RpbmcgY29udGV4dCBmb3IgcmVuZGVyIHRhcmdldCAlcCwgdGhyZWFkICVkXG4iLCBUaGlzLCB0YXJnZXQsIHRpZCk7CiAgICBpZihUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ICE9IHRhcmdldCB8fCB0aWQgIT0gVGhpcy0+bGFzdFRocmVhZCkgewogICAgICAgIGNvbnRleHQgPSBGaW5kQ29udGV4dChUaGlzLCB0YXJnZXQsIHRpZCwgJmRyYXdCdWZmZXIpOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgVGhpcy0+bGFzdFRocmVhZCA9IHRpZDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogU3RpY2sgdG8gdGhlIG9sZCBjb250ZXh0ICovCiAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICB9CgogICAgLyogQWN0aXZhdGUgdGhlIG9wZW5nbCBjb250ZXh0ICovCiAgICBpZihjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQpIHsKICAgICAgICBCT09MIHJldDsKCiAgICAgICAgLyogUHJldmVudCBhbiB1bm5lZWRlZCBjb250ZXh0IHN3aXRjaCBhcyB0aG9zZSBhcmUgZXhwZW5zaXZlICovCiAgICAgICAgaWYoY29udGV4dC0+Z2xDdHggJiYgKGNvbnRleHQtPmdsQ3R4ID09IHB3Z2xHZXRDdXJyZW50Q29udGV4dCgpKSkgewogICAgICAgICAgICBUUkFDRSgiQWxyZWFkeSB1c2luZyBnbCBjb250ZXh0ICVwXG4iLCBjb250ZXh0LT5nbEN0eCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBUUkFDRSgiU3dpdGNoaW5nIGdsIGN0eCB0byAlcCwgaGRjPSVwIGN0eD0lcFxuIiwgY29udGV4dCwgY29udGV4dC0+aGRjLCBjb250ZXh0LT5nbEN0eCk7CgogICAgICAgICAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2ZyYWdtZW50X2VuYWJsZSgoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgRkFMU0UpOwogICAgICAgICAgICByZXQgPSBwd2dsTWFrZUN1cnJlbnQoY29udGV4dC0+aGRjLCBjb250ZXh0LT5nbEN0eCk7CiAgICAgICAgICAgIGlmKHJldCA9PSBGQUxTRSkgewogICAgICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gYWN0aXZhdGUgdGhlIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICAgICAgfSBlbHNlIGlmKCFjb250ZXh0LT5sYXN0X3dhc19ibGl0KSB7CiAgICAgICAgICAgICAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2ZyYWdtZW50X2VuYWJsZSgoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgVFJVRSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYoVGhpcy0+YWN0aXZlQ29udGV4dC0+dnNoYWRlcl9jb25zdF9kaXJ0eSkgewogICAgICAgICAgICBtZW1zZXQoVGhpcy0+YWN0aXZlQ29udGV4dC0+dnNoYWRlcl9jb25zdF9kaXJ0eSwgMSwKICAgICAgICAgICAgICAgICAgIHNpemVvZigqVGhpcy0+YWN0aXZlQ29udGV4dC0+dnNoYWRlcl9jb25zdF9kaXJ0eSkgKiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSk7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHkpIHsKICAgICAgICAgICAgbWVtc2V0KFRoaXMtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHksIDEsCiAgICAgICAgICAgICAgICAgICBzaXplb2YoKlRoaXMtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHkpICogR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5hY3RpdmVDb250ZXh0ID0gY29udGV4dDsKICAgIH0KCiAgICAvKiBXZSBvbmx5IG5lZWQgRU5URVJfR0wgZm9yIHRoZSBnbCBjYWxscyBtYWRlIGJlbG93IGFuZCBmb3IgdGhlIGhlbHBlciBmdW5jdGlvbnMgd2hpY2ggbWFrZSBHTCBjYWxscyAqLwogICAgRU5URVJfR0woKTsKICAgIC8qIFNlbGVjdCB0aGUgcmlnaHQgZHJhdyBidWZmZXIuIEl0IGlzIHNlbGVjdGVkIGluIEZpbmRDb250ZXh0LiAqLwogICAgaWYoZHJhd0J1ZmZlciAmJiBjb250ZXh0LT5sYXN0X2RyYXdfYnVmZmVyICE9IGRyYXdCdWZmZXIpIHsKICAgICAgICBUUkFDRSgiRHJhd2luZyB0byBidWZmZXI6ICUjeFxuIiwgZHJhd0J1ZmZlcik7CiAgICAgICAgY29udGV4dC0+bGFzdF9kcmF3X2J1ZmZlciA9IGRyYXdCdWZmZXI7CgogICAgICAgIGdsRHJhd0J1ZmZlcihkcmF3QnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CiAgICB9CgogICAgc3dpdGNoKHVzYWdlKSB7CiAgICAgICAgY2FzZSBDVFhVU0FHRV9SRVNPVVJDRUxPQUQ6CiAgICAgICAgICAgIC8qIFRoaXMgZG9lcyBub3QgcmVxdWlyZSBhbnkgc3BlY2lhbCBzdGF0ZXMgdG8gYmUgc2V0IHVwICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENUWFVTQUdFX0NMRUFSOgogICAgICAgICAgICBpZihjb250ZXh0LT5sYXN0X3dhc19ibGl0KSB7CiAgICAgICAgICAgICAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2ZyYWdtZW50X2VuYWJsZSgoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgVFJVRSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIEJsZW5kaW5nIGFuZCBjbGVhcmluZyBzaG91bGQgYmUgb3J0aG9nb25hbCwgYnV0IHRlc3RzIG9uIHRoZSBudmlkaWEgZHJpdmVyIHNob3cgdGhhdCBkaXNhYmxpbmcKICAgICAgICAgICAgICogYmxlbmRpbmcgd2hlbiBjbGVhcmluZyBpbXByb3ZlcyB0aGUgY2xlYXJpbmcgcGVyZm9ybWFuY2UgaW5jcmVkaWJseS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19BTFBIQUJMRU5ERU5BQkxFKSwgU3RhdGVUYWJsZSk7CgogICAgICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfU0NJU1NPUl9URVNUIik7CiAgICAgICAgICAgIGNvbnRleHQtPmxhc3Rfd2FzX2JsaXQgPSBGQUxTRTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSwgU3RhdGVUYWJsZSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0NJU1NPUlJFQ1QsIFN0YXRlVGFibGUpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDVFhVU0FHRV9EUkFXUFJJTToKICAgICAgICAgICAgLyogVGhpcyBuZWVkcyBhbGwgZGlydHkgc3RhdGVzIGFwcGxpZWQgKi8KICAgICAgICAgICAgaWYoY29udGV4dC0+bGFzdF93YXNfYmxpdCkgewogICAgICAgICAgICAgICAgVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9mcmFnbWVudF9lbmFibGUoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIFRSVUUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfRmluZFRleFVuaXRNYXAoVGhpcyk7CgogICAgICAgICAgICBmb3IoaT0wOyBpIDwgY29udGV4dC0+bnVtRGlydHlFbnRyaWVzOyBpKyspIHsKICAgICAgICAgICAgICAgIGRpcnR5U3RhdGUgPSBjb250ZXh0LT5kaXJ0eUFycmF5W2ldOwogICAgICAgICAgICAgICAgaWR4ID0gZGlydHlTdGF0ZSA+PiA1OwogICAgICAgICAgICAgICAgc2hpZnQgPSBkaXJ0eVN0YXRlICYgMHgxZjsKICAgICAgICAgICAgICAgIGNvbnRleHQtPmlzU3RhdGVEaXJ0eVtpZHhdICY9IH4oMSA8PCBzaGlmdCk7CiAgICAgICAgICAgICAgICBTdGF0ZVRhYmxlW2RpcnR5U3RhdGVdLmFwcGx5KGRpcnR5U3RhdGUsIFRoaXMtPnN0YXRlQmxvY2ssIGNvbnRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRleHQtPm51bURpcnR5RW50cmllcyA9IDA7IC8qIFRoaXMgbWFrZXMgdGhlIHdob2xlIGxpc3QgY2xlYW4gKi8KICAgICAgICAgICAgY29udGV4dC0+bGFzdF93YXNfYmxpdCA9IEZBTFNFOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDVFhVU0FHRV9CTElUOgogICAgICAgICAgICBTZXR1cEZvckJsaXQoVGhpcywgY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXRhcmdldCktPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgKChJV2luZUQzRFN1cmZhY2VJbXBsICopdGFyZ2V0KS0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJVbmV4cGVjdGVkIGNvbnRleHQgdXNhZ2UgcmVxdWVzdGVkXG4iKTsKICAgIH0KICAgIExFQVZFX0dMKCk7Cn0K