LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNkZWZpbmUgTUFYX0ZSQU1FU0laRSAgICAgICAoMTYgKiAxMDI0ICogMTAyNCkKI2RlZmluZSBNQVhfRlJBTUVTSVpFX0RJRkYgIDUxMgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJQ01TdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJU3RyZWFtVnRibCBpaWNtc3QgPSB7CiAgSUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUNNU3RyZWFtX2ZuQWRkUmVmLAogIElDTVN0cmVhbV9mblJlbGVhc2UsCiAgSUNNU3RyZWFtX2ZuQ3JlYXRlLAogIElDTVN0cmVhbV9mbkluZm8sCiAgSUNNU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJQ01TdHJlYW1fZm5SZWFkRm9ybWF0LAogIElDTVN0cmVhbV9mblNldEZvcm1hdCwKICBJQ01TdHJlYW1fZm5SZWFkLAogIElDTVN0cmVhbV9mbldyaXRlLAogIElDTVN0cmVhbV9mbkRlbGV0ZSwKICBJQ01TdHJlYW1fZm5SZWFkRGF0YSwKICBJQ01TdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUNNU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklTdHJlYW1WdGJsICpscFZ0Ymw7CiAgTE9ORwkJICAgICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBQQVZJU1RSRUFNICAgICAgICAgcFN0cmVhbTsKICBBVklTVFJFQU1JTkZPVyAgICAgc0luZm87CgogIFBHRVRGUkFNRSAgICAgICAgICBwZzsKICBISUMgICAgICAgICAgICAgICAgaGljOwogIERXT1JEICAgICAgICAgICAgICBkd0lDTUZsYWdzOwoKICBMT05HICAgICAgICAgICAgICAgbEN1cnJlbnQ7CiAgTE9ORyAgICAgICAgICAgICAgIGxMYXN0S2V5OwogIExPTkcgICAgICAgICAgICAgICBsS2V5RnJhbWVFdmVyeTsKICBEV09SRCAgICAgICAgICAgICAgZHdMYXN0UXVhbGl0eTsKICBEV09SRCAgICAgICAgICAgICAgZHdCeXRlc1BlckZyYW1lOwogIERXT1JEICAgICAgICAgICAgICBkd1VudXNlZEJ5dGVzOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaUN1cjsgIC8qIGN1cnJlbnQgZnJhbWUgKi8KICBMUFZPSUQgICAgICAgICAgICAgbHBDdXI7CiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlQcmV2OyAvKiBwcmV2aW91cyBmcmFtZSAqLwogIExQVk9JRCAgICAgICAgICAgICBscFByZXY7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpT3V0cHV0OyAvKiBvdXRwdXQgZm9ybWF0IG9mIGNvZGVjICovCiAgTE9ORyAgICAgICAgICAgICAgIGNiT3V0cHV0OwogIExQQklUTUFQSU5GT0hFQURFUiBscGJpSW5wdXQ7ICAvKiBpbnB1dCBmb3JtYXQgZm9yIGNvZGVjICovCiAgTE9ORyAgICAgICAgICAgICAgIGNiSW5wdXQ7Cn0gSUFWSVN0cmVhbUltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0VuY29kZUZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLAoJCQkJICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmksIExQVk9JRCBscEJpdHMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX09wZW5HZXRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CgpzdGF0aWMgaW5saW5lIHZvaWQgQVZJRklMRV9SZXNldChJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIFRoaXMtPmxDdXJyZW50ICAgICAgPSAtMTsKICBUaGlzLT5sTGFzdEtleSAgICAgID0gMDsKICBUaGlzLT5kd0xhc3RRdWFsaXR5ID0gSUNRVUFMSVRZX0hJR0g7CiAgVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IDA7Cn0KCkhSRVNVTFQgQVZJRklMRV9DcmVhdGVJQ01TdHJlYW0oUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSVN0cmVhbUltcGwgKnBzdHJlYW07CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBzdHJlYW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklTdHJlYW1JbXBsKSk7CiAgaWYgKHBzdHJlYW0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwc3RyZWFtLT5scFZ0YmwgID0gJmlpY21zdDsKICBBVklGSUxFX1Jlc2V0KHBzdHJlYW0pOwoKICBociA9IElBVklTdHJlYW1fUXVlcnlJbnRlcmZhY2UoKElBVklTdHJlYW0qKXBzdHJlYW0sIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwc3RyZWFtKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIC8qIGFsc28gYWRkIHJlZmVyZW5jZSB0byB0aGUgbmVzdGVkIHN0cmVhbSAqLwogIGlmIChUaGlzLT5wU3RyZWFtICE9IE5VTEwpCiAgICBJQVZJU3RyZWFtX0FkZFJlZihUaGlzLT5wU3RyZWFtKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAocmVmID09IDApIHsKICAgIC8qIGRlc3RydWN0ICovCiAgICBpZiAoVGhpcy0+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+c0luZm8uZmNjSGFuZGxlciA9IGNvbXB0eXBlRElCOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWQsMHglMDhYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgaWYgKGZsYWdzICYgRklORF9SRVQpCiAgICBXQVJOKCI6IEZJTkRfUkVUIGZsYWdzIHdpbGwgYmUgaWdub3JlZCFcbiIpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0tFWSkgewogICAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKQogICAgICByZXR1cm4gcG9zOyAvKiB3ZSBkZWNvbXByZXNzIHNvIGV2ZXJ5IGZyYW1lIGlzIGEga2V5ZnJhbWUgKi8KCiAgICBpZiAoZmxhZ3MgJiBGSU5EX1BSRVYpIHsKICAgICAgLyogbmVlZCB0byByZWFkIG9sZCBvciBuZXcgZnJhbWVzPyAqLwogICAgICBpZiAoVGhpcy0+bExhc3RLZXkgPD0gcG9zIHx8IHBvcyA8IFRoaXMtPmxDdXJyZW50KQoJSUFWSVN0cmVhbV9SZWFkKGlmYWNlLCBwb3MsIDEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwoKICAgICAgcmV0dXJuIFRoaXMtPmxMYXN0S2V5OwogICAgfQogIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgcmV0dXJuIHBvczsgLyogV2UgcmVhbGx5IGRvbid0IGtub3csIHJlcmVhZCBpcyB0byBleHBlbnNpdmUsIHNvIGd1ZXNzLiAqLwogIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgewogICAgaWYgKGZsYWdzICYgRklORF9QUkVWKQogICAgICByZXR1cm4gMDsKICB9CgogIHJldHVybiAtMTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaTsKICBIUkVTVUxUICAgICAgICAgICAgaHI7CgogIFRSQUNFKCIoJXAsJWQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKFRoaXMtPnBnID09IE5VTEwpIHsKICAgIGhyID0gQVZJRklMRV9PcGVuR2V0RnJhbWUoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKUFWSVN0cmVhbUdldEZyYW1lKFRoaXMtPnBnLCBwb3MpOwogIGlmIChscGJpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKSB7CiAgICBMT05HIHNpemUgPSBscGJpLT5iaVNpemUgKyBscGJpLT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCk7CgogICAgaWYgKHNpemUgPiAwKSB7CiAgICAgIGlmIChUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBscGJpLT5iaVNpemVJbWFnZSkKCVRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IGxwYmktPmJpU2l6ZUltYWdlOwoKICAgICAgVGhpcy0+Y2JPdXRwdXQgPSBzaXplOwogICAgICBpZiAoZm9ybWF0ICE9IE5VTEwpIHsKCWlmIChUaGlzLT5scGJpT3V0cHV0ICE9IE5VTEwpCgkgIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwYmlPdXRwdXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+Y2JPdXRwdXQpKTsKCWVsc2UKCSAgbWVtY3B5KGZvcm1hdCwgbHBiaSwgbWluKCpmb3JtYXRzaXplLCBzaXplKSk7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKGZvcm1hdCAhPSBOVUxMKQogICAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+bHBiaU91dHB1dCwgbWluKCpmb3JtYXRzaXplLCBUaGlzLT5jYk91dHB1dCkpOwoKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5jYk91dHB1dCkKICAgIGhyID0gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIGVsc2UKICAgIGhyID0gQVZJRVJSX09LOwoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0cHV0OwogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVwLCVkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBXZSBjYW4gb25seSBhY2NlcHQgUkdCIGRhdGEgZm9yIHdyaXRpbmcgKi8KICBpZiAoKChMUEJJVE1BUElORk9IRUFERVIpZm9ybWF0KS0+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+bHBiaUlucHV0LT5iaUNsclVzZWQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogZ2V0IG5ldyBvdXRwdXQgZm9ybWF0ICovCiAgICBpZiAoSUNDb21wcmVzc0dldEZvcm1hdChUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpIDwgU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogICAgLyogcmVzdGFydCBjb21wcmVzc2lvbiAqLwogICAgSUNDb21wcmVzc0VuZChUaGlzLT5oaWMpOwogICAgaWYgKElDQ29tcHJlc3NCZWdpbihUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBjaGVjayBpZiB3ZSBuZWVkIHRvIHJlc3RhcnQgZGVjb21wcmVzc2lvbiBhbHNvICovCiAgICBpZiAoVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMSAmJgoJKFRoaXMtPmR3SUNNRmxhZ3MgJiBWSURDRl9GQVNUVEVNUE9SQUxDKSA9PSAwKSB7CiAgICAgIElDRGVjb21wcmVzc0VuZChUaGlzLT5oaWMpOwogICAgICBpZiAoSUNEZWNvbXByZXNzR2V0Rm9ybWF0KFRoaXMtPmhpYyxUaGlzLT5scGJpT3V0cHV0LFRoaXMtPmxwYmlQcmV2KSA8IFNfT0spCglyZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgICAgIGlmIChJQ0RlY29tcHJlc3NCZWdpbihUaGlzLT5oaWMsVGhpcy0+bHBiaU91dHB1dCxUaGlzLT5scGJpUHJldikgIT0gU19PSykKCXJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgIH0KICB9CgogIC8qIHRlbGwgbmVzdGVkIHN0cmVhbSB0aGUgbmV3IGZvcm1hdCAqLwogIHJldHVybiBJQVZJU3RyZWFtX1NldEZvcm1hdChUaGlzLT5wU3RyZWFtLCBwb3MsCgkJCSAgICAgIFRoaXMtPmxwYmlPdXRwdXQsIFRoaXMtPmNiT3V0cHV0KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaTsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAogCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc2FtcGxlcyAhPSAxICYmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNhbXBsZXMgPT0gLTEpIC8qIHJlYWQgYXMgbXVjaCBhcyB3ZSBjb3VsZCAqLwogICAgc2FtcGxlcyA9IDE7CgogIGlmIChUaGlzLT5wZyA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyID0gQVZJRklMRV9PcGVuR2V0RnJhbWUoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIC8qIGNvbXByZXNzIG9yIGRlY29tcHJlc3M/ICovCiAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKSB7CiAgICAvKiBkZWNvbXByZXNzICovCiAgICBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilBVklTdHJlYW1HZXRGcmFtZShUaGlzLT5wZywgc3RhcnQpOwogICAgaWYgKGxwYmkgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICAgIC8qIGNoZWNrIGJ1ZmZlcnNpemUgKi8KICAgICAgaWYgKGJ1ZmZlcnNpemUgPCBscGJpLT5iaVNpemVJbWFnZSkKCXJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogICAgICBtZW1jcHkoYnVmZmVyLCBESUJQVFIobHBiaSksIGxwYmktPmJpU2l6ZUltYWdlKTsKICAgIH0KCiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gbHBiaS0+YmlTaXplSW1hZ2U7CiAgfSBlbHNlIHsKICAgIC8qIGNvbXByZXNzICovCiAgICBpZiAoVGhpcy0+bEN1cnJlbnQgPiBzdGFydCkKICAgICAgQVZJRklMRV9SZXNldChUaGlzKTsKCiAgICB3aGlsZSAoc3RhcnQgPiBUaGlzLT5sQ3VycmVudCkgewogICAgICBIUkVTVUxUIGhyOwoKICAgICAgbHBiaSA9IChMUEJJVE1BUElORk9IRUFERVIpQVZJU3RyZWFtR2V0RnJhbWUoVGhpcy0+cGcsICsrVGhpcy0+bEN1cnJlbnQpOwogICAgICBpZiAobHBiaSA9PSBOVUxMKSB7CglBVklGSUxFX1Jlc2V0KFRoaXMpOwoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIH0KCiAgICAgIGhyID0gQVZJRklMRV9FbmNvZGVGcmFtZShUaGlzLCBscGJpLCBESUJQVFIobHBiaSkpOwogICAgICBpZiAoRkFJTEVEKGhyKSkgewoJQVZJRklMRV9SZXNldChUaGlzKTsKCXJldHVybiBocjsKICAgICAgfQogICAgfQoKICAgIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID4gMCkgewogICAgICAvKiBjaGVjayBidWZmZXJzaXplICovCiAgICAgIGlmIChUaGlzLT5scGJpQ3VyLT5iaVNpemVJbWFnZSA+IGJ1ZmZlcnNpemUpCglyZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICAgICAgbWVtY3B5KGJ1ZmZlciwgVGhpcy0+bHBDdXIsIFRoaXMtPmxwYmlDdXItPmJpU2l6ZUltYWdlKTsKICAgIH0KCiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2U7CiAgfQoKICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsMHglMDhYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBpZiAoVGhpcy0+c0luZm8uZmNjSGFuZGxlciA9PSBjb21wdHlwZURJQikgewogICAgLyogb25seSBwYXNzIHRocm91Z2ggKi8KICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwoKICAgIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSAgICBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CiAgfSBlbHNlIHsKICAgIC8qIGNvbXByZXNzIGRhdGEgYmVmb3JlIHdyaXRpbmcgdG8gcFN0cmVhbSAqLwogICAgaWYgKHNhbXBsZXMgIT0gMSAmJiAoc2FtcHdyaXR0ZW4gPT0gTlVMTCAmJiBieXRlc3dyaXR0ZW4gPT0gTlVMTCkpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgVGhpcy0+bEN1cnJlbnQgPSBzdGFydDsKICAgIGhyID0gQVZJRklMRV9FbmNvZGVGcmFtZShUaGlzLCBUaGlzLT5scGJpSW5wdXQsIGJ1ZmZlcik7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIGlmIChUaGlzLT5sTGFzdEtleSA9PSBzdGFydCkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CgogICAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIHNhbXBsZXMsIFRoaXMtPmxwQ3VyLAoJCQkgICAgVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UsIGZsYWdzLCBieXRlc3dyaXR0ZW4sCgkJCSAgICBzYW1wd3JpdHRlbik7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlZCwlZClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIHJldHVybiBJQVZJU3RyZWFtX0RlbGV0ZShUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ01TdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4WCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4eCwlcCwlZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlRGF0YShUaGlzLT5wU3RyZWFtLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDTVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0VuY29kZUZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLAoJCQkJICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmksIExQVk9JRCBscEJpdHMpCnsKICBEV09SRCBkd01pblF1YWwsIGR3TWF4UXVhbCwgZHdDdXJRdWFsOwogIERXT1JEIGR3UmVxdWVzdDsKICBEV09SRCBpY21GbGFncyA9IDA7CiAgRFdPUkQgaWR4RmxhZ3MgPSAwOwogIEJPT0wgIGJEZWNyZWFzZWRRdWFsID0gRkFMU0U7CiAgQk9PTCAgZG9TaXplQ2hlY2s7CiAgQk9PTCAgbm9QcmV2OwoKICAvKiBtYWtlIGxLZXlGcmFtZUV2ZXJ5IGFuZCBhdCBzdGFydCBhIGtleWZyYW1lICovCiAgaWYgKChUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAwICYmCiAgICAgICAoVGhpcy0+bEN1cnJlbnQgLSBUaGlzLT5sTGFzdEtleSkgPj0gVGhpcy0+bEtleUZyYW1lRXZlcnkpIHx8CiAgICAgIFRoaXMtPmxDdXJyZW50ID09IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIGlkeEZsYWdzID0gQVZJSUZfS0VZRlJBTUU7CiAgICBpY21GbGFncyA9IElDQ09NUFJFU1NfS0VZRlJBTUU7CiAgfQoKICBpZiAoVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMCkgewogICAgaWYgKFRoaXMtPmxDdXJyZW50ID09IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgICAgaWYgKGlkeEZsYWdzICYgQVZJSUZfS0VZRlJBTUUpIHsKCS8qIGZvciBrZXlmcmFtZXMgYWxsb3cgdG8gY29uc3VtZSBhbGwgdW51c2VkIGJ5dGVzICovCglkd1JlcXVlc3QgPSBUaGlzLT5kd0J5dGVzUGVyRnJhbWUgKyBUaGlzLT5kd1VudXNlZEJ5dGVzOwoJVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IDA7CiAgICAgIH0gZWxzZSB7CgkvKiBmb3Igbm9uLWtleWZyYW1lcyBvbmx5IGFsbG93IHNvbWV0aGluZyBvZiB0aGUgdW51c2VkIGJ5dGVzIHRvIGJlIGNvbnN1bWVkICovCglEV09SRCB0bXAxID0gMDsKCURXT1JEIHRtcDI7CgoJaWYgKFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSA+PSBUaGlzLT5kd1VudXNlZEJ5dGVzKQoJICB0bXAxID0gVGhpcy0+ZHdCeXRlc1BlckZyYW1lIC8gVGhpcy0+bEtleUZyYW1lRXZlcnk7Cgl0bXAyID0gKFRoaXMtPmR3VW51c2VkQnl0ZXMgKyB0bXAxKSAvIFRoaXMtPmxLZXlGcmFtZUV2ZXJ5OwoKCWR3UmVxdWVzdCA9IFRoaXMtPmR3Qnl0ZXNQZXJGcmFtZSAtIHRtcDEgKyB0bXAyOwoJVGhpcy0+ZHdVbnVzZWRCeXRlcyAtPSB0bXAyOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgZHdSZXF1ZXN0ID0gTUFYX0ZSQU1FU0laRTsKICB9IGVsc2UgewogICAgLyogb25seSBvbmUga2V5ZnJhbWUgYXQgc3RhcnQgZGVzaXJlZCAqLwogICAgaWYgKFRoaXMtPmxDdXJyZW50ID09IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgICAgZHdSZXF1ZXN0ID0gVGhpcy0+ZHdCeXRlc1BlckZyYW1lICsgVGhpcy0+ZHdVbnVzZWRCeXRlczsKICAgICAgVGhpcy0+ZHdVbnVzZWRCeXRlcyA9IDA7CiAgICB9IGVsc2UKICAgICAgZHdSZXF1ZXN0ID0gTUFYX0ZSQU1FU0laRTsKICB9CgogIC8qIG11c3Qgd2UgY2hlY2sgZm9yIGZyYW1lc2l6ZSB0byBnYWluIHJlcXVlc3RlZAogICAqIGRhdGFyYXRlIG9yIGNvdWxkIHdlIHRydXN0IGNvZGVjPyAqLwogIGRvU2l6ZUNoZWNrID0gKGR3UmVxdWVzdCAhPSAwICYmICgoVGhpcy0+ZHdJQ01GbGFncyAmIChWSURDRl9DUlVOQ0h8VklEQ0ZfUVVBTElUWSkpID09IDApKTsKCiAgZHdNYXhRdWFsID0gZHdDdXJRdWFsID0gVGhpcy0+c0luZm8uZHdRdWFsaXR5OwogIGR3TWluUXVhbCA9IElDUVVBTElUWV9MT1c7CgogIG5vUHJldiA9IFRSVUU7CiAgaWYgKChpY21GbGFncyAmIElDQ09NUFJFU1NfS0VZRlJBTUUpID09IDAgJiYgCiAgICAgIChUaGlzLT5kd0lDTUZsYWdzICYgVklEQ0ZfRkFTVFRFTVBPUkFMQykgPT0gMCkKICAgIG5vUHJldiA9IEZBTFNFOwoKICBkbyB7CiAgICBEV09SRCAgIGlkeENraWQgPSAwOwogICAgSFJFU1VMVCBocjsKCiAgICBociA9IElDQ29tcHJlc3MoVGhpcy0+aGljLGljbUZsYWdzLFRoaXMtPmxwYmlDdXIsVGhpcy0+bHBDdXIsbHBiaSxscEJpdHMsCgkJICAgICZpZHhDa2lkLCAmaWR4RmxhZ3MsIFRoaXMtPmxDdXJyZW50LCBkd1JlcXVlc3QsIGR3Q3VyUXVhbCwKCQkgICAgbm9QcmV2ID8gTlVMTDpUaGlzLT5scGJpUHJldiwgbm9QcmV2ID8gTlVMTDpUaGlzLT5scFByZXYpOwogICAgaWYgKGhyID09IElDRVJSX05FV1BBTEVUVEUpIHsKICAgICAgRklYTUUoIjogY29kZWMgaGFzIGNoYW5nZWQgcGFsZXR0ZSAtLSB1bmhhbmRsZWQhXG4iKTsKICAgIH0gZWxzZSBpZiAoaHIgIT0gSUNFUlJfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKCiAgICAvKiBuZWVkIHRvIGNoZWNrIGZvciBmcmFtZXNpemUgKi8KICAgIGlmICghIGRvU2l6ZUNoZWNrKQogICAgICBicmVhazsKCiAgICBpZiAoZHdSZXF1ZXN0ID49IFRoaXMtPmxwYmlDdXItPmJpU2l6ZUltYWdlKSB7CiAgICAgIC8qIGZyYW1lIGlzIHNtYWxsZXIgLS0gdHJ5IHRvIG1heGltaXplIHF1YWxpdHkgKi8KICAgICAgaWYgKGR3TWF4UXVhbCAtIGR3Q3VyUXVhbCA+IDEwKSB7CglEV09SRCB0bXAgPSBkd1JlcXVlc3QgLyA4OwoKCWlmICh0bXAgPCBNQVhfRlJBTUVTSVpFX0RJRkYpCgkgIHRtcCA9IE1BWF9GUkFNRVNJWkVfRElGRjsKCglpZiAodG1wIDwgZHdSZXF1ZXN0IC0gVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2UgJiYgYkRlY3JlYXNlZFF1YWwpIHsKCSAgdG1wID0gZHdDdXJRdWFsOwoJICBkd0N1clF1YWwgPSAoZHdNaW5RdWFsICsgZHdNYXhRdWFsKSAvIDI7CgkgIGR3TWluUXVhbCA9IHRtcDsKCSAgY29udGludWU7Cgl9CiAgICAgIH0gZWxzZQoJYnJlYWs7CiAgICB9IGVsc2UgaWYgKGR3TWF4UXVhbCAtIGR3TWluUXVhbCA8PSAxKSB7CiAgICAgIGJyZWFrOwogICAgfSBlbHNlIHsKICAgICAgZHdNYXhRdWFsID0gZHdDdXJRdWFsOwoKICAgICAgaWYgKGJEZWNyZWFzZWRRdWFsIHx8IGR3Q3VyUXVhbCA9PSBUaGlzLT5kd0xhc3RRdWFsaXR5KQoJZHdDdXJRdWFsID0gKGR3TWluUXVhbCArIGR3TWF4UXVhbCkgLyAyOwogICAgICBlbHNlCglGSVhNRSgiOiBubyBuZXcgcXVhbGl0eSBjb21wdXRlZCBtaW49JXUgY3VyPSV1IG1heD0ldSBsYXN0PSV1XG4iLAoJICAgICAgZHdNaW5RdWFsLCBkd0N1clF1YWwsIGR3TWF4UXVhbCwgVGhpcy0+ZHdMYXN0UXVhbGl0eSk7CgogICAgICBiRGVjcmVhc2VkUXVhbCA9IFRSVUU7CiAgICB9CiAgfSB3aGlsZSAoVFJVRSk7CgogIC8qIHJlbWVtYmVyIHNvbWUgdmFsdWVzICovCiAgVGhpcy0+ZHdMYXN0UXVhbGl0eSA9IGR3Q3VyUXVhbDsKICBUaGlzLT5kd1VudXNlZEJ5dGVzID0gZHdSZXF1ZXN0IC0gVGhpcy0+bHBiaUN1ci0+YmlTaXplSW1hZ2U7CiAgaWYgKGljbUZsYWdzICYgSUNDT01QUkVTU19LRVlGUkFNRSkKICAgIFRoaXMtPmxMYXN0S2V5ID0gVGhpcy0+bEN1cnJlbnQ7CgogIC8qIERvZXMgd2UgbWFuYWdlIHByZXZpb3VzIGZyYW1lPyAqLwogIGlmIChUaGlzLT5scFByZXYgIT0gTlVMTCAmJiBUaGlzLT5sS2V5RnJhbWVFdmVyeSAhPSAxKQogICAgSUNEZWNvbXByZXNzKFRoaXMtPmhpYywgMCwgVGhpcy0+bHBiaUN1ciwgVGhpcy0+bHBDdXIsCgkJIFRoaXMtPmxwYmlQcmV2LCBUaGlzLT5scFByZXYpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX09wZW5HZXRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIExQQklUTUFQSU5GT0hFQURFUiBscGJpOwogIERXT1JEICAgICAgICAgICAgICBzaXplOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wU3RyZWFtICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wZyA9PSBOVUxMKTsKCiAgVGhpcy0+cGcgPSBBVklTdHJlYW1HZXRGcmFtZU9wZW4oVGhpcy0+cFN0cmVhbSwgTlVMTCk7CiAgaWYgKFRoaXMtPnBnID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICAvKiBXaGVuIHdlIG9ubHkgZGVjb21wcmVzcyB0aGlzIGlzIGVub3VnaCAqLwogIGlmIChUaGlzLT5zSW5mby5mY2NIYW5kbGVyID09IGNvbXB0eXBlRElCKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgYXNzZXJ0KFRoaXMtPmhpYyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+bHBiaU91dHB1dCA9PSBOVUxMKTsKCiAgLyogZ2V0IGlucHV0IGZvcm1hdCAqLwogIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKUFWSVN0cmVhbUdldEZyYW1lKFRoaXMtPnBnLCBUaGlzLT5zSW5mby5kd1N0YXJ0KTsKICBpZiAobHBiaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGdldCBtZW1vcnkgZm9yIG91dHB1dCBmb3JtYXQgKi8KICBzaXplID0gSUNDb21wcmVzc0dldEZvcm1hdFNpemUoVGhpcy0+aGljLCBscGJpKTsKICBpZiAoKExPTkcpc2l6ZSA8IChMT05HKXNpemVvZihCSVRNQVBJTkZPSEVBREVSKSkKICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICBUaGlzLT5scGJpT3V0cHV0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogIGlmIChUaGlzLT5scGJpT3V0cHV0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBUaGlzLT5jYk91dHB1dCA9IHNpemU7CgogIGlmIChJQ0NvbXByZXNzR2V0Rm9ybWF0KFRoaXMtPmhpYywgbHBiaSwgVGhpcy0+bHBiaU91dHB1dCkgPCBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIHVwZGF0ZSBBVklTVFJFQU1JTkZPIHN0cnVjdHVyZSAqLwogIFRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgID0KICAgIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCArIFRoaXMtPmxwYmlPdXRwdXQtPmJpV2lkdGg7CiAgVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gPQogICAgVGhpcy0+c0luZm8ucmNGcmFtZS50b3AgICsgVGhpcy0+bHBiaU91dHB1dC0+YmlIZWlnaHQ7CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0KICAgIElDQ29tcHJlc3NHZXRTaXplKFRoaXMtPmhpYywgbHBiaSwgVGhpcy0+bHBiaU91dHB1dCk7CgogIC8qIHByZXBhcmUgY29kZWMgZm9yIGNvbXByZXNzaW9uICovCiAgaWYgKElDQ29tcHJlc3NCZWdpbihUaGlzLT5oaWMsIGxwYmksIFRoaXMtPmxwYmlPdXRwdXQpICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CgogIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgY3VycmVudCBmcmFtZSAqLwogIHNpemUgKz0gVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogIFRoaXMtPmxwYmlDdXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgaWYgKFRoaXMtPmxwYmlDdXIgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIG1lbWNweShUaGlzLT5scGJpQ3VyLCBUaGlzLT5scGJpT3V0cHV0LCBUaGlzLT5jYk91dHB1dCk7CiAgVGhpcy0+bHBDdXIgPSBESUJQVFIoVGhpcy0+bHBiaUN1cik7CgogIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgbGFzdCBmcmFtZSBpZiBuZWVkZWQgKi8KICBpZiAoVGhpcy0+bEtleUZyYW1lRXZlcnkgIT0gMSAmJgogICAgICAoVGhpcy0+ZHdJQ01GbGFncyAmIFZJRENGX0ZBU1RURU1QT1JBTEMpID09IDApIHsKICAgIHNpemUgPSBJQ0RlY29tcHJlc3NHZXRGb3JtYXRTaXplKFRoaXMtPmhpYywgVGhpcy0+bHBiaU91dHB1dCk7CiAgICBUaGlzLT5scGJpUHJldiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGlmIChUaGlzLT5scGJpUHJldiA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIGlmIChJQ0RlY29tcHJlc3NHZXRGb3JtYXQoVGhpcy0+aGljLCBUaGlzLT5scGJpT3V0cHV0LCBUaGlzLT5scGJpUHJldikgPCBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CgogICAgaWYgKFRoaXMtPmxwYmlQcmV2LT5iaVNpemVJbWFnZSA9PSAwKSB7CiAgICAgIFRoaXMtPmxwYmlQcmV2LT5iaVNpemVJbWFnZSA9CglESUJXSURUSEJZVEVTKCpUaGlzLT5scGJpUHJldikgKiBUaGlzLT5scGJpUHJldi0+YmlIZWlnaHQ7CiAgICB9CgogICAgLyogZ2V0IG1lbW9yeSBmb3IgZm9ybWF0IGFuZCBwaWN0dXJlICovCiAgICBzaXplICs9IFRoaXMtPmxwYmlQcmV2LT5iaVNpemVJbWFnZTsKICAgIFRoaXMtPmxwYmlQcmV2ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBiaVByZXYsIHNpemUgKTsKICAgIGlmIChUaGlzLT5scGJpUHJldiA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmxwUHJldiA9IERJQlBUUihUaGlzLT5scGJpUHJldik7CgogICAgLyogcHJlcGFyZSBjb2RlYyBhbHNvIGZvciBkZWNvbXByZXNzaW9uICovCiAgICBpZiAoSUNEZWNvbXByZXNzQmVnaW4oVGhpcy0+aGljLFRoaXMtPmxwYmlPdXRwdXQsVGhpcy0+bHBiaVByZXYpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0K