LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBBQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RydWN0IElBVklTdHJlYW1WdGJsIGlhY21zdCA9IHsKICBBQ01TdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBBQ01TdHJlYW1fZm5BZGRSZWYsCiAgQUNNU3RyZWFtX2ZuUmVsZWFzZSwKICBBQ01TdHJlYW1fZm5DcmVhdGUsCiAgQUNNU3RyZWFtX2ZuSW5mbywKICBBQ01TdHJlYW1fZm5GaW5kU2FtcGxlLAogIEFDTVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIEFDTVN0cmVhbV9mblJlYWQsCiAgQUNNU3RyZWFtX2ZuV3JpdGUsCiAgQUNNU3RyZWFtX2ZuRGVsZXRlLAogIEFDTVN0cmVhbV9mblJlYWREYXRhLAogIEFDTVN0cmVhbV9mbldyaXRlRGF0YSwKICBBQ01TdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBEV09SRAkJICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBQQVZJU1RSRUFNICAgICAgcFN0cmVhbTsKICBBVklTVFJFQU1JTkZPVyAgc0luZm87CgogIEhBQ01TVFJFQU0gICAgICBoYXM7CgogIExQV0FWRUZPUk1BVEVYICBscEluRm9ybWF0OwogIExPTkcgICAgICAgICAgICBjYkluRm9ybWF0OwoKICBMUFdBVkVGT1JNQVRFWCAgbHBPdXRGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgIGNiT3V0Rm9ybWF0OwoKICBBQ01TVFJFQU1IRUFERVIgYWNtU3RyZWFtSGRyOwp9IElBVklTdHJlYW1JbXBsOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBDT05WRVJUX1NUUkVBTV90b19USElTKGEpIHsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLChhKSpUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbixcCiAgICAgICAgICAgICAgICAgICAgICAgICAmKGEpLCBBQ01fU1RSRUFNU0laRUZfU09VUkNFKTsgXAogICAgICAgICAgIChhKSAvPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247IH0KI2RlZmluZSBDT05WRVJUX1RISVNfdG9fU1RSRUFNKGEpIHsgXAogICAgICAgICAgIGFjbVN0cmVhbVNpemUoVGhpcy0+aGFzLChhKSpUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24sXAogICAgICAgICAgICAgICAgICAgICAgICAgJihhKSwgQUNNX1NUUkVBTVNJWkVGX0RFU1RJTkFUSU9OKTsgXAogICAgICAgICAgIChhKSAvPSBUaGlzLT5scEluRm9ybWF0LT5uQmxvY2tBbGlnbjsgfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQUNNU3RyZWFtKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwc3RyZWFtID0gKElBVklTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChwc3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcHN0cmVhbS0+bHBWdGJsID0gJmlhY21zdDsKCiAgaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgoSVVua25vd24qKXBzdHJlYW0sIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBMb2NhbEZyZWUoKEhMT0NBTClwc3RyZWFtKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBBQ01TdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgKyAxKTsKCiAgLyogYWxzbyBhZGQgcmVmZXJlbmNlIHRvIHRoZSBuZXN0ZWQgc3RyZWFtICovCiAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkKICAgIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmIC0gMSk7CgogIGlmIChUaGlzLT5yZWYgPT0gMCkgewogICAgLyogZGVzdHJ1Y3QgKi8KICAgIGlmIChUaGlzLT5oYXMgIT0gTlVMTCkgewogICAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLmZkd1N0YXR1cyAmIEFDTVNUUkVBTUhFQURFUl9TVEFUVVNGX1BSRVBBUkVEKQoJYWNtU3RyZWFtVW5wcmVwYXJlSGVhZGVyKFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCk7CiAgICAgIGFjbVN0cmVhbUNsb3NlKFRoaXMtPmhhcywgMCk7CiAgICAgIFRoaXMtPmhhcyA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMpOwogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0KTsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gTlVMTDsKICAgIH0KICAgIGlmIChUaGlzLT5scEluRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEluRm9ybWF0KTsKICAgICAgVGhpcy0+bHBJbkZvcm1hdCA9IE5VTEw7CiAgICAgIFRoaXMtPmNiSW5Gb3JtYXQgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scE91dEZvcm1hdCk7CiAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkgewogICAgICBJQVZJU3RyZWFtX1JlbGVhc2UoVGhpcy0+cFN0cmVhbSk7CiAgICAgIFRoaXMtPnBTdHJlYW0gPSBOVUxMOwogICAgfQogICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcyk7CgogICAgcmV0dXJuIDA7CiAgfQoKICAvKiBhbHNvIHJlbGVhc2UgcmVmZXJlbmNlIHRvIHRoZSBuZXN0ZWQgc3RyZWFtICovCiAgaWYgKFRoaXMtPnBTdHJlYW0gIT0gTlVMTCkKICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtKTsKCiAgcmV0dXJuIC0tVGhpcy0+cmVmOwp9CgovKiBsUGFyYW0xOiBQQVZJU1RSRUFNCiAqIGxQYXJhbTI6IExQQVZJQ09NUFJFU1NPUFRJT05TIC0tIGV2ZW4gaWYgZG9jJ3Mgc2F5IExQV0FWRUZPUk1BVAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtICppZmFjZSwgTFBBUkFNIGxQYXJhbTEsCgkJCQkJICBMUEFSQU0gbFBhcmFtMikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgaWZhY2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAvKiBjaGVjayBmb3Igc3dhcHBlZCBwYXJhbWV0ZXJzICovCiAgaWYgKChMUFZPSUQpbFBhcmFtMSAhPSBOVUxMICYmCiAgICAgICgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMSktPmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKSB7CiAgICByZWdpc3RlciBMUEFSQU0gdG1wID0gbFBhcmFtMTsKCiAgICBsUGFyYW0xID0gbFBhcmFtMjsKICAgIGxQYXJhbTIgPSB0bXA7CiAgfQoKICBpZiAoKExQVk9JRClsUGFyYW0xID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBJQVZJU3RyZWFtX0luZm8oKFBBVklTVFJFQU0pbFBhcmFtMSwgJlRoaXMtPnNJbmZvLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBlcnJvciBpbiByZWdpc3RyeSBvciBBVklNYWtlQ29tcHJlc3NlZFN0cmVhbSAqLwoKICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyID0gMDsgLyogYmUgcGFyYW5vaWQgKi8KCiAgLyogRklYTUU6IGNoZWNrIEFDTSB2ZXJzaW9uPyBXaGljaCB2ZXJzaW9uIGRvZXMgd2UgbmVlZD8gKi8KCiAgaWYgKChMUFZPSUQpbFBhcmFtMiAhPSBOVUxMKSB7CiAgICAvKiBXZSBvbmx5IG5lZWQgdGhlIGZvcm1hdCBmcm9tIHRoZSBjb21wcmVzcy1vcHRpb25zICovCiAgICBpZiAoKChMUEFWSUNPTVBSRVNTT1BUSU9OUylsUGFyYW0yKS0+ZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIGxQYXJhbTIgPSAoTFBBUkFNKSgoTFBBVklDT01QUkVTU09QVElPTlMpbFBhcmFtMiktPmxwRm9ybWF0OwoKICAgIGlmICgoKExQV0FWRUZPUk1BVEVYKWxQYXJhbTIpLT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSBzaXplb2YoV0FWRUZPUk1BVEVYKSArICgoTFBXQVZFRk9STUFURVgpbFBhcmFtMiktPmNiU2l6ZTsKICAgIGVsc2UKICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQgPSBzaXplb2YoUENNV0FWRUZPUk1BVCk7CgogICAgVGhpcy0+bHBPdXRGb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR0hORCwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIG1lbWNweShUaGlzLT5scE91dEZvcm1hdCwgKExQVk9JRClsUGFyYW0yLCBUaGlzLT5jYk91dEZvcm1hdCk7CiAgfSBlbHNlIHsKICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gTlVMTDsKICAgIFRoaXMtPmNiT3V0Rm9ybWF0ID0gMDsKICB9CgogIFRoaXMtPnBTdHJlYW0gPSAoUEFWSVNUUkVBTSlsUGFyYW0xOwogIElBVklTdHJlYW1fQWRkUmVmKFRoaXMtPnBTdHJlYW0pOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogTmVlZCBjb2RlYyB0byBjb3JyZWN0IHNvbWUgdmFsdWVzIGluIHN0cnVjdHVyZSAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgSFJFU1VMVCBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIG1lbWNweShwc2ksICZUaGlzLT5zSW5mbywgbWluKHNpemUsIChMT05HKXNpemVvZihUaGlzLT5zSW5mbykpKTsKCiAgaWYgKHNpemUgPCAoTE9ORylzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgQUNNU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICAvKiBjb252ZXJ0IHBvcyBmcm9tIG91ciAnc3BhY2UnIHRvIFRoaXMtPnBTdHJlYW0ncyBvbmUgKi8KICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKHBvcyk7CgogIC8qIGFzayBzdHJlYW0gKi8KICBwb3MgPSBJQVZJU3RyZWFtX0ZpbmRTYW1wbGUoVGhpcy0+cFN0cmVhbSwgcG9zLCBmbGFncyk7CgogIGlmIChwb3MgIT0gLTEpIHsKICAgIC8qIGNvbnZlcnQgcG9zIGJhY2sgdG8gb3VyICdzcGFjZScgaWYgaXQncyBubyBzaXplIG9yIHBoeXNpY2FsIHBvcyAqLwogICAgaWYgKChmbGFncyAmIEZJTkRfUkVUKSA9PSAwKQogICAgICBDT05WRVJUX1NUUkVBTV90b19USElTKHBvcyk7CiAgfQoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyAqZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgSFJFU1VMVCBociA9IEFWSUZJTEVfT3BlbkNvbXByZXNzb3IoVGhpcyk7CgogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICB9CgogIC8qIG9ubHkgaW50ZXJlc3RlZCBpbiBuZWVkZWQgYnVmZmVyc2l6ZT8gKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgKmZvcm1hdHNpemUgPD0gMCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYk91dEZvcm1hdDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogY29weSBpbml0aWFsIGZvcm1hdCAob25seSBhcyBtdWNoIGFzIHdpbGwgZml0KSAqLwogIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwT3V0Rm9ybWF0LCBtaW4oKmZvcm1hdHNpemUsIFRoaXMtPmNiT3V0Rm9ybWF0KSk7CiAgaWYgKCpmb3JtYXRzaXplIDwgVGhpcy0+Y2JPdXRGb3JtYXQpIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JPdXRGb3JtYXQ7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYk91dEZvcm1hdDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSW5wdXQgZm9ybWF0IGFscmVhZHkga25vd24/CiAgICogQ2hhbmdpbmcgaXMgdW5zdXBwb3J0ZWQsIGJ1dCBiZSBxdWlldCBpZiBpdCdzIHRoZSBzYW1lICovCiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgIT0gTlVMTCkgewogICAgaWYgKFRoaXMtPmNiSW5Gb3JtYXQgIT0gZm9ybWF0c2l6ZSB8fAoJbWVtY21wKGZvcm1hdCwgVGhpcy0+bHBJbkZvcm1hdCwgZm9ybWF0c2l6ZSkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogRG9lcyB0aGUgbmVzdGVkIHN0cmVhbSBzdXBwb3J0IHdyaXRpbmc/ICovCiAgaWYgKChUaGlzLT5zSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19DQU5XUklURSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmxwSW5Gb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgZm9ybWF0c2l6ZSk7CiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIFRoaXMtPmNiSW5Gb3JtYXQgPSBmb3JtYXRzaXplOwogIG1lbWNweShUaGlzLT5scEluRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBpbml0aWFsaXplIGZvcm1hdHMgYW5kIGdldCBjb21wcmVzc29yICovCiAgaHIgPSBBVklGSUxFX09wZW5Db21wcmVzc29yKFRoaXMpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKHBvcyk7CgogIC8qIHRlbGwgdGhlIG5lc3RlZCBzdHJlYW0gdGhlIG5ldyBmb3JtYXQgKi8KICByZXR1cm4gSUFWSVN0cmVhbV9TZXRGb3JtYXQoVGhpcy0+cFN0cmVhbSwgcG9zLCBUaGlzLT5scE91dEZvcm1hdCwKCQkJICAgICAgVGhpcy0+Y2JPdXRGb3JtYXQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQUNNU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEhSRVNVTFQgaHI7CiAgRFdPUkQgICBzaXplOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBEbyB3ZSBoYXZlIG91ciBjb21wcmVzc29yPyAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkgewogICAgaHIgPSBBVklGSUxFX09wZW5Db21wcmVzc29yKFRoaXMpOwoKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQoKICAvKiBvbmx5IG5lZWQgdG8gcGFzcyB0aHJvdWdoPyAqLwogIGlmIChUaGlzLT5jYkluRm9ybWF0ID09IFRoaXMtPmNiT3V0Rm9ybWF0ICYmCiAgICAgIG1lbWNtcChUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5scE91dEZvcm1hdCwgVGhpcy0+Y2JJbkZvcm1hdCkgPT0gMCkgewogICAgcmV0dXJuIElBVklTdHJlYW1fUmVhZChUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLCBidWZmZXJzaXplLAoJCQkgICBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKICB9CgogIC8qIHJlYWQgYXMgbXVjaCBhcyBmaXQ/ICovCiAgaWYgKHNhbXBsZXMgPT0gLTEpCiAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPmxwT3V0Rm9ybWF0LT5uQmxvY2tBbGlnbjsKICAvKiBsaW1pdCB0byBidWZmZXJzaXplICovCiAgaWYgKHNhbXBsZXMgKiBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24gPiBidWZmZXJzaXplKQogICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CgogIC8qIG9ubHkgcmV0dXJuIG5lZWRlZCBzaXplPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCB8fCBidWZmZXJzaXplIDw9IDAgfHwgc2FtcGxlcyA9PSAwKSB7CiAgICBpZiAoYnl0ZXNyZWFkID09IE5VTEwgJiYgc2FtcGxlc3JlYWQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzYW1wbGVzICogVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIG1hcCBvdXIgcG9zaXRpb25zIHRvIHBTdHJlYW0gcG9zaXRpb25zICovCiAgQ09OVkVSVF9USElTX3RvX1NUUkVBTShzdGFydCk7CgogIC8qIG91ciBuZWVkZWQgaW50ZXJuYWwgYnVmZmVyc2l6ZSAqLwogIHNpemUgPSBzYW1wbGVzICogVGhpcy0+bHBJbkZvcm1hdC0+bkJsb2NrQWxpZ247CgogIC8qIE5lZWQgdG8gZnJlZSBkZXN0aW5hdGlvbiBidWZmZXIgdXNlZCBmb3Igd3JpdGluZz8gKi8KICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0KTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAgICAgPSBOVUxMOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3RHN0VXNlciA9IDA7CiAgfQoKICAvKiBuZWVkIGJpZ2dlciBzb3VyY2UgYnVmZmVyPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPT0gTlVMTCB8fAogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyIDwgc2l6ZSkgewogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYlNyYyA9PSBOVUxMKQogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBzaXplKTsKICAgIGVsc2UKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID0gR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMsCgkJCQkJCSAgc2l6ZSwgR01FTV9NT1ZFQUJMRSk7CiAgICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3U3JjVXNlciA9IHNpemU7CiAgfQoKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTdHJ1Y3QgPSBzaXplb2YoVGhpcy0+YWNtU3RyZWFtSGRyKTsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGhVc2VkID0gMDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkID0gMDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggICAgID0gc2l6ZTsKCiAgLyogcmVhZCBzb3VyY2UgZGF0YSAqLwogIGhyID0gSUFWSVN0cmVhbV9SZWFkKFRoaXMtPnBTdHJlYW0sIHN0YXJ0LCAtMSwgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjLAoJCSAgICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGgsCgkJICAgICAgICZUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGgsIE5VTEwpOwogIGlmIChGQUlMRUQoaHIpIHx8IFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCA9PSAwKQogICAgcmV0dXJuIGhyOwoKICAvKiBuZWVkIHRvIHByZXBhcmUgc3RyZWFtPyAqLwogIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAgICAgICA9IGJ1ZmZlcjsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGggPSBidWZmZXJzaXplOwogIGlmICgoVGhpcy0+YWNtU3RyZWFtSGRyLmZkd1N0YXR1cyAmIEFDTVNUUkVBTUhFQURFUl9TVEFUVVNGX1BSRVBBUkVEKSA9PSAwKSB7CiAgICBpZiAoYWNtU3RyZWFtUHJlcGFyZUhlYWRlcihUaGlzLT5oYXMsICZUaGlzLT5hY21TdHJlYW1IZHIsIDApICE9IFNfT0spIHsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ICAgICAgID0gTlVMTDsKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoID0gMDsKICAgICAgcmV0dXJuIEFWSUVSUl9DT01QUkVTU09SOwogICAgfQogIH0KCiAgLyogbm93IGRvIHRoZSBjb252ZXJzaW9uICovCiAgLyogRklYTUU6IHVzZSBBQ01fQ09OVkVSVEZfKiBmbGFncyAqLwogIGlmIChhY21TdHJlYW1Db252ZXJ0KFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykKICAgIGhyID0gQVZJRVJSX0NPTVBSRVNTT1I7CgogIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCAgICAgICA9IE5VTEw7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoID0gMDsKCiAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9CiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQgLyBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEhSRVNVTFQgaHI7CiAgVUxPTkcgICBzaXplOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugd3JpdGUgY2FwYWJpbGl0eT8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3Q2FwcyAmIEFWSUZJTEVDQVBTX0NBTldSSVRFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogYWxzbyBuZWVkIGEgY29tcHJlc3NvciAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAvKiBtYXAgb3VyIHNpemVzIHRvIHBTdHJlYW0gc2l6ZXMgKi8KICBzaXplID0gYnVmZmVyc2l6ZTsKICBDT05WRVJUX1RISVNfdG9fU1RSRUFNKHNpemUpOwogIENPTlZFUlRfVEhJU190b19TVFJFQU0oc3RhcnQpOwoKICAvKiBubyBieXRlcyB0byB3cml0ZT8gLS0gc2hvcnQgY2lyY3VpdCAqLwogIGlmIChzaXplID09IDApIHsKICAgIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlKFRoaXMtPnBTdHJlYW0sIC0xLCBzYW1wbGVzLCBidWZmZXIsIHNpemUsCgkJCSAgICBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CiAgfQoKICAvKiBOZWVkIHRvIGZyZWUgc291cmNlIGJ1ZmZlciB1c2VkIGZvciByZWFkaW5nPyAqLwogIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMpOwogICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICA9IE5VTEw7CiAgICBUaGlzLT5hY21TdHJlYW1IZHIuZHdTcmNVc2VyID0gMDsKICB9CgogIC8qIE5lZWQgYmlnZ2VyIGRlc3RpbmF0aW9uIGJ1ZmZlcj8gKi8KICBpZiAoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID09IE5VTEwgfHwKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLmR3RHN0VXNlciA8IHNpemUpIHsKICAgIGlmIChUaGlzLT5hY21TdHJlYW1IZHIucGJEc3QgPT0gTlVMTCkKICAgICAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0ID0gR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgc2l6ZSk7CiAgICBlbHNlCiAgICAgIFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9IEdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0LAoJCQkJCQkgIHNpemUsIEdNRU1fTU9WRUFCTEUpOwogICAgaWYgKFRoaXMtPmFjbVN0cmVhbUhkci5wYkRzdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmFjbVN0cmVhbUhkci5kd0RzdFVzZXIgPSBzaXplOwogIH0KICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTdHJ1Y3QgICAgICAgID0gc2l6ZW9mKFRoaXMtPmFjbVN0cmVhbUhkcik7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiU3JjTGVuZ3RoVXNlZCA9IDA7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoVXNlZCA9IDA7CiAgVGhpcy0+YWNtU3RyZWFtSGRyLmNiRHN0TGVuZ3RoICAgICA9IFRoaXMtPmFjbVN0cmVhbUhkci5kd0RzdFVzZXI7CgogIC8qIG5lZWQgdG8gcHJlcGFyZSBzdHJlYW0/ICovCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICAgID0gYnVmZmVyOwogIFRoaXMtPmFjbVN0cmVhbUhkci5jYlNyY0xlbmd0aCA9IGJ1ZmZlcnNpemU7CiAgaWYgKChUaGlzLT5hY21TdHJlYW1IZHIuZmR3U3RhdHVzICYgQUNNU1RSRUFNSEVBREVSX1NUQVRVU0ZfUFJFUEFSRUQpID09IDApIHsKICAgIGlmIChhY21TdHJlYW1QcmVwYXJlSGVhZGVyKFRoaXMtPmhhcywgJlRoaXMtPmFjbVN0cmVhbUhkciwgMCkgIT0gU19PSykgewogICAgICBUaGlzLT5hY21TdHJlYW1IZHIucGJTcmMgICAgICAgPSBOVUxMOwogICAgICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPSAwOwogICAgICByZXR1cm4gQVZJRVJSX0NPTVBSRVNTT1I7CiAgICB9CiAgfQoKICAvKiBub3cgZG8gdGhlIGNvbnZlcnNpb24gKi8KICAvKiBGSVhNRTogdXNlIEFDTV9DT05WRVJURl8qIGZsYWdzICovCiAgaWYgKGFjbVN0cmVhbUNvbnZlcnQoVGhpcy0+aGFzLCAmVGhpcy0+YWNtU3RyZWFtSGRyLCAwKSAhPSBTX09LKQogICAgaHIgPSBBVklFUlJfQ09NUFJFU1NPUjsKICBlbHNlCiAgICBociA9IEFWSUVSUl9PSzsKCiAgVGhpcy0+YWNtU3RyZWFtSGRyLnBiU3JjICAgICAgID0gTlVMTDsKICBUaGlzLT5hY21TdHJlYW1IZHIuY2JTcmNMZW5ndGggPSAwOwoKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgcmV0dXJuIElBVklTdHJlYW1fV3JpdGUoVGhpcy0+cFN0cmVhbSwtMSxUaGlzLT5hY21TdHJlYW1IZHIuY2JEc3RMZW5ndGhVc2VkIC8KCQkJICBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ24sVGhpcy0+YWNtU3RyZWFtSGRyLnBiRHN0LAoJCQkgIFRoaXMtPmFjbVN0cmVhbUhkci5jYkRzdExlbmd0aFVzZWQsZmxhZ3Msc2FtcHdyaXR0ZW4sCgkJCSAgYnl0ZXN3cml0dGVuKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLCVsZClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3RhcnQgPCAwIHx8IHNhbXBsZXMgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRGVsZXRlIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBEZWxldGUgYWZ0ZXIgZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKXN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBGb3IgdGhlIHJlc3Qgd2UgbmVlZCB3cml0ZSBjYXBhYmlsaXR5ICovCiAgaWYgKChUaGlzLT5zSW5mby5kd0NhcHMgJiBBVklGSUxFQ0FQU19DQU5XUklURSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIEEgY29tcHJlc3NvciBpcyBhbHNvIG5lY2Vzc2FyeSAqLwogIGlmIChUaGlzLT5oYXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAvKiBtYXAgb3VyIHBvc2l0aW9ucyB0byBwU3RyZWFtIHBvc2l0aW9ucyAqLwogIENPTlZFUlRfVEhJU190b19TVFJFQU0oc3RhcnQpOwogIENPTlZFUlRfVEhJU190b19TVFJFQU0oc2FtcGxlcyk7CgogIHJldHVybiBJQVZJU3RyZWFtX0RlbGV0ZShUaGlzLT5wU3RyZWFtLCBzdGFydCwgc2FtcGxlcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgZmNjLCBscCwgbHByZWFkKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1JlYWREYXRhKFRoaXMtPnBTdHJlYW0sIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBBQ01TdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGx4LCVwLCVsZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIHJldHVybiBJQVZJU3RyZWFtX1dyaXRlRGF0YShUaGlzLT5wU3RyZWFtLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIEFDTVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9PcGVuQ29tcHJlc3NvcihJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIEhSRVNVTFQgaHI7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBTdHJlYW0gIT0gTlVMTCk7CgogIGlmIChUaGlzLT5oYXMgIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpIHsKICAgIC8qIGRlY29kZSBvciBlbmNvZGUgdGhlIGRhdGEgZnJvbSBwU3RyZWFtICovCiAgICBociA9IEFWSVN0cmVhbUZvcm1hdFNpemUoVGhpcy0+cFN0cmVhbSwgVGhpcy0+c0luZm8uZHdTdGFydCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKICAgIFRoaXMtPmxwSW5Gb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBociA9IElBVklTdHJlYW1fUmVhZEZvcm1hdChUaGlzLT5wU3RyZWFtLCBUaGlzLT5zSW5mby5kd1N0YXJ0LAoJCQkgICAgICAgVGhpcy0+bHBJbkZvcm1hdCwgJlRoaXMtPmNiSW5Gb3JtYXQpOwogICAgaWYgKEZBSUxFRChocikpCiAgICAgIHJldHVybiBocjsKCiAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkgewogICAgICAvKiB3ZSBtdXN0IGRlY29kZSB0byBkZWZhdWx0IGZvcm1hdCAqLwogICAgICBUaGlzLT5jYk91dEZvcm1hdCA9IHNpemVvZihQQ01XQVZFRk9STUFUKTsKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR0hORCwgVGhpcy0+Y2JPdXRGb3JtYXQpOwogICAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQtPndGb3JtYXRUYWcgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmxwT3V0Rm9ybWF0LAoJCQkgICBUaGlzLT5jYk91dEZvcm1hdCwgQUNNX0ZPUk1BVFNVR0dFU1RGX1dGT1JNQVRUQUcpICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX05PQ09NUFJFU1NPUjsKICAgIH0KICB9IGVsc2UgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBUbyB3aGF0IHNob3VsZCBJIGVuY29kZT8gKi8KCiAgaWYgKGFjbVN0cmVhbU9wZW4oJlRoaXMtPmhhcywgTlVMTCwgVGhpcy0+bHBJbkZvcm1hdCwgVGhpcy0+bHBPdXRGb3JtYXQsCgkJICAgIE5VTEwsIDAsIDAsIEFDTV9TVFJFQU1PUEVORl9OT05SRUFMVElNRSkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfTk9DT01QUkVTU09SOwoKICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgKi8KICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSBUaGlzLT5scE91dEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICAgID0gVGhpcy0+bHBPdXRGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdRdWFsaXR5ICAgID0gKERXT1JEKUlDUVVBTElUWV9ERUZBVUxUOwogIFNldFJlY3RFbXB0eSgmVGhpcy0+c0luZm8ucmNGcmFtZSk7CgogIC8qIGNvbnZlcnQgcG9zaXRpb25zIGFuc2Qgc2l6ZXMgdG8gb3V0cHV0IGZvcm1hdCAqLwogIENPTlZFUlRfU1RSRUFNX3RvX1RISVMoVGhpcy0+c0luZm8uZHdTdGFydCk7CiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUyhUaGlzLT5zSW5mby5kd0xlbmd0aCk7CiAgQ09OVkVSVF9TVFJFQU1fdG9fVEhJUyhUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==