LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1zYWNtLmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIEFDTVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIEFDTVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIEFDTVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLExPTkcgKnNhbXB3cml0dGVuLExPTkcgKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGlhY21zdCA9IHsKICBBQ01TdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBBQ01TdHJlYW1fZm5BZGRSZWYsCiAgQUNNU3RyZWFtX2ZuUmVsZWFzZSwKICBBQ01TdHJlYW1fZm5DcmVhdGUsCiAgQUNNU3RyZWFtX2ZuSW5mbywKICBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlLAogIEFDTVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIEFDTVN0cmVhbV9mblJlYWQsCiAgQUNNU3RyZWFtX2ZuV3JpdGUsCiAgQUNNU3RyZWFtX2ZuRGVsZXRlLAogIEFDTVN0cmVhbV9mblJlYWREYXRhLAogIEFDTVN0cmVhbV9mbldyaXRlRGF0YSwKICBBQ01TdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBMT05HCQkgIHJlZjsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIFBBVklTVFJFQU0gICAgICBwU3RyZWFtOwogIEFWSVNUUkVBTUlORk9XICBzSW5mbzsKCiAgSEFDTVNUUkVBTSAgICAgIGhhczsKCiAgTFBXQVZFRk9STUFURVggIGxwSW5Gb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgIGNiSW5Gb3JtYXQ7CgogIExQV0FWRUZPUk1BVEVYICBscE91dEZvcm1hdDsKICBMT05HICAgICAgICAgICAgY2JPdXRGb3JtYXQ7CgogIEFDTVNUUkVBTUhFQURFUiBhY21TdHJlYW1IZHI7Cn0gSUFWSVN0cmVhbUltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoYSkgZG8geyBcCiAgICAgICAgICAgRFdPUkQgX19ieXRlczsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLCooYSkgKiBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbixcCiAgICAgICAgICAgICAgICAgICAgICAgICAmX19ieXRlcywgQUNNX1NUUkVBTVNJWkVGX1NPVVJDRSk7IFwKICAgICAgICAgICAqKGEpID0gX19ieXRlcyAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsgfSB3aGlsZSgwKQoKI2RlZmluZSBDT05WRVJUX1RISVNfdG9fU1RSRUFNKGEpIGRvIHsgXAogICAgICAgICAgIERXT1JEIF9fYnl0ZXM7IFwKICAgICAgICAgICBhY21TdHJlYW1TaXplKFRoaXMtPmhhcywqKGEpICogVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduLFwKICAgICAgICAgICAgICAgICAgICAgICAgICZfX2J5dGVzLCBBQ01fU1RSRUFNU0laRUZfREVTVElOQVRJT04pOyBcCiAgICAgICAgICAgKihhKSA9IF9fYnl0ZXMgLyBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbjsgfSB3aGlsZSgwKQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQUNNU3RyZWFtKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwc3RyZWFtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcHN0cmVhbS0+bHBWdGJsID0gJmlhY21zdDsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJU3RyZWFtKilwc3RyZWFtLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHN0cmVhbSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICAvKiBhbHNvIGFkZCByZWZlcmVuY2UgdG8gdGhlIG5lc3RlZCBzdHJlYW0gKi8KICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKQogICAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbSk7CgogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVkXG4iLCBpZmFjZSwgcmVmKTsKCiAgaWYgKHJlZiA9PSAwKSB7CiAgICAvKiBkZXN0cnVjdCAqLwogICAgaWYgKFRoaXMtPmhhcyAhPSBOVUxMKSB7CiAgICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIuZmR3U3RhdHVzICYgQUNNU1RSRUFNSEVBREVSX1NUQVRVU0ZfUFJFUEFSRUQpCglhY21TdHJlYW1VbnByZXBhcmVIZWFkZXIoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKTsKICAgICAgYWNtU3RyZWFtQ2xvc2UoVGhpcy0+aGFzLCAwKTsKICAgICAgVGhpcy0+aGFzID0gTlVMTDsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPSBOVUxMOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0KTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9IE5VTEw7CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwSW5Gb3JtYXQpOwogICAgICBUaGlzLT5scEluRm9ybWF0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JJbkZvcm1hdCA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scE91dEZvcm1hdCk7CiAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkgewogICAgICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbSk7CiAgICAgIFRoaXMtPnBTdHJlYW0gPSBOVUxMOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBhbHNvIHJlbGVhc2UgcmVmZXJlbmNlIHRvIHRoZSBuZXN0ZWQgc3RyZWFtICovCiAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkKICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtKTsKCiAgcmV0dXJuIHJlZjsKfQoKLyogbFBhcmFtMTogUEFWSVNUUkVBTQogKiBsUGFyYW0yOiBMUEFWSUNPTVBSRVNTT1BUSU9OUyAtLSBldmVuIGlmIGRvYydzIHNheSBMUFdBVkVGT1JNQVQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogY2hlY2sgZm9yIHN3YXBwZWQgcGFyYW1ldGVycyAqLwogIGlmICgoTFBWT0lEKWxQYXJhbTEgIT0gTlVMTCAmJgogICAgICAoKExQQVZJQ09NUFJFU1NPUFRJT05TKWxQYXJhbTEpLT5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykgewogICAgcmVnaXN0ZXIgTFBBUkFNIHRtcCA9IGxQYXJhbTE7CgogICAgbFBhcmFtMSA9IGxQYXJhbTI7CiAgICBsUGFyYW0yID0gdG1wOwogIH0KCiAgaWYgKChMUFZPSUQpbFBhcmFtMSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgSUFWSVN0cmVhbV9JbmZvKChQQVZJU1RSRUFNKWxQYXJhbTEsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogZXJyb3IgaW4gcmVnaXN0cnkgb3IgQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0gKi8KCiAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IDA7IC8qIGJlIHBhcmFub2lkICovCgogIC8qIEZJWE1FOiBjaGVjayBBQ00gdmVyc2lvbj8gV2hpY2ggdmVyc2lvbiBkb2VzIHdlIG5lZWQ/ICovCgogIGlmICgoTFBWT0lEKWxQYXJhbTIgIT0gTlVMTCkgewogICAgLyogV2Ugb25seSBuZWVkIHRoZSBmb3JtYXQgZnJvbSB0aGUgY29tcHJlc3Mtb3B0aW9ucyAqLwogICAgaWYgKCgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMiktPmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQogICAgICBsUGFyYW0yID0gKExQQVJBTSkoKExQQVZJQ09NUFJFU1NPUFRJT05TKWxQYXJhbTIpLT5scEZvcm1hdDsKCiAgICBpZiAoKChMUFdBVkVGT1JNQVRFWClsUGFyYW0yKS0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pCiAgICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gc2l6ZW9mKFdBVkVGT1JNQVRFWCkgKyAoKExQV0FWRUZPUk1BVEVYKWxQYXJhbTIpLT5jYlNpemU7CiAgICBlbHNlCiAgICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpOwoKICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmNiT3V0Rm9ybWF0KTsKICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBtZW1jcHkoVGhpcy0+bHBPdXRGb3JtYXQsIChMUFZPSUQpbFBhcmFtMiwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogIH0gZWxzZSB7CiAgICBUaGlzLT5scE91dEZvcm1hdCA9IE5VTEw7CiAgICBUaGlzLT5jYk91dEZvcm1hdCA9IDA7CiAgfQoKICBUaGlzLT5wU3RyZWFtID0gKFBBVklTVFJFQU0pbFBhcmFtMTsKICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSAqaWZhY2UsTFBBVklTVFJFQU1JTkZPVyBwc2ksCgkJCQkJTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogTmVlZCBjb2RlYyB0byBjb3JyZWN0IHNvbWUgdmFsdWVzIGluIHN0cnVjdHVyZSAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgSFJFU1VMVCBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIG1lbWNweShwc2ksICZUaGlzLT5zSW5mbywgbWluKHNpemUsIChMT05HKXNpemVvZihUaGlzLT5zSW5mbykpKTsKCiAgaWYgKHNpemUgPCAoTE9ORylzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWQsMHglMDhYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgLyogY29udmVydCBwb3MgZnJvbSBvdXIgJ3NwYWNlJyB0byBUaGlzLT5wU3RyZWFtJ3Mgb25lICovCiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmcG9zKTsKCiAgLyogYXNrIHN0cmVhbSAqLwogIHBvcyA9IElBVklTdHJlYW1fRmluZFNhbXBsZShUaGlzLT5wU3RyZWFtLCBwb3MsIGZsYWdzKTsKCiAgaWYgKHBvcyAhPSAtMSkgewogICAgLyogY29udmVydCBwb3MgYmFjayB0byBvdXIgJ3NwYWNlJyBpZiBpdCdzIG5vIHNpemUgb3IgcGh5c2ljYWwgcG9zICovCiAgICBpZiAoKGZsYWdzICYgRklORF9SRVQpID09IDApCiAgICAgIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoJnBvcyk7CiAgfQoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyAqZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyID0gQVZJRklMRV9PcGVuQ29tcHJlc3NvcihUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgLyogb25seSBpbnRlcmVzdGVkIGluIG5lZWRlZCBidWZmZXJzaXplPyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAqZm9ybWF0c2l6ZSA8PSAwKSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IChvbmx5IGFzIG11Y2ggYXMgd2lsbCBmaXQpICovCiAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+Y2JPdXRGb3JtYXQpKTsKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5jYk91dEZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYk91dEZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlZCwlcCwlZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSW5wdXQgZm9ybWF0IGFscmVhZHkga25vd24/CiAgICogQ2hhbmdpbmcgaXMgdW5zdXBwb3J0ZWQsIGJ1dCBiZSBxdWlldCBpZiBpdCdzIHRoZSBzYW1lICovCiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgIT0gTlVMTCkgewogICAgaWYgKFRoaXMtPmNiSW5Gb3JtYXQgIT0gZm9ybWF0c2l6ZSB8fAoJbWVtY21wKGZvcm1hdCwgVGhpcy0+bHBJbkZvcm1hdCwgZm9ybWF0c2l6ZSkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogRG9lcyB0aGUgbmVzdGVkIHN0cmVhbSBzdXBwb3J0IHdyaXRpbmc/ICovCiAgaWYgKChUaGlzLT5zSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19DQU5XUklURSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmxwSW5Gb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm9ybWF0c2l6ZSk7CiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIFRoaXMtPmNiSW5Gb3JtYXQgPSBmb3JtYXRzaXplOwogIG1lbWNweShUaGlzLT5scEluRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBpbml0aWFsaXplIGZvcm1hdHMgYW5kIGdldCBjb21wcmVzc29yICovCiAgaHIgPSBBVklGSUxFX09wZW5Db21wcmVzc29yKFRoaXMpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZwb3MpOwoKICAvKiB0ZWxsIHRoZSBuZXN0ZWQgc3RyZWFtIHRoZSBuZXcgZm9ybWF0ICovCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KFRoaXMtPnBTdHJlYW0sIHBvcywgVGhpcy0+bHBPdXRGb3JtYXQsCgkJCSAgICAgIFRoaXMtPmNiT3V0Rm9ybWF0KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBIUkVTVUxUIGhyOwogIERXT1JEICAgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAogCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogRG8gd2UgaGF2ZSBvdXIgY29tcHJlc3Nvcj8gKi8KICBpZiAoVGhpcy0+aGFzID09IE5VTEwpIHsKICAgIGhyID0gQVZJRklMRV9PcGVuQ29tcHJlc3NvcihUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgLyogb25seSBuZWVkIHRvIHBhc3MgdGhyb3VnaD8gKi8KICBpZiAoVGhpcy0+Y2JJbkZvcm1hdCA9PSBUaGlzLT5jYk91dEZvcm1hdCAmJgogICAgICBtZW1jbXAoVGhpcy0+bHBJbkZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsIFRoaXMtPmNiSW5Gb3JtYXQpID09IDApIHsKICAgIHJldHVybiBJQVZJU3RyZWFtX1JlYWQoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwgYnVmZmVyc2l6ZSwKCQkJICAgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CiAgfQoKICAvKiByZWFkIGFzIG11Y2ggYXMgZml0PyAqLwogIGlmIChzYW1wbGVzID09IC0xKQogICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgLyogbGltaXQgdG8gYnVmZmVyc2l6ZSAqLwogIGlmIChzYW1wbGVzICogVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduID4gYnVmZmVyc2l6ZSkKICAgIHNhbXBsZXMgPSBidWZmZXJzaXplIC8gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwoKICAvKiBvbmx5IHJldHVybiBuZWVkZWQgc2l6ZT8gKi8KICBpZiAoYnVmZmVyID09IE5VTEwgfHwgYnVmZmVyc2l6ZSA8PSAwIHx8IHNhbXBsZXMgPT0gMCkgewogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2FtcGxlcyAqIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBtYXAgb3VyIHBvc2l0aW9ucyB0byBwU3RyZWFtIHBvc2l0aW9ucyAqLwogIENPTlZFUlRfVEhJU190b19TVFJFQU0oJnN0YXJ0KTsKCiAgLyogb3VyIG5lZWRlZCBpbnRlcm5hbCBidWZmZXJzaXplICovCiAgc2l6ZSA9IHNhbXBsZXMgKiBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbjsKCiAgLyogTmVlZCB0byBmcmVlIGRlc3RpbmF0aW9uIGJ1ZmZlciB1c2VkIGZvciB3cml0aW5nPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgIT0gTlVMTCkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0KTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAgICAgPSBOVUxMOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3RHN0VXNlciA9IDA7CiAgfQoKICAvKiBuZWVkIGJpZ2dlciBzb3VyY2UgYnVmZmVyPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPT0gTlVMTCB8fAogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyIDwgc2l6ZSkgewogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9PSBOVUxMKQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICBlbHNlCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYywgc2l6ZSk7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3U3JjVXNlciA9IHNpemU7CiAgfQoKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTdHJ1Y3QgPSBzaXplb2YoVGhpcy0+YWNtU3RyZWFtSGRyKTsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGhVc2VkID0gMDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkID0gMDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggICAgID0gc2l6ZTsKCiAgLyogcmVhZCBzb3VyY2UgZGF0YSAqLwogIGhyID0gSUFWSVN0cmVhbV9SZWFkKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCAtMSwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjLAoJCSAgICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGgsCgkJICAgICAgIChMT05HICopJlRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCwgTlVMTCk7CiAgaWYgKEZBSUxFRChocikgfHwgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID09IDApCiAgICByZXR1cm4gaHI7CgogIC8qIG5lZWQgdG8gcHJlcGFyZSBzdHJlYW0/ICovCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICAgID0gYnVmZmVyOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCA9IGJ1ZmZlcnNpemU7CiAgaWYgKChUaGlzLT5hY21TdHJlYW1IZHIuZmR3U3RhdHVzICYgQUNNU1RSRUFNSEVBREVSX1NUQVRVU0ZfUFJFUEFSRUQpID09IDApIHsKICAgIGlmIChhY21TdHJlYW1QcmVwYXJlSGVhZGVyKFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykgewogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgICAgICAgPSBOVUxMOwogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGggPSAwOwogICAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgICB9CiAgfQoKICAvKiBub3cgZG8gdGhlIGNvbnZlcnNpb24gKi8KICAvKiBGSVhNRTogdXNlIEFDTV9DT05WRVJURl8qIGZsYWdzICovCiAgaWYgKGFjbVN0cmVhbUNvbnZlcnQoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKQogICAgaHIgPSBBVklFUlJfQ09NUFJFU1NPUjsKCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICAgID0gTlVMTDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGggPSAwOwoKICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0KICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKICBVTE9ORyAgIHNpemU7CgogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsMHglMDhYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHdlIHdyaXRlIGNhcGFiaWxpdHk/ICovCiAgaWYgKChUaGlzLT5zSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19DQU5XUklURSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGFsc28gbmVlZCBhIGNvbXByZXNzb3IgKi8KICBpZiAoVGhpcy0+aGFzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKCiAgLyogbWFwIG91ciBzaXplcyB0byBwU3RyZWFtIHNpemVzICovCiAgc2l6ZSA9IGJ1ZmZlcnNpemU7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc2l6ZSk7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc3RhcnQpOwoKICAvKiBubyBieXRlcyB0byB3cml0ZT8gLS0gc2hvcnQgY2lyY3VpdCAqLwogIGlmIChzaXplID09IDApIHsKICAgIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sIC0xLCBzYW1wbGVzLCBidWZmZXIsIHNpemUsCgkJCSAgICBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CiAgfQoKICAvKiBOZWVkIHRvIGZyZWUgc291cmNlIGJ1ZmZlciB1c2VkIGZvciByZWFkaW5nPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgIT0gTlVMTCkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjKTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgPSBOVUxMOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3U3JjVXNlciA9IDA7CiAgfQoKICAvKiBOZWVkIGJpZ2dlciBkZXN0aW5hdGlvbiBidWZmZXI/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9PSBOVUxMIHx8CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd0RzdFVzZXIgPCBzaXplKSB7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID09IE5VTEwpCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGVsc2UKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0LCBzaXplKTsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyID0gc2l6ZTsKICB9CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3RydWN0ICAgICAgICA9IHNpemVvZihUaGlzLT5hY21TdHJlYW1IZHIpOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCAgICAgPSBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyOwoKICAvKiBuZWVkIHRvIHByZXBhcmUgc3RyZWFtPyAqLwogIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgICA9IGJ1ZmZlcjsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPSBidWZmZXJzaXplOwogIGlmICgoVGhpcy0+YWNtU3RyZWFtSGRyLmZkd1N0YXR1cyAmIEFDTVNUUkVBTUhFQURFUl9TVEFUVVNGX1BSRVBBUkVEKSA9PSAwKSB7CiAgICBpZiAoYWNtU3RyZWFtUHJlcGFyZUhlYWRlcihUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApICE9IFNfT0spIHsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICAgID0gTlVMTDsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID0gMDsKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgfQogIH0KCiAgLyogbm93IGRvIHRoZSBjb252ZXJzaW9uICovCiAgLyogRklYTUU6IHVzZSBBQ01fQ09OVkVSVEZfKiBmbGFncyAqLwogIGlmIChhY21TdHJlYW1Db252ZXJ0KFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykKICAgIGhyID0gQVZJRVJSX0NPTVBSRVNTT1I7CiAgZWxzZQogICAgaHIgPSBBVklFUlJfT0s7CgogIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgICA9IE5VTEw7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID0gMDsKCiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sLTEsVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCAvCgkJCSAgVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduLFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCwKCQkJICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkLGZsYWdzLHNhbXB3cml0dGVuLAoJCQkgIGJ5dGVzd3JpdHRlbik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIGNhcGFiaWxpdHkgKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogQSBjb21wcmVzc29yIGlzIGFsc28gbmVjZXNzYXJ5ICovCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CgogIC8qIG1hcCBvdXIgcG9zaXRpb25zIHRvIHBTdHJlYW0gcG9zaXRpb25zICovCiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc3RhcnQpOwogIENPTlZFUlRfVEhJU190b19TVFJFQU0oJnNhbXBsZXMpOwoKICByZXR1cm4gSUFWSVN0cmVhbV9EZWxldGUoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIHNhbXBsZXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgTFBWT0lEIGxwLCBMUExPTkcgbHByZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgZmNjLCBscCwgbHByZWFkKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWREYXRhKFRoaXMtPnBTdHJlYW0sIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOHgsJXAsJWQpXG4iLCBpZmFjZSwgZmNjLCBscCwgc2l6ZSk7CgogIGFzc2VydChUaGlzLT5wU3RyZWFtICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZURhdGEoVGhpcy0+cFN0cmVhbSwgZmNjLCBscCwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCSAgIExQQVZJU1RSRUFNSU5GT1cgaW5mbywgTE9ORyBpbmZvbGVuKQp7CiAgRklYTUUoIiglcCwlcCwlZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIEhSRVNVTFQgaHI7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIGlmIChUaGlzLT5oYXMgIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpIHsKICAgIC8qIGRlY29kZSBvciBlbmNvZGUgdGhlIGRhdGEgZnJvbSBwU3RyZWFtICovCiAgICBociA9IEFWSVN0cmVhbUZvcm1hdFNpemUoVGhpcy0+cFN0cmVhbSwgVGhpcy0+c0luZm8uZHdTdGFydCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICAgIFRoaXMtPmxwSW5Gb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBociA9IElBVklTdHJlYW1fUmVhZEZvcm1hdChUaGlzLT5wU3RyZWFtLCBUaGlzLT5zSW5mby5kd1N0YXJ0LAoJCQkgICAgICAgVGhpcy0+bHBJbkZvcm1hdCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKCiAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkgewogICAgICAvKiB3ZSBtdXN0IGRlY29kZSB0byBkZWZhdWx0IGZvcm1hdCAqLwogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IHNpemVvZihQQ01XQVZFRk9STUFUKTsKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogICAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQtPndGb3JtYXRUYWcgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmxwT3V0Rm9ybWF0LAoJCQkgICBUaGlzLT5jYk91dEZvcm1hdCwgQUNNX0ZPUk1BVFNVR0dFU1RGX1dGT1JNQVRUQUcpICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKICAgIH0KICB9IGVsc2UgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBUbyB3aGF0IHNob3VsZCBJIGVuY29kZT8gKi8KCiAgaWYgKGFjbVN0cmVhbU9wZW4oJlRoaXMtPmhhcywgTlVMTCwgVGhpcy0+bHBJbkZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsCgkJICAgIE5VTEwsIDAsIDAsIEFDTV9TVFJFQU1PUEVORl9OT05SRUFMVElNRSkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgKi8KICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICAgID0gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdRdWFsaXR5ICAgID0gKERXT1JEKUlDUVVBTElUWV9ERUZBVUxUOwogIFNldFJlY3RFbXB0eSgmVGhpcy0+c0luZm8ucmNGcmFtZSk7CgogIC8qIGNvbnZlcnQgcG9zaXRpb25zIGFuZCBzaXplcyB0byBvdXRwdXQgZm9ybWF0ICovCiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUygmVGhpcy0+c0luZm8uZHdTdGFydCk7CiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUygmVGhpcy0+c0luZm8uZHdMZW5ndGgpOwogIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoJlRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0K