LyoKICogQ29udGV4dCBhbmQgcmVuZGVyIHRhcmdldCBtYW5hZ2VtZW50IGluIHdpbmVkM2QKICoKICogQ29weXJpZ2h0IDIwMDcgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlIDxzdGRpby5oPgojaWZkZWYgSEFWRV9GTE9BVF9ICiMgaW5jbHVkZSA8ZmxvYXQuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZCk7CgojZGVmaW5lIEdMSU5GT19MT0NBVElPTiBUaGlzLT5hZGFwdGVyLT5nbF9pbmZvCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29udGV4dF9NYXJrU3RhdGVEaXJ0eQogKgogKiBNYXJrcyBhIHN0YXRlIGluIGEgY29udGV4dCBkaXJ0eS4gT25seSBvbmUgY29udGV4dCwgb3Bwb3NlZCB0bwogKiBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHksIHdoaWNoIG1hcmtzIHRoZSBzdGF0ZSBkaXJ0eSBpbiBhbGwKICogY29udGV4dHMKICoKICogUGFyYW1zOgogKiAgY29udGV4dDogQ29udGV4dCB0byBtYXJrIHRoZSBzdGF0ZSBkaXJ0eSBpbgogKiAgc3RhdGU6IFN0YXRlIHRvIG1hcmsgZGlydHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBDb250ZXh0X01hcmtTdGF0ZURpcnR5KFdpbmVEM0RDb250ZXh0ICpjb250ZXh0LCBEV09SRCBzdGF0ZSkgewogICAgRFdPUkQgcmVwID0gU3RhdGVUYWJsZVtzdGF0ZV0ucmVwcmVzZW50YXRpdmU7CiAgICBEV09SRCBpZHg7CiAgICBCWVRFIHNoaWZ0OwoKICAgIGlmKCFyZXAgfHwgaXNTdGF0ZURpcnR5KGNvbnRleHQsIHJlcCkpIHJldHVybjsKCiAgICBjb250ZXh0LT5kaXJ0eUFycmF5W2NvbnRleHQtPm51bURpcnR5RW50cmllcysrXSA9IHJlcDsKICAgIGlkeCA9IHJlcCA+PiA1OwogICAgc2hpZnQgPSByZXAgJiAweDFmOwogICAgY29udGV4dC0+aXNTdGF0ZURpcnR5W2lkeF0gfD0gKDEgPDwgc2hpZnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQWRkQ29udGV4dFRvQXJyYXkKICoKICogQWRkcyBhIGNvbnRleHQgdG8gdGhlIGNvbnRleHQgYXJyYXkuIEhlbHBlciBmdW5jdGlvbiBmb3IgQ3JlYXRlQ29udGV4dAogKgogKiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGluIHBlcmZvcm1hbmNlLWNyaXRpY2FsIGNvZGUgcGF0aHMsIG9ubHkgd2hlbiBhCiAqIG5ldyByZW5kZXIgdGFyZ2V0IG9yIHN3YXBjaGFpbiBpcyBjcmVhdGVkLiBUaHVzIHBlcmZvcm1hbmNlIGlzIG5vdCBhbiBpc3N1ZQogKiBoZXJlLgogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWRkIHRoZSBjb250ZXh0IGZvcgogKiAgZGlzcGxheTogWCBkaXNwbGF5IHRoaXMgY29udGV4dCB1c2VzCiAqICBnbEN0eDogZ2xYIGNvbnRleHQgdG8gYWRkCiAqICBkcmF3YWJsZTogZHJhd2FibGUgdXNlZCB3aXRoIHRoaXMgY29udGV4dC4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgV2luZUQzRENvbnRleHQgKkFkZENvbnRleHRUb0FycmF5KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgRGlzcGxheSAqZGlzcGxheSwgR0xYQ29udGV4dCBnbEN0eCwgRHJhd2FibGUgZHJhd2FibGUpIHsKICAgIFdpbmVEM0RDb250ZXh0ICoqb2xkQXJyYXkgPSBUaGlzLT5jb250ZXh0czsKICAgIERXT1JEIHN0YXRlOwoKICAgIFRoaXMtPmNvbnRleHRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogKFRoaXMtPm51bUNvbnRleHRzICsgMSkpOwogICAgaWYoVGhpcy0+Y29udGV4dHMgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGdyb3cgdGhlIGNvbnRleHQgYXJyYXlcbiIpOwogICAgICAgIFRoaXMtPmNvbnRleHRzID0gb2xkQXJyYXk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZihvbGRBcnJheSkgewogICAgICAgIG1lbWNweShUaGlzLT5jb250ZXh0cywgb2xkQXJyYXksIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogVGhpcy0+bnVtQ29udGV4dHMpOwogICAgfQoKICAgIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZUQzRENvbnRleHQpKTsKICAgIGlmKFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gYWxsb2NhdGUgYSBuZXcgY29udGV4dFxuIik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y29udGV4dHMpOwogICAgICAgIFRoaXMtPmNvbnRleHRzID0gb2xkQXJyYXk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT5kaXNwbGF5ID0gZGlzcGxheTsKICAgIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXS0+Z2xDdHggPSBnbEN0eDsKICAgIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXS0+ZHJhd2FibGUgPSBkcmF3YWJsZTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZEFycmF5KTsKCiAgICAvKiBNYXJrIGFsbCBzdGF0ZXMgZGlydHkgdG8gZm9yY2UgYSBwcm9wZXIgaW5pdGlhbGl6YXRpb24gb2YgdGhlIHN0YXRlcyBvbiB0aGUgZmlyc3QgdXNlIG9mIHRoZSBjb250ZXh0CiAgICAgKi8KICAgIGZvcihzdGF0ZSA9IDA7IHN0YXRlIDw9IFNUQVRFX0hJR0hFU1Q7IHN0YXRlKyspIHsKICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXSwgc3RhdGUpOwogICAgfQoKICAgIFRoaXMtPm51bUNvbnRleHRzKys7CiAgICBUUkFDRSgiQ3JlYXRlZCBjb250ZXh0ICVwXG4iLCBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0cyAtIDFdKTsKICAgIHJldHVybiBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0cyAtIDFdOwp9CgovKiBSZXR1cm5zIGFuIGFycmF5IG9mIGNvbXBhdGlibGUgRkJjb25maWcocykuCiAqIFRoZSBhcnJheSBtdXN0IGJlIGZyZWVkIHdpdGggWEZyZWUuIFJlcXVpcmVzIEVOVEVSX0dMKCkKICovCnN0YXRpYyBHTFhGQkNvbmZpZyogcGJ1ZmZlcl9maW5kX2ZiY29uZmlncygKICAgIElXaW5lRDNERGV2aWNlSW1wbCogVGhpcywKICAgIElXaW5lRDNEU3VyZmFjZUltcGwqIFJlbmRlclN1cmZhY2UsCiAgICBEaXNwbGF5ICpkaXNwbGF5KSB7CgogICAgR0xYRkJDb25maWcqIGNmZ3MgPSBOVUxMOwogICAgaW50IG5DZmdzID0gMDsKICAgIGludCBhdHRyaWJzWzI1Nl07CiAgICBpbnQgbkF0dHJpYnMgPSAwOwoKICAgIElXaW5lRDNEU3VyZmFjZSAqU3RlbmNpbFN1cmZhY2UgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgV0lORUQzREZPUk1BVCBCYWNrQnVmZmVyRm9ybWF0ID0gUmVuZGVyU3VyZmFjZS0+cmVzb3VyY2UuZm9ybWF0OwogICAgV0lORUQzREZPUk1BVCBTdGVuY2lsQnVmZmVyRm9ybWF0ID0gKE5VTEwgIT0gU3RlbmNpbFN1cmZhY2UpID8gKChJV2luZUQzRFN1cmZhY2VJbXBsICopIFN0ZW5jaWxTdXJmYWNlKS0+cmVzb3VyY2UuZm9ybWF0IDogMDsKCiAgICAvKiBUT0RPOgogICAgICogIGlmIFN0ZW5jaWxTdXJmYWNlID09IE5VTEwgJiYgekJ1ZmZlclRhcmdldCAhPSBOVUxMIHRoZW4gc3dpdGNoIHRoZSB6YnVmZmVyIG9mZiwKICAgICAqICBpdCBTdGVuY2lsU3VyZmFjZSAhPSBOVUxMICYmIHpCdWZmZXJUYXJnZXQgPT0gTlVMTCBzd2l0Y2ggaXQgb24KICAgICAqLwoKI2RlZmluZSBQVVNIMShhdHQpICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gKGF0dCk7CiNkZWZpbmUgUFVTSDIoYXR0LHZhbHVlKSAgYXR0cmlic1tuQXR0cmlicysrXSA9IChhdHQpOyBhdHRyaWJzW25BdHRyaWJzKytdID0gKHZhbHVlKTsKCiAgICAvKiBQVVNIMihHTFhfQklORF9UT19URVhUVVJFX1JHQkFfQVRJLCBUcnVlKTsgZXhhbXBsZXMgb2YgdGhpcyBhcmUgZmV3IGFuZCBmYXIgYmV0d2VlbiAoYnV0IEkndmUgZ290IGEgbmljZSB3b3JraW5nIG9uZSEpKi8KCiAgICBQVVNIMihHTFhfRFJBV0FCTEVfVFlQRSwgR0xYX1BCVUZGRVJfQklUKTsKICAgIFBVU0gyKEdMWF9YX1JFTkRFUkFCTEUsICBUUlVFKTsKICAgIFBVU0gyKEdMWF9ET1VCTEVCVUZGRVIsICBUUlVFKTsKICAgIFRSQUNFKCJjYWxsaW5nIG1ha2VnbGNmZ1xuIik7CiAgICBEM0RGbXRNYWtlR2xDZmcoQmFja0J1ZmZlckZvcm1hdCwgU3RlbmNpbEJ1ZmZlckZvcm1hdCwgYXR0cmlicywgJm5BdHRyaWJzLCBGQUxTRSAvKiBhbHRlcm5hdGUgKi8pOwogICAgUFVTSDEoTm9uZSk7CiAgICBUUkFDRSgiY2FsbGluZyBjaG9vc2VGR0NvbmZpZ1xuIik7CiAgICBjZmdzID0gZ2xYQ2hvb3NlRkJDb25maWcoZGlzcGxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0U2NyZWVuKGRpc3BsYXkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnMsICZuQ2Zncyk7CiAgICBpZiAoY2ZncyA9PSBOVUxMKSB7CiAgICAgICAgLyogT0sgd2UgZGlkbid0IGZpbmQgdGhlIGV4YWN0IGNvbmZpZywgc28gdXNlIGFueSByZWFzb25hYmxlIG1hdGNoICovCiAgICAgICAgLyogVE9ETzogZmlsbCBpbiB0aGUgJ3JlcXVlc3RlZCcgYW5kICdjdXJyZW50JyBkZXB0aHMsIGFuZCBtYWtlIHN1cmUgdGhhdCdzCiAgICAgICAgICAgd2h5IHdlIGZhaWxlZC4gKi8KICAgICAgICBzdGF0aWMgQk9PTCBzaG93X21lc3NhZ2UgPSBUUlVFOwogICAgICAgIGlmIChzaG93X21lc3NhZ2UpIHsKICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gZmluZCBleGFjdCBtYXRjaCwgZmluZGluZyBhbHRlcm5hdGl2ZSBidXQgeW91IG1heSAiCiAgICAgICAgICAgICAgICAic3VmZmVyIHBlcmZvcm1hbmNlIGlzc3VlcywgdHJ5IGNoYW5naW5nIHhmcmVlJ3MgZGVwdGggdG8gbWF0Y2ggdGhlIHJlcXVlc3RlZCBkZXB0aFxuIik7CiAgICAgICAgICAgIHNob3dfbWVzc2FnZSA9IEZBTFNFOwogICAgICAgIH0KICAgICAgICBuQXR0cmlicyA9IDA7CiAgICAgICAgUFVTSDIoR0xYX0RSQVdBQkxFX1RZUEUsIEdMWF9QQlVGRkVSX0JJVCB8IEdMWF9XSU5ET1dfQklUKTsKICAgICAgICAvKiBQVVNIMihHTFhfWF9SRU5ERVJBQkxFLCAgVFJVRSk7ICovCiAgICAgICAgUFVTSDIoR0xYX1JFTkRFUl9UWVBFLCAgIEdMWF9SR0JBX0JJVCk7CiAgICAgICAgUFVTSDIoR0xYX0RPVUJMRUJVRkZFUiwgRkFMU0UpOwogICAgICAgIFRSQUNFKCJjYWxsaW5nIG1ha2VnbGNmZ1xuIik7CiAgICAgICAgRDNERm10TWFrZUdsQ2ZnKEJhY2tCdWZmZXJGb3JtYXQsIFN0ZW5jaWxCdWZmZXJGb3JtYXQsIGF0dHJpYnMsICZuQXR0cmlicywgVFJVRSAvKiBhbHRlcm5hdGUgKi8pOwogICAgICAgIFBVU0gxKE5vbmUpOwogICAgICAgIGNmZ3MgPSBnbFhDaG9vc2VGQkNvbmZpZyhkaXNwbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0U2NyZWVuKGRpc3BsYXkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJzLCAmbkNmZ3MpOwogICAgfQoKICAgIGlmIChjZmdzID09IE5VTEwpIHsKICAgICAgICBFUlIoIkNvdWxkIG5vdCBnZXQgYSB2YWxpZCBGQkNvbmZpZyBmb3IgKCV1LCVzKS8oJXUsJXMpXG4iLAogICAgICAgICAgICBCYWNrQnVmZmVyRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoQmFja0J1ZmZlckZvcm1hdCksCiAgICAgICAgICAgIFN0ZW5jaWxCdWZmZXJGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChTdGVuY2lsQnVmZmVyRm9ybWF0KSk7CiAgICB9IGVsc2UgewojaWZkZWYgRVhUUkFfVFJBQ0VTCiAgICAgICAgaW50IGk7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IG5DZmdzOyArK2kpIHsKICAgICAgICAgICAgVFJBQ0UoImZvciAoJXUsJXMpLygldSwlcykgZm91bmQgY29uZmlnWyVkXUAlcFxuIiwgQmFja0J1ZmZlckZvcm1hdCwKICAgICAgICAgICAgZGVidWdfZDNkZm9ybWF0KEJhY2tCdWZmZXJGb3JtYXQpLCBTdGVuY2lsQnVmZmVyRm9ybWF0LAogICAgICAgICAgICBkZWJ1Z19kM2Rmb3JtYXQoU3RlbmNpbEJ1ZmZlckZvcm1hdCksIGksIGNmZ3NbaV0pOwogICAgICAgIH0KI2VuZGlmCiAgICB9CiN1bmRlZiBQVVNIMQojdW5kZWYgUFVTSDIKCiAgIHJldHVybiBjZmdzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ3JlYXRlQ29udGV4dAogKgogKiBDcmVhdGVzIGEgbmV3IGNvbnRleHQgZm9yIGEgd2luZG93LCBvciBhIHBidWZmZXIgY29udGV4dC4KICoKICogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWN0aXZhdGUgdGhlIGNvbnRleHQgZm9yCiAqICB0YXJnZXQ6IFN1cmZhY2UgdGhpcyBjb250ZXh0IHdpbGwgcmVuZGVyIHRvCiAqICBkaXNwbGF5OiBYMTEgY29ubmVjdGlvbgogKiAgd2luOiBUYXJnZXQgd2luZG93LiBOVUxMIGZvciBhIHBidWZmZXIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpXaW5lRDNEQ29udGV4dCAqQ3JlYXRlQ29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCwgRGlzcGxheSAqZGlzcGxheSwgV2luZG93IHdpbikgewogICAgRHJhd2FibGUgZHJhd2FibGUgPSB3aW4sIG9sZERyYXdhYmxlOwogICAgWFZpc3VhbEluZm8gKnZpc2luZm8gPSBOVUxMOwogICAgR0xYRkJDb25maWcgKmNmZ3MgPSBOVUxMOwogICAgR0xYQ29udGV4dCBjdHggPSBOVUxMLCBvbGRDdHg7CiAgICBXaW5lRDNEQ29udGV4dCAqcmV0ID0gTlVMTDsKICAgIGludCBzOwoKICAgIFRSQUNFKCIoJXApOiBDcmVhdGluZyBhICVzIGNvbnRleHQgZm9yIHJlbmRlciB0YXJnZXQgJXBcbiIsIFRoaXMsIHdpbiA/ICJvbnNjcmVlbiIgOiAib2Zmc2NyZWVuIiwgdGFyZ2V0KTsKCiAgICBpZighd2luKSB7CiAgICAgICAgaW50IGF0dHJpYnNbMjU2XTsKICAgICAgICBpbnQgbkF0dHJpYnMgPSAwOwoKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgYSBwQnVmZmVyIGRyYXdhYmxlIGZvciB0aGUgbmV3IGNvbnRleHRcbiIpOwoKICAgICAgICBjZmdzID0gcGJ1ZmZlcl9maW5kX2ZiY29uZmlncyhUaGlzLCB0YXJnZXQsIGRpc3BsYXkpOwogICAgICAgIGlmKCFjZmdzKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IGZpbmQgYSBmcmFtZSBidWZmZXIgY29uZmlndXJhdGlvbiBmb3IgdGhlIHBidWZmZXJcbiIpOwogICAgICAgICAgICBnb3RvIG91dDsKICAgICAgICB9CgogICAgICAgIGF0dHJpYnNbbkF0dHJpYnMrK10gPSBHTFhfUEJVRkZFUl9XSURUSDsKICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gdGFyZ2V0LT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gR0xYX1BCVUZGRVJfSEVJR0hUOwogICAgICAgIGF0dHJpYnNbbkF0dHJpYnMrK10gPSB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gTm9uZTsKCiAgICAgICAgdmlzaW5mbyA9IGdsWEdldFZpc3VhbEZyb21GQkNvbmZpZyhkaXNwbGF5LCBjZmdzWzBdKTsKICAgICAgICBpZighdmlzaW5mbykgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBmaW5kIGEgdmlzdWFsIGZvciB0aGUgcGJ1ZmZlclxuIik7CiAgICAgICAgICAgIGdvdG8gb3V0OwogICAgICAgIH0KCiAgICAgICAgZHJhd2FibGUgPSBnbFhDcmVhdGVQYnVmZmVyKGRpc3BsYXksIGNmZ3NbMF0sIGF0dHJpYnMpOwoKICAgICAgICBpZighZHJhd2FibGUpIHsKICAgICAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIGEgcGJ1ZmZlclxuIik7CiAgICAgICAgICAgIGdvdG8gb3V0OwogICAgICAgIH0KICAgICAgICBYRnJlZShjZmdzKTsKICAgICAgICBjZmdzID0gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogQ3JlYXRlIGFuIG9uc2NyZWVuIHRhcmdldCAqLwogICAgICAgIFhWaXN1YWxJbmZvICAgICAgICAgICAgIHRlbXBsYXRlOwogICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgIG51bTsKCiAgICAgICAgdGVtcGxhdGUudmlzdWFsaWQgPSAoVmlzdWFsSUQpR2V0UHJvcEEoR2V0RGVza3RvcFdpbmRvdygpLCAiX193aW5lX3gxMV92aXN1YWxfaWQiKTsKICAgICAgICAvKiBUT0RPOiBjaGFuZ2UgdGhpcyB0byBmaW5kIGEgc2ltaWxhciB2aXN1YWwsIGJ1dCBvbmUgd2l0aCBhIHN0ZW5jaWwvemJ1ZmZlciBidWZmZXIgdGhhdCBtYXRjaGVzIHRoZSByZXF1ZXN0CiAgICAgICAgKG9yIHRoZSBiZXN0IHBvc3NpYmxlIGlmIG5vbmUgaXMgcmVxdWVzdGVkKSAqLwogICAgICAgIFRSQUNFKCJGb3VuZCB4IHZpc3VhbCBJRCAgOiAlbGRcbiIsIHRlbXBsYXRlLnZpc3VhbGlkKTsKICAgICAgICB2aXNpbmZvICAgPSBYR2V0VmlzdWFsSW5mbyhkaXNwbGF5LCBWaXN1YWxJRE1hc2ssICZ0ZW1wbGF0ZSwgJm51bSk7CgogICAgICAgIGlmIChOVUxMID09IHZpc2luZm8pIHsKICAgICAgICAgICAgRVJSKCJjYW5ub3QgcmVhbGx5IGdldCBYVmlzdWFsXG4iKTsKICAgICAgICAgICAgZ290byBvdXQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IG4sIHZhbHVlOwogICAgICAgICAgICAvKiBXcml0ZSBvdXQgc29tZSBkZWJ1ZyBpbmZvIGFib3V0IHRoZSB2aXN1YWwvcyAqLwogICAgICAgICAgICBUUkFDRSgiVXNpbmcgeCB2aXN1YWwgSUQgIDogJWxkXG4iLCB0ZW1wbGF0ZS52aXN1YWxpZCk7CiAgICAgICAgICAgIFRSQUNFKCIgICAgICAgIHZpc3VhbCBpbmZvOiAlcFxuIiwgdmlzaW5mbyk7CiAgICAgICAgICAgIFRSQUNFKCIgICAgICAgIG51bSBpdGVtcyAgOiAlZFxuIiwgbnVtKTsKICAgICAgICAgICAgZm9yIChuID0gMDtuIDwgbnVtOyBuKyspIHsKICAgICAgICAgICAgICAgIFRSQUNFKCI9PT09PWl0ZW09PT09PTogJWRcbiIsIG4gKyAxKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICB2aXN1YWxpZCAgICAgIDogJWxkXG4iLCB2aXNpbmZvW25dLnZpc3VhbGlkKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBzY3JlZW4gICAgICAgIDogJWRcbiIsICB2aXNpbmZvW25dLnNjcmVlbik7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZGVwdGggICAgICAgICA6ICV1XG4iLCAgdmlzaW5mb1tuXS5kZXB0aCk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgY2xhc3MgICAgICAgICA6ICVkXG4iLCAgdmlzaW5mb1tuXS5jbGFzcyk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgcmVkX21hc2sgICAgICA6ICVsZFxuIiwgdmlzaW5mb1tuXS5yZWRfbWFzayk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ3JlZW5fbWFzayAgICA6ICVsZFxuIiwgdmlzaW5mb1tuXS5ncmVlbl9tYXNrKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBibHVlX21hc2sgICAgIDogJWxkXG4iLCB2aXNpbmZvW25dLmJsdWVfbWFzayk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgY29sb3JtYXBfc2l6ZSA6ICVkXG4iLCAgdmlzaW5mb1tuXS5jb2xvcm1hcF9zaXplKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBiaXRzX3Blcl9yZ2IgIDogJWRcbiIsICB2aXNpbmZvW25dLmJpdHNfcGVyX3JnYik7CiAgICAgICAgICAgICAgICAvKiBsb2cgc29tZSBleHRyYSBnbHggaW5mbyAqLwogICAgICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKGRpc3BsYXksIHZpc2luZm8sIEdMWF9BVVhfQlVGRkVSUywgJnZhbHVlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBnbF9hdXhfYnVmZmVycyAgOiAlZFxuIiwgIHZhbHVlKTsKICAgICAgICAgICAgICAgIGdsWEdldENvbmZpZyhkaXNwbGF5LCB2aXNpbmZvLCBHTFhfQlVGRkVSX1NJWkUgLCZ2YWx1ZSk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ2xfYnVmZmVyX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgICAgICBnbFhHZXRDb25maWcoZGlzcGxheSwgdmlzaW5mbywgR0xYX1JFRF9TSVpFLCAmdmFsdWUpOwogICAgICAgICAgICAgICAgVFJBQ0UoIiAgIGdsX3JlZF9zaXplICA6ICVkXG4iLCAgdmFsdWUpOwogICAgICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKGRpc3BsYXksIHZpc2luZm8sIEdMWF9HUkVFTl9TSVpFLCAmdmFsdWUpOwogICAgICAgICAgICAgICAgVFJBQ0UoIiAgIGdsX2dyZWVuX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgICAgICBnbFhHZXRDb25maWcoZGlzcGxheSwgdmlzaW5mbywgR0xYX0JMVUVfU0laRSwgJnZhbHVlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBnbF9ibHVlX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgICAgICBnbFhHZXRDb25maWcoZGlzcGxheSwgdmlzaW5mbywgR0xYX0FMUEhBX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ2xfYWxwaGFfc2l6ZSAgOiAlZFxuIiwgIHZhbHVlKTsKICAgICAgICAgICAgICAgIGdsWEdldENvbmZpZyhkaXNwbGF5LCB2aXNpbmZvLCBHTFhfREVQVEhfU0laRSAsJnZhbHVlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBnbF9kZXB0aF9zaXplICA6ICVkXG4iLCAgdmFsdWUpOwogICAgICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKGRpc3BsYXksIHZpc2luZm8sIEdMWF9TVEVOQ0lMX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ2xfc3RlbmNpbF9zaXplIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogTm93IGNob29zZSBhIHNpbWlsYXIgdmlzdWFsIElEKi8KICAgICAgICB9CiAgICB9CgogICAgY3R4ID0gZ2xYQ3JlYXRlQ29udGV4dChkaXNwbGF5LCB2aXNpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5udW1Db250ZXh0cyA/IFRoaXMtPmNvbnRleHRzWzBdLT5nbEN0eCA6IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1RSVUUpOwogICAgaWYoIWN0eCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIGdsWCBjb250ZXh0XG4iKTsKICAgICAgICBpZihkcmF3YWJsZSAhPSB3aW4pIGdsWERlc3Ryb3lQYnVmZmVyKGRpc3BsYXksIGRyYXdhYmxlKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KICAgIHJldCA9IEFkZENvbnRleHRUb0FycmF5KFRoaXMsIGRpc3BsYXksIGN0eCwgZHJhd2FibGUpOwogICAgaWYoIXJldCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGFkZCB0aGUgbmV3bHkgY3JlYXRlZCBjb250ZXh0IHRvIHRoZSBjb250ZXh0IGxpc3RcbiIpOwogICAgICAgIGdsWERlc3Ryb3lDb250ZXh0KGRpc3BsYXksIGN0eCk7CiAgICAgICAgaWYoZHJhd2FibGUgIT0gd2luKSBnbFhEZXN0cm95UGJ1ZmZlcihkaXNwbGF5LCBkcmF3YWJsZSk7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CiAgICByZXQtPnN1cmZhY2UgPSAoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldDsKICAgIHJldC0+aXNQQnVmZmVyID0gd2luID09IDA7CiAgICByZXQtPnRpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwoKICAgIFRSQUNFKCJTdWNjZXNzZnVsbHkgY3JlYXRlZCBuZXcgY29udGV4dCAlcFxuIiwgcmV0KTsKCiAgICAvKiBTZXQgdXAgdGhlIGNvbnRleHQgZGVmYXVsdHMgKi8KICAgIG9sZEN0eCAgPSBnbFhHZXRDdXJyZW50Q29udGV4dCgpOwogICAgb2xkRHJhd2FibGUgPSBnbFhHZXRDdXJyZW50RHJhd2FibGUoKTsKICAgIGlmKGdsWE1ha2VDdXJyZW50KGRpc3BsYXksIGRyYXdhYmxlLCBjdHgpID09IEZBTFNFKSB7CiAgICAgICAgRVJSKCJDYW5ub3QgYWN0aXZhdGUgY29udGV4dCB0byBzZXQgdXAgZGVmYXVsdHNcbiIpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIFRSQUNFKCJTZXR0aW5nIHVwIHRoZSBzY3JlZW5cbiIpOwogICAgLyogQ2xlYXIgdGhlIHNjcmVlbiAqLwogICAgZ2xDbGVhckNvbG9yKDEuMCwgMC4wLCAwLjAsIDAuMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckNvbG9yIik7CiAgICBnbENsZWFySW5kZXgoMCk7CiAgICBnbENsZWFyRGVwdGgoMSk7CiAgICBnbENsZWFyU3RlbmNpbCgweGZmZmYpOwoKICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CgogICAgZ2xDb2xvcjNmKDEuMCwgMS4wLCAxLjApOwogICAgY2hlY2tHTGNhbGwoImdsQ29sb3IzZiIpOwoKICAgIGdsRW5hYmxlKEdMX0xJR0hUSU5HKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSIpOwoKICAgIGdsTGlnaHRNb2RlbGkoR0xfTElHSFRfTU9ERUxfTE9DQUxfVklFV0VSLCBHTF9UUlVFKTsKICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0xPQ0FMX1ZJRVdFUiwgR0xfVFJVRSk7Iik7CgogICAgZ2xUZXhFbnZmKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9DT01CSU5FX0VYVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZmKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9DT01CSU5FX0VYVCk7Iik7CgogICAgZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9DT0xPUl9DT05UUk9MLCBHTF9TRVBBUkFURV9TUEVDVUxBUl9DT0xPUik7CiAgICBjaGVja0dMY2FsbCgiZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9DT0xPUl9DT05UUk9MLCBHTF9TRVBBUkFURV9TUEVDVUxBUl9DT0xPUik7Iik7CgogICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX0FMSUdOTUVOVCwgVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQpOwogICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfUEFDS19BTElHTk1FTlQsIFRoaXMtPnN1cmZhY2VfYWxpZ25tZW50KTsiKTsKICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0FMSUdOTUVOVCwgVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQpOwogICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0FMSUdOTUVOVCwgVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQpOyIpOwoKICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgLyogTW9zdCB0ZXh0dXJlcyB3aWxsIHVzZSBjbGllbnQgc3RvcmFnZSBpZiBzdXBwb3J0ZWQuIEV4Y2VwdGlvbnMgYXJlIG5vbi1uYXRpdmUgcG93ZXIgb2YgMiB0ZXh0dXJlcwogICAgICAgICAqIGFuZCB0ZXh0dXJlcyBpbiBESUIgc2VjdGlvbnMoZHVlIHRvIHRoZSBtZW1vcnkgcHJvdGVjdGlvbikuCiAgICAgICAgICovCiAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfVFJVRSkiKTsKICAgIH0KICAgIGlmKEdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9CTEVORCkpIHsKICAgICAgICAvKiBEaXJlY3QzRCBhbHdheXMgdXNlcyBuLTEgd2VpZ2h0cyBmb3IgbiB3b3JsZCBtYXRyaWNlcyBhbmQgdXNlcyAxIC0gc3VtIGZvciB0aGUgbGFzdCBvbmUKICAgICAgICAgKiB0aGlzIGlzIGVxdWFsIHRvIEdMX1dFSUdIVF9TVU1fVU5JVFlfQVJCLiBFbmFibGluZyBpdCBkb2Vzbid0IGRvIGFueXRoaW5nIHVubGVzcwogICAgICAgICAqIEdMX1ZFUlRFWF9CTEVORF9BUkIgaXNuJ3QgZW5hYmxlZCB0b28KICAgICAgICAgKi8KICAgICAgICBnbEVuYWJsZShHTF9XRUlHSFRfU1VNX1VOSVRZX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1dFSUdIVF9TVU1fVU5JVFlfQVJCKSIpOwogICAgfQogICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUjIpKSB7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9TSEFERVJfTlYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVikiKTsKCiAgICAgICAgLyogU2V0IHVwIHRoZSBwcmV2aW91cyB0ZXh0dXJlIGlucHV0IGZvciBhbGwgc2hhZGVyIHVuaXRzLiBUaGlzIGFwcGxpZXMgdG8gYnVtcCBtYXBwaW5nLCBhbmQgaW4gZDNkCiAgICAgICAgICogdGhlIHByZXZpb3VzIHRleHR1cmUgd2hlcmUgdG8gc291cmNlIHRoZSBvZmZzZXQgZnJvbSBpcyBhbHdheXMgdW5pdCAtIDEuCiAgICAgICAgICovCiAgICAgICAgZm9yKHMgPSAxOyBzIDwgR0xfTElNSVRTKHRleHR1cmVzKTsgcysrKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQiArIHMpKTsKICAgICAgICAgICAgZ2xUZXhFbnZpKEdMX1RFWFRVUkVfU0hBREVSX05WLCBHTF9QUkVWSU9VU19URVhUVVJFX0lOUFVUX05WLCBHTF9URVhUVVJFMF9BUkIgKyBzIC0gMSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkoR0xfVEVYVFVSRV9TSEFERVJfTlYsIEdMX1BSRVZJT1VTX1RFWFRVUkVfSU5QVVRfTlYsIC4uLlxuIik7CiAgICAgICAgfQogICAgfQogICAgaWYoR0xfU1VQUE9SVChBUkJfUE9JTlRfU1BSSVRFKSkgewogICAgICAgIGZvcihzID0gMDsgcyA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7IHMrKykgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyBzKSk7CiAgICAgICAgICAgIGdsVGV4RW52aShHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgR0xfVFJVRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkoR0xfUE9JTlRfU1BSSVRFX0FSQiwgR0xfQ09PUkRfUkVQTEFDRV9BUkIsIEdMX1RSVUUpXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgaWYob2xkRHJhd2FibGUgJiYgb2xkQ3R4KSB7CiAgICAgICAgZ2xYTWFrZUN1cnJlbnQoZGlzcGxheSwgb2xkRHJhd2FibGUsIG9sZEN0eCk7CiAgICB9CgpvdXQ6CiAgICBpZih2aXNpbmZvKSBYRnJlZSh2aXNpbmZvKTsKICAgIGlmKGNmZ3MpIFhGcmVlKGNmZ3MpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlbW92ZUNvbnRleHRGcm9tQXJyYXkKICoKICogUmVtb3ZlcyBhIGNvbnRleHQgZnJvbSB0aGUgY29udGV4dCBtYW5hZ2VyLiBUaGUgb3BlbmdsIGNvbnRleHQgaXMgbm90CiAqIGRlc3Ryb3llZCBvciB1bnNldC4gY29udGV4dCBpcyBub3QgYSB2YWxpZCBwb2ludGVyIGFmdGVyIHRoYXQgY2FsbC4KICoKICogU2ltaWxhciB0byB0aGUgZm9ybWVyIGNhbGwgdGhpcyBpc24ndCBhIHBlcmZvcm1hbmNlIGNyaXRpY2FsIGZ1bmN0aW9uLiBBCiAqIGhlbHBlciBmdW5jdGlvbiBmb3IgRGVzdHJveUNvbnRleHQuCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICogIGNvbnRleHQ6IENvbnRleHQgdG8gcmVtb3ZlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgUmVtb3ZlQ29udGV4dEZyb21BcnJheShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0KSB7CiAgICBVSU5UIHQsIHM7CiAgICBXaW5lRDNEQ29udGV4dCAqKm9sZEFycmF5ID0gVGhpcy0+Y29udGV4dHM7CgogICAgVFJBQ0UoIlJlbW92aW5nIGN0eCAlcFxuIiwgY29udGV4dCk7CgogICAgVGhpcy0+bnVtQ29udGV4dHMtLTsKCiAgICBpZihUaGlzLT5udW1Db250ZXh0cykgewogICAgICAgIFRoaXMtPmNvbnRleHRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogVGhpcy0+bnVtQ29udGV4dHMpOwogICAgICAgIGlmKCFUaGlzLT5jb250ZXh0cykgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBhbGxvY2F0ZSBhIG5ldyBjb250ZXh0IGFycmF5LCBQQU5JQyEhIVxuIik7CiAgICAgICAgfQogICAgICAgIHQgPSAwOwogICAgICAgIGZvcihzID0gMDsgcyA8IFRoaXMtPm51bUNvbnRleHRzOyBzKyspIHsKICAgICAgICAgICAgaWYob2xkQXJyYXlbc10gPT0gY29udGV4dCkgY29udGludWU7CiAgICAgICAgICAgIFRoaXMtPmNvbnRleHRzW3RdID0gb2xkQXJyYXlbc107CiAgICAgICAgICAgIHQrKzsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmNvbnRleHRzID0gTlVMTDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjb250ZXh0KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZEFycmF5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlc3Ryb3lDb250ZXh0CiAqCiAqIERlc3Ryb3lzIGEgd2luZUQzRENvbnRleHQKICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgY29udGV4dDogQ29udGV4dCB0byBkZXN0cm95CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBEZXN0cm95Q29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0KSB7CgogICAgLyogY2hlY2sgdGhhdCB3ZSBhcmUgdGhlIGN1cnJlbnQgY29udGV4dCBmaXJzdCAqLwogICAgVFJBQ0UoIkRlc3Ryb3lpbmcgY3R4ICVwXG4iLCBjb250ZXh0KTsKICAgIGlmKGdsWEdldEN1cnJlbnRDb250ZXh0KCkgPT0gY29udGV4dC0+Z2xDdHgpewogICAgICAgIGdsWE1ha2VDdXJyZW50KGNvbnRleHQtPmRpc3BsYXksIE5vbmUsIE5VTEwpOwogICAgfQoKICAgIGdsWERlc3Ryb3lDb250ZXh0KGNvbnRleHQtPmRpc3BsYXksIGNvbnRleHQtPmdsQ3R4KTsKICAgIGlmKGNvbnRleHQtPmlzUEJ1ZmZlcikgewogICAgICAgIGdsWERlc3Ryb3lQYnVmZmVyKGNvbnRleHQtPmRpc3BsYXksIGNvbnRleHQtPmRyYXdhYmxlKTsKICAgIH0KICAgIFJlbW92ZUNvbnRleHRGcm9tQXJyYXkoVGhpcywgY29udGV4dCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXR1cEZvckJsaXQKICoKICogU2V0cyB1cCBhIGNvbnRleHQgZm9yIERpcmVjdERyYXcgYmxpdHRpbmcuCiAqIEFsbCB0ZXh0dXJlIHVuaXRzIGFyZSBkaXNhYmxlZCwgZXhjZXB0IHVuaXQgMAogKiBUZXh0dXJlIHVuaXQgMCBpcyBhY3RpdnRlZCB3aGVyZSBHTF9URVhUVVJFXzJEIGlzIGFjdGl2YXRlZAogKiBmb2csIGxpZ2h0aW5nLCBibGVuZGluZywgYWxwaGEgdGVzdCwgeiB0ZXN0LCBzY2lzc29yIHRlc3QsIGN1bGxpbmcgZGlhYmxlZAogKiBjb2xvciB3cml0aW5nIGVuYWJsZWQgZm9yIGFsbCBjaGFubmVscwogKiByZWdpc3RlciBjb21iaW5lcnMgZGlzYWJsZWQsIHNoYWRlcnMgZGlzYWJsZWQKICogd29ybGQgbWF0cmlzIGlzIHNldCB0byBpZGVudGl0eSwgdGV4dHVyZSBtYXRyaXggMCB0b28KICogcHJvamVjdGlvbiBtYXRyaXggaXMgc2V0dXAgZm9yIGRyYXdpbmcgc2NyZWVuIGNvb3JkaW5hdGVzCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICogIGNvbnRleHQ6IENvbnRleHQgdG8gc2V0dXAKICogIHdpZHRoOiByZW5kZXIgdGFyZ2V0IHdpZHRoCiAqICBoZWlnaHQ6IHJlbmRlciB0YXJnZXQgaGVpZ2h0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSB2b2lkIFNldHVwRm9yQmxpdChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0LCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCkgewogICAgaW50IGk7CgogICAgVFJBQ0UoIlNldHRpbmcgdXAgY29udGV4dCAlcCBmb3IgYmxpdHRpbmdcbiIsIGNvbnRleHQpOwogICAgaWYoY29udGV4dC0+bGFzdF93YXNfYmxpdCkgewogICAgICAgIFRSQUNFKCJDb250ZXh0IGlzIGFscmVhZHkgc2V0IHVwIGZvciBibGl0dGluZywgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29udGV4dC0+bGFzdF93YXNfYmxpdCA9IFRSVUU7CgogICAgLyogVE9ETzogVXNlIGEgZGlzcGxheSBsaXN0ICovCgogICAgLyogRGlzYWJsZSBzaGFkZXJzICovCiAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2NsZWFudXAoKElXaW5lRDNERGV2aWNlICopIFRoaXMpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WU0hBREVSKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUElYRUxTSEFERVIpOwoKICAgIC8qIERpc2FibGUgYWxsIHRleHR1cmVzLiBUaGUgY2FsbGVyIGNhbiB0aGVuIGJpbmQgYSB0ZXh0dXJlIGl0IHdhbnRzIHRvIGJsaXQKICAgICAqIGZyb20KICAgICAqLwogICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1JFR0lTVEVSX0NPTUJJTkVSU19OVik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9SRUdJU1RFUl9DT01CSU5FUlNfTlYpIik7CiAgICB9CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgIC8qIFRoZSBibGl0dGluZyBjb2RlIHVzZXMgKGZvciBub3cpIHRoZSBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSwgc28gbWFrZSBzdXJlIHRvIHJlc2V0IGFsbCBmaXhlZAogICAgICAgICAqIGZ1bmN0aW9uIHRleHR1cmUgdW5pdC4gTm8gbmVlZCB0byBjYXJlIGZvciBoaWdoZXIgc2FtcGxlcnMKICAgICAgICAgKi8KICAgICAgICBmb3IoaSA9IEdMX0xJTUlUUyh0ZXh0dXJlcykgLSAxOyBpID4gMCA7IGktLSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyBpKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKCiAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfQ1VCRV9NQVApKSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFX0NVQkVfTUFQX0FSQiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzNEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzNEIik7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzJEIik7CgogICAgICAgICAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZpKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsiKTsKCiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVEVYVFVSRVNUQUdFKGksIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1NBTVBMRVIoaSkpOwogICAgICAgIH0KICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICB9CiAgICBpZihHTF9TVVBQT1JUKEFSQl9URVhUVVJFX0NVQkVfTUFQKSkgewogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFX0NVQkVfTUFQX0FSQiIpOwogICAgfQogICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfM0QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9URVhUVVJFXzNEIik7CiAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSBHTF9URVhUVVJFXzJEIik7CgogICAgZ2xUZXhFbnZpKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKCiAgICBnbE1hdHJpeE1vZGUoR0xfVEVYVFVSRSk7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRyaXhNb2RlKEdMX1RFWFRVUkUpIik7CiAgICBnbExvYWRJZGVudGl0eSgpOwogICAgY2hlY2tHTGNhbGwoImdsTG9hZElkZW50aXR5KCkiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVFJBTlNGT1JNKFdJTkVEM0RUU19URVhUVVJFMCkpOwoKICAgIGlmIChHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0xPRF9CSUFTKSkgewogICAgICAgIGdsVGV4RW52ZihHTF9URVhUVVJFX0ZJTFRFUl9DT05UUk9MX0VYVCwKICAgICAgICAgICAgICAgICAgR0xfVEVYVFVSRV9MT0RfQklBU19FWFQsCiAgICAgICAgICAgICAgICAgIDAuMCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aSBHTF9URVhUVVJFX0xPRF9CSUFTX0VYVCAuLi4iKTsKICAgIH0KICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0FNUExFUigwKSk7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1RFWFRVUkVTVEFHRSgwLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKCiAgICAvKiBPdGhlciBtaXNjIHN0YXRlcyAqLwogICAgZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9BTFBIQV9URVNUKSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0FMUEhBVEVTVEVOQUJMRSkpOwogICAgZ2xEaXNhYmxlKEdMX0xJR0hUSU5HKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfTElHSFRJTkciKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19MSUdIVElORykpOwogICAgZ2xEaXNhYmxlKEdMX0RFUFRIX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9ERVBUSF9URVNUIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfWkVOQUJMRSkpOwogICAgZ2xEaXNhYmxlKEdMX0ZPRyk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0ZPRyIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0ZPR0VOQUJMRSkpOwogICAgZ2xEaXNhYmxlKEdMX0JMRU5EKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQkxFTkQiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19BTFBIQUJMRU5ERU5BQkxFKSk7CiAgICBnbERpc2FibGUoR0xfQ1VMTF9GQUNFKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfQ1VMTF9GQUNFIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQ1VMTE1PREUpKTsKICAgIGdsRGlzYWJsZShHTF9TVEVOQ0lMX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9TVEVOQ0lMX1RFU1QiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TVEVOQ0lMRU5BQkxFKSk7CiAgICBpZihHTF9TVVBQT1JUKEFSQl9QT0lOVF9TUFJJVEUpKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1BPSU5UX1NQUklURV9BUkIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfUE9JTlRfU1BSSVRFX0FSQiIpOwogICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19QT0lOVFNQUklURUVOQUJMRSkpOwogICAgfQogICAgZ2xDb2xvck1hc2soR0xfVFJVRSwgR0xfVFJVRSxHTF9UUlVFLEdMX1RSVUUpOwogICAgY2hlY2tHTGNhbGwoImdsQ29sb3JNYXNrIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQ0xJUFBJTkcpKTsKCiAgICAvKiBTZXR1cCB0cmFuc2Zvcm1zICovCiAgICBnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdHJpeE1vZGUoR0xfTU9ERUxWSUVXKSIpOwogICAgZ2xMb2FkSWRlbnRpdHkoKTsKICAgIGNoZWNrR0xjYWxsKCJnbExvYWRJZGVudGl0eSgpIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1RSQU5TRk9STShXSU5FRDNEVFNfV09STERNQVRSSVgoMCkpKTsKCiAgICBnbE1hdHJpeE1vZGUoR0xfUFJPSkVDVElPTik7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRyaXhNb2RlKEdMX1BST0pFQ1RJT04pIik7CiAgICBnbExvYWRJZGVudGl0eSgpOwogICAgY2hlY2tHTGNhbGwoImdsTG9hZElkZW50aXR5KCkiKTsKICAgIGdsT3J0aG8oMCwgd2lkdGgsIGhlaWdodCwgMCwgMC4wLCAtMS4wKTsKICAgIGNoZWNrR0xjYWxsKCJnbE9ydGhvIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1RSQU5TRk9STShXSU5FRDNEVFNfUFJPSkVDVElPTikpOwoKICAgIGNvbnRleHQtPmxhc3Rfd2FzX3JodyA9IFRSVUU7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZERUNMKTsgLyogYmVjYXVzZSBvZiBsYXN0X3dhc19yaHcgPSBUUlVFICovCgogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUwKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDApIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTEpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgMSkiKTsKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMik7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAyKSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUzKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDMpIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTQpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgNCkiKTsKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FNSk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSA1KSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0NMSVBQSU5HKSk7CgogICAgZ2xWaWV3cG9ydCgwLCAwLCB3aWR0aCwgaGVpZ2h0KTsKICAgIGNoZWNrR0xjYWxsKCJnbFZpZXdwb3J0Iik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZJRVdQT1JUKTsKCiAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMikpIHsKICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV9TSEFERVJfTlYpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfVEVYVFVSRV9TSEFERVJfTlYpIik7CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbgogKgogKiBTZWFyY2hlcyBhIHN3YXBjaGFpbiBmb3IgYWxsIGNvbnRleHRzIGFuZCBwaWNrcyBvbmUgZm9yIHRoZSB0aHJlYWQgdGlkLgogKiBJZiBub25lIGNhbiBiZSBmb3VuZCB0aGUgc3dhcGNoYWluIGlzIHJlcXVlc3RlZCB0byBjcmVhdGUgYSBuZXcgY29udGV4dAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBXaW5lRDNEQ29udGV4dCAqZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4oSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbiwgRFdPUkQgdGlkKSB7CiAgICBpbnQgaTsKCiAgICBmb3IoaSA9IDA7IGkgPCAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBzd2FwY2hhaW4pLT5udW1fY29udGV4dHM7IGkrKykgewogICAgICAgIGlmKCgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIHN3YXBjaGFpbiktPmNvbnRleHRbaV0tPnRpZCA9PSB0aWQpIHsKICAgICAgICAgICAgcmV0dXJuICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIHN3YXBjaGFpbiktPmNvbnRleHRbaV07CiAgICAgICAgfQoKICAgIH0KCiAgICAvKiBDcmVhdGUgYSBuZXcgY29udGV4dCBmb3IgdGhlIHRocmVhZCAqLwogICAgcmV0dXJuIElXaW5lRDNEU3dhcENoYWluSW1wbF9DcmVhdGVDb250ZXh0Rm9yVGhyZWFkKHN3YXBjaGFpbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBGaW5kQ29udGV4dAogKgogKiBGaW5kcyBhIGNvbnRleHQgZm9yIHRoZSBjdXJyZW50IHJlbmRlciB0YXJnZXQgYW5kIHRocmVhZAogKgogKiBQYXJhbWV0ZXJzOgogKiAgdGFyZ2V0OiBSZW5kZXIgdGFyZ2V0IHRvIGZpbmQgdGhlIGNvbnRleHQgZm9yCiAqICB0aWQ6IFRocmVhZCB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICoKICogUmV0dXJuczogVGhlIG5lZWRlZCBjb250ZXh0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSBXaW5lRDNEQ29udGV4dCAqRmluZENvbnRleHQoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKnRhcmdldCwgRFdPUkQgdGlkKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBCT09MIHJlYWRUZXh0dXJlID0gd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgIT0gT1JNX0ZCTyAmJiBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuOwogICAgV2luZUQzRENvbnRleHQgKmNvbnRleHQgPSBUaGlzLT5hY3RpdmVDb250ZXh0OwogICAgQk9PTCBvbGRSZW5kZXJPZmZzY3JlZW4gPSBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcih0YXJnZXQsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSAmc3dhcGNoYWluKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0sgJiYgc3dhcGNoYWluKSB7CiAgICAgICAgVFJBQ0UoIlJlbmRlcmluZyBvbnNjcmVlblxuIik7CgogICAgICAgIGNvbnRleHQgPSBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbihzd2FwY2hhaW4sIHRpZCk7CgogICAgICAgIFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gPSBGQUxTRTsKICAgICAgICAvKiBUaGUgY29udGV4dCAhPSBUaGlzLT5hY3RpdmVDb250ZXh0IHdpbGwgY2F0Y2ggYSBOT1AgY29udGV4dCBjaGFuZ2UuIFRoaXMgY2FuIG9jY3VyCiAgICAgICAgICogaWYgd2UgYXJlIHN3aXRjaGluZyBiYWNrIHRvIHN3YXBjaGFpbiByZW5kZXJpbmcgaW4gY2FzZSBvZiBGQk8gb3IgQmFjayBCdWZmZXIgb2Zmc2NyZWVuCiAgICAgICAgICogcmVuZGVyaW5nLiBObyBjb250ZXh0IGNoYW5nZSBpcyBuZWVkZWQgaW4gdGhhdCBjYXNlCiAgICAgICAgICovCgogICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fQkFDS0JVRkZFUikgewogICAgICAgICAgICBpZigoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBzd2FwY2hhaW4pLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZih3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fUEJVRkZFUikgewogICAgICAgICAgICBpZihUaGlzLT5wYnVmZmVyQ29udGV4dCAmJiB0aWQgPT0gVGhpcy0+cGJ1ZmZlckNvbnRleHQtPnRpZCkgewogICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckNvbnRleHQtPnRpZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwoKICAgICAgICBpZihvbGRSZW5kZXJPZmZzY3JlZW4pIHsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBXSU5FRDNEUlNfQ1VMTE1PREUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFdJTkVEM0RUU19QUk9KRUNUSU9OKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WREVDTCk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVklFV1BPUlQpOwogICAgICAgIH0KCiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJSZW5kZXJpbmcgb2Zmc2NyZWVuXG4iKTsKICAgICAgICBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuID0gVFJVRTsKCiAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlKSB7CiAgICAgICAgICAgIGNhc2UgT1JNX0ZCTzoKICAgICAgICAgICAgICAgIC8qIEZCT3MgZG8gbm90IG5lZWQgYSBkaWZmZXJlbnQgY29udGV4dC4gU3RheSB3aXRoIHdoYXRldmVyIGNvbnRleHQgaXMgYWN0aXZlIGF0IHRoZSBtb21lbnQgKi8KICAgICAgICAgICAgICAgIGlmKFRoaXMtPmFjdGl2ZUNvbnRleHQgJiYgdGlkID09IFRoaXMtPmxhc3RUaHJlYWQpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gVGhpcy0+YWN0aXZlQ29udGV4dDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBtYXkgaGFwcGVuIGlmIHRoZSBhcHAganVtcHMgc3RyZWlnaHQgaW50byBvZmZzY3JlZW4gcmVuZGVyaW5nCiAgICAgICAgICAgICAgICAgICAgICogU3RhcnQgdXNpbmcgdGhlIGNvbnRleHQgb2YgdGhlIHByaW1hcnkgc3dhcGNoYWluLiB0aWQgPT0gMCBpcyBubyBwcm9ibGVtCiAgICAgICAgICAgICAgICAgICAgICogZm9yIGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluLgogICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICogQ2FuIGFsc28gaGFwcGVuIG9uIHRocmVhZCBzd2l0Y2hlcyAtIGluIHRoYXQgY2FzZSBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbgogICAgICAgICAgICAgICAgICAgICAqIGlzIHBlcmZlY3QgdG8gY2FsbC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4oVGhpcy0+c3dhcGNoYWluc1swXSwgdGlkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBPUk1fUEJVRkZFUjoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqdGFyZ2V0aW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHRhcmdldDsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0ID09IE5VTEwgfHwKICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJXaWR0aCA8IHRhcmdldGltcGwtPmN1cnJlbnREZXNjLldpZHRoIHx8CiAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVySGVpZ2h0IDwgdGFyZ2V0aW1wbC0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVzdHJveUNvbnRleHQoVGhpcywgVGhpcy0+cGJ1ZmZlckNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogVGhlIGRpc3BsYXkgaXMgaXJyZWxldmFudCBoZXJlLCB0aGUgd2luZG93IGlzIDAuIEJ1dCBDcmVhdGVDb250ZXh0IG5lZWRzIGEgdmFsaWQgWCBjb25uZWN0aW9uLgogICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZSB0aGUgY29udGV4dCBvbiB0aGUgc2FtZSBzZXJ2ZXIgYXMgdGhlIHByaW1hcnkgc3dhcGNoYWluLiBUaGUgcHJpbWFyeSBzd2FwY2hhaW4gaXMgZXhpc3RzIGF0IHRoaXMgcG9pbnQuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckNvbnRleHQgPSBDcmVhdGVDb250ZXh0KFRoaXMsIHRhcmdldGltcGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBUaGlzLT5zd2FwY2hhaW5zWzBdKS0+Y29udGV4dFswXS0+ZGlzcGxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogV2luZG93ICovKTsKICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVyV2lkdGggPSB0YXJnZXRpbXBsLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVySGVpZ2h0ID0gdGFyZ2V0aW1wbC0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQtPnRpZCAhPSAwICYmIFRoaXMtPnBidWZmZXJDb250ZXh0LT50aWQgIT0gdGlkKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJUaGUgUEJ1ZmZyIGNvbnRleHQgaXMgb25seSBzdXBwb3J0ZWQgZm9yIG9uZSB0aHJlYWQgZm9yIG5vdyFcbiIpOwogICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVyQ29udGV4dC0+dGlkID0gdGlkOwogICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBUaGlzLT5wYnVmZmVyQ29udGV4dDsKICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgYnVmZmVyIGNvbnRleHQgYW5kIGRyYXdhYmxlLCBmYWxsaW5nIGJhY2sgdG8gYmFjayBidWZmZXIgb2Zmc2NyZWVuIHJlbmRlcmluZ1xuIik7CiAgICAgICAgICAgICAgICAgICAgICAgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPSBPUk1fQkFDS0JVRkZFUjsKICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgY2FzZSBPUk1fQkFDS0JVRkZFUjoKICAgICAgICAgICAgICAgIC8qIFN0YXkgd2l0aCB0aGUgY3VycmVudGx5IGFjdGl2ZSBjb250ZXh0IGZvciBiYWNrIGJ1ZmZlciByZW5kZXJpbmcgKi8KICAgICAgICAgICAgICAgIGlmKFRoaXMtPmFjdGl2ZUNvbnRleHQgJiYgdGlkID09IFRoaXMtPmxhc3RUaHJlYWQpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gVGhpcy0+YWN0aXZlQ29udGV4dDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBtYXkgaGFwcGVuIGlmIHRoZSBhcHAganVtcHMgc3RyZWlnaHQgaW50byBvZmZzY3JlZW4gcmVuZGVyaW5nCiAgICAgICAgICAgICAgICAgICAgICogU3RhcnQgdXNpbmcgdGhlIGNvbnRleHQgb2YgdGhlIHByaW1hcnkgc3dhcGNoYWluLiB0aWQgPT0gMCBpcyBubyBwcm9ibGVtCiAgICAgICAgICAgICAgICAgICAgICogZm9yIGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluLgogICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICogQ2FuIGFsc28gaGFwcGVuIG9uIHRocmVhZCBzd2l0Y2hlcyAtIGluIHRoYXQgY2FzZSBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbgogICAgICAgICAgICAgICAgICAgICAqIGlzIHBlcmZlY3QgdG8gY2FsbC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4oVGhpcy0+c3dhcGNoYWluc1swXSwgdGlkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihUaGlzLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihUaGlzLT5vZmZzY3JlZW5CdWZmZXIpIik7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSAhPSBPUk1fRkJPKSB7CiAgICAgICAgICAgIC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGEgT3BlbkdMIHRleHR1cmUgbmFtZSBzbyB0aGUgUHJlTG9hZCgpIHVzZWQgdG8gcmVhZCB0aGUgYnVmZmVyCiAgICAgICAgICAgICAqIGJhY2sgd2hlbiB3ZSBhcmUgZG9uZSB3b24ndCBtYXJrIHVzIGRpcnR5LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQodGFyZ2V0KTsKICAgICAgICB9CgogICAgICAgIGlmKCFvbGRSZW5kZXJPZmZzY3JlZW4pIHsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBXSU5FRDNEUlNfQ1VMTE1PREUpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFdJTkVEM0RUU19QUk9KRUNUSU9OKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WREVDTCk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVklFV1BPUlQpOwogICAgICAgIH0KICAgIH0KICAgIGlmIChyZWFkVGV4dHVyZSkgewogICAgICAgIEJPT0wgb2xkSW5EcmF3ID0gVGhpcy0+aXNJbkRyYXc7CgogICAgICAgIC8qIFByZUxvYWQgcmVxdWlyZXMgYSBjb250ZXh0IHRvIGxvYWQgdGhlIHRleHR1cmUsIHRodXMgaXQgd2lsbCBjYWxsIEFjdGl2YXRlQ29udGV4dC4KICAgICAgICAgKiBTZXQgdGhlIGlzSW5EcmF3IHRvIHRydWUgdG8gc2lnbmFsIFByZUxvYWQgdGhhdCBpdCBoYXMgYSBjb250ZXh0LiBXaWxsIGJlIHRyaWNreQogICAgICAgICAqIHdoZW4gdXNpbmcgb2Zmc2NyZWVuIHJlbmRlcmluZyB3aXRoIG11bHRpdGhyZWFkaW5nCiAgICAgICAgICovCiAgICAgICAgVGhpcy0+aXNJbkRyYXcgPSBUUlVFOwoKICAgICAgICAvKiBEbyB0aGF0IGJlZm9yZSBzd2l0Y2hpbmcgdGhlIGNvbnRleHQ6CiAgICAgICAgICogUmVhZCB0aGUgYmFjayBidWZmZXIgb2YgdGhlIG9sZCBkcmF3YWJsZSBpbnRvIHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCk7CgogICAgICAgIC8qIEFzc3VtZSB0aGF0IHRoZSBkcmF3YWJsZSB3aWxsIGJlIG1vZGlmaWVkIGJ5IHNvbWUgb3RoZXIgdGhpbmdzIG5vdyAqLwogICAgICAgICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KS0+RmxhZ3MgJj0gflNGTEFHX0lORFJBV0FCTEU7CgogICAgICAgIFRoaXMtPmlzSW5EcmF3ID0gb2xkSW5EcmF3OwogICAgfQoKICAgIGlmKG9sZFJlbmRlck9mZnNjcmVlbiAhPSBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuICYmIFRoaXMtPmRlcHRoX2NvcHlfc3RhdGUgIT0gV0lORUQzRF9EQ1NfTk9fQ09QWSkgewogICAgICAgIFRoaXMtPmRlcHRoX2NvcHlfc3RhdGUgPSBXSU5FRDNEX0RDU19DT1BZOwogICAgfQogICAgcmV0dXJuIGNvbnRleHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBY3RpdmF0ZUNvbnRleHQKICoKICogRmluZHMgYSByZW5kZXJpbmcgY29udGV4dCBhbmQgZHJhd2FibGUgbWF0Y2hpbmcgdGhlIGRldmljZSBhbmQgcmVuZGVyCiAqIHRhcmdldCBmb3IgdGhlIGN1cnJlbnQgdGhyZWFkLCBhY3RpdmF0ZXMgdGhlbSBhbmQgcHV0cyB0aGVtIGludG8gdGhlCiAqIHJlcXVlc3RlZCBzdGF0ZS4KICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgdGFyZ2V0OiBSZXF1ZXN0ZWQgcmVuZGVyIHRhcmdldAogKiAgdXNhZ2U6IFByZXBhcmVzIHRoZSBjb250ZXh0IGZvciBibGl0dGluZywgZHJhd2luZyBvciBvdGhlciBhY3Rpb25zCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBBY3RpdmF0ZUNvbnRleHQoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKnRhcmdldCwgQ29udGV4dFVzYWdlIHVzYWdlKSB7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICB0aWQgPSBHZXRDdXJyZW50VGhyZWFkSWQoKTsKICAgIGludCAgICAgICAgICAgICAgICAgICAgICAgICAgIGk7CiAgICBEV09SRCAgICAgICAgICAgICAgICAgICAgICAgICBkaXJ0eVN0YXRlLCBpZHg7CiAgICBCWVRFICAgICAgICAgICAgICAgICAgICAgICAgICBzaGlmdDsKICAgIFdpbmVEM0RDb250ZXh0ICAgICAgICAgICAgICAgICpjb250ZXh0OwoKICAgIFRSQUNFKCIoJXApOiBTZWxlY3RpbmcgY29udGV4dCBmb3IgcmVuZGVyIHRhcmdldCAlcCwgdGhyZWFkICVkXG4iLCBUaGlzLCB0YXJnZXQsIHRpZCk7CgogICAgaWYoVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCAhPSB0YXJnZXQgfHwgdGlkICE9IFRoaXMtPmxhc3RUaHJlYWQpIHsKICAgICAgICBjb250ZXh0ID0gRmluZENvbnRleHQoVGhpcywgdGFyZ2V0LCB0aWQpOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgVGhpcy0+bGFzdFRocmVhZCA9IHRpZDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogU3RpY2sgdG8gdGhlIG9sZCBjb250ZXh0ICovCiAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICB9CgogICAgLyogQWN0aXZhdGUgdGhlIG9wZW5nbCBjb250ZXh0ICovCiAgICBpZihjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQpIHsKICAgICAgICBCb29sIHJldDsKICAgICAgICBUUkFDRSgiU3dpdGNoaW5nIGdsIGN0eCB0byAlcCwgZHJhd2FibGU9JWxkLCBjdHg9JXBcbiIsIGNvbnRleHQsIGNvbnRleHQtPmRyYXdhYmxlLCBjb250ZXh0LT5nbEN0eCk7CiAgICAgICAgcmV0ID0gZ2xYTWFrZUN1cnJlbnQoY29udGV4dC0+ZGlzcGxheSwgY29udGV4dC0+ZHJhd2FibGUsIGNvbnRleHQtPmdsQ3R4KTsKICAgICAgICBpZihyZXQgPT0gRkFMU0UpIHsKICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gYWN0aXZhdGUgdGhlIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IGNvbnRleHQ7CiAgICB9CgogICAgc3dpdGNoKHVzYWdlKSB7CiAgICAgICAgY2FzZSBDVFhVU0FHRV9SRVNPVVJDRUxPQUQ6CiAgICAgICAgICAgIC8qIFRoaXMgZG9lcyBub3QgcmVxdWlyZSBhbnkgc3BlY2lhbCBzdGF0ZXMgdG8gYmUgc2V0IHVwICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENUWFVTQUdFX0NMRUFSOgogICAgICAgICAgICBpZihjb250ZXh0LT5sYXN0X3dhc19ibGl0ICYmIEdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIyKSkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9TSEFERVJfTlYpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfU0hBREVSX05WKSIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfU0NJU1NPUl9URVNUIik7CiAgICAgICAgICAgIGNvbnRleHQtPmxhc3Rfd2FzX2JsaXQgPSBGQUxTRTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0NJU1NPUlJFQ1QpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDVFhVU0FHRV9EUkFXUFJJTToKICAgICAgICAgICAgLyogVGhpcyBuZWVkcyBhbGwgZGlydHkgc3RhdGVzIGFwcGxpZWQgKi8KICAgICAgICAgICAgaWYoY29udGV4dC0+bGFzdF93YXNfYmxpdCAmJiBHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMikpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfU0hBREVSX05WKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVikiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX0ZpbmRUZXhVbml0TWFwKFRoaXMpOwoKICAgICAgICAgICAgZm9yKGk9MDsgaSA8IGNvbnRleHQtPm51bURpcnR5RW50cmllczsgaSsrKSB7CiAgICAgICAgICAgICAgICBkaXJ0eVN0YXRlID0gY29udGV4dC0+ZGlydHlBcnJheVtpXTsKICAgICAgICAgICAgICAgIGlkeCA9IGRpcnR5U3RhdGUgPj4gNTsKICAgICAgICAgICAgICAgIHNoaWZ0ID0gZGlydHlTdGF0ZSAmIDB4MWY7CiAgICAgICAgICAgICAgICBjb250ZXh0LT5pc1N0YXRlRGlydHlbaWR4XSAmPSB+KDEgPDwgc2hpZnQpOwogICAgICAgICAgICAgICAgU3RhdGVUYWJsZVtkaXJ0eVN0YXRlXS5hcHBseShkaXJ0eVN0YXRlLCBUaGlzLT5zdGF0ZUJsb2NrLCBjb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250ZXh0LT5udW1EaXJ0eUVudHJpZXMgPSAwOyAvKiBUaGlzIG1ha2VzIHRoZSB3aG9sZSBsaXN0IGNsZWFuICovCiAgICAgICAgICAgIGNvbnRleHQtPmxhc3Rfd2FzX2JsaXQgPSBGQUxTRTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQ1RYVVNBR0VfQkxJVDoKICAgICAgICAgICAgU2V0dXBGb3JCbGl0KFRoaXMsIGNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKElXaW5lRDNEU3VyZmFjZUltcGwgKil0YXJnZXQpLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXRhcmdldCktPmN1cnJlbnREZXNjLkhlaWdodCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5leHBlY3RlZCBjb250ZXh0IHVzYWdlIHJlcXVlc3RlZFxuIik7CiAgICB9Cn0K