LyoKICogQ29udGV4dCBhbmQgcmVuZGVyIHRhcmdldCBtYW5hZ2VtZW50IGluIHdpbmVkM2QKICoKICogQ29weXJpZ2h0IDIwMDcgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlIDxzdGRpby5oPgojaWZkZWYgSEFWRV9GTE9BVF9ICiMgaW5jbHVkZSA8ZmxvYXQuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZCk7CgojZGVmaW5lIEdMSU5GT19MT0NBVElPTiBUaGlzLT5hZGFwdGVyLT5nbF9pbmZvCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29udGV4dF9NYXJrU3RhdGVEaXJ0eQogKgogKiBNYXJrcyBhIHN0YXRlIGluIGEgY29udGV4dCBkaXJ0eS4gT25seSBvbmUgY29udGV4dCwgb3Bwb3NlZCB0bwogKiBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHksIHdoaWNoIG1hcmtzIHRoZSBzdGF0ZSBkaXJ0eSBpbiBhbGwKICogY29udGV4dHMKICoKICogUGFyYW1zOgogKiAgY29udGV4dDogQ29udGV4dCB0byBtYXJrIHRoZSBzdGF0ZSBkaXJ0eSBpbgogKiAgc3RhdGU6IFN0YXRlIHRvIG1hcmsgZGlydHkKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBDb250ZXh0X01hcmtTdGF0ZURpcnR5KFdpbmVEM0RDb250ZXh0ICpjb250ZXh0LCBEV09SRCBzdGF0ZSkgewogICAgRFdPUkQgcmVwID0gU3RhdGVUYWJsZVtzdGF0ZV0ucmVwcmVzZW50YXRpdmU7CiAgICBEV09SRCBpZHg7CiAgICBCWVRFIHNoaWZ0OwoKICAgIGlmKCFyZXAgfHwgaXNTdGF0ZURpcnR5KGNvbnRleHQsIHJlcCkpIHJldHVybjsKCiAgICBjb250ZXh0LT5kaXJ0eUFycmF5W2NvbnRleHQtPm51bURpcnR5RW50cmllcysrXSA9IHJlcDsKICAgIGlkeCA9IHJlcCA+PiA1OwogICAgc2hpZnQgPSByZXAgJiAweDFmOwogICAgY29udGV4dC0+aXNTdGF0ZURpcnR5W2lkeF0gfD0gKDEgPDwgc2hpZnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQWRkQ29udGV4dFRvQXJyYXkKICoKICogQWRkcyBhIGNvbnRleHQgdG8gdGhlIGNvbnRleHQgYXJyYXkuIEhlbHBlciBmdW5jdGlvbiBmb3IgQ3JlYXRlQ29udGV4dAogKgogKiBUaGlzIG1ldGhvZCBpcyBub3QgY2FsbGVkIGluIHBlcmZvcm1hbmNlLWNyaXRpY2FsIGNvZGUgcGF0aHMsIG9ubHkgd2hlbiBhCiAqIG5ldyByZW5kZXIgdGFyZ2V0IG9yIHN3YXBjaGFpbiBpcyBjcmVhdGVkLiBUaHVzIHBlcmZvcm1hbmNlIGlzIG5vdCBhbiBpc3N1ZQogKiBoZXJlLgogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWRkIHRoZSBjb250ZXh0IGZvcgogKiAgaGRjOiBkZXZpY2UgY29udGV4dAogKiAgZ2xDdHg6IFdHTCBjb250ZXh0IHRvIGFkZAogKiAgcGJ1ZmZlcjogb3B0aW9uYWwgcGJ1ZmZlciB1c2VkIHdpdGggdGhpcyBjb250ZXh0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFdpbmVEM0RDb250ZXh0ICpBZGRDb250ZXh0VG9BcnJheShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIEhXTkQgd2luX2hhbmRsZSwgSERDIGhkYywgSEdMUkMgZ2xDdHgsIEhQQlVGRkVSQVJCIHBidWZmZXIpIHsKICAgIFdpbmVEM0RDb250ZXh0ICoqb2xkQXJyYXkgPSBUaGlzLT5jb250ZXh0czsKICAgIERXT1JEIHN0YXRlOwoKICAgIFRoaXMtPmNvbnRleHRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogKFRoaXMtPm51bUNvbnRleHRzICsgMSkpOwogICAgaWYoVGhpcy0+Y29udGV4dHMgPT0gTlVMTCkgewogICAgICAgIEVSUigiVW5hYmxlIHRvIGdyb3cgdGhlIGNvbnRleHQgYXJyYXlcbiIpOwogICAgICAgIFRoaXMtPmNvbnRleHRzID0gb2xkQXJyYXk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZihvbGRBcnJheSkgewogICAgICAgIG1lbWNweShUaGlzLT5jb250ZXh0cywgb2xkQXJyYXksIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogVGhpcy0+bnVtQ29udGV4dHMpOwogICAgfQoKICAgIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZUQzRENvbnRleHQpKTsKICAgIGlmKFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gYWxsb2NhdGUgYSBuZXcgY29udGV4dFxuIik7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y29udGV4dHMpOwogICAgICAgIFRoaXMtPmNvbnRleHRzID0gb2xkQXJyYXk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT5oZGMgPSBoZGM7CiAgICBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0c10tPmdsQ3R4ID0gZ2xDdHg7CiAgICBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0c10tPnBidWZmZXIgPSBwYnVmZmVyOwogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT53aW5faGFuZGxlID0gd2luX2hhbmRsZTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZEFycmF5KTsKCiAgICAvKiBNYXJrIGFsbCBzdGF0ZXMgZGlydHkgdG8gZm9yY2UgYSBwcm9wZXIgaW5pdGlhbGl6YXRpb24gb2YgdGhlIHN0YXRlcyBvbiB0aGUgZmlyc3QgdXNlIG9mIHRoZSBjb250ZXh0CiAgICAgKi8KICAgIGZvcihzdGF0ZSA9IDA7IHN0YXRlIDw9IFNUQVRFX0hJR0hFU1Q7IHN0YXRlKyspIHsKICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzXSwgc3RhdGUpOwogICAgfQoKICAgIFRoaXMtPm51bUNvbnRleHRzKys7CiAgICBUUkFDRSgiQ3JlYXRlZCBjb250ZXh0ICVwXG4iLCBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0cyAtIDFdKTsKICAgIHJldHVybiBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0cyAtIDFdOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ3JlYXRlQ29udGV4dAogKgogKiBDcmVhdGVzIGEgbmV3IGNvbnRleHQgZm9yIGEgd2luZG93LCBvciBhIHBidWZmZXIgY29udGV4dC4KICoKICogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWN0aXZhdGUgdGhlIGNvbnRleHQgZm9yCiAqICB0YXJnZXQ6IFN1cmZhY2UgdGhpcyBjb250ZXh0IHdpbGwgcmVuZGVyIHRvCiAqICB3aW5faGFuZGxlOiBoYW5kbGUgdG8gdGhlIHdpbmRvdyB3aGljaCB3ZSBhcmUgZHJhd2luZyB0bwogKiAgY3JlYXRlX3BidWZmZXI6IHRlbGxzIHdoZXRoZXIgdG8gY3JlYXRlIGEgcGJ1ZmZlciBvciBub3QKICogIHBQcmVzZW50UGFyYW1ldGVyczogY29udGFpbnMgdGhlIHBpeGVsZm9ybWF0cyB0byB1c2UgZm9yIG9uc2NyZWVuIHJlbmRlcmluZwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCldpbmVEM0RDb250ZXh0ICpDcmVhdGVDb250ZXh0KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgSVdpbmVEM0RTdXJmYWNlSW1wbCAqdGFyZ2V0LCBIV05EIHdpbl9oYW5kbGUsIEJPT0wgY3JlYXRlX3BidWZmZXIsIGNvbnN0IFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMgKnBQcmVzZW50UGFybXMpIHsKICAgIEhEQyBvbGREcmF3YWJsZSwgaGRjOwogICAgSFBCVUZGRVJBUkIgcGJ1ZmZlciA9IE5VTEw7CiAgICBIR0xSQyBjdHggPSBOVUxMLCBvbGRDdHg7CiAgICBXaW5lRDNEQ29udGV4dCAqcmV0ID0gTlVMTDsKICAgIGludCBzOwoKICAgIFRSQUNFKCIoJXApOiBDcmVhdGluZyBhICVzIGNvbnRleHQgZm9yIHJlbmRlciB0YXJnZXQgJXBcbiIsIFRoaXMsIGNyZWF0ZV9wYnVmZmVyID8gIm9mZnNjcmVlbiIgOiAib25zY3JlZW4iLCB0YXJnZXQpOwoKI2RlZmluZSBQVVNIMShhdHQpICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gKGF0dCk7CiNkZWZpbmUgUFVTSDIoYXR0LHZhbHVlKSAgYXR0cmlic1tuQXR0cmlicysrXSA9IChhdHQpOyBhdHRyaWJzW25BdHRyaWJzKytdID0gKHZhbHVlKTsKICAgIGlmKGNyZWF0ZV9wYnVmZmVyKSB7CiAgICAgICAgSERDIGhkY19wYXJlbnQgPSBHZXREQyh3aW5faGFuZGxlKTsKICAgICAgICBpbnQgaVBpeGVsRm9ybWF0ID0gMDsKICAgICAgICBzaG9ydCByZWQsIGdyZWVuLCBibHVlLCBhbHBoYUJpdHMsIGNvbG9yQml0czsKICAgICAgICBzaG9ydCBkZXB0aEJpdHMsIHN0ZW5jaWxCaXRzOwoKICAgICAgICBJV2luZUQzRFN1cmZhY2UgKlN0ZW5jaWxTdXJmYWNlID0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldDsKICAgICAgICBXSU5FRDNERk9STUFUIFN0ZW5jaWxCdWZmZXJGb3JtYXQgPSAoTlVMTCAhPSBTdGVuY2lsU3VyZmFjZSkgPyAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3RlbmNpbFN1cmZhY2UpLT5yZXNvdXJjZS5mb3JtYXQgOiAwOwoKICAgICAgICBpbnQgYXR0cmlic1syNTZdOwogICAgICAgIGludCBuQXR0cmlicyA9IDA7CiAgICAgICAgdW5zaWduZWQgaW50IG5Gb3JtYXRzOwoKICAgICAgICAvKiBSZXRyaWV2ZSB0aGUgc3BlY2lmaWNhdGlvbnMgZm9yIHRoZSBwaXhlbGZvcm1hdCBmcm9tIHRoZSBiYWNrYnVmZmVyIC8gc3RlbmNpbGJ1ZmZlciAqLwogICAgICAgIGdldENvbG9yQml0cyh0YXJnZXQtPnJlc291cmNlLmZvcm1hdCwgJnJlZCwgJmdyZWVuLCAmYmx1ZSwgJmFscGhhQml0cywgJmNvbG9yQml0cyk7CiAgICAgICAgZ2V0RGVwdGhTdGVuY2lsQml0cyhTdGVuY2lsQnVmZmVyRm9ybWF0LCAmZGVwdGhCaXRzLCAmc3RlbmNpbEJpdHMpOwogICAgICAgIFBVU0gyKFdHTF9EUkFXX1RPX1BCVUZGRVJfQVJCLCAxKTsgLyogV2UgbmVlZCBwYnVmZmVyIHN1cHBvcnQ7IGRvdWJsZWJ1ZmZlcmluZyBpc24ndCBuZWVkZWQgKi8KICAgICAgICBQVVNIMihXR0xfUElYRUxfVFlQRV9BUkIsIFdHTF9UWVBFX1JHQkFfQVJCKTsgLyogTWFrZSBzdXJlIHdlIGRvbid0IGdldCBhIGZsb2F0IG9yIGNvbG9yIGluZGV4IGZvcm1hdCAqLwogICAgICAgIFBVU0gyKFdHTF9DT0xPUl9CSVRTX0FSQiwgY29sb3JCaXRzKTsKICAgICAgICBQVVNIMihXR0xfQUxQSEFfQklUU19BUkIsIGFscGhhQml0cyk7CiAgICAgICAgUFVTSDIoV0dMX0RFUFRIX0JJVFNfQVJCLCBkZXB0aEJpdHMpOwogICAgICAgIFBVU0gyKFdHTF9TVEVOQ0lMX0JJVFNfQVJCLCBzdGVuY2lsQml0cyk7CiAgICAgICAgUFVTSDEoMCk7IC8qIGVuZCB0aGUgbGlzdCAqLwoKICAgICAgICAvKiBUcnkgdG8gZmluZCBhIHBpeGVsZm9ybWF0IHRoYXQgbWF0Y2hlcyBleGFjdGx5LiBJZiB0aGF0IGZhaWxzIGxldCBDaG9vc2VQaXhlbEZvcm1hdCB0cnkgdG8gZmluZCBhIGNsb3NlIG1hdGNoICovCiAgICAgICAgaWYoIUdMX0VYVENBTEwod2dsQ2hvb3NlUGl4ZWxGb3JtYXRBUkIoaGRjX3BhcmVudCwgKGNvbnN0IGludCopJmF0dHJpYnMsIE5VTEwsIDEsICZpUGl4ZWxGb3JtYXQsICZuRm9ybWF0cykpKQogICAgICAgIHsKICAgICAgICAgICAgUElYRUxGT1JNQVRERVNDUklQVE9SIHBmZDsKCiAgICAgICAgICAgIFRSQUNFKCJGYWxsaW5nIGJhY2sgdG8gQ2hvb3NlUGl4ZWxGb3JtYXQgYXMgd2dsQ2hvb3NlUGl4ZWxGb3JtYXRBUkIgZmFpbGVkXG4iKTsKCiAgICAgICAgICAgIFplcm9NZW1vcnkoJnBmZCwgc2l6ZW9mKHBmZCkpOwogICAgICAgICAgICBwZmQublNpemUgICAgICA9IHNpemVvZihwZmQpOwogICAgICAgICAgICBwZmQublZlcnNpb24gICA9IDE7CiAgICAgICAgICAgIHBmZC5kd0ZsYWdzICAgID0gUEZEX1NVUFBPUlRfT1BFTkdMIHwgUEZEX0RPVUJMRUJVRkZFUl9ET05UQ0FSRSB8IFBGRF9EUkFXX1RPX1dJTkRPVzsKICAgICAgICAgICAgcGZkLmlQaXhlbFR5cGUgPSBQRkRfVFlQRV9SR0JBOwogICAgICAgICAgICBwZmQuY0NvbG9yQml0cyA9IGNvbG9yQml0czsKICAgICAgICAgICAgcGZkLmNEZXB0aEJpdHMgPSBkZXB0aEJpdHM7CiAgICAgICAgICAgIHBmZC5jU3RlbmNpbEJpdHMgPSBzdGVuY2lsQml0czsKICAgICAgICAgICAgcGZkLmlMYXllclR5cGUgPSBQRkRfTUFJTl9QTEFORTsKCiAgICAgICAgICAgIGlQaXhlbEZvcm1hdCA9IENob29zZVBpeGVsRm9ybWF0KGhkY19wYXJlbnQsICZwZmQpOwogICAgICAgICAgICBpZighaVBpeGVsRm9ybWF0KSB7CiAgICAgICAgICAgICAgICAvKiBJZiB0aGlzIGhhcHBlbnMgc29tZXRoaW5nIGlzIHZlcnkgd3JvbmcgYXMgQ2hvb3NlUGl4ZWxGb3JtYXQgYmFyZWx5IGZhaWxzICovCiAgICAgICAgICAgICAgICBFUlIoIkNhbid0IGZpbmQgYSBzdWl0YWJsZSBpUGl4ZWxGb3JtYXQgZm9yIHRoZSBwYnVmZmVyXG4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIkNyZWF0aW5nIGEgcEJ1ZmZlciBkcmF3YWJsZSBmb3IgdGhlIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICBwYnVmZmVyID0gR0xfRVhUQ0FMTCh3Z2xDcmVhdGVQYnVmZmVyQVJCKGhkY19wYXJlbnQsIGlQaXhlbEZvcm1hdCwgdGFyZ2V0LT5jdXJyZW50RGVzYy5XaWR0aCwgdGFyZ2V0LT5jdXJyZW50RGVzYy5IZWlnaHQsIDApKTsKICAgICAgICBpZighcGJ1ZmZlcikgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBjcmVhdGUgYSBwYnVmZmVyXG4iKTsKICAgICAgICAgICAgUmVsZWFzZURDKHdpbl9oYW5kbGUsIGhkY19wYXJlbnQpOwogICAgICAgICAgICBnb3RvIG91dDsKICAgICAgICB9CgogICAgICAgIC8qIEluIFdHTCBhIHBidWZmZXIgaXMgJ3dyYXBwZWQnIGluc2lkZSBhIEhEQyB0byAnZm9vbCcgd2dsTWFrZUN1cnJlbnQgKi8KICAgICAgICBoZGMgPSBHTF9FWFRDQUxMKHdnbEdldFBidWZmZXJEQ0FSQihwYnVmZmVyKSk7CiAgICAgICAgaWYoIWhkYykgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBnZXQgYSBIREMgZm9yIHBidWZmZXIgKCVwKVxuIiwgcGJ1ZmZlcik7CiAgICAgICAgICAgIEdMX0VYVENBTEwod2dsRGVzdHJveVBidWZmZXJBUkIocGJ1ZmZlcikpOwogICAgICAgICAgICBSZWxlYXNlREMod2luX2hhbmRsZSwgaGRjX3BhcmVudCk7CiAgICAgICAgICAgIGdvdG8gb3V0OwogICAgICAgIH0KICAgICAgICBSZWxlYXNlREMod2luX2hhbmRsZSwgaGRjX3BhcmVudCk7CiAgICB9IGVsc2UgewogICAgICAgIFBJWEVMRk9STUFUREVTQ1JJUFRPUiBwZmQ7CiAgICAgICAgaW50IGlQaXhlbEZvcm1hdDsKICAgICAgICBzaG9ydCByZWRCaXRzLCBncmVlbkJpdHMsIGJsdWVCaXRzLCBhbHBoYUJpdHMsIGNvbG9yQml0czsKICAgICAgICBzaG9ydCBkZXB0aEJpdHM9MCwgc3RlbmNpbEJpdHM9MDsKICAgICAgICBpbnQgcmVzOwogICAgICAgIGludCBhdHRyaWJzWzI1Nl07CiAgICAgICAgaW50IG5BdHRyaWJzID0gMDsKICAgICAgICB1bnNpZ25lZCBpbnQgbkZvcm1hdHM7CgogICAgICAgIGhkYyA9IEdldERDKHdpbl9oYW5kbGUpOwogICAgICAgIGlmKGhkYyA9PSBOVUxMKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IHJldHJpZXZlIGEgZGV2aWNlIGNvbnRleHQhXG4iKTsKICAgICAgICAgICAgZ290byBvdXQ7CiAgICAgICAgfQoKICAgICAgICAvKiBQaXhlbEZvcm1hdCBzZWxlY3Rpb24gKi8KICAgICAgICBQVVNIMihXR0xfRFJBV19UT19XSU5ET1dfQVJCLCBHTF9UUlVFKTsgLyogV2Ugd2FudCB0byBkcmF3IHRvIGEgd2luZG93ICovCiAgICAgICAgUFVTSDIoV0dMX0RPVUJMRV9CVUZGRVJfQVJCLCBHTF9UUlVFKTsKICAgICAgICBQVVNIMihXR0xfUElYRUxfVFlQRV9BUkIsIFdHTF9UWVBFX1JHQkFfQVJCKTsgLyogTWFrZSBzdXJlIHdlIGRvbid0IGdldCBhIGZsb2F0IG9yIGNvbG9yIGluZGV4IGZvcm1hdCAqLwoKICAgICAgICBpZighZ2V0Q29sb3JCaXRzKHRhcmdldC0+cmVzb3VyY2UuZm9ybWF0LCAmcmVkQml0cywgJmdyZWVuQml0cywgJmJsdWVCaXRzLCAmYWxwaGFCaXRzLCAmY29sb3JCaXRzKSkgewogICAgICAgICAgICBFUlIoIlVuYWJsZSB0byBnZXQgY29sb3IgYml0cyBmb3IgZm9ybWF0ICUjeCFcbiIsIHRhcmdldC0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgICAgICBQVVNIMihXR0xfQ09MT1JfQklUU19BUkIsIGNvbG9yQml0cyk7CiAgICAgICAgUFVTSDIoV0dMX1JFRF9CSVRTX0FSQiwgcmVkQml0cyk7CiAgICAgICAgUFVTSDIoV0dMX0dSRUVOX0JJVFNfQVJCLCBncmVlbkJpdHMpOwogICAgICAgIFBVU0gyKFdHTF9CTFVFX0JJVFNfQVJCLCBibHVlQml0cyk7CiAgICAgICAgUFVTSDIoV0dMX0FMUEhBX0JJVFNfQVJCLCBhbHBoYUJpdHMpOwoKICAgICAgICAvKiBSZXRyaWV2ZSB0aGUgZGVwdGggc3RlbmNpbCBmb3JtYXQgZnJvbSB0aGUgcHJlc2VudCBwYXJhbWV0ZXJzLgogICAgICAgICAqIFRoZSBjaG9pY2Ugb2YgdGhlIHByb3BlciBmb3JtYXQgY2FuIGdpdmUgYSBuaWNlIHBlcmZvcm1hbmNlIGJvb3N0CiAgICAgICAgICogaW4gY2FzZSBvZiBHUFUgbGltaXRlZCBwcm9ncmFtcy4gKi8KICAgICAgICBpZihwUHJlc2VudFBhcm1zLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsKSB7CiAgICAgICAgICAgIFRSQUNFKCJwUHJlc2VudFBhcm1zLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsPWVuYWJsZWQ7IHVzaW5nIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQ9JXNcbiIsIGRlYnVnX2QzZGZvcm1hdChwUHJlc2VudFBhcm1zLT5BdXRvRGVwdGhTdGVuY2lsRm9ybWF0KSk7CiAgICAgICAgICAgIGlmKCFnZXREZXB0aFN0ZW5jaWxCaXRzKHBQcmVzZW50UGFybXMtPkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQsICZkZXB0aEJpdHMsICZzdGVuY2lsQml0cykpIHsKICAgICAgICAgICAgICAgIEVSUigiVW5hYmxlIHRvIGdldCBkZXB0aCAvIHN0ZW5jaWwgYml0cyBmb3IgQXV0b0RlcHRoU3RlbmNpbEZvcm1hdCAlI3ghXG4iLCBwUHJlc2VudFBhcm1zLT5BdXRvRGVwdGhTdGVuY2lsRm9ybWF0KTsKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBQVVNIMihXR0xfREVQVEhfQklUU19BUkIsIGRlcHRoQml0cyk7CiAgICAgICAgICAgIFBVU0gyKFdHTF9TVEVOQ0lMX0JJVFNfQVJCLCBzdGVuY2lsQml0cyk7CiAgICAgICAgfQoKICAgICAgICBQVVNIMSgwKTsgLyogZW5kIHRoZSBsaXN0ICovCiAgICAgICAgaVBpeGVsRm9ybWF0ID0gQ2hvb3NlUGl4ZWxGb3JtYXQoaGRjLCAmcGZkKTsKCiAgICAgICAgLyogSW4gY2FzZSBvZiBmYWlsdXJlIGhvcGUgdGhhdCBzdGFuZGFyZCBDaG9vb3NlUGl4ZWxGb3JtYXQgd2lsbCBmaW5kIHNvbWV0aGluZyBzdWl0YWJsZSAqLwogICAgICAgIGlmKCFHTF9FWFRDQUxMKHdnbENob29zZVBpeGVsRm9ybWF0QVJCKGhkYywgKGNvbnN0IGludCopJmF0dHJpYnMsIE5VTEwsIDEsICZpUGl4ZWxGb3JtYXQsICZuRm9ybWF0cykpKQogICAgICAgIHsKICAgICAgICAgICAgLyogUGl4ZWxGb3JtYXQgc2VsZWN0aW9uICovCiAgICAgICAgICAgIFplcm9NZW1vcnkoJnBmZCwgc2l6ZW9mKHBmZCkpOwogICAgICAgICAgICBwZmQublNpemUgICAgICA9IHNpemVvZihwZmQpOwogICAgICAgICAgICBwZmQublZlcnNpb24gICA9IDE7CiAgICAgICAgICAgIHBmZC5kd0ZsYWdzICAgID0gUEZEX1NVUFBPUlRfT1BFTkdMIHwgUEZEX0RPVUJMRUJVRkZFUiB8IFBGRF9EUkFXX1RPX1dJTkRPVzsvKlBGRF9HRU5FUklDX0FDQ0VMRVJBVEVEKi8KICAgICAgICAgICAgcGZkLmlQaXhlbFR5cGUgPSBQRkRfVFlQRV9SR0JBOwogICAgICAgICAgICBwZmQuY0FscGhhQml0cyA9IGFscGhhQml0czsKICAgICAgICAgICAgcGZkLmNDb2xvckJpdHMgPSBjb2xvckJpdHM7CiAgICAgICAgICAgIHBmZC5jRGVwdGhCaXRzID0gZGVwdGhCaXRzOwogICAgICAgICAgICBwZmQuY1N0ZW5jaWxCaXRzID0gc3RlbmNpbEJpdHM7CiAgICAgICAgICAgIHBmZC5pTGF5ZXJUeXBlID0gUEZEX01BSU5fUExBTkU7CgogICAgICAgICAgICBpUGl4ZWxGb3JtYXQgPSBDaG9vc2VQaXhlbEZvcm1hdChoZGMsICZwZmQpOwogICAgICAgICAgICBpZighaVBpeGVsRm9ybWF0KSB7CiAgICAgICAgICAgICAgICAvKiBJZiB0aGlzIGhhcHBlbnMgc29tZXRoaW5nIGlzIHZlcnkgd3JvbmcgYXMgQ2hvb3NlUGl4ZWxGb3JtYXQgYmFyZWx5IGZhaWxzICovCiAgICAgICAgICAgICAgICBFUlIoIkNhbid0IGZpbmQgYSBzdWl0YWJsZSBpUGl4ZWxGb3JtYXRcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBEZXNjcmliZVBpeGVsRm9ybWF0KGhkYywgaVBpeGVsRm9ybWF0LCBzaXplb2YocGZkKSwgJnBmZCk7CiAgICAgICAgcmVzID0gU2V0UGl4ZWxGb3JtYXQoaGRjLCBpUGl4ZWxGb3JtYXQsIE5VTEwpOwogICAgICAgIGlmKCFyZXMpIHsKICAgICAgICAgICAgaW50IG9sZFBpeGVsRm9ybWF0ID0gR2V0UGl4ZWxGb3JtYXQoaGRjKTsKCiAgICAgICAgICAgIGlmKG9sZFBpeGVsRm9ybWF0KSB7CiAgICAgICAgICAgICAgICAvKiBPcGVuR0wgZG9lc24ndCBhbGxvdyBwaXhlbCBmb3JtYXQgYWRqdXN0bWVudHMuIFByaW50IGFuIGVycm9yIGFuZCBjb250aW51ZSB1c2luZyB0aGUgb2xkIGZvcm1hdC4KICAgICAgICAgICAgICAgICAqIFRoZXJlJ3MgYSBiaWcgY2hhbmNlIHRoYXQgdGhlIG9sZCBmb3JtYXQgd29ya3MgYWx0aG91Z2ggd2l0aCBhIHBlcmZvcm1hbmNlIGhpdCBhbmQgcGVyaGFwcyByZW5kZXJpbmcgZXJyb3JzLiAqLwogICAgICAgICAgICAgICAgRVJSKCJIREM9JXAgaXMgYWxyZWFkeSBzZXQgdG8gaVBpeGVsRm9ybWF0PSVkIGFuZCBPcGVuR0wgZG9lc24ndCBhbGxvdyBjaGFuZ2VzIVxuIiwgaGRjLCBvbGRQaXhlbEZvcm1hdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBFUlIoIlNldFBpeGVsRm9ybWF0IGZhaWxlZCBvbiBIREM9JXAgZm9yIGlQaXhlbEZvcm1hdD0lZFxuIiwgaGRjLCBpUGl4ZWxGb3JtYXQpOwogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQojdW5kZWYgUFVTSDEKI3VuZGVmIFBVU0gyCgogICAgY3R4ID0gcHdnbENyZWF0ZUNvbnRleHQoaGRjKTsKICAgIGlmKFRoaXMtPm51bUNvbnRleHRzKSBwd2dsU2hhcmVMaXN0cyhUaGlzLT5jb250ZXh0c1swXS0+Z2xDdHgsIGN0eCk7CgogICAgaWYoIWN0eCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIFdHTCBjb250ZXh0XG4iKTsKICAgICAgICBpZihjcmVhdGVfcGJ1ZmZlcikgewogICAgICAgICAgICBHTF9FWFRDQUxMKHdnbFJlbGVhc2VQYnVmZmVyRENBUkIocGJ1ZmZlciwgaGRjKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwod2dsRGVzdHJveVBidWZmZXJBUkIocGJ1ZmZlcikpOwogICAgICAgIH0KICAgICAgICBnb3RvIG91dDsKICAgIH0KICAgIHJldCA9IEFkZENvbnRleHRUb0FycmF5KFRoaXMsIHdpbl9oYW5kbGUsIGhkYywgY3R4LCBwYnVmZmVyKTsKICAgIGlmKCFyZXQpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBhZGQgdGhlIG5ld2x5IGNyZWF0ZWQgY29udGV4dCB0byB0aGUgY29udGV4dCBsaXN0XG4iKTsKICAgICAgICBwd2dsRGVsZXRlQ29udGV4dChjdHgpOwogICAgICAgIGlmKGNyZWF0ZV9wYnVmZmVyKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwod2dsUmVsZWFzZVBidWZmZXJEQ0FSQihwYnVmZmVyLCBoZGMpKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTCh3Z2xEZXN0cm95UGJ1ZmZlckFSQihwYnVmZmVyKSk7CiAgICAgICAgfQogICAgICAgIGdvdG8gb3V0OwogICAgfQogICAgcmV0LT5zdXJmYWNlID0gKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQ7CiAgICByZXQtPmlzUEJ1ZmZlciA9IGNyZWF0ZV9wYnVmZmVyOwogICAgcmV0LT50aWQgPSBHZXRDdXJyZW50VGhyZWFkSWQoKTsKCiAgICBUUkFDRSgiU3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgbmV3IGNvbnRleHQgJXBcbiIsIHJldCk7CgogICAgLyogU2V0IHVwIHRoZSBjb250ZXh0IGRlZmF1bHRzICovCiAgICBvbGRDdHggID0gcHdnbEdldEN1cnJlbnRDb250ZXh0KCk7CiAgICBvbGREcmF3YWJsZSA9IHB3Z2xHZXRDdXJyZW50REMoKTsKICAgIGlmKHB3Z2xNYWtlQ3VycmVudChoZGMsIGN0eCkgPT0gRkFMU0UpIHsKICAgICAgICBFUlIoIkNhbm5vdCBhY3RpdmF0ZSBjb250ZXh0IHRvIHNldCB1cCBkZWZhdWx0c1xuIik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgVFJBQ0UoIlNldHRpbmcgdXAgdGhlIHNjcmVlblxuIik7CiAgICAvKiBDbGVhciB0aGUgc2NyZWVuICovCiAgICBnbENsZWFyQ29sb3IoMS4wLCAwLjAsIDAuMCwgMC4wKTsKICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyQ29sb3IiKTsKICAgIGdsQ2xlYXJJbmRleCgwKTsKICAgIGdsQ2xlYXJEZXB0aCgxKTsKICAgIGdsQ2xlYXJTdGVuY2lsKDB4ZmZmZik7CgogICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKCiAgICBnbENvbG9yM2YoMS4wLCAxLjAsIDEuMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDb2xvcjNmIik7CgogICAgZ2xFbmFibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIik7CgogICAgZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9MT0NBTF9WSUVXRVIsIEdMX1RSVUUpOwogICAgY2hlY2tHTGNhbGwoImdsTGlnaHRNb2RlbGkoR0xfTElHSFRfTU9ERUxfTE9DQUxfVklFV0VSLCBHTF9UUlVFKTsiKTsKCiAgICBnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsiKTsKCiAgICBnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0NPTE9SX0NPTlRST0wsIEdMX1NFUEFSQVRFX1NQRUNVTEFSX0NPTE9SKTsKICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0NPTE9SX0NPTlRST0wsIEdMX1NFUEFSQVRFX1NQRUNVTEFSX0NPTE9SKTsiKTsKCiAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfQUxJR05NRU5ULCBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCk7CiAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9QQUNLX0FMSUdOTUVOVCwgVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQpOyIpOwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCk7CiAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCk7Iik7CgogICAgaWYoR0xfU1VQUE9SVChBUFBMRV9DTElFTlRfU1RPUkFHRSkpIHsKICAgICAgICAvKiBNb3N0IHRleHR1cmVzIHdpbGwgdXNlIGNsaWVudCBzdG9yYWdlIGlmIHN1cHBvcnRlZC4gRXhjZXB0aW9ucyBhcmUgbm9uLW5hdGl2ZSBwb3dlciBvZiAyIHRleHR1cmVzCiAgICAgICAgICogYW5kIHRleHR1cmVzIGluIERJQiBzZWN0aW9ucyhkdWUgdG8gdGhlIG1lbW9yeSBwcm90ZWN0aW9uKS4KICAgICAgICAgKi8KICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfVFJVRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKSIpOwogICAgfQogICAgaWYoR0xfU1VQUE9SVChBUkJfVkVSVEVYX0JMRU5EKSkgewogICAgICAgIC8qIERpcmVjdDNEIGFsd2F5cyB1c2VzIG4tMSB3ZWlnaHRzIGZvciBuIHdvcmxkIG1hdHJpY2VzIGFuZCB1c2VzIDEgLSBzdW0gZm9yIHRoZSBsYXN0IG9uZQogICAgICAgICAqIHRoaXMgaXMgZXF1YWwgdG8gR0xfV0VJR0hUX1NVTV9VTklUWV9BUkIuIEVuYWJsaW5nIGl0IGRvZXNuJ3QgZG8gYW55dGhpbmcgdW5sZXNzCiAgICAgICAgICogR0xfVkVSVEVYX0JMRU5EX0FSQiBpc24ndCBlbmFibGVkIHRvbwogICAgICAgICAqLwogICAgICAgIGdsRW5hYmxlKEdMX1dFSUdIVF9TVU1fVU5JVFlfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfV0VJR0hUX1NVTV9VTklUWV9BUkIpIik7CiAgICB9CiAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMikpIHsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfU0hBREVSX05WKSIpOwoKICAgICAgICAvKiBTZXQgdXAgdGhlIHByZXZpb3VzIHRleHR1cmUgaW5wdXQgZm9yIGFsbCBzaGFkZXIgdW5pdHMuIFRoaXMgYXBwbGllcyB0byBidW1wIG1hcHBpbmcsIGFuZCBpbiBkM2QKICAgICAgICAgKiB0aGUgcHJldmlvdXMgdGV4dHVyZSB3aGVyZSB0byBzb3VyY2UgdGhlIG9mZnNldCBmcm9tIGlzIGFsd2F5cyB1bml0IC0gMS4KICAgICAgICAgKi8KICAgICAgICBmb3IocyA9IDE7IHMgPCBHTF9MSU1JVFModGV4dHVyZXMpOyBzKyspIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCICsgcykpOwogICAgICAgICAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9TSEFERVJfTlYsIEdMX1BSRVZJT1VTX1RFWFRVUkVfSU5QVVRfTlYsIEdMX1RFWFRVUkUwX0FSQiArIHMgLSAxKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aShHTF9URVhUVVJFX1NIQURFUl9OViwgR0xfUFJFVklPVVNfVEVYVFVSRV9JTlBVVF9OViwgLi4uXG4iKTsKICAgICAgICB9CiAgICB9CiAgICBpZihHTF9TVVBQT1JUKEFSQl9QT0lOVF9TUFJJVEUpKSB7CiAgICAgICAgZm9yKHMgPSAwOyBzIDwgR0xfTElNSVRTKHRleHR1cmVzKTsgcysrKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQiArIHMpKTsKICAgICAgICAgICAgZ2xUZXhFbnZpKEdMX1BPSU5UX1NQUklURV9BUkIsIEdMX0NPT1JEX1JFUExBQ0VfQVJCLCBHTF9UUlVFKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aShHTF9QT0lOVF9TUFJJVEVfQVJCLCBHTF9DT09SRF9SRVBMQUNFX0FSQiwgR0xfVFJVRSlcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBpZihvbGREcmF3YWJsZSAmJiBvbGRDdHgpIHsKICAgICAgICBwd2dsTWFrZUN1cnJlbnQob2xkRHJhd2FibGUsIG9sZEN0eCk7CiAgICB9CgpvdXQ6CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUmVtb3ZlQ29udGV4dEZyb21BcnJheQogKgogKiBSZW1vdmVzIGEgY29udGV4dCBmcm9tIHRoZSBjb250ZXh0IG1hbmFnZXIuIFRoZSBvcGVuZ2wgY29udGV4dCBpcyBub3QKICogZGVzdHJveWVkIG9yIHVuc2V0LiBjb250ZXh0IGlzIG5vdCBhIHZhbGlkIHBvaW50ZXIgYWZ0ZXIgdGhhdCBjYWxsLgogKgogKiBTaW1pbGFyIHRvIHRoZSBmb3JtZXIgY2FsbCB0aGlzIGlzbid0IGEgcGVyZm9ybWFuY2UgY3JpdGljYWwgZnVuY3Rpb24uIEEKICogaGVscGVyIGZ1bmN0aW9uIGZvciBEZXN0cm95Q29udGV4dC4KICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgY29udGV4dDogQ29udGV4dCB0byByZW1vdmUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBSZW1vdmVDb250ZXh0RnJvbUFycmF5KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgV2luZUQzRENvbnRleHQgKmNvbnRleHQpIHsKICAgIFVJTlQgdCwgczsKICAgIFdpbmVEM0RDb250ZXh0ICoqb2xkQXJyYXkgPSBUaGlzLT5jb250ZXh0czsKCiAgICBUUkFDRSgiUmVtb3ZpbmcgY3R4ICVwXG4iLCBjb250ZXh0KTsKCiAgICBUaGlzLT5udW1Db250ZXh0cy0tOwoKICAgIGlmKFRoaXMtPm51bUNvbnRleHRzKSB7CiAgICAgICAgVGhpcy0+Y29udGV4dHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpUaGlzLT5jb250ZXh0cykgKiBUaGlzLT5udW1Db250ZXh0cyk7CiAgICAgICAgaWYoIVRoaXMtPmNvbnRleHRzKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IGFsbG9jYXRlIGEgbmV3IGNvbnRleHQgYXJyYXksIFBBTklDISEhXG4iKTsKICAgICAgICB9CiAgICAgICAgdCA9IDA7CiAgICAgICAgZm9yKHMgPSAwOyBzIDwgVGhpcy0+bnVtQ29udGV4dHM7IHMrKykgewogICAgICAgICAgICBpZihvbGRBcnJheVtzXSA9PSBjb250ZXh0KSBjb250aW51ZTsKICAgICAgICAgICAgVGhpcy0+Y29udGV4dHNbdF0gPSBvbGRBcnJheVtzXTsKICAgICAgICAgICAgdCsrOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVGhpcy0+Y29udGV4dHMgPSBOVUxMOwogICAgfQoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNvbnRleHQpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2xkQXJyYXkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGVzdHJveUNvbnRleHQKICoKICogRGVzdHJveXMgYSB3aW5lRDNEQ29udGV4dAogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWN0aXZhdGUgdGhlIGNvbnRleHQgZm9yCiAqICBjb250ZXh0OiBDb250ZXh0IHRvIGRlc3Ryb3kKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIERlc3Ryb3lDb250ZXh0KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgV2luZUQzRENvbnRleHQgKmNvbnRleHQpIHsKCiAgICAvKiBjaGVjayB0aGF0IHdlIGFyZSB0aGUgY3VycmVudCBjb250ZXh0IGZpcnN0ICovCiAgICBUUkFDRSgiRGVzdHJveWluZyBjdHggJXBcbiIsIGNvbnRleHQpOwogICAgaWYocHdnbEdldEN1cnJlbnRDb250ZXh0KCkgPT0gY29udGV4dC0+Z2xDdHgpewogICAgICAgIHB3Z2xNYWtlQ3VycmVudChOVUxMLCBOVUxMKTsKICAgIH0KCiAgICBpZihjb250ZXh0LT5pc1BCdWZmZXIpIHsKICAgICAgICBHTF9FWFRDQUxMKHdnbFJlbGVhc2VQYnVmZmVyRENBUkIoY29udGV4dC0+cGJ1ZmZlciwgY29udGV4dC0+aGRjKSk7CiAgICAgICAgR0xfRVhUQ0FMTCh3Z2xEZXN0cm95UGJ1ZmZlckFSQihjb250ZXh0LT5wYnVmZmVyKSk7CiAgICB9IGVsc2UgUmVsZWFzZURDKGNvbnRleHQtPndpbl9oYW5kbGUsIGNvbnRleHQtPmhkYyk7CiAgICBwd2dsRGVsZXRlQ29udGV4dChjb250ZXh0LT5nbEN0eCk7CgogICAgUmVtb3ZlQ29udGV4dEZyb21BcnJheShUaGlzLCBjb250ZXh0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNldHVwRm9yQmxpdAogKgogKiBTZXRzIHVwIGEgY29udGV4dCBmb3IgRGlyZWN0RHJhdyBibGl0dGluZy4KICogQWxsIHRleHR1cmUgdW5pdHMgYXJlIGRpc2FibGVkLCBleGNlcHQgdW5pdCAwCiAqIFRleHR1cmUgdW5pdCAwIGlzIGFjdGl2dGVkIHdoZXJlIEdMX1RFWFRVUkVfMkQgaXMgYWN0aXZhdGVkCiAqIGZvZywgbGlnaHRpbmcsIGJsZW5kaW5nLCBhbHBoYSB0ZXN0LCB6IHRlc3QsIHNjaXNzb3IgdGVzdCwgY3VsbGluZyBkaWFibGVkCiAqIGNvbG9yIHdyaXRpbmcgZW5hYmxlZCBmb3IgYWxsIGNoYW5uZWxzCiAqIHJlZ2lzdGVyIGNvbWJpbmVycyBkaXNhYmxlZCwgc2hhZGVycyBkaXNhYmxlZAogKiB3b3JsZCBtYXRyaXMgaXMgc2V0IHRvIGlkZW50aXR5LCB0ZXh0dXJlIG1hdHJpeCAwIHRvbwogKiBwcm9qZWN0aW9uIG1hdHJpeCBpcyBzZXR1cCBmb3IgZHJhd2luZyBzY3JlZW4gY29vcmRpbmF0ZXMKICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgY29udGV4dDogQ29udGV4dCB0byBzZXR1cAogKiAgd2lkdGg6IHJlbmRlciB0YXJnZXQgd2lkdGgKICogIGhlaWdodDogcmVuZGVyIHRhcmdldCBoZWlnaHQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIHZvaWQgU2V0dXBGb3JCbGl0KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgV2luZUQzRENvbnRleHQgKmNvbnRleHQsIFVJTlQgd2lkdGgsIFVJTlQgaGVpZ2h0KSB7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiU2V0dGluZyB1cCBjb250ZXh0ICVwIGZvciBibGl0dGluZ1xuIiwgY29udGV4dCk7CiAgICBpZihjb250ZXh0LT5sYXN0X3dhc19ibGl0KSB7CiAgICAgICAgVFJBQ0UoIkNvbnRleHQgaXMgYWxyZWFkeSBzZXQgdXAgZm9yIGJsaXR0aW5nLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjb250ZXh0LT5sYXN0X3dhc19ibGl0ID0gVFJVRTsKCiAgICAvKiBUT0RPOiBVc2UgYSBkaXNwbGF5IGxpc3QgKi8KCiAgICAvKiBEaXNhYmxlIHNoYWRlcnMgKi8KICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfY2xlYW51cCgoSVdpbmVEM0REZXZpY2UgKikgVGhpcyk7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZTSEFERVIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9QSVhFTFNIQURFUik7CgogICAgLyogRGlzYWJsZSBhbGwgdGV4dHVyZXMuIFRoZSBjYWxsZXIgY2FuIHRoZW4gYmluZCBhIHRleHR1cmUgaXQgd2FudHMgdG8gYmxpdAogICAgICogZnJvbQogICAgICovCiAgICBpZihHTF9TVVBQT1JUKE5WX1JFR0lTVEVSX0NPTUJJTkVSUykpIHsKICAgICAgICBnbERpc2FibGUoR0xfUkVHSVNURVJfQ09NQklORVJTX05WKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX1JFR0lTVEVSX0NPTUJJTkVSU19OVikiKTsKICAgIH0KICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgLyogVGhlIGJsaXR0aW5nIGNvZGUgdXNlcyAoZm9yIG5vdykgdGhlIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lLCBzbyBtYWtlIHN1cmUgdG8gcmVzZXQgYWxsIGZpeGVkCiAgICAgICAgICogZnVuY3Rpb24gdGV4dHVyZSB1bml0LiBObyBuZWVkIHRvIGNhcmUgZm9yIGhpZ2hlciBzYW1wbGVycwogICAgICAgICAqLwogICAgICAgIGZvcihpID0gR0xfTElNSVRTKHRleHR1cmVzKSAtIDE7IGkgPiAwIDsgaS0tKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQiArIGkpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9DVUJFX01BUCkpIHsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQik7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfM0QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfM0QiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfMkQiKTsKCiAgICAgICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOyIpOwoKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9URVhUVVJFU1RBR0UoaSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0FNUExFUihpKSk7CiAgICAgICAgfQogICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgIH0KICAgIGlmKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfQ1VCRV9NQVApKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCIik7CiAgICB9CiAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8zRCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfM0QiKTsKICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX1RFWFRVUkVfMkQiKTsKCiAgICBnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOwoKICAgIGdsTWF0cml4TW9kZShHTF9URVhUVVJFKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdHJpeE1vZGUoR0xfVEVYVFVSRSkiKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMb2FkSWRlbnRpdHkoKSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9UUkFOU0ZPUk0oV0lORUQzRFRTX1RFWFRVUkUwKSk7CgogICAgaWYgKEdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfTE9EX0JJQVMpKSB7CiAgICAgICAgZ2xUZXhFbnZmKEdMX1RFWFRVUkVfRklMVEVSX0NPTlRST0xfRVhULAogICAgICAgICAgICAgICAgICBHTF9URVhUVVJFX0xPRF9CSUFTX0VYVCwKICAgICAgICAgICAgICAgICAgMC4wKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhFbnZpIEdMX1RFWFRVUkVfTE9EX0JJQVNfRVhUIC4uLiIpOwogICAgfQogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9TQU1QTEVSKDApKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVEVYVFVSRVNUQUdFKDAsIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwoKICAgIC8qIE90aGVyIG1pc2Mgc3RhdGVzICovCiAgICBnbERpc2FibGUoR0xfQUxQSEFfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQUxQSEFURVNURU5BQkxFKSk7CiAgICBnbERpc2FibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9MSUdIVElORyIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0xJR0hUSU5HKSk7CiAgICBnbERpc2FibGUoR0xfREVQVEhfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0RFUFRIX1RFU1QiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aRU5BQkxFKSk7CiAgICBnbERpc2FibGUoR0xfRk9HKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfRk9HIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfRk9HRU5BQkxFKSk7CiAgICBnbERpc2FibGUoR0xfQkxFTkQpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9CTEVORCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0FMUEhBQkxFTkRFTkFCTEUpKTsKICAgIGdsRGlzYWJsZShHTF9DVUxMX0ZBQ0UpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9DVUxMX0ZBQ0UiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DVUxMTU9ERSkpOwogICAgZ2xEaXNhYmxlKEdMX1NURU5DSUxfVEVTVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1NURU5DSUxfVEVTVCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NURU5DSUxFTkFCTEUpKTsKICAgIGlmKEdMX1NVUFBPUlQoQVJCX1BPSU5UX1NQUklURSkpIHsKICAgICAgICBnbERpc2FibGUoR0xfUE9JTlRfU1BSSVRFX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9QT0lOVF9TUFJJVEVfQVJCIik7CiAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1BPSU5UU1BSSVRFRU5BQkxFKSk7CiAgICB9CiAgICBnbENvbG9yTWFzayhHTF9UUlVFLCBHTF9UUlVFLEdMX1RSVUUsR0xfVFJVRSk7CiAgICBjaGVja0dMY2FsbCgiZ2xDb2xvck1hc2siKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DTElQUElORykpOwogICAgaWYgKEdMX1NVUFBPUlQoRVhUX1NFQ09OREFSWV9DT0xPUikpIHsKICAgICAgICBnbERpc2FibGUoR0xfQ09MT1JfU1VNX0VYVCk7CiAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NQRUNVTEFSRU5BQkxFKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9DT0xPUl9TVU1fRVhUKSIpOwogICAgfQogICAgaWYgKEdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSkgewogICAgICAgIEdMX0VYVENBTEwoZ2xGaW5hbENvbWJpbmVySW5wdXROVihHTF9WQVJJQUJMRV9CX05WLCBHTF9TUEFSRTBfTlYsIEdMX1VOU0lHTkVEX0lERU5USVRZX05WLCBHTF9SR0IpKTsKICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1BFQ1VMQVJFTkFCTEUpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xGaW5hbENvbWJpbmVySW5wdXROViIpOwogICAgfQoKICAgIC8qIFNldHVwIHRyYW5zZm9ybXMgKi8KICAgIGdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0cml4TW9kZShHTF9NT0RFTFZJRVcpIik7CiAgICBnbExvYWRJZGVudGl0eSgpOwogICAgY2hlY2tHTGNhbGwoImdsTG9hZElkZW50aXR5KCkiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVFJBTlNGT1JNKFdJTkVEM0RUU19XT1JMRE1BVFJJWCgwKSkpOwoKICAgIGdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdHJpeE1vZGUoR0xfUFJPSkVDVElPTikiKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMb2FkSWRlbnRpdHkoKSIpOwogICAgZ2xPcnRobygwLCB3aWR0aCwgaGVpZ2h0LCAwLCAwLjAsIC0xLjApOwogICAgY2hlY2tHTGNhbGwoImdsT3J0aG8iKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVFJBTlNGT1JNKFdJTkVEM0RUU19QUk9KRUNUSU9OKSk7CgogICAgY29udGV4dC0+bGFzdF93YXNfcmh3ID0gVFJVRTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVkRFQ0wpOyAvKiBiZWNhdXNlIG9mIGxhc3Rfd2FzX3JodyA9IFRSVUUgKi8KCiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTApOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgMCkiKTsKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMSk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAxKSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUyKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDIpIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTMpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgMykiKTsKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FNCk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSA0KSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkU1KTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDUpIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQ0xJUFBJTkcpKTsKCiAgICBnbFZpZXdwb3J0KDAsIDAsIHdpZHRoLCBoZWlnaHQpOwogICAgY2hlY2tHTGNhbGwoImdsVmlld3BvcnQiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVklFV1BPUlQpOwoKICAgIGlmKEdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIyKSkgewogICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVikiKTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluCiAqCiAqIFNlYXJjaGVzIGEgc3dhcGNoYWluIGZvciBhbGwgY29udGV4dHMgYW5kIHBpY2tzIG9uZSBmb3IgdGhlIHRocmVhZCB0aWQuCiAqIElmIG5vbmUgY2FuIGJlIGZvdW5kIHRoZSBzd2FwY2hhaW4gaXMgcmVxdWVzdGVkIHRvIGNyZWF0ZSBhIG5ldyBjb250ZXh0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFdpbmVEM0RDb250ZXh0ICpmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbihJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluLCBEV09SRCB0aWQpIHsKICAgIGludCBpOwoKICAgIGZvcihpID0gMDsgaSA8ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIHN3YXBjaGFpbiktPm51bV9jb250ZXh0czsgaSsrKSB7CiAgICAgICAgaWYoKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgc3dhcGNoYWluKS0+Y29udGV4dFtpXS0+dGlkID09IHRpZCkgewogICAgICAgICAgICByZXR1cm4gKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKikgc3dhcGNoYWluKS0+Y29udGV4dFtpXTsKICAgICAgICB9CgogICAgfQoKICAgIC8qIENyZWF0ZSBhIG5ldyBjb250ZXh0IGZvciB0aGUgdGhyZWFkICovCiAgICByZXR1cm4gSVdpbmVEM0RTd2FwQ2hhaW5JbXBsX0NyZWF0ZUNvbnRleHRGb3JUaHJlYWQoc3dhcGNoYWluKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEZpbmRDb250ZXh0CiAqCiAqIEZpbmRzIGEgY29udGV4dCBmb3IgdGhlIGN1cnJlbnQgcmVuZGVyIHRhcmdldCBhbmQgdGhyZWFkCiAqCiAqIFBhcmFtZXRlcnM6CiAqICB0YXJnZXQ6IFJlbmRlciB0YXJnZXQgdG8gZmluZCB0aGUgY29udGV4dCBmb3IKICogIHRpZDogVGhyZWFkIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKgogKiBSZXR1cm5zOiBUaGUgbmVlZGVkIGNvbnRleHQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIFdpbmVEM0RDb250ZXh0ICpGaW5kQ29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZSAqdGFyZ2V0LCBEV09SRCB0aWQpIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW4gPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIEJPT0wgcmVhZFRleHR1cmUgPSB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSAhPSBPUk1fRkJPICYmIFRoaXMtPnJlbmRlcl9vZmZzY3JlZW47CiAgICBXaW5lRDNEQ29udGV4dCAqY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICBCT09MIG9sZFJlbmRlck9mZnNjcmVlbiA9IFRoaXMtPnJlbmRlcl9vZmZzY3JlZW47CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKHRhcmdldCwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopICZzd2FwY2hhaW4pOwogICAgaWYoaHIgPT0gV0lORUQzRF9PSyAmJiBzd2FwY2hhaW4pIHsKICAgICAgICBUUkFDRSgiUmVuZGVyaW5nIG9uc2NyZWVuXG4iKTsKCiAgICAgICAgY29udGV4dCA9IGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluKHN3YXBjaGFpbiwgdGlkKTsKCiAgICAgICAgVGhpcy0+cmVuZGVyX29mZnNjcmVlbiA9IEZBTFNFOwogICAgICAgIC8qIFRoZSBjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQgd2lsbCBjYXRjaCBhIE5PUCBjb250ZXh0IGNoYW5nZS4gVGhpcyBjYW4gb2NjdXIKICAgICAgICAgKiBpZiB3ZSBhcmUgc3dpdGNoaW5nIGJhY2sgdG8gc3dhcGNoYWluIHJlbmRlcmluZyBpbiBjYXNlIG9mIEZCTyBvciBCYWNrIEJ1ZmZlciBvZmZzY3JlZW4KICAgICAgICAgKiByZW5kZXJpbmcuIE5vIGNvbnRleHQgY2hhbmdlIGlzIG5lZWRlZCBpbiB0aGF0IGNhc2UKICAgICAgICAgKi8KCiAgICAgICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9CQUNLQlVGRkVSKSB7CiAgICAgICAgICAgIGlmKCgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIHN3YXBjaGFpbiktPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9QQlVGRkVSKSB7CiAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0ICYmIHRpZCA9PSBUaGlzLT5wYnVmZmVyQ29udGV4dC0+dGlkKSB7CiAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVyQ29udGV4dC0+dGlkID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CgogICAgICAgIGlmKG9sZFJlbmRlck9mZnNjcmVlbikgewogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFdJTkVEM0RSU19DVUxMTU9ERSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgV0lORUQzRFRTX1BST0pFQ1RJT04pOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZERUNMKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WSUVXUE9SVCk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0NJU1NPUlJFQ1QpOwogICAgICAgIH0KCiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJSZW5kZXJpbmcgb2Zmc2NyZWVuXG4iKTsKICAgICAgICBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuID0gVFJVRTsKCiAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlKSB7CiAgICAgICAgICAgIGNhc2UgT1JNX0ZCTzoKICAgICAgICAgICAgICAgIC8qIEZCT3MgZG8gbm90IG5lZWQgYSBkaWZmZXJlbnQgY29udGV4dC4gU3RheSB3aXRoIHdoYXRldmVyIGNvbnRleHQgaXMgYWN0aXZlIGF0IHRoZSBtb21lbnQgKi8KICAgICAgICAgICAgICAgIGlmKFRoaXMtPmFjdGl2ZUNvbnRleHQgJiYgdGlkID09IFRoaXMtPmxhc3RUaHJlYWQpIHsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gVGhpcy0+YWN0aXZlQ29udGV4dDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBtYXkgaGFwcGVuIGlmIHRoZSBhcHAganVtcHMgc3RyZWlnaHQgaW50byBvZmZzY3JlZW4gcmVuZGVyaW5nCiAgICAgICAgICAgICAgICAgICAgICogU3RhcnQgdXNpbmcgdGhlIGNvbnRleHQgb2YgdGhlIHByaW1hcnkgc3dhcGNoYWluLiB0aWQgPT0gMCBpcyBubyBwcm9ibGVtCiAgICAgICAgICAgICAgICAgICAgICogZm9yIGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluLgogICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgICogQ2FuIGFsc28gaGFwcGVuIG9uIHRocmVhZCBzd2l0Y2hlcyAtIGluIHRoYXQgY2FzZSBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbgogICAgICAgICAgICAgICAgICAgICAqIGlzIHBlcmZlY3QgdG8gY2FsbC4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4oVGhpcy0+c3dhcGNoYWluc1swXSwgdGlkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBPUk1fUEJVRkZFUjoKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqdGFyZ2V0aW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHRhcmdldDsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0ID09IE5VTEwgfHwKICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJXaWR0aCA8IHRhcmdldGltcGwtPmN1cnJlbnREZXNjLldpZHRoIHx8CiAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVySGVpZ2h0IDwgdGFyZ2V0aW1wbC0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRGVzdHJveUNvbnRleHQoVGhpcywgVGhpcy0+cGJ1ZmZlckNvbnRleHQpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogVGhlIGRpc3BsYXkgaXMgaXJyZWxldmFudCBoZXJlLCB0aGUgd2luZG93IGlzIDAuIEJ1dCBDcmVhdGVDb250ZXh0IG5lZWRzIGEgdmFsaWQgWCBjb25uZWN0aW9uLgogICAgICAgICAgICAgICAgICAgICAqIENyZWF0ZSB0aGUgY29udGV4dCBvbiB0aGUgc2FtZSBzZXJ2ZXIgYXMgdGhlIHByaW1hcnkgc3dhcGNoYWluLiBUaGUgcHJpbWFyeSBzd2FwY2hhaW4gaXMgZXhpc3RzIGF0IHRoaXMgcG9pbnQuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckNvbnRleHQgPSBDcmVhdGVDb250ZXh0KFRoaXMsIHRhcmdldGltcGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBUaGlzLT5zd2FwY2hhaW5zWzBdKS0+Y29udGV4dFswXS0+d2luX2hhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogcGJ1ZmZlciAqLywgJigoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopVGhpcy0+c3dhcGNoYWluc1swXSktPnByZXNlbnRQYXJtcyk7CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlcldpZHRoID0gdGFyZ2V0aW1wbC0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckhlaWdodCA9IHRhcmdldGltcGwtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICBpZihUaGlzLT5wYnVmZmVyQ29udGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0LT50aWQgIT0gMCAmJiBUaGlzLT5wYnVmZmVyQ29udGV4dC0+dGlkICE9IHRpZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVGhlIFBCdWZmciBjb250ZXh0IGlzIG9ubHkgc3VwcG9ydGVkIGZvciBvbmUgdGhyZWFkIGZvciBub3chXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckNvbnRleHQtPnRpZCA9IHRpZDsKICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gVGhpcy0+cGJ1ZmZlckNvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIGJ1ZmZlciBjb250ZXh0IGFuZCBkcmF3YWJsZSwgZmFsbGluZyBiYWNrIHRvIGJhY2sgYnVmZmVyIG9mZnNjcmVlbiByZW5kZXJpbmdcbiIpOwogICAgICAgICAgICAgICAgICAgICAgIHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID0gT1JNX0JBQ0tCVUZGRVI7CiAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNhc2UgT1JNX0JBQ0tCVUZGRVI6CiAgICAgICAgICAgICAgICAvKiBTdGF5IHdpdGggdGhlIGN1cnJlbnRseSBhY3RpdmUgY29udGV4dCBmb3IgYmFjayBidWZmZXIgcmVuZGVyaW5nICovCiAgICAgICAgICAgICAgICBpZihUaGlzLT5hY3RpdmVDb250ZXh0ICYmIHRpZCA9PSBUaGlzLT5sYXN0VGhyZWFkKSB7CiAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgbWF5IGhhcHBlbiBpZiB0aGUgYXBwIGp1bXBzIHN0cmVpZ2h0IGludG8gb2Zmc2NyZWVuIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICAqIFN0YXJ0IHVzaW5nIHRoZSBjb250ZXh0IG9mIHRoZSBwcmltYXJ5IHN3YXBjaGFpbi4gdGlkID09IDAgaXMgbm8gcHJvYmxlbQogICAgICAgICAgICAgICAgICAgICAqIGZvciBmaW5kVGhyZWFkQ29udGV4dEZvclN3YXBDaGFpbi4KICAgICAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICAgICAqIENhbiBhbHNvIGhhcHBlbiBvbiB0aHJlYWQgc3dpdGNoZXMgLSBpbiB0aGF0IGNhc2UgZmluZFRocmVhZENvbnRleHRGb3JTd2FwQ2hhaW4KICAgICAgICAgICAgICAgICAgICAgKiBpcyBwZXJmZWN0IHRvIGNhbGwuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IGZpbmRUaHJlYWRDb250ZXh0Rm9yU3dhcENoYWluKFRoaXMtPnN3YXBjaGFpbnNbMF0sIHRpZCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoVGhpcy0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoVGhpcy0+b2Zmc2NyZWVuQnVmZmVyKSIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgIT0gT1JNX0ZCTykgewogICAgICAgICAgICAvKiBNYWtlIHN1cmUgd2UgaGF2ZSBhIE9wZW5HTCB0ZXh0dXJlIG5hbWUgc28gdGhlIFByZUxvYWQoKSB1c2VkIHRvIHJlYWQgdGhlIGJ1ZmZlcgogICAgICAgICAgICAgKiBiYWNrIHdoZW4gd2UgYXJlIGRvbmUgd29uJ3QgbWFyayB1cyBkaXJ0eS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHRhcmdldCk7CiAgICAgICAgfQoKICAgICAgICBpZighb2xkUmVuZGVyT2Zmc2NyZWVuKSB7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgV0lORUQzRFJTX0NVTExNT0RFKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBXSU5FRDNEVFNfUFJPSkVDVElPTik7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfVkRFQ0wpOwogICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1ZJRVdQT1JUKTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9TQ0lTU09SUkVDVCk7CiAgICAgICAgfQogICAgfQogICAgaWYgKHJlYWRUZXh0dXJlKSB7CiAgICAgICAgQk9PTCBvbGRJbkRyYXcgPSBUaGlzLT5pc0luRHJhdzsKCiAgICAgICAgLyogUHJlTG9hZCByZXF1aXJlcyBhIGNvbnRleHQgdG8gbG9hZCB0aGUgdGV4dHVyZSwgdGh1cyBpdCB3aWxsIGNhbGwgQWN0aXZhdGVDb250ZXh0LgogICAgICAgICAqIFNldCB0aGUgaXNJbkRyYXcgdG8gdHJ1ZSB0byBzaWduYWwgUHJlTG9hZCB0aGF0IGl0IGhhcyBhIGNvbnRleHQuIFdpbGwgYmUgdHJpY2t5CiAgICAgICAgICogd2hlbiB1c2luZyBvZmZzY3JlZW4gcmVuZGVyaW5nIHdpdGggbXVsdGl0aHJlYWRpbmcKICAgICAgICAgKi8KICAgICAgICBUaGlzLT5pc0luRHJhdyA9IFRSVUU7CgogICAgICAgIC8qIERvIHRoYXQgYmVmb3JlIHN3aXRjaGluZyB0aGUgY29udGV4dDoKICAgICAgICAgKiBSZWFkIHRoZSBiYWNrIGJ1ZmZlciBvZiB0aGUgb2xkIGRyYXdhYmxlIGludG8gdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KTsKCiAgICAgICAgLyogQXNzdW1lIHRoYXQgdGhlIGRyYXdhYmxlIHdpbGwgYmUgbW9kaWZpZWQgYnkgc29tZSBvdGhlciB0aGluZ3Mgbm93ICovCiAgICAgICAgKChJV2luZUQzRFN1cmZhY2VJbXBsICopIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQpLT5GbGFncyAmPSB+U0ZMQUdfSU5EUkFXQUJMRTsKCiAgICAgICAgVGhpcy0+aXNJbkRyYXcgPSBvbGRJbkRyYXc7CiAgICB9CgogICAgaWYob2xkUmVuZGVyT2Zmc2NyZWVuICE9IFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gJiYgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSAhPSBXSU5FRDNEX0RDU19OT19DT1BZKSB7CiAgICAgICAgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9IFdJTkVEM0RfRENTX0NPUFk7CiAgICB9CiAgICByZXR1cm4gY29udGV4dDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEFjdGl2YXRlQ29udGV4dAogKgogKiBGaW5kcyBhIHJlbmRlcmluZyBjb250ZXh0IGFuZCBkcmF3YWJsZSBtYXRjaGluZyB0aGUgZGV2aWNlIGFuZCByZW5kZXIKICogdGFyZ2V0IGZvciB0aGUgY3VycmVudCB0aHJlYWQsIGFjdGl2YXRlcyB0aGVtIGFuZCBwdXRzIHRoZW0gaW50byB0aGUKICogcmVxdWVzdGVkIHN0YXRlLgogKgogKiBQYXJhbXM6CiAqICBUaGlzOiBEZXZpY2UgdG8gYWN0aXZhdGUgdGhlIGNvbnRleHQgZm9yCiAqICB0YXJnZXQ6IFJlcXVlc3RlZCByZW5kZXIgdGFyZ2V0CiAqICB1c2FnZTogUHJlcGFyZXMgdGhlIGNvbnRleHQgZm9yIGJsaXR0aW5nLCBkcmF3aW5nIG9yIG90aGVyIGFjdGlvbnMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIEFjdGl2YXRlQ29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZSAqdGFyZ2V0LCBDb250ZXh0VXNhZ2UgdXNhZ2UpIHsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgIHRpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgaTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgIGRpcnR5U3RhdGUsIGlkeDsKICAgIEJZVEUgICAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0OwogICAgV2luZUQzRENvbnRleHQgICAgICAgICAgICAgICAgKmNvbnRleHQ7CgogICAgVFJBQ0UoIiglcCk6IFNlbGVjdGluZyBjb250ZXh0IGZvciByZW5kZXIgdGFyZ2V0ICVwLCB0aHJlYWQgJWRcbiIsIFRoaXMsIHRhcmdldCwgdGlkKTsKCiAgICBFTlRFUl9HTCgpOwogICAgaWYoVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCAhPSB0YXJnZXQgfHwgdGlkICE9IFRoaXMtPmxhc3RUaHJlYWQpIHsKICAgICAgICBjb250ZXh0ID0gRmluZENvbnRleHQoVGhpcywgdGFyZ2V0LCB0aWQpOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgVGhpcy0+bGFzdFRocmVhZCA9IHRpZDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogU3RpY2sgdG8gdGhlIG9sZCBjb250ZXh0ICovCiAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICB9CgogICAgLyogQWN0aXZhdGUgdGhlIG9wZW5nbCBjb250ZXh0ICovCiAgICBpZihjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQpIHsKICAgICAgICBCT09MIHJldDsKICAgICAgICBUUkFDRSgiU3dpdGNoaW5nIGdsIGN0eCB0byAlcCwgaGRjPSVwIGN0eD0lcFxuIiwgY29udGV4dCwgY29udGV4dC0+aGRjLCBjb250ZXh0LT5nbEN0eCk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICByZXQgPSBwd2dsTWFrZUN1cnJlbnQoY29udGV4dC0+aGRjLCBjb250ZXh0LT5nbEN0eCk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBpZihyZXQgPT0gRkFMU0UpIHsKICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gYWN0aXZhdGUgdGhlIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IGNvbnRleHQ7CiAgICB9CgogICAgc3dpdGNoKHVzYWdlKSB7CiAgICAgICAgY2FzZSBDVFhVU0FHRV9SRVNPVVJDRUxPQUQ6CiAgICAgICAgICAgIC8qIFRoaXMgZG9lcyBub3QgcmVxdWlyZSBhbnkgc3BlY2lhbCBzdGF0ZXMgdG8gYmUgc2V0IHVwICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENUWFVTQUdFX0NMRUFSOgogICAgICAgICAgICBpZihjb250ZXh0LT5sYXN0X3dhc19ibGl0ICYmIEdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIyKSkgewogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9TSEFERVJfTlYpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfU0hBREVSX05WKSIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfU0NJU1NPUl9URVNUIik7CiAgICAgICAgICAgIGNvbnRleHQtPmxhc3Rfd2FzX2JsaXQgPSBGQUxTRTsKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0NJU1NPUlJFQ1QpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDVFhVU0FHRV9EUkFXUFJJTToKICAgICAgICAgICAgLyogVGhpcyBuZWVkcyBhbGwgZGlydHkgc3RhdGVzIGFwcGxpZWQgKi8KICAgICAgICAgICAgaWYoY29udGV4dC0+bGFzdF93YXNfYmxpdCAmJiBHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMikpIHsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfU0hBREVSX05WKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX1NIQURFUl9OVikiKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX0ZpbmRUZXhVbml0TWFwKFRoaXMpOwoKICAgICAgICAgICAgZm9yKGk9MDsgaSA8IGNvbnRleHQtPm51bURpcnR5RW50cmllczsgaSsrKSB7CiAgICAgICAgICAgICAgICBkaXJ0eVN0YXRlID0gY29udGV4dC0+ZGlydHlBcnJheVtpXTsKICAgICAgICAgICAgICAgIGlkeCA9IGRpcnR5U3RhdGUgPj4gNTsKICAgICAgICAgICAgICAgIHNoaWZ0ID0gZGlydHlTdGF0ZSAmIDB4MWY7CiAgICAgICAgICAgICAgICBjb250ZXh0LT5pc1N0YXRlRGlydHlbaWR4XSAmPSB+KDEgPDwgc2hpZnQpOwogICAgICAgICAgICAgICAgU3RhdGVUYWJsZVtkaXJ0eVN0YXRlXS5hcHBseShkaXJ0eVN0YXRlLCBUaGlzLT5zdGF0ZUJsb2NrLCBjb250ZXh0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250ZXh0LT5udW1EaXJ0eUVudHJpZXMgPSAwOyAvKiBUaGlzIG1ha2VzIHRoZSB3aG9sZSBsaXN0IGNsZWFuICovCiAgICAgICAgICAgIGNvbnRleHQtPmxhc3Rfd2FzX2JsaXQgPSBGQUxTRTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQ1RYVVNBR0VfQkxJVDoKICAgICAgICAgICAgU2V0dXBGb3JCbGl0KFRoaXMsIGNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAoKElXaW5lRDNEU3VyZmFjZUltcGwgKil0YXJnZXQpLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXRhcmdldCktPmN1cnJlbnREZXNjLkhlaWdodCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5leHBlY3RlZCBjb250ZXh0IHVzYWdlIHJlcXVlc3RlZFxuIik7CiAgICB9CiAgICBMRUFWRV9HTCgpOwp9Cg==