LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1zYWNtLmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgojZGVmaW5lIE1BWF9GUkFNRVNJWkUgICAgICAgKDE2ICogMTAyNCAqIDEwMjQpCiNkZWZpbmUgTUFYX0ZSQU1FU0laRV9ESUZGICA1MTIKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUNNU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUNNU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsTE9ORyAqYnl0ZXNyZWFkLExPTkcgKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSVN0cmVhbVZ0YmwgaWljbXN0ID0gewogIElDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElDTVN0cmVhbV9mbkFkZFJlZiwKICBJQ01TdHJlYW1fZm5SZWxlYXNlLAogIElDTVN0cmVhbV9mbkNyZWF0ZSwKICBJQ01TdHJlYW1fZm5JbmZvLAogIElDTVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUNNU3RyZWFtX2ZuUmVhZEZvcm1hdCwKICBJQ01TdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUNNU3RyZWFtX2ZuUmVhZCwKICBJQ01TdHJlYW1fZm5Xcml0ZSwKICBJQ01TdHJlYW1fZm5EZWxldGUsCiAgSUNNU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUNNU3RyZWFtX2ZuV3JpdGVEYXRhLAogIElDTVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwogIExPTkcJCSAgICAgcmVmOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgUEFWSVNUUkVBTSAgICAgICAgIHBTdHJlYW07CiAgQVZJU1RSRUFNSU5GT1cgICAgIHNJbmZvOwoKICBQR0VURlJBTUUgICAgICAgICAgcGc7CiAgSElDICAgICAgICAgICAgICAgIGhpYzsKICBEV09SRCAgICAgICAgICAgICAgZHdJQ01GbGFnczsKCiAgTE9ORyAgICAgICAgICAgICAgIGxDdXJyZW50OwogIExPTkcgICAgICAgICAgICAgICBsTGFzdEtleTsKICBMT05HICAgICAgICAgICAgICAgbEtleUZyYW1lRXZlcnk7CiAgRFdPUkQgICAgICAgICAgICAgIGR3TGFzdFF1YWxpdHk7CiAgRFdPUkQgICAgICAgICAgICAgIGR3Qnl0ZXNQZXJGcmFtZTsKICBEV09SRCAgICAgICAgICAgICAgZHdVbnVzZWRCeXRlczsKCiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlDdXI7ICAvKiBjdXJyZW50IGZyYW1lICovCiAgTFBWT0lEICAgICAgICAgICAgIGxwQ3VyOwogIExQQklUTUFQSU5GT0hFQURFUiBscGJpUHJldjsgLyogcHJldmlvdXMgZnJhbWUgKi8KICBMUFZPSUQgICAgICAgICAgICAgbHBQcmV2OwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU91dHB1dDsgLyogb3V0cHV0IGZvcm1hdCBvZiBjb2RlYyAqLwogIExPTkcgICAgICAgICAgICAgICBjYk91dHB1dDsKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaUlucHV0OyAgLyogaW5wdXQgZm9ybWF0IGZvciBjb2RlYyAqLwogIExPTkcgICAgICAgICAgICAgICBjYklucHV0Owp9IElBVklTdHJlYW1JbXBsOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9FbmNvZGVGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywKCQkJCSAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpLCBMUFZPSUQgbHBCaXRzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuR2V0RnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMpOwoKc3RhdGljIGlubGluZSB2b2lkIEFWSUZJTEVfUmVzZXQoSUFWSVN0cmVhbUltcGwgKlRoaXMpCnsKICBUaGlzLT5sQ3VycmVudCAgICAgID0gLTE7CiAgVGhpcy0+bExhc3RLZXkgICAgICA9IDA7CiAgVGhpcy0+ZHdMYXN0UXVhbGl0eSA9IElDUVVBTElUWV9ISUdIOwogIFRoaXMtPmR3VW51c2VkQnl0ZXMgPSAwOwp9CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlSUNNU3RyZWFtKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwc3RyZWFtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcHN0cmVhbS0+bHBWdGJsICA9ICZpaWNtc3Q7CiAgQVZJRklMRV9SZXNldChwc3RyZWFtKTsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJU3RyZWFtKilwc3RyZWFtLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHN0cmVhbSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUNNU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgLyogYWxzbyBhZGQgcmVmZXJlbmNlIHRvIHRoZSBuZXN0ZWQgc3RyZWFtICovCiAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkKICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDTVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAocmVmID09IDApIHsKICAgIC8qIGRlc3RydWN0ICovCiAgICBpZiAoVGhpcy0+cGcgIT0gTlVMTCkgewogICAgICBBVklTdHJlYW1HZXRGcmFtZUNsb3NlKFRoaXMtPnBnKTsKICAgICAgVGhpcy0+cGcgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkgewogICAgICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbSk7CiAgICAgIFRoaXMtPnBTdHJlYW0gPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmhpYyAhPSBOVUxMKSB7CiAgICAgIGlmIChUaGlzLT5scGJpUHJldiAhPSBOVUxMKSB7CglJQ0RlY29tcHJlc3NFbmQoVGhpcy0+aGljKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlQcmV2KTsKCVRoaXMtPmxwYmlQcmV2ID0gTlVMTDsKCVRoaXMtPmxwUHJldiAgID0gTlVMTDsKICAgICAgfQogICAgICBJQ0NvbXByZXNzRW5kKFRoaXMtPmhpYyk7CiAgICAgIFRoaXMtPmhpYyA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBiaUN1ciAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlDdXIpOwogICAgICBUaGlzLT5scGJpQ3VyID0gTlVMTDsKICAgICAgVGhpcy0+bHBDdXIgICA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBiaU91dHB1dCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlPdXRwdXQpOwogICAgICBUaGlzLT5scGJpT3V0cHV0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JPdXRwdXQgICA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBiaUlucHV0ICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBiaUlucHV0KTsKICAgICAgVGhpcy0+bHBiaUlucHV0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JJbnB1dCAgID0gMDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICByZXR1cm4gMDsKICB9CgogIC8qIGFsc28gcmVsZWFzZSByZWZlcmVuY2UgdG8gdGhlIG5lc3RlZCBzdHJlYW0gKi8KICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKQogICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgovKiBsUGFyYW0xOiBQQVZJU1RSRUFNCiAqIGxQYXJhbTI6IExQQVZJQ09NUFJFU1NPUFRJT05TCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSUNJTkZPICAgICAgICAgICAgICAgaWNpbmZvOwogIElDQ09NUFJFU1NGUkFNRVMgICAgIGljRnJhbWVzOwogIExQQVZJQ09NUFJFU1NPUFRJT05TIHBjbyA9IChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0yOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKChMUFZPSUQpbFBhcmFtMSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogZ2V0IGluZm9zIGZyb20gc3RyZWFtICovCiAgSUFWSVN0cmVhbV9JbmZvKChQQVZJU1RSRUFNKWxQYXJhbTEsICZUaGlzLT5zSW5mbywgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogZXJyb3IgaW4gcmVnaXN0cnkgb3IgQVZJTWFrZUNvbXByZXNzZWRTdHJlYW0gKi8KCiAgLyogYWRkIHJlZmVyZW5jZSB0byB0aGUgc3RyZWFtICovCiAgVGhpcy0+cFN0cmVhbSA9IChQQVZJU1RSRUFNKWxQYXJhbTE7CiAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbSk7CgogIEFWSUZJTEVfUmVzZXQoVGhpcyk7CgogIGlmIChwY28gIT0gTlVMTCAmJiBwY28tPmZjY0hhbmRsZXIgIT0gY29tcHR5cGVESUIpIHsKICAgIC8qIHdlIHNob3VsZCBjb21wcmVzcyAqLwogICAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IHBjby0+ZmNjSGFuZGxlcjsKCiAgICBUaGlzLT5oaWMgPSBJQ09wZW4oSUNUWVBFX1ZJREVPLCBwY28tPmZjY0hhbmRsZXIsIElDTU9ERV9DT01QUkVTUyk7CiAgICBpZiAoVGhpcy0+aGljID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAgIC8qIHJlc3RvcmUgc2F2ZWQgc3RhdGUgb2YgY29kZWMgKi8KICAgIGlmIChwY28tPmNiUGFybXMgPiAwICYmIHBjby0+bHBQYXJtcyAhPSBOVUxMKSB7CiAgICAgIElDU2V0U3RhdGUoVGhpcy0+aGljLCBwY28tPmxwUGFybXMsIHBjby0+Y2JQYXJtcyk7CiAgICB9CgogICAgLyogc2V0IHF1YWxpdHkgLS0gcmVzb2x2ZSBkZWZhdWx0IHF1YWxpdHkgKi8KICAgIFRoaXMtPnNJbmZvLmR3UXVhbGl0eSA9IHBjby0+ZHdRdWFsaXR5OwogICAgaWYgKHBjby0+ZHdRdWFsaXR5ID09IElDUVVBTElUWV9ERUZBVUxUKQogICAgICBUaGlzLT5zSW5mby5kd1F1YWxpdHkgPSBJQ0dldERlZmF1bHRRdWFsaXR5KFRoaXMtPmhpYyk7CgogICAgLyogZ2V0IGNhcGFiaWxpdGllcyBvZiBjb2RlYyAqLwogICAgSUNHZXRJbmZvKFRoaXMtPmhpYywgJmljaW5mbywgc2l6ZW9mKGljaW5mbykpOwogICAgVGhpcy0+ZHdJQ01GbGFncyA9IGljaW5mby5kd0ZsYWdzOwoKICAgIC8qIHVzZSBrZXlmcmFtZXM/ICovCiAgICBpZiAoKHBjby0+ZHdGbGFncyAmIEFWSUNPTVBSRVNTRl9LRVlGUkFNRVMpICYmCgkoaWNpbmZvLmR3RmxhZ3MgJiAoVklEQ0ZfVEVNUE9SQUx8VklEQ0ZfRkFTVFRFTVBPUkFMQykpKSB7CiAgICAgIFRoaXMtPmxLZXlGcmFtZUV2ZXJ5ID0gcGNvLT5kd0tleUZyYW1lRXZlcnk7CiAgICB9IGVsc2UKICAgICAgVGhpcy0+bEtleUZyYW1lRXZlcnkgPSAxOwoKICAgIC8qIHVzZSBkYXRhcmF0ZT8gKi8KICAgIGlmICgocGNvLT5kd0ZsYWdzICYgQVZJQ09NUFJFU1NGX0RBVEFSQVRFKSkgewogICAgICAvKiBEbyB3ZSBoYXZlIGEgY2hhbmNlIHRvIHJlZHVjZSBzaXplIHRvIGRlc2lyZWQgb25lPyAqLwogICAgICBpZiAoKGljaW5mby5kd0ZsYWdzICYgKFZJRENGX0NSVU5DSHxWSURDRl9RVUFMSVRZKSkgPT0gMCkKCXJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAgICAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3UmF0ZSAhPSAwKTsKCiAgICAgIFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSA9IE11bERpdihwY28tPmR3Qnl0ZXNQZXJTZWNvbmQsCgkJCQkgICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUsIFRoaXMtPnNJbmZvLmR3UmF0ZSk7CiAgICB9IGVsc2UgewogICAgICBwY28tPmR3Qnl0ZXNQZXJTZWNvbmQgPSAwOwogICAgICBUaGlzLT5kd0J5dGVzUGVyRnJhbWUgPSAwOwogICAgfQoKICAgIGlmIChpY2luZm8uZHdGbGFncyAmIFZJRENGX0NPTVBSRVNTRlJBTUVTKSB7CiAgICAgIG1lbXNldCgmaWNGcmFtZXMsIDAsIHNpemVvZihpY0ZyYW1lcykpOwogICAgICBpY0ZyYW1lcy5scGJpT3V0cHV0ICA9IFRoaXMtPmxwYmlPdXRwdXQ7CiAgICAgIGljRnJhbWVzLmxwYmlJbnB1dCAgID0gVGhpcy0+bHBiaUlucHV0OwogICAgICBpY0ZyYW1lcy5sRnJhbWVDb3VudCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgICBpY0ZyYW1lcy5sUXVhbGl0eSAgICA9IFRoaXMtPnNJbmZvLmR3UXVhbGl0eTsKICAgICAgaWNGcmFtZXMubERhdGFSYXRlICAgPSBwY28tPmR3Qnl0ZXNQZXJTZWNvbmQ7CiAgICAgIGljRnJhbWVzLmxLZXlSYXRlICAgID0gVGhpcy0+bEtleUZyYW1lRXZlcnk7CiAgICAgIGljRnJhbWVzLmR3UmF0ZSAgICAgID0gVGhpcy0+c0luZm8uZHdSYXRlOwogICAgICBpY0ZyYW1lcy5kd1NjYWxlICAgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgICAgIElDU2VuZE1lc3NhZ2UoVGhpcy0+aGljLCBJQ01fQ09NUFJFU1NfRlJBTUVTX0lORk8sCgkJICAgIChMUEFSQU0pJmljRnJhbWVzLCAoTFBBUkFNKXNpemVvZihpY0ZyYW1lcykpOwogICAgfQogIH0gZWxzZQogICAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnNJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5zSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIExPTkcgV0lOQVBJIElDTVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwweCUwOGxYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgaWYgKGZsYWdzICYgRklORF9SRVQpCiAgICBXQVJOKCI6IEZJTkRfUkVUIGZsYWdzIHdpbGwgYmUgaWdub3JlZCFcbiIpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0tFWSkgewogICAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKQogICAgICByZXR1cm4gcG9zOyAvKiB3ZSBkZWNvbXByZXNzIHNvIGV2ZXJ5IGZyYW1lIGlzIGEga2V5ZnJhbWUgKi8KCiAgICBpZiAoZmxhZ3MgJiBGSU5EX1BSRVYpIHsKICAgICAgLyogbmVlZCB0byByZWFkIG9sZCBvciBuZXcgZnJhbWVzPyAqLwogICAgICBpZiAoVGhpcy0+bExhc3RLZXkgPD0gcG9zIHx8IHBvcyA8IFRoaXMtPmxDdXJyZW50KQoJSUFWSVN0cmVhbV9SZWFkKGlmYWNlLCBwb3MsIDEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwoKICAgICAgcmV0dXJuIFRoaXMtPmxMYXN0S2V5OwogICAgfQogIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgcmV0dXJuIHBvczsgLyogV2UgcmVhbGx5IGRvbid0IGtub3csIHJlcmVhZCBpcyB0byBleHBlbnNpdmUsIHNvIGd1ZXNzLiAqLwogIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgewogICAgaWYgKGZsYWdzICYgRklORF9QUkVWKQogICAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiAtMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaTsKICBIUkVTVUxUICAgICAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGlmIChUaGlzLT5wZyA9PSBOVUxMKSB7CiAgICBociA9IEFWSUZJTEVfT3BlbkdldEZyYW1lKFRoaXMpOwoKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgcG9zKTsKICBpZiAobHBiaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGlmIChUaGlzLT5oaWMgPT0gTlVMTCkgewogICAgTE9ORyBzaXplID0gbHBiaS0+YmlTaXplICsgbHBiaS0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpOwoKICAgIGlmIChzaXplID4gMCkgewogICAgICBpZiAoVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgbHBiaS0+YmlTaXplSW1hZ2UpCglUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBscGJpLT5iaVNpemVJbWFnZTsKCiAgICAgIFRoaXMtPmNiT3V0cHV0ID0gc2l6ZTsKICAgICAgaWYgKGZvcm1hdCAhPSBOVUxMKSB7CglpZiAoVGhpcy0+bHBiaU91dHB1dCAhPSBOVUxMKQoJICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5scGJpT3V0cHV0LCBtaW4oKmZvcm1hdHNpemUsIFRoaXMtPmNiT3V0cHV0KSk7CgllbHNlCgkgIG1lbWNweShmb3JtYXQsIGxwYmksIG1pbigqZm9ybWF0c2l6ZSwgc2l6ZSkpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIGlmIChmb3JtYXQgIT0gTlVMTCkKICAgIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwYmlPdXRwdXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+Y2JPdXRwdXQpKTsKCiAgaWYgKCpmb3JtYXRzaXplIDwgVGhpcy0+Y2JPdXRwdXQpCiAgICBociA9IEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICBlbHNlCiAgICBociA9IEFWSUVSUl9PSzsKCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYk91dHB1dDsKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBXZSBjYW4gb25seSBhY2NlcHQgUkdCIGRhdGEgZm9yIHdyaXRpbmcgKi8KICBpZiAoKChMUEJJVE1BUElORk9IRUFERVIpZm9ybWF0KS0+YmlDb21wcmVzc2lvbiAhPSBCSV9SR0IpIHsKICAgIFdBUk4oIjogbmVlZCBSR0IgZGF0YSBhcyBpbnB1dFxuIik7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogSW5wdXQgZm9ybWF0IGFscmVhZHkga25vd24/CiAgICogQ2hhbmdpbmcgb2YgcGFsZXR0ZSBpcyBzdXBwb3J0ZWQsIGJ1dCBiZSBxdWlldCBpZiBpdCdzIHRoZSBzYW1lICovCiAgaWYgKFRoaXMtPmxwYmlJbnB1dCAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+Y2JJbnB1dCAhPSBmb3JtYXRzaXplKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIGlmIChtZW1jbXAoZm9ybWF0LCBUaGlzLT5scGJpSW5wdXQsIGZvcm1hdHNpemUpID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBEb2VzIHRoZSBuZXN0ZWQgc3RyZWFtIHN1cHBvcnQgd3JpdGluZz8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogY2hlY2sgaWYgZnJhbWUgaXMgYWxyZWFkeSB3cml0dGVuICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoICsgVGhpcy0+c0luZm8uZHdTdGFydCA+IHBvcykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIGNoZWNrIGlmIHdlIHNob3VsZCBjb21wcmVzcyAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NIYW5kbGVyID09IDAgfHwKICAgICAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdOJywnTycsJ04nLCdFJykpCiAgICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CgogIC8qIG9ubHkgcGFzcyB0aHJvdWdoPyAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NIYW5kbGVyID09IGNvbXB0eXBlRElCKQogICAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KFRoaXMtPnBTdHJlYW0sIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogaW5pdGlhbCBmb3JtYXQgc2V0dGluZz8gKi8KICBpZiAoVGhpcy0+bHBiaUlucHV0ID09IE5VTEwpIHsKICAgIFVMT05HIHNpemU7CgogICAgYXNzZXJ0KFRoaXMtPmhpYyAhPSBOVUxMKTsKCiAgICAvKiBnZXQgbWVtb3J5IGZvciBpbnB1dCBmb3JtYXQgKi8KICAgIFRoaXMtPmxwYmlJbnB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmb3JtYXRzaXplKTsKICAgIGlmIChUaGlzLT5scGJpSW5wdXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYklucHV0ID0gZm9ybWF0c2l6ZTsKICAgIG1lbWNweShUaGlzLT5scGJpSW5wdXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogICAgLyogZ2V0IG91dHB1dCBmb3JtYXQgKi8KICAgIHNpemUgPSBJQ0NvbXByZXNzR2V0Rm9ybWF0U2l6ZShUaGlzLT5oaWMsIFRoaXMtPmxwYmlJbnB1dCk7CiAgICBpZiAoc2l6ZSA8IHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSkKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgVGhpcy0+bHBiaU91dHB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGlmIChUaGlzLT5scGJpT3V0cHV0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JPdXRwdXQgPSBzaXplOwogICAgaWYgKElDQ29tcHJlc3NHZXRGb3JtYXQoVGhpcy0+aGljLFRoaXMtPmxwYmlJbnB1dCxUaGlzLT5scGJpT3V0cHV0KSA8IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgKi8KICAgIFRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgID0KICAgICAgVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0ICsgVGhpcy0+bHBiaU91dHB1dC0+YmlXaWR0aDsKICAgIFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tID0KICAgICAgVGhpcy0+c0luZm8ucmNGcmFtZS50b3AgICsgVGhpcy0+bHBiaU91dHB1dC0+YmlIZWlnaHQ7CgogICAgLyogcHJlcGFyZSBjb2RlYyBmb3IgY29tcHJlc3Npb24gKi8KICAgIGlmIChJQ0NvbXByZXNzQmVnaW4oVGhpcy0+aGljLCBUaGlzLT5scGJpSW5wdXQsIFRoaXMtPmxwYmlPdXRwdXQpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGNvbXByZXNzZWQgZnJhbWUgKi8KICAgIHNpemUgPSBJQ0NvbXByZXNzR2V0U2l6ZShUaGlzLT5oaWMsIFRoaXMtPmxwYmlJbnB1dCwgVGhpcy0+bHBiaU91dHB1dCk7CiAgICBUaGlzLT5scGJpQ3VyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmNiT3V0cHV0ICsgc2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBiaUN1ciA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIG1lbWNweShUaGlzLT5scGJpQ3VyLCBUaGlzLT5scGJpT3V0cHV0LCBUaGlzLT5jYk91dHB1dCk7CiAgICBUaGlzLT5scEN1ciA9IERJQlBUUihUaGlzLT5scGJpQ3VyKTsKCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGxhc3QgZnJhbWUgaWYgbmVlZGVkICovCiAgICBpZiAoVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMSAmJgoJKFRoaXMtPmR3SUNNRmxhZ3MgJiBWSURDRl9GQVNUVEVNUE9SQUxDKSA9PSAwKSB7CiAgICAgIHNpemUgPSBJQ0RlY29tcHJlc3NHZXRGb3JtYXRTaXplKFRoaXMtPmhpYywgVGhpcy0+bHBiaU91dHB1dCk7CiAgICAgIFRoaXMtPmxwYmlQcmV2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgICBpZiAoVGhpcy0+bHBiaVByZXYgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBpZiAoSUNEZWNvbXByZXNzR2V0Rm9ybWF0KFRoaXMtPmhpYywgVGhpcy0+bHBiaU91dHB1dCwgVGhpcy0+bHBiaVByZXYpIDwgU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAgIGlmIChUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2UgPT0gMCkgewoJVGhpcy0+bHBiaVByZXYtPmJpU2l6ZUltYWdlID0KCSAgRElCV0lEVEhCWVRFUygqVGhpcy0+bHBiaVByZXYpICogVGhpcy0+bHBiaVByZXYtPmJpSGVpZ2h0OwogICAgICB9CgogICAgICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIHBpY3R1cmUgKi8KICAgICAgc2l6ZSArPSBUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2U7CiAgICAgIFRoaXMtPmxwYmlQcmV2ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBiaVByZXYsIHNpemUpOwogICAgICBpZiAoVGhpcy0+bHBiaVByZXYgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBUaGlzLT5scFByZXYgPSBESUJQVFIoVGhpcy0+bHBiaVByZXYpOwoKICAgICAgLyogcHJlcGFyZSBjb2RlYyBhbHNvIGZvciBkZWNvbXByZXNzaW9uICovCiAgICAgIGlmIChJQ0RlY29tcHJlc3NCZWdpbihUaGlzLT5oaWMsVGhpcy0+bHBiaU91dHB1dCxUaGlzLT5scGJpUHJldikgIT0gU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgIH0KICB9IGVsc2UgewogICAgLyogZm9ybWF0IGNoYW5nZSAtLSBjaGVjayB0aGF0J3Mgb25seSB0aGUgcGFsZXR0ZSAqLwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKWZvcm1hdDsKCiAgICBpZiAobHBiaS0+YmlTaXplICE9IFRoaXMtPmxwYmlJbnB1dC0+YmlTaXplIHx8CglscGJpLT5iaVdpZHRoICE9IFRoaXMtPmxwYmlJbnB1dC0+YmlXaWR0aCB8fAoJbHBiaS0+YmlIZWlnaHQgIT0gVGhpcy0+bHBiaUlucHV0LT5iaUhlaWdodCB8fAoJbHBiaS0+YmlCaXRDb3VudCAhPSBUaGlzLT5scGJpSW5wdXQtPmJpQml0Q291bnQgfHwKCWxwYmktPmJpUGxhbmVzICE9IFRoaXMtPmxwYmlJbnB1dC0+YmlQbGFuZXMgfHwKCWxwYmktPmJpQ29tcHJlc3Npb24gIT0gVGhpcy0+bHBiaUlucHV0LT5iaUNvbXByZXNzaW9uIHx8CglscGJpLT5iaUNsclVzZWQgIT0gVGhpcy0+bHBiaUlucHV0LT5iaUNsclVzZWQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogZ2V0IG5ldyBvdXRwdXQgZm9ybWF0ICovCiAgICBpZiAoSUNDb21wcmVzc0dldEZvcm1hdChUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpIDwgU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogICAgLyogcmVzdGFydCBjb21wcmVzc2lvbiAqLwogICAgSUNDb21wcmVzc0VuZChUaGlzLT5oaWMpOwogICAgaWYgKElDQ29tcHJlc3NCZWdpbihUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBjaGVjayBpZiB3ZSBuZWVkIHRvIHJlc3RhcnQgZGVjb21wcmVzaW9uIGFsc28gKi8KICAgIGlmIChUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAxICYmCgkoVGhpcy0+ZHdJQ01GbGFncyAmIFZJRENGX0ZBU1RURU1QT1JBTEMpID09IDApIHsKICAgICAgSUNEZWNvbXByZXNzRW5kKFRoaXMtPmhpYyk7CiAgICAgIGlmIChJQ0RlY29tcHJlc3NHZXRGb3JtYXQoVGhpcy0+aGljLFRoaXMtPmxwYmlPdXRwdXQsVGhpcy0+bHBiaVByZXYpIDwgU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgICAgaWYgKElDRGVjb21wcmVzc0JlZ2luKFRoaXMtPmhpYyxUaGlzLT5scGJpT3V0cHV0LFRoaXMtPmxwYmlQcmV2KSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgfQogIH0KCiAgLyogdGVsbCBuZXN0ZWQgc3RyZWFtIHRoZSBuZXcgZm9ybWF0ICovCiAgcmV0dXJuIElBVklTdHJlYW1fU2V0Rm9ybWF0KFRoaXMtPnBTdHJlYW0sIHBvcywKCQkJICAgICAgVGhpcy0+bHBiaU91dHB1dCwgVGhpcy0+Y2JPdXRwdXQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICBpZiAoc2FtcGxlcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzYW1wbGVzICE9IDEgJiYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2FtcGxlcyA9PSAtMSkgLyogcmVhZCBhcyBtdWNoIGFzIHdlIGNvdWxkICovCiAgICBzYW1wbGVzID0gMTsKCiAgaWYgKFRoaXMtPnBnID09IE5VTEwpIHsKICAgIEhSRVNVTFQgaHIgPSBBVklGSUxFX09wZW5HZXRGcmFtZShUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgLyogY29tcHJlc3Mgb3IgZGVjb21wcmVzcz8gKi8KICBpZiAoVGhpcy0+aGljID09IE5VTEwpIHsKICAgIC8qIGRlY29tcHJlc3MgKi8KICAgIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKUFWSVN0cmVhbUdldEZyYW1lKFRoaXMtPnBnLCBzdGFydCk7CiAgICBpZiAobHBiaSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmZmVyc2l6ZSA+IDApIHsKICAgICAgLyogY2hlY2sgYnVmZmVyc2l6ZSAqLwogICAgICBpZiAoYnVmZmVyc2l6ZSA8IGxwYmktPmJpU2l6ZUltYWdlKQoJcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgICAgIG1lbWNweShidWZmZXIsIERJQlBUUihscGJpKSwgbHBiaS0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBscGJpLT5iaVNpemVJbWFnZTsKICB9IGVsc2UgewogICAgLyogY29tcHJlc3MgKi8KICAgIGlmIChUaGlzLT5sQ3VycmVudCA+IHN0YXJ0KQogICAgICBBVklGSUxFX1Jlc2V0KFRoaXMpOwoKICAgIHdoaWxlIChzdGFydCA+IFRoaXMtPmxDdXJyZW50KSB7CiAgICAgIEhSRVNVTFQgaHI7CgogICAgICBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgKytUaGlzLT5sQ3VycmVudCk7CiAgICAgIGlmIChscGJpID09IE5VTEwpIHsKCUFWSUZJTEVfUmVzZXQoVGhpcyk7CglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgfQoKICAgICAgaHIgPSBBVklGSUxFX0VuY29kZUZyYW1lKFRoaXMsIGxwYmksIERJQlBUUihscGJpKSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKSB7CglBVklGSUxFX1Jlc2V0KFRoaXMpOwoJcmV0dXJuIGhyOwogICAgICB9CiAgICB9CgogICAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICAgIC8qIGNoZWNrIGJ1ZmZlcnNpemUgKi8KICAgICAgaWYgKFRoaXMtPmxwYmlDdXItPmJpU2l6ZUltYWdlID4gYnVmZmVyc2l6ZSkKCXJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogICAgICBtZW1jcHkoYnVmZmVyLCBUaGlzLT5scEN1ciwgVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UpOwogICAgfQoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBUaGlzLT5scGJpQ3VyLT5iaVNpemVJbWFnZTsKICB9CgogIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBpZiAoVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9PSBjb21wdHlwZURJQikgewogICAgLyogb25seSBwYXNzIHRocm91Z2ggKi8KICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwoKICAgIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSAgICBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CiAgfSBlbHNlIHsKICAgIC8qIGNvbXByZXNzIGRhdGEgYmVmb3JlIHdyaXRpbmcgdG8gcFN0cmVhbSAqLwogICAgaWYgKHNhbXBsZXMgIT0gMSAmJiAoc2FtcHdyaXR0ZW4gPT0gTlVMTCAmJiBieXRlc3dyaXR0ZW4gPT0gTlVMTCkpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgVGhpcy0+bEN1cnJlbnQgPSBzdGFydDsKICAgIGhyID0gQVZJRklMRV9FbmNvZGVGcmFtZShUaGlzLCBUaGlzLT5scGJpSW5wdXQsIGJ1ZmZlcik7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIGlmIChUaGlzLT5sTGFzdEtleSA9PSBzdGFydCkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CgogICAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIFRoaXMtPmxwQ3VyLAoJCQkgICAgVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UsIGZsYWdzLCBieXRlc3dyaXR0ZW4sCgkJCSAgICBzYW1wd3JpdHRlbik7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fRGVsZXRlKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCBzYW1wbGVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bHgsJXAsJWxkKVxuIiwgaWZhY2UsIGZjYywgbHAsIHNpemUpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGVEYXRhKFRoaXMtPnBTdHJlYW0sIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWxkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0VuY29kZUZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLAoJCQkJICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmksIExQVk9JRCBscEJpdHMpCnsKICBEV09SRCBkd01pblF1YWwsIGR3TWF4UXVhbCwgZHdDdXJRdWFsOwogIERXT1JEIGR3UmVxdWVzdDsKICBEV09SRCBpY21GbGFncyA9IDA7CiAgRFdPUkQgaWR4RmxhZ3MgPSAwOwogIEJPT0wgIGJEZWNyZWFzZWRRdWFsID0gRkFMU0U7CiAgQk9PTCAgZG9TaXplQ2hlY2s7CiAgQk9PTCAgbm9QcmV2OwoKICAvKiBtYWtlIGxLZXlGcmFtZUV2ZXJ5IGFuZCBhdCBzdGFydCBhIGtleWZyYW1lICovCiAgaWYgKChUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAwICYmCiAgICAgICAoVGhpcy0+bEN1cnJlbnQgLSBUaGlzLT5sTGFzdEtleSkgPj0gVGhpcy0+bEtleUZyYW1lRXZlcnkpIHx8CiAgICAgIFRoaXMtPmxDdXJyZW50ID09IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIGlkeEZsYWdzID0gQVZJSUZfS0VZRlJBTUU7CiAgICBpY21GbGFncyA9IElDQ09NUFJFU1NfS0VZRlJBTUU7CiAgfQoKICBpZiAoVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMCkgewogICAgaWYgKFRoaXMtPmxDdXJyZW50ID09IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgICAgaWYgKGlkeEZsYWdzICYgQVZJSUZfS0VZRlJBTUUpIHsKCS8qIGZvciBrZXlmcmFtZXMgYWxsb3cgdG8gY29uc3VtZSBhbGwgdW51c2VkIGJ5dGVzICovCglkd1JlcXVlc3QgPSBUaGlzLT5kd0J5dGVzUGVyRnJhbWUgKyBUaGlzLT5kd1VudXNlZEJ5dGVzOwoJVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IDA7CiAgICAgIH0gZWxzZSB7CgkvKiBmb3Igbm9uLWtleWZyYW1lcyBvbmx5IGFsbG93IHNvbWV0aGluZyBvZiB0aGUgdW51c2VkIGJ5dGVzIHRvIGJlIGNvbnN1bWVkICovCglEV09SRCB0bXAxID0gMDsKCURXT1JEIHRtcDI7CgoJaWYgKFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSA+PSBUaGlzLT5kd1VudXNlZEJ5dGVzKQoJICB0bXAxID0gVGhpcy0+ZHdCeXRlc1BlckZyYW1lIC8gVGhpcy0+bEtleUZyYW1lRXZlcnk7Cgl0bXAyID0gKFRoaXMtPmR3VW51c2VkQnl0ZXMgKyB0bXAxKSAvIFRoaXMtPmxLZXlGcmFtZUV2ZXJ5OwoKCWR3UmVxdWVzdCA9IFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSAtIHRtcDEgKyB0bXAyOwoJVGhpcy0+ZHdVbnVzZWRCeXRlcyAtPSB0bXAyOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgZHdSZXF1ZXN0ID0gTUFYX0ZSQU1FU0laRTsKICB9IGVsc2UgewogICAgLyogb25seSBvbmUga2V5ZnJhbWUgYXQgc3RhcnQgZGVzaXJlZCAqLwogICAgaWYgKFRoaXMtPmxDdXJyZW50ID09IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgICAgZHdSZXF1ZXN0ID0gVGhpcy0+ZHdCeXRlc1BlckZyYW1lICsgVGhpcy0+ZHdVbnVzZWRCeXRlczsKICAgICAgVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IDA7CiAgICB9IGVsc2UKICAgICAgZHdSZXF1ZXN0ID0gTUFYX0ZSQU1FU0laRTsKICB9CgogIC8qIG11c3Qgd2UgY2hlY2sgZm9yIGZyYW1lc2l6ZSB0byBnYWluIHJlcXVlc3RlZAogICAqIGRhdGFyYXRlIG9yIGNvdWxkIHdlIHRydXN0IGNvZGVjPyAqLwogIGRvU2l6ZUNoZWNrID0gKGR3UmVxdWVzdCAhPSAwICYmICgoVGhpcy0+ZHdJQ01GbGFncyAmIChWSURDRl9DUlVOQ0h8VklEQ0ZfUVVBTElUWSkpID09IDApKTsKCiAgZHdNYXhRdWFsID0gZHdDdXJRdWFsID0gVGhpcy0+c0luZm8uZHdRdWFsaXR5OwogIGR3TWluUXVhbCA9IElDUVVBTElUWV9MT1c7CgogIG5vUHJldiA9IFRSVUU7CiAgaWYgKChpY21GbGFncyAmIElDQ09NUFJFU1NfS0VZRlJBTUUpID09IDAgJiYgCiAgICAgIChUaGlzLT5kd0lDTUZsYWdzICYgVklEQ0ZfRkFTVFRFTVBPUkFMQykgPT0gMCkKICAgIG5vUHJldiA9IEZBTFNFOwoKICBkbyB7CiAgICBEV09SRCAgIGlkeENraWQgPSAwOwogICAgSFJFU1VMVCBocjsKCiAgICBociA9IElDQ29tcHJlc3MoVGhpcy0+aGljLGljbUZsYWdzLFRoaXMtPmxwYmlDdXIsVGhpcy0+bHBDdXIsbHBiaSxscEJpdHMsCgkJICAgICZpZHhDa2lkLCAmaWR4RmxhZ3MsIFRoaXMtPmxDdXJyZW50LCBkd1JlcXVlc3QsIGR3Q3VyUXVhbCwKCQkgICAgbm9QcmV2ID8gTlVMTDpUaGlzLT5scGJpUHJldiwgbm9QcmV2ID8gTlVMTDpUaGlzLT5scFByZXYpOwogICAgaWYgKGhyID09IElDRVJSX05FV1BBTEVUVEUpIHsKICAgICAgRklYTUUoIjogY29kZWMgaGFzIGNoYW5nZWQgcGFsZXR0ZSAtLSB1bmhhbmRsZWQhXG4iKTsKICAgIH0gZWxzZSBpZiAoaHIgIT0gSUNFUlJfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBuZWVkIHRvIGNoZWNrIGZvciBmcmFtZXNpemUgKi8KICAgIGlmICghIGRvU2l6ZUNoZWNrKQogICAgICBicmVhazsKCiAgICBpZiAoZHdSZXF1ZXN0ID49IFRoaXMtPmxwYmlDdXItPmJpU2l6ZUltYWdlKSB7CiAgICAgIC8qIGZyYW1lIGlzIHNtYWxsZXIgLS0gdHJ5IHRvIG1heGltaXplIHF1YWxpdHkgKi8KICAgICAgaWYgKGR3TWF4UXVhbCAtIGR3Q3VyUXVhbCA+IDEwKSB7CglEV09SRCB0bXAgPSBkd1JlcXVlc3QgLyA4OwoKCWlmICh0bXAgPCBNQVhfRlJBTUVTSVpFX0RJRkYpCgkgIHRtcCA9IE1BWF9GUkFNRVNJWkVfRElGRjsKCglpZiAodG1wIDwgZHdSZXF1ZXN0IC0gVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UgJiYgYkRlY3JlYXNlZFF1YWwpIHsKCSAgdG1wID0gZHdDdXJRdWFsOwoJICBkd0N1clF1YWwgPSAoZHdNaW5RdWFsICsgZHdNYXhRdWFsKSAvIDI7CgkgIGR3TWluUXVhbCA9IHRtcDsKCSAgY29udGludWU7Cgl9CiAgICAgIH0gZWxzZQoJYnJlYWs7CiAgICB9IGVsc2UgaWYgKGR3TWF4UXVhbCAtIGR3TWluUXVhbCA8PSAxKSB7CiAgICAgIGJyZWFrOwogICAgfSBlbHNlIHsKICAgICAgZHdNYXhRdWFsID0gZHdDdXJRdWFsOwoKICAgICAgaWYgKGJEZWNyZWFzZWRRdWFsIHx8IGR3Q3VyUXVhbCA9PSBUaGlzLT5kd0xhc3RRdWFsaXR5KQoJZHdDdXJRdWFsID0gKGR3TWluUXVhbCArIGR3TWF4UXVhbCkgLyAyOwogICAgICBlbHNlCglGSVhNRSgiOiBubyBuZXcgcXVhbGl0eSBjb21wdXRlZCBtaW49JWx1IGN1cj0lbHUgbWF4PSVsdSBsYXN0PSVsdVxuIiwKCSAgICAgIGR3TWluUXVhbCwgZHdDdXJRdWFsLCBkd01heFF1YWwsIFRoaXMtPmR3TGFzdFF1YWxpdHkpOwoKICAgICAgYkRlY3JlYXNlZFF1YWwgPSBUUlVFOwogICAgfQogIH0gd2hpbGUgKFRSVUUpOwoKICAvKiByZW1lbWJlciBzb21lIHZhbHVlcyAqLwogIFRoaXMtPmR3TGFzdFF1YWxpdHkgPSBkd0N1clF1YWw7CiAgVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IGR3UmVxdWVzdCAtIFRoaXMtPmxwYmlDdXItPmJpU2l6ZUltYWdlOwogIGlmIChpY21GbGFncyAmIElDQ09NUFJFU1NfS0VZRlJBTUUpCiAgICBUaGlzLT5sTGFzdEtleSA9IFRoaXMtPmxDdXJyZW50OwoKICAvKiBEb2VzIHdlIG1hbmFnZSBwcmV2aW91cyBmcmFtZT8gKi8KICBpZiAoVGhpcy0+bHBQcmV2ICE9IE5VTEwgJiYgVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMSkKICAgIElDRGVjb21wcmVzcyhUaGlzLT5oaWMsIDAsIFRoaXMtPmxwYmlDdXIsIFRoaXMtPmxwQ3VyLAoJCSBUaGlzLT5scGJpUHJldiwgVGhpcy0+bHBQcmV2KTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuR2V0RnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMpCnsKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaTsKICBEV09SRCAgICAgICAgICAgICAgc2l6ZTsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGcgPT0gTlVMTCk7CgogIFRoaXMtPnBnID0gQVZJU3RyZWFtR2V0RnJhbWVPcGVuKFRoaXMtPnBTdHJlYW0sIE5VTEwpOwogIGlmIChUaGlzLT5wZyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsKCiAgLyogV2hlbiB3ZSBvbmx5IGRlY29tcHJlc3MgdGhpcyBpcyBlbm91Z2ggKi8KICBpZiAoVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9PSBjb21wdHlwZURJQikKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGFzc2VydChUaGlzLT5oaWMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPmxwYmlPdXRwdXQgPT0gTlVMTCk7CgogIC8qIGdldCBpbnB1dCBmb3JtYXQgKi8KICBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgVGhpcy0+c0luZm8uZHdTdGFydCk7CiAgaWYgKGxwYmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBnZXQgbWVtb3J5IGZvciBvdXRwdXQgZm9ybWF0ICovCiAgc2l6ZSA9IElDQ29tcHJlc3NHZXRGb3JtYXRTaXplKFRoaXMtPmhpYywgbHBiaSk7CiAgaWYgKChMT05HKXNpemUgPCAoTE9ORylzaXplb2YoQklUTUFQSU5GT0hFQURFUikpCiAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgVGhpcy0+bHBiaU91dHB1dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICBpZiAoVGhpcy0+bHBiaU91dHB1dCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgVGhpcy0+Y2JPdXRwdXQgPSBzaXplOwoKICBpZiAoSUNDb21wcmVzc0dldEZvcm1hdChUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpIDwgU19PSykKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgKi8KICBUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0ICA9CiAgICBUaGlzLT5zSW5mby5yY0ZyYW1lLmxlZnQgKyBUaGlzLT5scGJpT3V0cHV0LT5iaVdpZHRoOwogIFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tID0KICAgIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wICArIFRoaXMtPmxwYmlPdXRwdXQtPmJpSGVpZ2h0OwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9CiAgICBJQ0NvbXByZXNzR2V0U2l6ZShUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpOwoKICAvKiBwcmVwYXJlIGNvZGVjIGZvciBjb21wcmVzc2lvbiAqLwogIGlmIChJQ0NvbXByZXNzQmVnaW4oVGhpcy0+aGljLCBscGJpLCBUaGlzLT5scGJpT3V0cHV0KSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwoKICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGN1cnJlbnQgZnJhbWUgKi8KICBzaXplICs9IFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICBUaGlzLT5scGJpQ3VyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogIGlmIChUaGlzLT5scGJpQ3VyID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBtZW1jcHkoVGhpcy0+bHBiaUN1ciwgVGhpcy0+bHBiaU91dHB1dCwgVGhpcy0+Y2JPdXRwdXQpOwogIFRoaXMtPmxwQ3VyID0gRElCUFRSKFRoaXMtPmxwYmlDdXIpOwoKICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGxhc3QgZnJhbWUgaWYgbmVlZGVkICovCiAgaWYgKFRoaXMtPmxLZXlGcmFtZUV2ZXJ5ICE9IDEgJiYKICAgICAgKFRoaXMtPmR3SUNNRmxhZ3MgJiBWSURDRl9GQVNUVEVNUE9SQUxDKSA9PSAwKSB7CiAgICBzaXplID0gSUNEZWNvbXByZXNzR2V0Rm9ybWF0U2l6ZShUaGlzLT5oaWMsIFRoaXMtPmxwYmlPdXRwdXQpOwogICAgVGhpcy0+bHBiaVByZXYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBiaVByZXYgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBpZiAoSUNEZWNvbXByZXNzR2V0Rm9ybWF0KFRoaXMtPmhpYywgVGhpcy0+bHBiaU91dHB1dCwgVGhpcy0+bHBiaVByZXYpIDwgU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwoKICAgIGlmIChUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2UgPT0gMCkgewogICAgICBUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2UgPQoJRElCV0lEVEhCWVRFUygqVGhpcy0+bHBiaVByZXYpICogVGhpcy0+bHBiaVByZXYtPmJpSGVpZ2h0OwogICAgfQoKICAgIC8qIGdldCBtZW1vcnkgZm9yIGZvcm1hdCBhbmQgcGljdHVyZSAqLwogICAgc2l6ZSArPSBUaGlzLT5scGJpUHJldi0+YmlTaXplSW1hZ2U7CiAgICBUaGlzLT5scGJpUHJldiA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwYmlQcmV2LCBzaXplICk7CiAgICBpZiAoVGhpcy0+bHBiaVByZXYgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5scFByZXYgPSBESUJQVFIoVGhpcy0+bHBiaVByZXYpOwoKICAgIC8qIHByZXBhcmUgY29kZWMgYWxzbyBmb3IgZGVjb21wcmVzc2lvbiAqLwogICAgaWYgKElDRGVjb21wcmVzc0JlZ2luKFRoaXMtPmhpYyxUaGlzLT5scGJpT3V0cHV0LFRoaXMtPmxwYmlQcmV2KSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==