LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBBQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RydWN0IElBVklTdHJlYW1WdGJsIGlhY21zdCA9IHsKICBBQ01TdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBBQ01TdHJlYW1fZm5BZGRSZWYsCiAgQUNNU3RyZWFtX2ZuUmVsZWFzZSwKICBBQ01TdHJlYW1fZm5DcmVhdGUsCiAgQUNNU3RyZWFtX2ZuSW5mbywKICBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlLAogIEFDTVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIEFDTVN0cmVhbV9mblJlYWQsCiAgQUNNU3RyZWFtX2ZuV3JpdGUsCiAgQUNNU3RyZWFtX2ZuRGVsZXRlLAogIEFDTVN0cmVhbV9mblJlYWREYXRhLAogIEFDTVN0cmVhbV9mbldyaXRlRGF0YSwKICBBQ01TdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBEV09SRAkJICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBQQVZJU1RSRUFNICAgICAgcFN0cmVhbTsKICBBVklTVFJFQU1JTkZPVyAgc0luZm87CgogIEhBQ01TVFJFQU0gICAgICBoYXM7CgogIExQV0FWRUZPUk1BVEVYICBscEluRm9ybWF0OwogIExPTkcgICAgICAgICAgICBjYkluRm9ybWF0OwoKICBMUFdBVkVGT1JNQVRFWCAgbHBPdXRGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgIGNiT3V0Rm9ybWF0OwoKICBBQ01TVFJFQU1IRUFERVIgYWNtU3RyZWFtSGRyOwp9IElBVklTdHJlYW1JbXBsOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBDT05WRVJUX1NUUkVBTV90b19USElTKGEpIHsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLChhKSpUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbixcCiAgICAgICAgICAgICAgICAgICAgICAgICAmKGEpLCBBQ01fU1RSRUFNU0laRUZfU09VUkNFKTsgXAogICAgICAgICAgIChhKSAvPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247IH0KI2RlZmluZSBDT05WRVJUX1RISVNfdG9fU1RSRUFNKGEpIHsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLChhKSpUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24sXAogICAgICAgICAgICAgICAgICAgICAgICAgJihhKSwgQUNNX1NUUkVBTVNJWkVGX0RFU1RJTkFUSU9OKTsgXAogICAgICAgICAgIChhKSAvPSBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbjsgfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQUNNU3RyZWFtKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwc3RyZWFtID0gKElBVklTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcHN0cmVhbS0+bHBWdGJsID0gJmlhY21zdDsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJU3RyZWFtKilwc3RyZWFtLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgTG9jYWxGcmVlKChITE9DQUwpcHN0cmVhbSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgLyogYWxzbyBhZGQgcmVmZXJlbmNlIHRvIHRoZSBuZXN0ZWQgc3RyZWFtICovCiAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkKICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIEFDTVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAocmVmID09IDApIHsKICAgIC8qIGRlc3RydWN0ICovCiAgICBpZiAoVGhpcy0+aGFzICE9IE5VTEwpIHsKICAgICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5mZHdTdGF0dXMgJiBBQ01TVFJFQU1IRUFERVJfU1RBVFVTRl9QUkVQQVJFRCkKCWFjbVN0cmVhbVVucHJlcGFyZUhlYWRlcihUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApOwogICAgICBhY21TdHJlYW1DbG9zZShUaGlzLT5oYXMsIDApOwogICAgICBUaGlzLT5oYXMgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjKTsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID0gTlVMTDsKICAgIH0KICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCk7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBJbkZvcm1hdCk7CiAgICAgIFRoaXMtPmxwSW5Gb3JtYXQgPSBOVUxMOwogICAgICBUaGlzLT5jYkluRm9ybWF0ID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBPdXRGb3JtYXQpOwogICAgICBUaGlzLT5scE91dEZvcm1hdCA9IE5VTEw7CiAgICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5wU3RyZWFtICE9IE5VTEwpIHsKICAgICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW0pOwogICAgICBUaGlzLT5wU3RyZWFtID0gTlVMTDsKICAgIH0KICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMpOwoKICAgIHJldHVybiAwOwogIH0KCiAgLyogYWxzbyByZWxlYXNlIHJlZmVyZW5jZSB0byB0aGUgbmVzdGVkIHN0cmVhbSAqLwogIGlmIChUaGlzLT5wU3RyZWFtICE9IE5VTEwpCiAgICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbSk7CgogIHJldHVybiByZWY7Cn0KCi8qIGxQYXJhbTE6IFBBVklTVFJFQU0KICogbFBhcmFtMjogTFBBVklDT01QUkVTU09QVElPTlMgLS0gZXZlbiBpZiBkb2MncyBzYXkgTFBXQVZFRk9STUFUCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBpZmFjZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogIC8qIGNoZWNrIGZvciBzd2FwcGVkIHBhcmFtZXRlcnMgKi8KICBpZiAoKExQVk9JRClsUGFyYW0xICE9IE5VTEwgJiYKICAgICAgKChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0xKS0+ZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pIHsKICAgIHJlZ2lzdGVyIExQQVJBTSB0bXAgPSBsUGFyYW0xOwoKICAgIGxQYXJhbTEgPSBsUGFyYW0yOwogICAgbFBhcmFtMiA9IHRtcDsKICB9CgogIGlmICgoTFBWT0lEKWxQYXJhbTEgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIElBVklTdHJlYW1fSW5mbygoUEFWSVNUUkVBTSlsUGFyYW0xLCAmVGhpcy0+c0luZm8sIHNpemVvZihUaGlzLT5zSW5mbykpOwogIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIGVycm9yIGluIHJlZ2lzdHJ5IG9yIEFWSU1ha2VDb21wcmVzc2VkU3RyZWFtICovCgogIFRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgPSAwOyAvKiBiZSBwYXJhbm9pZCAqLwoKICAvKiBGSVhNRTogY2hlY2sgQUNNIHZlcnNpb24/IFdoaWNoIHZlcnNpb24gZG9lcyB3ZSBuZWVkPyAqLwoKICBpZiAoKExQVk9JRClsUGFyYW0yICE9IE5VTEwpIHsKICAgIC8qIFdlIG9ubHkgbmVlZCB0aGUgZm9ybWF0IGZyb20gdGhlIGNvbXByZXNzLW9wdGlvbnMgKi8KICAgIGlmICgoKExQQVZJQ09NUFJFU1NPUFRJT05TKWxQYXJhbTIpLT5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgbFBhcmFtMiA9IChMUEFSQU0pKChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0yKS0+bHBGb3JtYXQ7CgogICAgaWYgKCgoTFBXQVZFRk9STUFURVgpbFBhcmFtMiktPndGb3JtYXRUYWcgIT0gV0FWRV9GT1JNQVRfUENNKQogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IHNpemVvZihXQVZFRk9STUFURVgpICsgKChMUFdBVkVGT1JNQVRFWClsUGFyYW0yKS0+Y2JTaXplOwogICAgZWxzZQogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IHNpemVvZihQQ01XQVZFRk9STUFUKTsKCiAgICBUaGlzLT5scE91dEZvcm1hdCA9IChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5jYk91dEZvcm1hdCk7CiAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgbWVtY3B5KFRoaXMtPmxwT3V0Rm9ybWF0LCAoTFBWT0lEKWxQYXJhbTIsIFRoaXMtPmNiT3V0Rm9ybWF0KTsKICB9IGVsc2UgewogICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBOVUxMOwogICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSAwOwogIH0KCiAgVGhpcy0+cFN0cmVhbSA9IChQQVZJU1RSRUFNKWxQYXJhbTE7CiAgSUFWSVN0cmVhbV9BZGRSZWYoVGhpcy0+cFN0cmVhbSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBOZWVkIGNvZGVjIHRvIGNvcnJlY3Qgc29tZSB2YWx1ZXMgaW4gc3RydWN0dXJlICovCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyID0gQVZJRklMRV9PcGVuQ29tcHJlc3NvcihUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnNJbmZvLCBtaW4oc2l6ZSwgKExPTkcpc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoc2l6ZSA8IChMT05HKXNpemVvZihUaGlzLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICBMT05HIGZsYWdzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsMHglMDhsWClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKSB7CiAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZmxhZ3MgJj0gfihGSU5EX0ZST01fU1RBUlR8RklORF9QUkVWKTsKICAgIGZsYWdzIHw9IEZJTkRfTkVYVDsKICB9CgogIC8qIGNvbnZlcnQgcG9zIGZyb20gb3VyICdzcGFjZScgdG8gVGhpcy0+cFN0cmVhbSdzIG9uZSAqLwogIENPTlZFUlRfVEhJU190b19TVFJFQU0ocG9zKTsKCiAgLyogYXNrIHN0cmVhbSAqLwogIHBvcyA9IElBVklTdHJlYW1fRmluZFNhbXBsZShUaGlzLT5wU3RyZWFtLCBwb3MsIGZsYWdzKTsKCiAgaWYgKHBvcyAhPSAtMSkgewogICAgLyogY29udmVydCBwb3MgYmFjayB0byBvdXIgJ3NwYWNlJyBpZiBpdCdzIG5vIHNpemUgb3IgcGh5c2ljYWwgcG9zICovCiAgICBpZiAoKGZsYWdzICYgRklORF9SRVQpID09IDApCiAgICAgIENPTlZFUlRfU1RSRUFNX3RvX1RISVMocG9zKTsKICB9CgogIHJldHVybiBwb3M7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyID0gQVZJRklMRV9PcGVuQ29tcHJlc3NvcihUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgLyogb25seSBpbnRlcmVzdGVkIGluIG5lZWRlZCBidWZmZXJzaXplPyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAqZm9ybWF0c2l6ZSA8PSAwKSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IChvbmx5IGFzIG11Y2ggYXMgd2lsbCBmaXQpICovCiAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+Y2JPdXRGb3JtYXQpKTsKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5jYk91dEZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYk91dEZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBJbnB1dCBmb3JtYXQgYWxyZWFkeSBrbm93bj8KICAgKiBDaGFuZ2luZyBpcyB1bnN1cHBvcnRlZCwgYnV0IGJlIHF1aWV0IGlmIGl0J3MgdGhlIHNhbWUgKi8KICBpZiAoVGhpcy0+bHBJbkZvcm1hdCAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+Y2JJbkZvcm1hdCAhPSBmb3JtYXRzaXplIHx8CgltZW1jbXAoZm9ybWF0LCBUaGlzLT5scEluRm9ybWF0LCBmb3JtYXRzaXplKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBEb2VzIHRoZSBuZXN0ZWQgc3RyZWFtIHN1cHBvcnQgd3JpdGluZz8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+bHBJbkZvcm1hdCA9IChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBmb3JtYXRzaXplKTsKICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgVGhpcy0+Y2JJbkZvcm1hdCA9IGZvcm1hdHNpemU7CiAgbWVtY3B5KFRoaXMtPmxwSW5Gb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGluaXRpYWxpemUgZm9ybWF0cyBhbmQgZ2V0IGNvbXByZXNzb3IgKi8KICBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIENPTlZFUlRfVEhJU190b19TVFJFQU0ocG9zKTsKCiAgLyogdGVsbCB0aGUgbmVzdGVkIHN0cmVhbSB0aGUgbmV3IGZvcm1hdCAqLwogIHJldHVybiBJQVZJU3RyZWFtX1NldEZvcm1hdChUaGlzLT5wU3RyZWFtLCBwb3MsIFRoaXMtPmxwT3V0Rm9ybWF0LAoJCQkgICAgICBUaGlzLT5jYk91dEZvcm1hdCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKICBEV09SRCAgIHNpemU7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKIAlidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CgogIC8qIERvIHdlIGhhdmUgb3VyIGNvbXByZXNzb3I/ICovCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKSB7CiAgICBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIC8qIG9ubHkgbmVlZCB0byBwYXNzIHRocm91Z2g/ICovCiAgaWYgKFRoaXMtPmNiSW5Gb3JtYXQgPT0gVGhpcy0+Y2JPdXRGb3JtYXQgJiYKICAgICAgbWVtY21wKFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmxwT3V0Rm9ybWF0LCBUaGlzLT5jYkluRm9ybWF0KSA9PSAwKSB7CiAgICByZXR1cm4gSUFWSVN0cmVhbV9SZWFkKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsIGJ1ZmZlcnNpemUsCgkJCSAgIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwogIH0KCiAgLyogcmVhZCBhcyBtdWNoIGFzIGZpdD8gKi8KICBpZiAoc2FtcGxlcyA9PSAtMSkKICAgIHNhbXBsZXMgPSBidWZmZXJzaXplIC8gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogIC8qIGxpbWl0IHRvIGJ1ZmZlcnNpemUgKi8KICBpZiAoc2FtcGxlcyAqIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbiA+IGJ1ZmZlcnNpemUpCiAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKCiAgLyogb25seSByZXR1cm4gbmVlZGVkIHNpemU/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMIHx8IGJ1ZmZlcnNpemUgPD0gMCB8fCBzYW1wbGVzID09IDApIHsKICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNhbXBsZXMgKiBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogbWFwIG91ciBwb3NpdGlvbnMgdG8gcFN0cmVhbSBwb3NpdGlvbnMgKi8KICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKHN0YXJ0KTsKCiAgLyogb3VyIG5lZWRlZCBpbnRlcm5hbCBidWZmZXJzaXplICovCiAgc2l6ZSA9IHNhbXBsZXMgKiBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbjsKCiAgLyogTmVlZCB0byBmcmVlIGRlc3RpbmF0aW9uIGJ1ZmZlciB1c2VkIGZvciB3cml0aW5nPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QpOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICA9IE5VTEw7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyID0gMDsKICB9CgogIC8qIG5lZWQgYmlnZ2VyIHNvdXJjZSBidWZmZXI/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9PSBOVUxMIHx8CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd1NyY1VzZXIgPCBzaXplKSB7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID09IE5VTEwpCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIHNpemUpOwogICAgZWxzZQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPSBHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYywKCQkJCQkJICBzaXplLCBHTUVNX01PVkVBQkxFKTsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyID0gc2l6ZTsKICB9CgogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlN0cnVjdCA9IHNpemVvZihUaGlzLT5hY21TdHJlYW1IZHIpOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCAgICAgPSBzaXplOwoKICAvKiByZWFkIHNvdXJjZSBkYXRhICovCiAgaHIgPSBJQVZJU3RyZWFtX1JlYWQoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIC0xLCBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMsCgkJICAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCwKCQkgICAgICAgJlRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCwgTlVMTCk7CiAgaWYgKEZBSUxFRChocikgfHwgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID09IDApCiAgICByZXR1cm4gaHI7CgogIC8qIG5lZWQgdG8gcHJlcGFyZSBzdHJlYW0/ICovCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICAgID0gYnVmZmVyOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCA9IGJ1ZmZlcnNpemU7CiAgaWYgKChUaGlzLT5hY21TdHJlYW1IZHIuZmR3U3RhdHVzICYgQUNNU1RSRUFNSEVBREVSX1NUQVRVU0ZfUFJFUEFSRUQpID09IDApIHsKICAgIGlmIChhY21TdHJlYW1QcmVwYXJlSGVhZGVyKFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykgewogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgICAgICAgPSBOVUxMOwogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGggPSAwOwogICAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgICB9CiAgfQoKICAvKiBub3cgZG8gdGhlIGNvbnZlcnNpb24gKi8KICAvKiBGSVhNRTogdXNlIEFDTV9DT05WRVJURl8qIGZsYWdzICovCiAgaWYgKGFjbVN0cmVhbUNvbnZlcnQoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKQogICAgaHIgPSBBVklFUlJfQ09NUFJFU1NPUjsKCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICAgID0gTlVMTDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGggPSAwOwoKICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0KICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKICBVTE9ORyAgIHNpemU7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB3ZSB3cml0ZSBjYXBhYmlsaXR5PyAqLwogIGlmICgoVGhpcy0+c0luZm8uZHdDYXBzICYgQVZJRklMRUNBUFNfQ0FOV1JJVEUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBhbHNvIG5lZWQgYSBjb21wcmVzc29yICovCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CgogIC8qIG1hcCBvdXIgc2l6ZXMgdG8gcFN0cmVhbSBzaXplcyAqLwogIHNpemUgPSBidWZmZXJzaXplOwogIENPTlZFUlRfVEhJU190b19TVFJFQU0oc2l6ZSk7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTShzdGFydCk7CgogIC8qIG5vIGJ5dGVzIHRvIHdyaXRlPyAtLSBzaG9ydCBjaXJjdWl0ICovCiAgaWYgKHNpemUgPT0gMCkgewogICAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwgLTEsIHNhbXBsZXMsIGJ1ZmZlciwgc2l6ZSwKCQkJICAgIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKICB9CgogIC8qIE5lZWQgdG8gZnJlZSBzb3VyY2UgYnVmZmVyIHVzZWQgZm9yIHJlYWRpbmc/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgICAgID0gTlVMTDsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd1NyY1VzZXIgPSAwOwogIH0KCiAgLyogTmVlZCBiaWdnZXIgZGVzdGluYXRpb24gYnVmZmVyPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPT0gTlVMTCB8fAogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyIDwgc2l6ZSkgewogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9PSBOVUxMKQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBzaXplKTsKICAgIGVsc2UKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QsCgkJCQkJCSAgc2l6ZSwgR01FTV9NT1ZFQUJMRSk7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3RHN0VXNlciA9IHNpemU7CiAgfQogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlN0cnVjdCAgICAgICAgPSBzaXplb2YoVGhpcy0+YWNtU3RyZWFtSGRyKTsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGhVc2VkID0gMDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkID0gMDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGggICAgID0gVGhpcy0+YWNtU3RyZWFtSGRyLmR3RHN0VXNlcjsKCiAgLyogbmVlZCB0byBwcmVwYXJlIHN0cmVhbT8gKi8KICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgICAgICAgPSBidWZmZXI7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID0gYnVmZmVyc2l6ZTsKICBpZiAoKFRoaXMtPmFjbVN0cmVhbUhkci5mZHdTdGF0dXMgJiBBQ01TVFJFQU1IRUFERVJfU1RBVFVTRl9QUkVQQVJFRCkgPT0gMCkgewogICAgaWYgKGFjbVN0cmVhbVByZXBhcmVIZWFkZXIoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKSB7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgICA9IE5VTEw7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCA9IDA7CiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgIH0KICB9CgogIC8qIG5vdyBkbyB0aGUgY29udmVyc2lvbiAqLwogIC8qIEZJWE1FOiB1c2UgQUNNX0NPTlZFUlRGXyogZmxhZ3MgKi8KICBpZiAoYWNtU3RyZWFtQ29udmVydChUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApICE9IFNfT0spCiAgICBociA9IEFWSUVSUl9DT01QUkVTU09SOwogIGVsc2UKICAgIGhyID0gQVZJRVJSX09LOwoKICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgICAgICAgPSBOVUxMOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCA9IDA7CgogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICByZXR1cm4gSUFWSVN0cmVhbV9Xcml0ZShUaGlzLT5wU3RyZWFtLC0xLFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgLwoJCQkgIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbixUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QsCgkJCSAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCxmbGFncyxzYW1wd3JpdHRlbiwKCQkJICBieXRlc3dyaXR0ZW4pOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIGNhcGFiaWxpdHkgKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogQSBjb21wcmVzc29yIGlzIGFsc28gbmVjZXNzYXJ5ICovCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CgogIC8qIG1hcCBvdXIgcG9zaXRpb25zIHRvIHBTdHJlYW0gcG9zaXRpb25zICovCiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTShzdGFydCk7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTShzYW1wbGVzKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fRGVsZXRlKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCBzYW1wbGVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fUmVhZERhdGEoVGhpcy0+cFN0cmVhbSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bHgsJXAsJWxkKVxuIiwgaWZhY2UsIGZjYywgbHAsIHNpemUpOwoKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGVEYXRhKFRoaXMtPnBTdHJlYW0sIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWxkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX09wZW5Db21wcmVzc29yKElBVklTdHJlYW1JbXBsICpUaGlzKQp7CiAgSFJFU1VMVCBocjsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPmhhcyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgPT0gTlVMTCkgewogICAgLyogZGVjb2RlIG9yIGVuY29kZSB0aGUgZGF0YSBmcm9tIHBTdHJlYW0gKi8KICAgIGhyID0gQVZJU3RyZWFtRm9ybWF0U2l6ZShUaGlzLT5wU3RyZWFtLCBUaGlzLT5zSW5mby5kd1N0YXJ0LCAmVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogICAgVGhpcy0+bHBJbkZvcm1hdCA9IChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBUaGlzLT5jYkluRm9ybWF0KTsKICAgIGlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGhyID0gSUFWSVN0cmVhbV9SZWFkRm9ybWF0KFRoaXMtPnBTdHJlYW0sIFRoaXMtPnNJbmZvLmR3U3RhcnQsCgkJCSAgICAgICBUaGlzLT5scEluRm9ybWF0LCAmVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwoKICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCA9PSBOVUxMKSB7CiAgICAgIC8qIHdlIG11c3QgZGVjb2RlIHRvIGRlZmF1bHQgZm9ybWF0ICovCiAgICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpOwogICAgICBUaGlzLT5scE91dEZvcm1hdCA9IChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5jYk91dEZvcm1hdCk7CiAgICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgICBUaGlzLT5scE91dEZvcm1hdC0+d0Zvcm1hdFRhZyA9IFdBVkVfRk9STUFUX1BDTTsKICAgICAgaWYgKGFjbUZvcm1hdFN1Z2dlc3QoTlVMTCwgVGhpcy0+bHBJbkZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsCgkJCSAgIFRoaXMtPmNiT3V0Rm9ybWF0LCBBQ01fRk9STUFUU1VHR0VTVEZfV0ZPUk1BVFRBRykgIT0gU19PSykKCXJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwogICAgfQogIH0gZWxzZSBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIFRvIHdoYXQgc2hvdWxkIEkgZW5jb2RlPyAqLwoKICBpZiAoYWNtU3RyZWFtT3BlbigmVGhpcy0+aGFzLCBOVUxMLCBUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCwKCQkgICAgTlVMTCwgMCwgMCwgQUNNX1NUUkVBTU9QRU5GX05PTlJFQUxUSU1FKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CgogIC8qIHVwZGF0ZSBBVklTVFJFQU1JTkZPIHN0cnVjdHVyZSAqLwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgICAgPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgID0gVGhpcy0+bHBPdXRGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd1F1YWxpdHkgICAgPSAoRFdPUkQpSUNRVUFMSVRZX0RFRkFVTFQ7CiAgU2V0UmVjdEVtcHR5KCZUaGlzLT5zSW5mby5yY0ZyYW1lKTsKCiAgLyogY29udmVydCBwb3NpdGlvbnMgYW5zZCBzaXplcyB0byBvdXRwdXQgZm9ybWF0ICovCiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUyhUaGlzLT5zSW5mby5kd1N0YXJ0KTsKICBDT05WRVJUX1NUUkVBTV90b19USElTKFRoaXMtPnNJbmZvLmR3TGVuZ3RoKTsKICBDT05WRVJUX1NUUkVBTV90b19USElTKFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0K