LyoKICogUlBDIHRyYW5zcG9ydCBsYXllcgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKiBDb3B5cmlnaHQgMjAwMyBNaWtlIEhlYXJuCiAqIENvcHlyaWdodCAyMDA0IEZpbGlwIE5hdmFyYQogKiBDb3B5cmlnaHQgMjAwNiBNaWtlIE1jQ29ybWFjawogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmZGVmIEhBVkVfU1lTX1RZUEVTCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1NZU19TT0NLRVRfSAojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfTkVUSU5FVF9JTl9ICiNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9BUlBBX0lORVRfSAojaW5jbHVkZSA8YXJwYS9pbmV0Lmg+CiNlbmRpZgojaWZkZWYgSEFWRV9ORVREQl9ICiNpbmNsdWRlIDxuZXRkYi5oPgojZW5kaWYKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInJwY19iaW5kaW5nLmgiCiNpbmNsdWRlICJycGNfbWVzc2FnZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCi8qKioqIG5jYWNuX25wIHN1cHBvcnQgKioqKi8KCnR5cGVkZWYgc3RydWN0IF9ScGNDb25uZWN0aW9uX25wCnsKICBScGNDb25uZWN0aW9uIGNvbW1vbjsKICBIQU5ETEUgcGlwZSwgdGhyZWFkOwogIE9WRVJMQVBQRUQgb3ZsOwp9IFJwY0Nvbm5lY3Rpb25fbnA7CgpzdGF0aWMgUnBjQ29ubmVjdGlvbiAqcnBjcnQ0X2Nvbm5fbnBfYWxsb2Modm9pZCkKewogIHJldHVybiBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0Nvbm5lY3Rpb25fbnApKTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X2Nvbm5lY3RfcGlwZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLCBMUENTVFIgcG5hbWUpCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIFRSQUNFKCJsaXN0ZW5pbmcgb24gJXNcbiIsIHBuYW1lKTsKCiAgbnBjLT5waXBlID0gQ3JlYXRlTmFtZWRQaXBlQShwbmFtZSwgUElQRV9BQ0NFU1NfRFVQTEVYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElQRV9UWVBFX01FU1NBR0UgfCBQSVBFX1JFQURNT0RFX01FU1NBR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLCBSUENfTUFYX1BBQ0tFVF9TSVpFLCA1MDAwLCBOVUxMKTsKICBtZW1zZXQoJm5wYy0+b3ZsLCAwLCBzaXplb2YobnBjLT5vdmwpKTsKICBucGMtPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogIGlmIChDb25uZWN0TmFtZWRQaXBlKG5wYy0+cGlwZSwgJm5wYy0+b3ZsKSkKICAgICByZXR1cm4gUlBDX1NfT0s7CgogIFdBUk4oIkNvdWxkbid0IENvbm5lY3ROYW1lZFBpcGUgKGVycm9yIHdhcyAlbGQpXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgaWYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX1BJUEVfQ09OTkVDVEVEKSB7CiAgICBTZXRFdmVudChucGMtPm92bC5oRXZlbnQpOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KICBpZiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfSU9fUEVORElORykgewogICAgLyogRklYTUU6IGxvb2tzIGxpa2Ugd2UgbmVlZCB0byBHZXRPdmVybGFwcGVkUmVzdWx0IGhlcmU/ICovCiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQogIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9vcGVuX3BpcGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgTFBDU1RSIHBuYW1lLCBCT09MIHdhaXQpCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIEhBTkRMRSBwaXBlOwogIERXT1JEIGVyciwgZHdNb2RlOwoKICBUUkFDRSgiY29ubmVjdGluZyB0byAlc1xuIiwgcG5hbWUpOwoKICB3aGlsZSAoVFJVRSkgewogICAgcGlwZSA9IENyZWF0ZUZpbGVBKHBuYW1lLCBHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURSwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICBPUEVOX0VYSVNUSU5HLCAwLCAwKTsKICAgIGlmIChwaXBlICE9IElOVkFMSURfSEFORExFX1ZBTFVFKSBicmVhazsKICAgIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0JVU1kpIHsKICAgICAgVFJBQ0UoImNvbm5lY3Rpb24gZmFpbGVkLCBlcnJvcj0lbHhcbiIsIGVycik7CiAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVE9PX0JVU1k7CiAgICB9CiAgICBpZiAoIXdhaXQpCiAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICBpZiAoIVdhaXROYW1lZFBpcGVBKHBuYW1lLCBOTVBXQUlUX1dBSVRfRk9SRVZFUikpIHsKICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgIFdBUk4oImNvbm5lY3Rpb24gZmFpbGVkLCBlcnJvcj0lbHhcbiIsIGVycik7CiAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICB9CiAgfQoKICAvKiBzdWNjZXNzICovCiAgbWVtc2V0KCZucGMtPm92bCwgMCwgc2l6ZW9mKG5wYy0+b3ZsKSk7CiAgLyogcGlwZSBpcyBjb25uZWN0ZWQ7IGNoYW5nZSB0byBtZXNzYWdlLXJlYWQgbW9kZS4gKi8KICBkd01vZGUgPSBQSVBFX1JFQURNT0RFX01FU1NBR0U7CiAgU2V0TmFtZWRQaXBlSGFuZGxlU3RhdGUocGlwZSwgJmR3TW9kZSwgTlVMTCwgTlVMTCk7CiAgbnBjLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICBucGMtPnBpcGUgPSBwaXBlOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9uY2FscnBjX29wZW4oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC5cXHBpcGVcXGxycGNcXCI7CiAgUlBDX1NUQVRVUyByOwogIExQU1RSIHBuYW1lOwoKICAvKiBhbHJlYWR5IGNvbm5lY3RlZD8gKi8KICBpZiAobnBjLT5waXBlKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICAvKiBwcm90c2VxPW5jYWxycGM6IHN1cHBvc2VkIHRvIHVzZSBOVCBMUEMgcG9ydHMsCiAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CgogIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpCiAgICByID0gcnBjcnQ0X2Nvbm5lY3RfcGlwZShDb25uZWN0aW9uLCBwbmFtZSk7CiAgZWxzZQogICAgciA9IHJwY3J0NF9vcGVuX3BpcGUoQ29ubmVjdGlvbiwgcG5hbWUsIFRSVUUpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKCiAgcmV0dXJuIHI7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9uY2Fjbl9ucF9vcGVuKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIHN0YXRpYyBMUENTVFIgcHJlZml4ID0gIlxcXFwuIjsKICBSUENfU1RBVFVTIHI7CiAgTFBTVFIgcG5hbWU7CgogIC8qIGFscmVhZHkgY29ubmVjdGVkPyAqLwogIGlmIChucGMtPnBpcGUpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIC8qIHByb3RzZXE9bmNhY25fbnA6IG5hbWVkIHBpcGVzICovCiAgcG5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpCiAgICByID0gcnBjcnQ0X2Nvbm5lY3RfcGlwZShDb25uZWN0aW9uLCBwbmFtZSk7CiAgZWxzZQogICAgciA9IHJwY3J0NF9vcGVuX3BpcGUoQ29ubmVjdGlvbiwgcG5hbWUsIEZBTFNFKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CgogIHJldHVybiByOwp9CgpzdGF0aWMgSEFORExFIHJwY3J0NF9jb25uX25wX2dldF9jb25uZWN0X2V2ZW50KFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIHJldHVybiBucGMtPm92bC5oRXZlbnQ7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9jb25uX25wX2hhbmRvZmYoUnBjQ29ubmVjdGlvbiAqb2xkX2Nvbm4sIFJwY0Nvbm5lY3Rpb24gKm5ld19jb25uKQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqb2xkX25wYyA9IChScGNDb25uZWN0aW9uX25wICopIG9sZF9jb25uOwogIFJwY0Nvbm5lY3Rpb25fbnAgKm5ld19ucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBuZXdfY29ubjsKICAvKiBiZWNhdXNlIG9mIHRoZSB3YXkgbmFtZWQgcGlwZXMgd29yaywgd2UnbGwgdHJhbnNmZXIgdGhlIGNvbm5lY3RlZCBwaXBlCiAgICogdG8gdGhlIGNoaWxkLCB0aGVuIHJlb3BlbiB0aGUgc2VydmVyIGJpbmRpbmcgdG8gY29udGludWUgbGlzdGVuaW5nICovCgogIG5ld19ucGMtPnBpcGUgPSBvbGRfbnBjLT5waXBlOwogIG5ld19ucGMtPm92bCA9IG9sZF9ucGMtPm92bDsKICBvbGRfbnBjLT5waXBlID0gMDsKICBtZW1zZXQoJm9sZF9ucGMtPm92bCwgMCwgc2l6ZW9mKG9sZF9ucGMtPm92bCkpOwogIHJldHVybiBSUENSVDRfT3BlbkNvbm5lY3Rpb24ob2xkX2Nvbm4pOwp9CgpzdGF0aWMgaW50IHJwY3J0NF9jb25uX25wX3JlYWQoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBpbnQgY291bnQpCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIERXT1JEIGR3UmVhZCA9IDA7CiAgaWYgKCFSZWFkRmlsZShucGMtPnBpcGUsIGJ1ZmZlciwgY291bnQsICZkd1JlYWQsIE5VTEwpICYmCiAgICAgIChHZXRMYXN0RXJyb3IoKSAhPSBFUlJPUl9NT1JFX0RBVEEpKQogICAgcmV0dXJuIC0xOwogIHJldHVybiBkd1JlYWQ7Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fbnBfd3JpdGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBjb3VudCkKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgRFdPUkQgZHdXcml0dGVuID0gMDsKICBpZiAoIVdyaXRlRmlsZShucGMtPnBpcGUsIGJ1ZmZlciwgY291bnQsICZkd1dyaXR0ZW4sIE5VTEwpKQogICAgcmV0dXJuIC0xOwogIHJldHVybiBkd1dyaXR0ZW47Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fbnBfY2xvc2UoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgaWYgKG5wYy0+cGlwZSkgewogICAgRmx1c2hGaWxlQnVmZmVycyhucGMtPnBpcGUpOwogICAgQ2xvc2VIYW5kbGUobnBjLT5waXBlKTsKICAgIG5wYy0+cGlwZSA9IDA7CiAgfQogIGlmIChucGMtPm92bC5oRXZlbnQpIHsKICAgIENsb3NlSGFuZGxlKG5wYy0+b3ZsLmhFdmVudCk7CiAgICBucGMtPm92bC5oRXZlbnQgPSAwOwogIH0KICByZXR1cm4gMDsKfQoKLyoqKiogbmNhY25faXBfdGNwIHN1cHBvcnQgKioqKi8KCnR5cGVkZWYgc3RydWN0IF9ScGNDb25uZWN0aW9uX3RjcAp7CiAgUnBjQ29ubmVjdGlvbiBjb21tb247CiAgaW50IHNvY2s7Cn0gUnBjQ29ubmVjdGlvbl90Y3A7CgpzdGF0aWMgUnBjQ29ubmVjdGlvbiAqcnBjcnQ0X2Nvbm5fdGNwX2FsbG9jKHZvaWQpCnsKICBScGNDb25uZWN0aW9uX3RjcCAqdGNwYzsKICB0Y3BjID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihScGNDb25uZWN0aW9uX3RjcCkpOwogIHRjcGMtPnNvY2sgPSAtMTsKICByZXR1cm4gJnRjcGMtPmNvbW1vbjsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWNuX2lwX3RjcF9vcGVuKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBScGNDb25uZWN0aW9uX3RjcCAqdGNwYyA9IChScGNDb25uZWN0aW9uX3RjcCAqKSBDb25uZWN0aW9uOwogIGludCBzb2NrOwogIGludCByZXQ7CiAgc3RydWN0IGFkZHJpbmZvICphaTsKICBzdHJ1Y3QgYWRkcmluZm8gKmFpX2N1cjsKICBzdHJ1Y3QgYWRkcmluZm8gaGludHM7CgogIFRSQUNFKCIoJXMsICVzKVxuIiwgQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKCiAgaWYgKENvbm5lY3Rpb24tPnNlcnZlcikKICB7CiAgICBFUlIoIm5jYWNuX2lwX3RjcCBzZXJ2ZXJzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgfQoKICBpZiAodGNwYy0+c29jayAhPSAtMSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgaGludHMuYWlfZmxhZ3MgICAgICAgICAgPSAwOwogIGhpbnRzLmFpX2ZhbWlseSAgICAgICAgID0gUEZfVU5TUEVDOwogIGhpbnRzLmFpX3NvY2t0eXBlICAgICAgID0gU09DS19TVFJFQU07CiAgaGludHMuYWlfcHJvdG9jb2wgICAgICAgPSBJUFBST1RPX1RDUDsKICBoaW50cy5haV9hZGRybGVuICAgICAgICA9IDA7CiAgaGludHMuYWlfYWRkciAgICAgICAgICAgPSBOVUxMOwogIGhpbnRzLmFpX2Nhbm9ubmFtZSAgICAgID0gTlVMTDsKICBoaW50cy5haV9uZXh0ICAgICAgICAgICA9IE5VTEw7CgogIHJldCA9IGdldGFkZHJpbmZvKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLCBDb25uZWN0aW9uLT5FbmRwb2ludCwgJmhpbnRzLCAmYWkpOwogIGlmIChyZXQgPCAwKQogIHsKICAgIEVSUigiZ2V0YWRkcmluZm8gZmFpbGVkIHdpdGggJWRcbiIsIHJldCk7CiAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogIH0KCiAgZm9yIChhaV9jdXIgPSBhaTsgYWlfY3VyOyBhaV9jdXIgPSBhaS0+YWlfbmV4dCkKICB7CiAgICBpZiAoVFJBQ0VfT04ocnBjKSkKICAgIHsKICAgICAgY2hhciBob3N0WzI1Nl07CiAgICAgIGNoYXIgc2VydmljZVsyNTZdOwogICAgICBnZXRuYW1laW5mbyhhaV9jdXItPmFpX2FkZHIsIGFpX2N1ci0+YWlfYWRkcmxlbiwKICAgICAgICBob3N0LCBzaXplb2YoaG9zdCksIHNlcnZpY2UsIHNpemVvZihzZXJ2aWNlKSwKICAgICAgICBOSV9OVU1FUklDSE9TVCB8IE5JX05VTUVSSUNTRVJWKTsKICAgICAgVFJBQ0UoInRyeWluZyAlczolc1xuIiwgaG9zdCwgc2VydmljZSk7CiAgICB9CgogICAgc29jayA9IHNvY2tldChhaV9jdXItPmFpX2ZhbWlseSwgYWlfY3VyLT5haV9zb2NrdHlwZSwgYWlfY3VyLT5haV9wcm90b2NvbCk7CiAgICBpZiAoc29jayA8IDApCiAgICB7CiAgICAgIFdBUk4oInNvY2tldCgpIGZhaWxlZFxuIik7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIGlmICgwPmNvbm5lY3Qoc29jaywgYWlfY3VyLT5haV9hZGRyLCBhaV9jdXItPmFpX2FkZHJsZW4pKQogICAgewogICAgICBXQVJOKCJjb25uZWN0KCkgZmFpbGVkXG4iKTsKICAgICAgY2xvc2Uoc29jayk7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIHRjcGMtPnNvY2sgPSBzb2NrOwoKICAgIGZyZWVhZGRyaW5mbyhhaSk7CiAgICBUUkFDRSgiY29ubmVjdGVkXG4iKTsKICAgIHJldHVybiBSUENfU19PSzsKICB9CgogIGZyZWVhZGRyaW5mbyhhaSk7CiAgRVJSKCJjb3VsZG4ndCBjb25uZWN0IHRvICVzOiVzXG4iLCBDb25uZWN0aW9uLT5OZXR3b3JrQWRkciwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7Cn0KCnN0YXRpYyBIQU5ETEUgcnBjcnQ0X2Nvbm5fdGNwX2dldF93YWl0X2hhbmRsZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uKQp7CiAgYXNzZXJ0KDApOwogIHJldHVybiAwOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfY29ubl90Y3BfaGFuZG9mZihScGNDb25uZWN0aW9uICpvbGRfY29ubiwgUnBjQ29ubmVjdGlvbiAqbmV3X2Nvbm4pCnsKICBhc3NlcnQoMCk7CiAgcmV0dXJuIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl90Y3BfcmVhZChScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGNvdW50KQp7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnRjcGMgPSAoUnBjQ29ubmVjdGlvbl90Y3AgKikgQ29ubmVjdGlvbjsKICBpbnQgciA9IHJlYWQodGNwYy0+c29jaywgYnVmZmVyLCBjb3VudCk7CiAgVFJBQ0UoIiVkICVwICV1IC0+ICVkXG4iLCB0Y3BjLT5zb2NrLCBidWZmZXIsIGNvdW50LCByKTsKICByZXR1cm4gcjsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl90Y3Bfd3JpdGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqYnVmZmVyLCB1bnNpZ25lZCBpbnQgY291bnQpCnsKICBScGNDb25uZWN0aW9uX3RjcCAqdGNwYyA9IChScGNDb25uZWN0aW9uX3RjcCAqKSBDb25uZWN0aW9uOwogIGludCByID0gd3JpdGUodGNwYy0+c29jaywgYnVmZmVyLCBjb3VudCk7CiAgVFJBQ0UoIiVkICVwICV1IC0+ICVkXG4iLCB0Y3BjLT5zb2NrLCBidWZmZXIsIGNvdW50LCByKTsKICByZXR1cm4gcjsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl90Y3BfY2xvc2UoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fdGNwICp0Y3BjID0gKFJwY0Nvbm5lY3Rpb25fdGNwICopIENvbm5lY3Rpb247CgogIFRSQUNFKCIlZFxuIiwgdGNwYy0+c29jayk7CiAgaWYgKHRjcGMtPnNvY2sgIT0gLTEpCiAgICBjbG9zZSh0Y3BjLT5zb2NrKTsKICB0Y3BjLT5zb2NrID0gLTE7CiAgcmV0dXJuIDA7Cn0KCnN0cnVjdCBwcm90c2VxX29wcyBwcm90c2VxX2xpc3RbXSA9IHsKICB7ICJuY2Fjbl9ucCIsCiAgICBycGNydDRfY29ubl9ucF9hbGxvYywKICAgIHJwY3J0NF9uY2FscnBjX29wZW4sCiAgICBycGNydDRfY29ubl9ucF9nZXRfY29ubmVjdF9ldmVudCwKICAgIHJwY3J0NF9jb25uX25wX2hhbmRvZmYsCiAgICBycGNydDRfY29ubl9ucF9yZWFkLAogICAgcnBjcnQ0X2Nvbm5fbnBfd3JpdGUsCiAgICBycGNydDRfY29ubl9ucF9jbG9zZSwKICB9LAogIHsgIm5jYWxycGMiLAogICAgcnBjcnQ0X2Nvbm5fbnBfYWxsb2MsCiAgICBycGNydDRfbmNhY25fbnBfb3BlbiwKICAgIHJwY3J0NF9jb25uX25wX2dldF9jb25uZWN0X2V2ZW50LAogICAgcnBjcnQ0X2Nvbm5fbnBfaGFuZG9mZiwKICAgIHJwY3J0NF9jb25uX25wX3JlYWQsCiAgICBycGNydDRfY29ubl9ucF93cml0ZSwKICAgIHJwY3J0NF9jb25uX25wX2Nsb3NlLAogIH0sCiAgeyAibmNhY25faXBfdGNwIiwKICAgIHJwY3J0NF9jb25uX3RjcF9hbGxvYywKICAgIHJwY3J0NF9uY2Fjbl9pcF90Y3Bfb3BlbiwKICAgIHJwY3J0NF9jb25uX3RjcF9nZXRfd2FpdF9oYW5kbGUsCiAgICBycGNydDRfY29ubl90Y3BfaGFuZG9mZiwKICAgIHJwY3J0NF9jb25uX3RjcF9yZWFkLAogICAgcnBjcnQ0X2Nvbm5fdGNwX3dyaXRlLAogICAgcnBjcnQ0X2Nvbm5fdGNwX2Nsb3NlLAogIH0KfTsKCiNkZWZpbmUgTUFYX1BST1RTRVEgKHNpemVvZiBwcm90c2VxX2xpc3QgLyBzaXplb2YgcHJvdHNlcV9saXN0WzBdKQoKc3RhdGljIHN0cnVjdCBwcm90c2VxX29wcyAqcnBjcnQ0X2dldF9wcm90c2VxX29wcyhjb25zdCBjaGFyICpwcm90c2VxKQp7CiAgaW50IGk7CiAgZm9yKGk9MDsgaTxNQVhfUFJPVFNFUTsgaSsrKQogICAgaWYgKCFzdHJjbXAocHJvdHNlcV9saXN0W2ldLm5hbWUsIHByb3RzZXEpKQogICAgICByZXR1cm4gJnByb3RzZXFfbGlzdFtpXTsKICByZXR1cm4gTlVMTDsKfQoKLyoqKiogaW50ZXJmYWNlIHRvIHJlc3Qgb2YgY29kZSAqKioqLwoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKCiAgcmV0dXJuIENvbm5lY3Rpb24tPm9wcy0+b3Blbl9jb25uZWN0aW9uKENvbm5lY3Rpb24pOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBycGNydDRfY29ubl9jbG9zZShDb25uZWN0aW9uKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIEJPT0wgc2VydmVyLCBMUENTVFIgUHJvdHNlcSwgTFBDU1RSIE5ldHdvcmtBZGRyLCBMUENTVFIgRW5kcG9pbnQsIExQQ1NUUiBOZXR3b3JrT3B0aW9ucywgUnBjQmluZGluZyogQmluZGluZykKewogIHN0cnVjdCBwcm90c2VxX29wcyAqb3BzOwogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CgogIG9wcyA9IHJwY3J0NF9nZXRfcHJvdHNlcV9vcHMoUHJvdHNlcSk7CiAgaWYgKCFvcHMpCiAgICByZXR1cm4gUlBDX1NfUFJPVFNFUV9OT1RfU1VQUE9SVEVEOwoKICBOZXdDb25uZWN0aW9uID0gb3BzLT5hbGxvYygpOwogIE5ld0Nvbm5lY3Rpb24tPnNlcnZlciA9IHNlcnZlcjsKICBOZXdDb25uZWN0aW9uLT5vcHMgPSBvcHM7CiAgTmV3Q29ubmVjdGlvbi0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShOZXR3b3JrQWRkcik7CiAgTmV3Q29ubmVjdGlvbi0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CiAgTmV3Q29ubmVjdGlvbi0+VXNlZCA9IEJpbmRpbmc7CiAgTmV3Q29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSA9IFJQQ19NQVhfUEFDS0VUX1NJWkU7CgogIFRSQUNFKCJjb25uZWN0aW9uOiAlcFxuIiwgTmV3Q29ubmVjdGlvbik7CiAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NwYXduQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwgUnBjQ29ubmVjdGlvbiogT2xkQ29ubmVjdGlvbikKewogIFJQQ19TVEFUVVMgZXJyOwoKICBlcnIgPSBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbihDb25uZWN0aW9uLCBPbGRDb25uZWN0aW9uLT5zZXJ2ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnBjcnQ0X2Nvbm5fZ2V0X25hbWUoT2xkQ29ubmVjdGlvbiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2xkQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT2xkQ29ubmVjdGlvbi0+RW5kcG9pbnQsIE5VTEwsIE5VTEwpOwogIGlmIChlcnIgPT0gUlBDX1NfT0spCiAgICBycGNydDRfY29ubl9oYW5kb2ZmKE9sZENvbm5lY3Rpb24sICpDb25uZWN0aW9uKTsKICByZXR1cm4gZXJyOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0Nsb3NlQ29ubmVjdGlvbihDb25uZWN0aW9uKTsKICBSUENSVDRfc3RyZnJlZShDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIENvbm5lY3Rpb24pOwogIHJldHVybiBSUENfU19PSzsKfQo=