LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1zYWNtLmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIEFDTVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIEFDTVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIEFDTVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLExPTkcgKnNhbXB3cml0dGVuLExPTkcgKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGlhY21zdCA9IHsKICBBQ01TdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBBQ01TdHJlYW1fZm5BZGRSZWYsCiAgQUNNU3RyZWFtX2ZuUmVsZWFzZSwKICBBQ01TdHJlYW1fZm5DcmVhdGUsCiAgQUNNU3RyZWFtX2ZuSW5mbywKICBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlLAogIEFDTVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIEFDTVN0cmVhbV9mblJlYWQsCiAgQUNNU3RyZWFtX2ZuV3JpdGUsCiAgQUNNU3RyZWFtX2ZuRGVsZXRlLAogIEFDTVN0cmVhbV9mblJlYWREYXRhLAogIEFDTVN0cmVhbV9mbldyaXRlRGF0YSwKICBBQ01TdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBMT05HCQkgIHJlZjsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIFBBVklTVFJFQU0gICAgICBwU3RyZWFtOwogIEFWSVNUUkVBTUlORk9XICBzSW5mbzsKCiAgSEFDTVNUUkVBTSAgICAgIGhhczsKCiAgTFBXQVZFRk9STUFURVggIGxwSW5Gb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgIGNiSW5Gb3JtYXQ7CgogIExQV0FWRUZPUk1BVEVYICBscE91dEZvcm1hdDsKICBMT05HICAgICAgICAgICAgY2JPdXRGb3JtYXQ7CgogIEFDTVNUUkVBTUhFQURFUiBhY21TdHJlYW1IZHI7Cn0gSUFWSVN0cmVhbUltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoYSkgZG8geyBcCiAgICAgICAgICAgRFdPUkQgX19ieXRlczsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLCooYSkgKiBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbixcCiAgICAgICAgICAgICAgICAgICAgICAgICAmX19ieXRlcywgQUNNX1NUUkVBTVNJWkVGX1NPVVJDRSk7IFwKICAgICAgICAgICAqKGEpID0gX19ieXRlcyAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsgfSB3aGlsZSgwKQoKI2RlZmluZSBDT05WRVJUX1RISVNfdG9fU1RSRUFNKGEpIGRvIHsgXAogICAgICAgICAgIERXT1JEIF9fYnl0ZXM7IFwKICAgICAgICAgICBhY21TdHJlYW1TaXplKFRoaXMtPmhhcywqKGEpICogVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduLFwKICAgICAgICAgICAgICAgICAgICAgICAgICZfX2J5dGVzLCBBQ01fU1RSRUFNU0laRUZfREVTVElOQVRJT04pOyBcCiAgICAgICAgICAgKihhKSA9IF9fYnl0ZXMgLyBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbjsgfSB3aGlsZSgwKQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQUNNU3RyZWFtKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwc3RyZWFtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcHN0cmVhbS0+bHBWdGJsID0gJmlhY21zdDsKCiAgaHIgPSBJQVZJU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKChJQVZJU3RyZWFtKilwc3RyZWFtLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcHN0cmVhbSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgLyogYWxzbyBhZGQgcmVmZXJlbmNlIHRvIHRoZSBuZXN0ZWQgc3RyZWFtICovCiAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkKICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIEFDTVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAocmVmID09IDApIHsKICAgIC8qIGRlc3RydWN0ICovCiAgICBpZiAoVGhpcy0+aGFzICE9IE5VTEwpIHsKICAgICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5mZHdTdGF0dXMgJiBBQ01TVFJFQU1IRUFERVJfU1RBVFVTRl9QUkVQQVJFRCkKCWFjbVN0cmVhbVVucHJlcGFyZUhlYWRlcihUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApOwogICAgICBhY21TdHJlYW1DbG9zZShUaGlzLT5oYXMsIDApOwogICAgICBUaGlzLT5oYXMgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyk7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0KTsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gTlVMTDsKICAgIH0KICAgIGlmIChUaGlzLT5scEluRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBJbkZvcm1hdCk7CiAgICAgIFRoaXMtPmxwSW5Gb3JtYXQgPSBOVUxMOwogICAgICBUaGlzLT5jYkluRm9ybWF0ID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwT3V0Rm9ybWF0KTsKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBOVUxMOwogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKSB7CiAgICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbSA9IE5VTEw7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICByZXR1cm4gMDsKICB9CgogIC8qIGFsc28gcmVsZWFzZSByZWZlcmVuY2UgdG8gdGhlIG5lc3RlZCBzdHJlYW0gKi8KICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKQogICAgSUFWSVN0cmVhbV9SZWxlYXNlKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gcmVmOwp9CgovKiBsUGFyYW0xOiBQQVZJU1RSRUFNCiAqIGxQYXJhbTI6IExQQVZJQ09NUFJFU1NPUFRJT05TIC0tIGV2ZW4gaWYgZG9jJ3Mgc2F5IExQV0FWRUZPUk1BVAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtICppZmFjZSwgTFBBUkFNIGxQYXJhbTEsCgkJCQkJICBMUEFSQU0gbFBhcmFtMikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgaWZhY2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAvKiBjaGVjayBmb3Igc3dhcHBlZCBwYXJhbWV0ZXJzICovCiAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMICYmCiAgICAgICgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMSktPmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CiAgICByZWdpc3RlciBMUEFSQU0gdG1wID0gbFBhcmFtMTsKCiAgICBsUGFyYW0xID0gbFBhcmFtMjsKICAgIGxQYXJhbTIgPSB0bXA7CiAgfQoKICBpZiAoKExQVk9JRClsUGFyYW0xID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBJQVZJU3RyZWFtX0luZm8oKFBBVklTVFJFQU0pbFBhcmFtMSwgJlRoaXMtPnNJbmZvLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBlcnJvciBpbiByZWdpc3RyeSBvciBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbSAqLwoKICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyID0gMDsgLyogYmUgcGFyYW5vaWQgKi8KCiAgLyogRklYTUU6IGNoZWNrIEFDTSB2ZXJzaW9uPyBXaGljaCB2ZXJzaW9uIGRvZXMgd2UgbmVlZD8gKi8KCiAgaWYgKChMUFZPSUQpbFBhcmFtMiAhPSBOVUxMKSB7CiAgICAvKiBXZSBvbmx5IG5lZWQgdGhlIGZvcm1hdCBmcm9tIHRoZSBjb21wcmVzcy1vcHRpb25zICovCiAgICBpZiAoKChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0yKS0+ZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIGxQYXJhbTIgPSAoTFBBUkFNKSgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMiktPmxwRm9ybWF0OwoKICAgIGlmICgoKExQV0FWRUZPUk1BVEVYKWxQYXJhbTIpLT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSBzaXplb2YoV0FWRUZPUk1BVEVYKSArICgoTFBXQVZFRk9STUFURVgpbFBhcmFtMiktPmNiU2l6ZTsKICAgIGVsc2UKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSBzaXplb2YoUENNV0FWRUZPUk1BVCk7CgogICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIG1lbWNweShUaGlzLT5scE91dEZvcm1hdCwgKExQVk9JRClsUGFyYW0yLCBUaGlzLT5jYk91dEZvcm1hdCk7CiAgfSBlbHNlIHsKICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gTlVMTDsKICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gMDsKICB9CgogIFRoaXMtPnBTdHJlYW0gPSAoUEFWSVNUUkVBTSlsUGFyYW0xOwogIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogTmVlZCBjb2RlYyB0byBjb3JyZWN0IHNvbWUgdmFsdWVzIGluIHN0cnVjdHVyZSAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgSFJFU1VMVCBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIG1lbWNweShwc2ksICZUaGlzLT5zSW5mbywgbWluKHNpemUsIChMT05HKXNpemVvZihUaGlzLT5zSW5mbykpKTsKCiAgaWYgKHNpemUgPCAoTE9ORylzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICAvKiBjb252ZXJ0IHBvcyBmcm9tIG91ciAnc3BhY2UnIHRvIFRoaXMtPnBTdHJlYW0ncyBvbmUgKi8KICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZwb3MpOwoKICAvKiBhc2sgc3RyZWFtICovCiAgcG9zID0gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKFRoaXMtPnBTdHJlYW0sIHBvcywgZmxhZ3MpOwoKICBpZiAocG9zICE9IC0xKSB7CiAgICAvKiBjb252ZXJ0IHBvcyBiYWNrIHRvIG91ciAnc3BhY2UnIGlmIGl0J3Mgbm8gc2l6ZSBvciBwaHlzaWNhbCBwb3MgKi8KICAgIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gMCkKICAgICAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUygmcG9zKTsKICB9CgogIHJldHVybiBwb3M7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKFRoaXMtPmhhcyA9PSBOVUxMKSB7CiAgICBIUkVTVUxUIGhyID0gQVZJRklMRV9PcGVuQ29tcHJlc3NvcihUaGlzKTsKCiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KCiAgLyogb25seSBpbnRlcmVzdGVkIGluIG5lZWRlZCBidWZmZXJzaXplPyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAqZm9ybWF0c2l6ZSA8PSAwKSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IChvbmx5IGFzIG11Y2ggYXMgd2lsbCBmaXQpICovCiAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+Y2JPdXRGb3JtYXQpKTsKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5jYk91dEZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYk91dEZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiT3V0Rm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJWxkKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBmb3JtYXRzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBJbnB1dCBmb3JtYXQgYWxyZWFkeSBrbm93bj8KICAgKiBDaGFuZ2luZyBpcyB1bnN1cHBvcnRlZCwgYnV0IGJlIHF1aWV0IGlmIGl0J3MgdGhlIHNhbWUgKi8KICBpZiAoVGhpcy0+bHBJbkZvcm1hdCAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+Y2JJbkZvcm1hdCAhPSBmb3JtYXRzaXplIHx8CgltZW1jbXAoZm9ybWF0LCBUaGlzLT5scEluRm9ybWF0LCBmb3JtYXRzaXplKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBEb2VzIHRoZSBuZXN0ZWQgc3RyZWFtIHN1cHBvcnQgd3JpdGluZz8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+bHBJbkZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmb3JtYXRzaXplKTsKICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgVGhpcy0+Y2JJbkZvcm1hdCA9IGZvcm1hdHNpemU7CiAgbWVtY3B5KFRoaXMtPmxwSW5Gb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGluaXRpYWxpemUgZm9ybWF0cyBhbmQgZ2V0IGNvbXByZXNzb3IgKi8KICBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIENPTlZFUlRfVEhJU190b19TVFJFQU0oJnBvcyk7CgogIC8qIHRlbGwgdGhlIG5lc3RlZCBzdHJlYW0gdGhlIG5ldyBmb3JtYXQgKi8KICByZXR1cm4gSUFWSVN0cmVhbV9TZXRGb3JtYXQoVGhpcy0+cFN0cmVhbSwgcG9zLCBUaGlzLT5scE91dEZvcm1hdCwKCQkJICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEhSRVNVTFQgaHI7CiAgRFdPUkQgICBzaXplOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBEbyB3ZSBoYXZlIG91ciBjb21wcmVzc29yPyAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgaHIgPSBBVklGSUxFX09wZW5Db21wcmVzc29yKFRoaXMpOwoKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICAvKiBvbmx5IG5lZWQgdG8gcGFzcyB0aHJvdWdoPyAqLwogIGlmIChUaGlzLT5jYkluRm9ybWF0ID09IFRoaXMtPmNiT3V0Rm9ybWF0ICYmCiAgICAgIG1lbWNtcChUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCwgVGhpcy0+Y2JJbkZvcm1hdCkgPT0gMCkgewogICAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgICBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKICB9CgogIC8qIHJlYWQgYXMgbXVjaCBhcyBmaXQ/ICovCiAgaWYgKHNhbXBsZXMgPT0gLTEpCiAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKICAvKiBsaW1pdCB0byBidWZmZXJzaXplICovCiAgaWYgKHNhbXBsZXMgKiBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24gPiBidWZmZXJzaXplKQogICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CgogIC8qIG9ubHkgcmV0dXJuIG5lZWRlZCBzaXplPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCB8fCBidWZmZXJzaXplIDw9IDAgfHwgc2FtcGxlcyA9PSAwKSB7CiAgICBpZiAoYnl0ZXNyZWFkID09IE5VTEwgJiYgc2FtcGxlc3JlYWQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzYW1wbGVzICogVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIG1hcCBvdXIgcG9zaXRpb25zIHRvIHBTdHJlYW0gcG9zaXRpb25zICovCiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc3RhcnQpOwoKICAvKiBvdXIgbmVlZGVkIGludGVybmFsIGJ1ZmZlcnNpemUgKi8KICBzaXplID0gc2FtcGxlcyAqIFRoaXMtPmxwSW5Gb3JtYXQtPm5CbG9ja0FsaWduOwoKICAvKiBOZWVkIHRvIGZyZWUgZGVzdGluYXRpb24gYnVmZmVyIHVzZWQgZm9yIHdyaXRpbmc/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QpOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICA9IE5VTEw7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyID0gMDsKICB9CgogIC8qIG5lZWQgYmlnZ2VyIHNvdXJjZSBidWZmZXI/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9PSBOVUxMIHx8CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd1NyY1VzZXIgPCBzaXplKSB7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID09IE5VTEwpCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGVsc2UKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjLCBzaXplKTsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyID0gc2l6ZTsKICB9CgogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlN0cnVjdCA9IHNpemVvZihUaGlzLT5hY21TdHJlYW1IZHIpOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCAgICAgPSBzaXplOwoKICAvKiByZWFkIHNvdXJjZSBkYXRhICovCiAgaHIgPSBJQVZJU3RyZWFtX1JlYWQoVGhpcy0+cFN0cmVhbSwgc3RhcnQsIC0xLCBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMsCgkJICAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCwKCQkgICAgICAgKExPTkcgKikmVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoLCBOVUxMKTsKICBpZiAoRkFJTEVEKGhyKSB8fCBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPT0gMCkKICAgIHJldHVybiBocjsKCiAgLyogbmVlZCB0byBwcmVwYXJlIHN0cmVhbT8gKi8KICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgICAgICAgPSBidWZmZXI7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoID0gYnVmZmVyc2l6ZTsKICBpZiAoKFRoaXMtPmFjbVN0cmVhbUhkci5mZHdTdGF0dXMgJiBBQ01TVFJFQU1IRUFERVJfU1RBVFVTRl9QUkVQQVJFRCkgPT0gMCkgewogICAgaWYgKGFjbVN0cmVhbVByZXBhcmVIZWFkZXIoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKSB7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAgICAgICA9IE5VTEw7CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCA9IDA7CiAgICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICAgIH0KICB9CgogIC8qIG5vdyBkbyB0aGUgY29udmVyc2lvbiAqLwogIC8qIEZJWE1FOiB1c2UgQUNNX0NPTlZFUlRGXyogZmxhZ3MgKi8KICBpZiAoYWNtU3RyZWFtQ29udmVydChUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApICE9IFNfT0spCiAgICBociA9IEFWSUVSUl9DT01QUkVTU09SOwoKICBUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgICAgICAgPSBOVUxMOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCA9IDA7CgogIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQ7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkIC8gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBIUkVTVUxUIGhyOwogIFVMT05HICAgc2l6ZTsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHdlIHdyaXRlIGNhcGFiaWxpdHk/ICovCiAgaWYgKChUaGlzLT5zSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19DQU5XUklURSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGFsc28gbmVlZCBhIGNvbXByZXNzb3IgKi8KICBpZiAoVGhpcy0+aGFzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKCiAgLyogbWFwIG91ciBzaXplcyB0byBwU3RyZWFtIHNpemVzICovCiAgc2l6ZSA9IGJ1ZmZlcnNpemU7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc2l6ZSk7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc3RhcnQpOwoKICAvKiBubyBieXRlcyB0byB3cml0ZT8gLS0gc2hvcnQgY2lyY3VpdCAqLwogIGlmIChzaXplID09IDApIHsKICAgIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sIC0xLCBzYW1wbGVzLCBidWZmZXIsIHNpemUsCgkJCSAgICBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CiAgfQoKICAvKiBOZWVkIHRvIGZyZWUgc291cmNlIGJ1ZmZlciB1c2VkIGZvciByZWFkaW5nPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgIT0gTlVMTCkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjKTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgPSBOVUxMOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3U3JjVXNlciA9IDA7CiAgfQoKICAvKiBOZWVkIGJpZ2dlciBkZXN0aW5hdGlvbiBidWZmZXI/ICovCiAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9PSBOVUxMIHx8CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd0RzdFVzZXIgPCBzaXplKSB7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID09IE5VTEwpCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGVsc2UKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0LCBzaXplKTsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyID0gc2l6ZTsKICB9CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3RydWN0ICAgICAgICA9IHNpemVvZihUaGlzLT5hY21TdHJlYW1IZHIpOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgPSAwOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aCAgICAgPSBUaGlzLT5hY21TdHJlYW1IZHIuZHdEc3RVc2VyOwoKICAvKiBuZWVkIHRvIHByZXBhcmUgc3RyZWFtPyAqLwogIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgICA9IGJ1ZmZlcjsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPSBidWZmZXJzaXplOwogIGlmICgoVGhpcy0+YWNtU3RyZWFtSGRyLmZkd1N0YXR1cyAmIEFDTVNUUkVBTUhFQURFUl9TVEFUVVNGX1BSRVBBUkVEKSA9PSAwKSB7CiAgICBpZiAoYWNtU3RyZWFtUHJlcGFyZUhlYWRlcihUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApICE9IFNfT0spIHsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICAgID0gTlVMTDsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID0gMDsKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgfQogIH0KCiAgLyogbm93IGRvIHRoZSBjb252ZXJzaW9uICovCiAgLyogRklYTUU6IHVzZSBBQ01fQ09OVkVSVEZfKiBmbGFncyAqLwogIGlmIChhY21TdHJlYW1Db252ZXJ0KFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykKICAgIGhyID0gQVZJRVJSX0NPTVBSRVNTT1I7CiAgZWxzZQogICAgaHIgPSBBVklFUlJfT0s7CgogIFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyAgICAgICA9IE5VTEw7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoID0gMDsKCiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sLTEsVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCAvCgkJCSAgVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduLFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCwKCQkJICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkLGZsYWdzLHNhbXB3cml0dGVuLAoJCQkgIGJ5dGVzd3JpdHRlbik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgY2FwYWJpbGl0eSAqLwogIGlmICgoVGhpcy0+c0luZm8uZHdDYXBzICYgQVZJRklMRUNBUFNfQ0FOV1JJVEUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBBIGNvbXByZXNzb3IgaXMgYWxzbyBuZWNlc3NhcnkgKi8KICBpZiAoVGhpcy0+aGFzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKCiAgLyogbWFwIG91ciBwb3NpdGlvbnMgdG8gcFN0cmVhbSBwb3NpdGlvbnMgKi8KICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKCZzdGFydCk7CiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTSgmc2FtcGxlcyk7CgogIHJldHVybiBJQVZJU3RyZWFtX0RlbGV0ZShUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgZmNjLCBscCwgbHByZWFkKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWREYXRhKFRoaXMtPnBTdHJlYW0sIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGx4LCVwLCVsZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlRGF0YShUaGlzLT5wU3RyZWFtLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIEhSRVNVTFQgaHI7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIGlmIChUaGlzLT5oYXMgIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpIHsKICAgIC8qIGRlY29kZSBvciBlbmNvZGUgdGhlIGRhdGEgZnJvbSBwU3RyZWFtICovCiAgICBociA9IEFWSVN0cmVhbUZvcm1hdFNpemUoVGhpcy0+cFN0cmVhbSwgVGhpcy0+c0luZm8uZHdTdGFydCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICAgIFRoaXMtPmxwSW5Gb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBociA9IElBVklTdHJlYW1fUmVhZEZvcm1hdChUaGlzLT5wU3RyZWFtLCBUaGlzLT5zSW5mby5kd1N0YXJ0LAoJCQkgICAgICAgVGhpcy0+bHBJbkZvcm1hdCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKCiAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkgewogICAgICAvKiB3ZSBtdXN0IGRlY29kZSB0byBkZWZhdWx0IGZvcm1hdCAqLwogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IHNpemVvZihQQ01XQVZFRk9STUFUKTsKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogICAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQtPndGb3JtYXRUYWcgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmxwT3V0Rm9ybWF0LAoJCQkgICBUaGlzLT5jYk91dEZvcm1hdCwgQUNNX0ZPUk1BVFNVR0dFU1RGX1dGT1JNQVRUQUcpICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKICAgIH0KICB9IGVsc2UgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBUbyB3aGF0IHNob3VsZCBJIGVuY29kZT8gKi8KCiAgaWYgKGFjbVN0cmVhbU9wZW4oJlRoaXMtPmhhcywgTlVMTCwgVGhpcy0+bHBJbkZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsCgkJICAgIE5VTEwsIDAsIDAsIEFDTV9TVFJFQU1PUEVORl9OT05SRUFMVElNRSkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgKi8KICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICAgID0gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdRdWFsaXR5ICAgID0gKERXT1JEKUlDUVVBTElUWV9ERUZBVUxUOwogIFNldFJlY3RFbXB0eSgmVGhpcy0+c0luZm8ucmNGcmFtZSk7CgogIC8qIGNvbnZlcnQgcG9zaXRpb25zIGFuc2Qgc2l6ZXMgdG8gb3V0cHV0IGZvcm1hdCAqLwogIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoJlRoaXMtPnNJbmZvLmR3U3RhcnQpOwogIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoJlRoaXMtPnNJbmZvLmR3TGVuZ3RoKTsKICBDT05WRVJUX1NUUkVBTV90b19USElTKCZUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==