LyoKICogQ29weXJpZ2h0IKkgMjAwOSBJbnRlbCBDb3Jwb3JhdGlvbgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWIgbGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlCiAqIG5leHQgcGFyYWdyYXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zCiAqIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MKICogT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULgogKiBJTiBOTyBFVkVOVCBTSEFMTCBQUkVDSVNJT04gSU5TSUdIVCBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRSBMSUFCTEUgRk9SCiAqIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAogKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQogKiBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KICoKICogQXV0aG9yczoKICogICAgWGlhbmcgSGFpaGFvIDxoYWloYW8ueGlhbmdAaW50ZWwuY29tPgogKiAgICBab3UgTmFuIGhhaSA8bmFuaGFpLnpvdUBpbnRlbC5jb20+CiAqCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgPHZhL3ZhX2JhY2tlbmQuaD4KCiNpbmNsdWRlICJpbnRlbF9iYXRjaGJ1ZmZlci5oIgojaW5jbHVkZSAiaW50ZWxfZHJpdmVyLmgiCgojaW5jbHVkZSAiaTk2NV9kZWZpbmVzLmgiCiNpbmNsdWRlICJpOTY1X21lZGlhX21wZWcyLmgiCiNpbmNsdWRlICJpOTY1X21lZGlhX2gyNjQuaCIKI2luY2x1ZGUgImdlbjZfbWZkLmgiCiNpbmNsdWRlICJpOTY1X21lZGlhLmgiCiNpbmNsdWRlICJpOTY1X2Rydl92aWRlby5oIgoKc3RhdGljIHZvaWQKaTk2NV9tZWRpYV9waXBlbGluZV9zZWxlY3QoVkFEcml2ZXJDb250ZXh0UCBjdHgpCnsKICAgIEJFR0lOX0JBVENIKGN0eCwgMSk7CiAgICBPVVRfQkFUQ0goY3R4LCBDTURfUElQRUxJTkVfU0VMRUNUIHwgUElQRUxJTkVfU0VMRUNUX01FRElBKTsKICAgIEFEVkFOQ0VfQkFUQ0goY3R4KTsKfQoKc3RhdGljIHZvaWQKaTk2NV9tZWRpYV91cmJfbGF5b3V0KFZBRHJpdmVyQ29udGV4dFAgY3R4KQp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsKICAgIHN0cnVjdCBpOTY1X21lZGlhX3N0YXRlICptZWRpYV9zdGF0ZSA9ICZpOTY1LT5tZWRpYV9zdGF0ZTsKICAgIHVuc2lnbmVkIGludCB2ZmVfZmVuY2UsIGNzX2ZlbmNlOwoKICAgIHZmZV9mZW5jZSA9IG1lZGlhX3N0YXRlLT51cmIuY3Nfc3RhcnQ7CiAgICBjc19mZW5jZSA9IFVSQl9TSVpFKCgmaTk2NS0+aW50ZWwpKTsKCiAgICBCRUdJTl9CQVRDSChjdHgsIDMpOwogICAgT1VUX0JBVENIKGN0eCwgQ01EX1VSQl9GRU5DRSB8IFVGMF9WRkVfUkVBTExPQyB8IFVGMF9DU19SRUFMTE9DIHwgMSk7CiAgICBPVVRfQkFUQ0goY3R4LCAwKTsKICAgIE9VVF9CQVRDSChjdHgsIAogICAgICAgICAgICAgICh2ZmVfZmVuY2UgPDwgVUYyX1ZGRV9GRU5DRV9TSElGVCkgfCAgICAgIC8qIFZGRV9TSVpFICovCiAgICAgICAgICAgICAgKGNzX2ZlbmNlIDw8IFVGMl9DU19GRU5DRV9TSElGVCkpOyAgICAgICAgLyogQ1NfU0laRSAqLwogICAgQURWQU5DRV9CQVRDSChjdHgpOwp9CgpzdGF0aWMgdm9pZAppOTY1X21lZGlhX3N0YXRlX2Jhc2VfYWRkcmVzcyhWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7IAogICAgc3RydWN0IGk5NjVfbWVkaWFfc3RhdGUgKm1lZGlhX3N0YXRlID0gJmk5NjUtPm1lZGlhX3N0YXRlOwoKICAgIGlmIChJU19JUk9OTEFLRShpOTY1LT5pbnRlbC5kZXZpY2VfaWQpKSB7CiAgICAgICAgQkVHSU5fQkFUQ0goY3R4LCA4KTsKICAgICAgICBPVVRfQkFUQ0goY3R4LCBDTURfU1RBVEVfQkFTRV9BRERSRVNTIHwgNik7CiAgICAgICAgT1VUX0JBVENIKGN0eCwgMCB8IEJBU0VfQUREUkVTU19NT0RJRlkpOwogICAgICAgIE9VVF9CQVRDSChjdHgsIDAgfCBCQVNFX0FERFJFU1NfTU9ESUZZKTsKICAgICAgICAKICAgICAgICBpZiAobWVkaWFfc3RhdGUtPmluZGlyZWN0X29iamVjdC5ibykgewogICAgICAgICAgICBPVVRfUkVMT0MoY3R4LCBtZWRpYV9zdGF0ZS0+aW5kaXJlY3Rfb2JqZWN0LmJvLCBJOTE1X0dFTV9ET01BSU5fSU5TVFJVQ1RJT04sIDAsIAogICAgICAgICAgICAgICAgICAgICAgbWVkaWFfc3RhdGUtPmluZGlyZWN0X29iamVjdC5vZmZzZXQgfCBCQVNFX0FERFJFU1NfTU9ESUZZKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBPVVRfQkFUQ0goY3R4LCAwIHwgQkFTRV9BRERSRVNTX01PRElGWSk7CiAgICAgICAgfQoKICAgICAgICBPVVRfQkFUQ0goY3R4LCAwIHwgQkFTRV9BRERSRVNTX01PRElGWSk7CiAgICAgICAgT1VUX0JBVENIKGN0eCwgMCB8IEJBU0VfQUREUkVTU19NT0RJRlkpOwogICAgICAgIE9VVF9CQVRDSChjdHgsIDAgfCBCQVNFX0FERFJFU1NfTU9ESUZZKTsKICAgICAgICBPVVRfQkFUQ0goY3R4LCAwIHwgQkFTRV9BRERSRVNTX01PRElGWSk7CiAgICAgICAgQURWQU5DRV9CQVRDSChjdHgpOwogICAgfSBlbHNlIHsKICAgICAgICBCRUdJTl9CQVRDSChjdHgsIDYpOwogICAgICAgIE9VVF9CQVRDSChjdHgsIENNRF9TVEFURV9CQVNFX0FERFJFU1MgfCA0KTsKICAgICAgICBPVVRfQkFUQ0goY3R4LCAwIHwgQkFTRV9BRERSRVNTX01PRElGWSk7CiAgICAgICAgT1VUX0JBVENIKGN0eCwgMCB8IEJBU0VfQUREUkVTU19NT0RJRlkpOwoKICAgICAgICBpZiAobWVkaWFfc3RhdGUtPmluZGlyZWN0X29iamVjdC5ibykgewogICAgICAgICAgICBPVVRfUkVMT0MoY3R4LCBtZWRpYV9zdGF0ZS0+aW5kaXJlY3Rfb2JqZWN0LmJvLCBJOTE1X0dFTV9ET01BSU5fSU5TVFJVQ1RJT04sIDAsIAogICAgICAgICAgICAgICAgICAgICAgbWVkaWFfc3RhdGUtPmluZGlyZWN0X29iamVjdC5vZmZzZXQgfCBCQVNFX0FERFJFU1NfTU9ESUZZKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBPVVRfQkFUQ0goY3R4LCAwIHwgQkFTRV9BRERSRVNTX01PRElGWSk7CiAgICAgICAgfQoKICAgICAgICBPVVRfQkFUQ0goY3R4LCAwIHwgQkFTRV9BRERSRVNTX01PRElGWSk7CiAgICAgICAgT1VUX0JBVENIKGN0eCwgMCB8IEJBU0VfQUREUkVTU19NT0RJRlkpOwogICAgICAgIEFEVkFOQ0VfQkFUQ0goY3R4KTsKICAgIH0KfQoKc3RhdGljIHZvaWQKaTk2NV9tZWRpYV9zdGF0ZV9wb2ludGVycyhWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3QgaTk2NV9tZWRpYV9zdGF0ZSAqbWVkaWFfc3RhdGUgPSAmaTk2NS0+bWVkaWFfc3RhdGU7CgogICAgQkVHSU5fQkFUQ0goY3R4LCAzKTsKICAgIE9VVF9CQVRDSChjdHgsIENNRF9NRURJQV9TVEFURV9QT0lOVEVSUyB8IDEpOwoKICAgIGlmIChtZWRpYV9zdGF0ZS0+ZXh0ZW5kZWRfc3RhdGUuZW5hYmxlZCkKICAgICAgICBPVVRfUkVMT0MoY3R4LCBtZWRpYV9zdGF0ZS0+ZXh0ZW5kZWRfc3RhdGUuYm8sIEk5MTVfR0VNX0RPTUFJTl9JTlNUUlVDVElPTiwgMCwgMSk7CiAgICBlbHNlCiAgICAgICAgT1VUX0JBVENIKGN0eCwgMCk7CgogICAgT1VUX1JFTE9DKGN0eCwgbWVkaWFfc3RhdGUtPnZmZV9zdGF0ZS5ibywgSTkxNV9HRU1fRE9NQUlOX0lOU1RSVUNUSU9OLCAwLCAwKTsKICAgIEFEVkFOQ0VfQkFUQ0goY3R4KTsKfQoKc3RhdGljIHZvaWQgCmk5NjVfbWVkaWFfY3NfdXJiX2xheW91dChWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3QgaTk2NV9tZWRpYV9zdGF0ZSAqbWVkaWFfc3RhdGUgPSAmaTk2NS0+bWVkaWFfc3RhdGU7CgogICAgQkVHSU5fQkFUQ0goY3R4LCAyKTsKICAgIE9VVF9CQVRDSChjdHgsIENNRF9DU19VUkJfU1RBVEUgfCAwKTsKICAgIE9VVF9CQVRDSChjdHgsCiAgICAgICAgICAgICAgKChtZWRpYV9zdGF0ZS0+dXJiLnNpemVfY3NfZW50cnkgLSAxKSA8PCA0KSB8ICAgICAvKiBVUkIgRW50cnkgQWxsb2NhdGlvbiBTaXplICovCiAgICAgICAgICAgICAgKG1lZGlhX3N0YXRlLT51cmIubnVtX2NzX2VudHJpZXMgPDwgMCkpOyAgICAgICAgICAvKiBOdW1iZXIgb2YgVVJCIEVudHJpZXMgKi8KICAgIEFEVkFOQ0VfQkFUQ0goY3R4KTsKfQoKc3RhdGljIHZvaWQgCmk5NjVfbWVkaWFfcGlwZWxpbmVfc3RhdGUoVkFEcml2ZXJDb250ZXh0UCBjdHgpCnsKICAgIGk5NjVfbWVkaWFfc3RhdGVfYmFzZV9hZGRyZXNzKGN0eCk7CiAgICBpOTY1X21lZGlhX3N0YXRlX3BvaW50ZXJzKGN0eCk7CiAgICBpOTY1X21lZGlhX2NzX3VyYl9sYXlvdXQoY3R4KTsKfQoKc3RhdGljIHZvaWQKaTk2NV9tZWRpYV9jb25zdGFudF9idWZmZXIoVkFEcml2ZXJDb250ZXh0UCBjdHgsIHN0cnVjdCBkZWNvZGVfc3RhdGUgKmRlY29kZV9zdGF0ZSkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3QgaTk2NV9tZWRpYV9zdGF0ZSAqbWVkaWFfc3RhdGUgPSAmaTk2NS0+bWVkaWFfc3RhdGU7CgogICAgQkVHSU5fQkFUQ0goY3R4LCAyKTsKICAgIE9VVF9CQVRDSChjdHgsIENNRF9DT05TVEFOVF9CVUZGRVIgfCAoMSA8PCA4KSB8ICgyIC0gMikpOwogICAgT1VUX1JFTE9DKGN0eCwgbWVkaWFfc3RhdGUtPmN1cmJlLmJvLAogICAgICAgICAgICAgIEk5MTVfR0VNX0RPTUFJTl9JTlNUUlVDVElPTiwgMCwKICAgICAgICAgICAgICBtZWRpYV9zdGF0ZS0+dXJiLnNpemVfY3NfZW50cnkgLSAxKTsKICAgIEFEVkFOQ0VfQkFUQ0goY3R4KTsgICAgCn0KCnN0YXRpYyB2b2lkIAppOTY1X21lZGlhX2RlcHRoX2J1ZmZlcihWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgQkVHSU5fQkFUQ0goY3R4LCA2KTsKICAgIE9VVF9CQVRDSChjdHgsIENNRF9ERVBUSF9CVUZGRVIgfCA0KTsKICAgIE9VVF9CQVRDSChjdHgsIChJOTY1X0RFUFRIRk9STUFUX0QzMl9GTE9BVCA8PCAxOCkgfCAKICAgICAgICAgICAgICAoSTk2NV9TVVJGQUNFX05VTEwgPDwgMjkpKTsKICAgIE9VVF9CQVRDSChjdHgsIDApOwogICAgT1VUX0JBVENIKGN0eCwgMCk7CiAgICBPVVRfQkFUQ0goY3R4LCAwKTsKICAgIE9VVF9CQVRDSChjdHgsIDApOwogICAgQURWQU5DRV9CQVRDSChjdHgpOwp9CgpzdGF0aWMgdm9pZAppOTY1X21lZGlhX3BpcGVsaW5lX3NldHVwKFZBRHJpdmVyQ29udGV4dFAgY3R4LCBzdHJ1Y3QgZGVjb2RlX3N0YXRlICpkZWNvZGVfc3RhdGUpCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgc3RydWN0IGk5NjVfbWVkaWFfc3RhdGUgKm1lZGlhX3N0YXRlID0gJmk5NjUtPm1lZGlhX3N0YXRlOwoKICAgIGludGVsX2JhdGNoYnVmZmVyX3N0YXJ0X2F0b21pYyhjdHgsIDB4MTAwMCk7CiAgICBpbnRlbF9iYXRjaGJ1ZmZlcl9lbWl0X21pX2ZsdXNoKGN0eCk7ICAgICAgICAgICAgICAgICAgICAgICAvKiBzdGVwIDEgKi8KICAgIGk5NjVfbWVkaWFfZGVwdGhfYnVmZmVyKGN0eCk7CiAgICBpOTY1X21lZGlhX3BpcGVsaW5lX3NlbGVjdChjdHgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzdGVwIDIgKi8KICAgIGk5NjVfbWVkaWFfdXJiX2xheW91dChjdHgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHN0ZXAgMyAqLwogICAgaTk2NV9tZWRpYV9waXBlbGluZV9zdGF0ZShjdHgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RlcCA0ICovCiAgICBpOTY1X21lZGlhX2NvbnN0YW50X2J1ZmZlcihjdHgsIGRlY29kZV9zdGF0ZSk7ICAgICAgICAgICAgICAvKiBzdGVwIDUgKi8KICAgIGFzc2VydChtZWRpYV9zdGF0ZS0+bWVkaWFfb2JqZWN0cyk7CiAgICBtZWRpYV9zdGF0ZS0+bWVkaWFfb2JqZWN0cyhjdHgsIGRlY29kZV9zdGF0ZSk7ICAgICAgICAgICAgICAvKiBzdGVwIDYgKi8KICAgIGludGVsX2JhdGNoYnVmZmVyX2VuZF9hdG9taWMoY3R4KTsKfQoKc3RhdGljIHZvaWQgCmk5NjVfbWVkaWFfZGVjb2RlX2luaXQoVkFEcml2ZXJDb250ZXh0UCBjdHgsIFZBUHJvZmlsZSBwcm9maWxlLCBzdHJ1Y3QgZGVjb2RlX3N0YXRlICpkZWNvZGVfc3RhdGUpCnsKICAgIGludCBpOwogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3QgaTk2NV9tZWRpYV9zdGF0ZSAqbWVkaWFfc3RhdGUgPSAmaTk2NS0+bWVkaWFfc3RhdGU7CiAgICBkcmlfYm8gKmJvOwoKICAgIC8qIGNvbnN0YW50IGJ1ZmZlciAqLwogICAgZHJpX2JvX3VucmVmZXJlbmNlKG1lZGlhX3N0YXRlLT5jdXJiZS5ibyk7CiAgICBibyA9IGRyaV9ib19hbGxvYyhpOTY1LT5pbnRlbC5idWZtZ3IsCiAgICAgICAgICAgICAgICAgICAgICAiY29uc3RhbnQgYnVmZmVyIiwKICAgICAgICAgICAgICAgICAgICAgIDQwOTYsIDY0KTsKICAgIGFzc2VydChibyk7CiAgICBtZWRpYV9zdGF0ZS0+Y3VyYmUuYm8gPSBibzsKCiAgICAvKiBzdXJmYWNlIHN0YXRlICovCiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX01FRElBX1NVUkZBQ0VTOyBpKyspIHsKICAgICAgICBkcmlfYm9fdW5yZWZlcmVuY2UobWVkaWFfc3RhdGUtPnN1cmZhY2Vfc3RhdGVbaV0uYm8pOwogICAgICAgIG1lZGlhX3N0YXRlLT5zdXJmYWNlX3N0YXRlW2ldLmJvID0gTlVMTDsKICAgIH0KCiAgICAvKiBiaW5kaW5nIHRhYmxlICovCiAgICBkcmlfYm9fdW5yZWZlcmVuY2UobWVkaWFfc3RhdGUtPmJpbmRpbmdfdGFibGUuYm8pOwogICAgYm8gPSBkcmlfYm9fYWxsb2MoaTk2NS0+aW50ZWwuYnVmbWdyLCAKICAgICAgICAgICAgICAgICAgICAgICJiaW5kaW5nIHRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgIE1BWF9NRURJQV9TVVJGQUNFUyAqIHNpemVvZih1bnNpZ25lZCBpbnQpLCAzMik7CiAgICBhc3NlcnQoYm8pOwogICAgbWVkaWFfc3RhdGUtPmJpbmRpbmdfdGFibGUuYm8gPSBibzsKCiAgICAvKiBpbnRlcmZhY2UgZGVzY3JpcHRvciByZW1hcHBpbmcgdGFibGUgKi8KICAgIGRyaV9ib191bnJlZmVyZW5jZShtZWRpYV9zdGF0ZS0+aWRydC5ibyk7CiAgICBibyA9IGRyaV9ib19hbGxvYyhpOTY1LT5pbnRlbC5idWZtZ3IsIAogICAgICAgICAgICAgICAgICAgICAgImludGVyZmFjZSBkaXNjcmlwdG9yIiwgCiAgICAgICAgICAgICAgICAgICAgICBNQVhfSU5URVJGQUNFX0RFU0MgKiBzaXplb2Yoc3RydWN0IGk5NjVfaW50ZXJmYWNlX2Rlc2NyaXB0b3IpLCAxNik7CiAgICBhc3NlcnQoYm8pOwogICAgbWVkaWFfc3RhdGUtPmlkcnQuYm8gPSBibzsKCiAgICAvKiB2ZmUgc3RhdGUgKi8KICAgIGRyaV9ib191bnJlZmVyZW5jZShtZWRpYV9zdGF0ZS0+dmZlX3N0YXRlLmJvKTsKICAgIGJvID0gZHJpX2JvX2FsbG9jKGk5NjUtPmludGVsLmJ1Zm1nciwgCiAgICAgICAgICAgICAgICAgICAgICAidmZlIHN0YXRlIiwgCiAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3RydWN0IGk5NjVfdmZlX3N0YXRlKSwgMzIpOwogICAgYXNzZXJ0KGJvKTsKICAgIG1lZGlhX3N0YXRlLT52ZmVfc3RhdGUuYm8gPSBibzsKCiAgICAvKiBleHRlbmRlZCBzdGF0ZSAqLwogICAgbWVkaWFfc3RhdGUtPmV4dGVuZGVkX3N0YXRlLmVuYWJsZWQgPSAwOwoKICAgIHN3aXRjaCAocHJvZmlsZSkgewogICAgY2FzZSBWQVByb2ZpbGVNUEVHMlNpbXBsZToKICAgIGNhc2UgVkFQcm9maWxlTVBFRzJNYWluOgogICAgICAgIGk5NjVfbWVkaWFfbXBlZzJfZGVjb2RlX2luaXQoY3R4LCBkZWNvZGVfc3RhdGUpOwogICAgICAgIGJyZWFrOwogICAgICAgIAogICAgY2FzZSBWQVByb2ZpbGVIMjY0QmFzZWxpbmU6CiAgICBjYXNlIFZBUHJvZmlsZUgyNjRNYWluOgogICAgY2FzZSBWQVByb2ZpbGVIMjY0SGlnaDoKICAgICAgICBpOTY1X21lZGlhX2gyNjRfZGVjb2RlX2luaXQoY3R4LCBkZWNvZGVfc3RhdGUpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgYXNzZXJ0KDApOwogICAgICAgIGJyZWFrOwogICAgfQp9Cgp2b2lkIAppOTY1X21lZGlhX2RlY29kZV9waWN0dXJlKFZBRHJpdmVyQ29udGV4dFAgY3R4LCAKICAgICAgICAgICAgICAgICAgICAgICAgICBWQVByb2ZpbGUgcHJvZmlsZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGRlY29kZV9zdGF0ZSAqZGVjb2RlX3N0YXRlKQp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsKICAgIHN0cnVjdCBpOTY1X21lZGlhX3N0YXRlICptZWRpYV9zdGF0ZSA9ICZpOTY1LT5tZWRpYV9zdGF0ZTsKCiAgICBpZiAoSVNfR0VONihpOTY1LT5pbnRlbC5kZXZpY2VfaWQpKSB7CiAgICAgICAgZ2VuNl9tZmRfZGVjb2RlX3BpY3R1cmUoY3R4LCBwcm9maWxlLCBkZWNvZGVfc3RhdGUpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpOTY1X21lZGlhX2RlY29kZV9pbml0KGN0eCwgcHJvZmlsZSwgZGVjb2RlX3N0YXRlKTsKICAgIGFzc2VydChtZWRpYV9zdGF0ZS0+bWVkaWFfc3RhdGVzX3NldHVwKTsKICAgIG1lZGlhX3N0YXRlLT5tZWRpYV9zdGF0ZXNfc2V0dXAoY3R4LCBkZWNvZGVfc3RhdGUpOwogICAgaTk2NV9tZWRpYV9waXBlbGluZV9zZXR1cChjdHgsIGRlY29kZV9zdGF0ZSk7Cn0KCkJvb2wgCmk5NjVfbWVkaWFfaW5pdChWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CgogICAgaWYgKElTX0dFTjYoaTk2NS0+aW50ZWwuZGV2aWNlX2lkKSkKICAgICAgICByZXR1cm4gZ2VuNl9tZmRfaW5pdChjdHgpOwoKICAgIHJldHVybiBUcnVlOwp9CgpCb29sIAppOTY1X21lZGlhX3Rlcm1pbmF0ZShWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3QgaTk2NV9tZWRpYV9zdGF0ZSAqbWVkaWFfc3RhdGUgPSAmaTk2NS0+bWVkaWFfc3RhdGU7CiAgICBpbnQgaTsKCiAgICBpZiAoSVNfR0VONihpOTY1LT5pbnRlbC5kZXZpY2VfaWQpKQogICAgICAgIHJldHVybiBnZW42X21mZF90ZXJtaW5hdGUoY3R4KTsKCiAgICBpZiAobWVkaWFfc3RhdGUtPmZyZWVfcHJpdmF0ZV9jb250ZXh0KQogICAgICAgIG1lZGlhX3N0YXRlLT5mcmVlX3ByaXZhdGVfY29udGV4dCgmbWVkaWFfc3RhdGUtPnByaXZhdGVfY29udGV4dCk7CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9NRURJQV9TVVJGQUNFUzsgaSsrKSB7CiAgICAgICAgZHJpX2JvX3VucmVmZXJlbmNlKG1lZGlhX3N0YXRlLT5zdXJmYWNlX3N0YXRlW2ldLmJvKTsKICAgICAgICBtZWRpYV9zdGF0ZS0+c3VyZmFjZV9zdGF0ZVtpXS5ibyA9IE5VTEw7CiAgICB9CiAgICAKICAgIGRyaV9ib191bnJlZmVyZW5jZShtZWRpYV9zdGF0ZS0+ZXh0ZW5kZWRfc3RhdGUuYm8pOwogICAgbWVkaWFfc3RhdGUtPmV4dGVuZGVkX3N0YXRlLmJvID0gTlVMTDsKCiAgICBkcmlfYm9fdW5yZWZlcmVuY2UobWVkaWFfc3RhdGUtPnZmZV9zdGF0ZS5ibyk7CiAgICBtZWRpYV9zdGF0ZS0+dmZlX3N0YXRlLmJvID0gTlVMTDsKCiAgICBkcmlfYm9fdW5yZWZlcmVuY2UobWVkaWFfc3RhdGUtPmlkcnQuYm8pOwogICAgbWVkaWFfc3RhdGUtPmlkcnQuYm8gPSBOVUxMOwoKICAgIGRyaV9ib191bnJlZmVyZW5jZShtZWRpYV9zdGF0ZS0+YmluZGluZ190YWJsZS5ibyk7CiAgICBtZWRpYV9zdGF0ZS0+YmluZGluZ190YWJsZS5ibyA9IE5VTEw7CgogICAgZHJpX2JvX3VucmVmZXJlbmNlKG1lZGlhX3N0YXRlLT5jdXJiZS5ibyk7CiAgICBtZWRpYV9zdGF0ZS0+Y3VyYmUuYm8gPSBOVUxMOwoKICAgIGRyaV9ib191bnJlZmVyZW5jZShtZWRpYV9zdGF0ZS0+aW5kaXJlY3Rfb2JqZWN0LmJvKTsKICAgIG1lZGlhX3N0YXRlLT5pbmRpcmVjdF9vYmplY3QuYm8gPSBOVUxMOwoKICAgIHJldHVybiBUcnVlOwp9Cgo=