LyoKICogQ29weXJpZ2h0IKkgMjAwOSBJbnRlbCBDb3Jwb3JhdGlvbgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWIgbGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlCiAqIG5leHQgcGFyYWdyYXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zCiAqIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MKICogT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULgogKiBJTiBOTyBFVkVOVCBTSEFMTCBQUkVDSVNJT04gSU5TSUdIVCBBTkQvT1IgSVRTIFNVUFBMSUVSUyBCRSBMSUFCTEUgRk9SCiAqIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAogKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQogKiBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KICoKICogQXV0aG9yczoKICogICAgWGlhbmcgSGFpaGFvIDxoYWloYW8ueGlhbmdAaW50ZWwuY29tPgogKiAgICBab3UgTmFuIGhhaSA8bmFuaGFpLnpvdUBpbnRlbC5jb20+CiAqCiAqLwoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojaW5jbHVkZSAidmFfYmFja2VuZC5oIgojaW5jbHVkZSAidmFfZHJpY29tbW9uLmgiCgojaW5jbHVkZSAiaW50ZWxfZHJpdmVyLmgiCiNpbmNsdWRlICJpbnRlbF9tZW1tYW4uaCIKI2luY2x1ZGUgImludGVsX2JhdGNoYnVmZmVyLmgiCgojaW5jbHVkZSAiaTk2NV9tZWRpYS5oIgojaW5jbHVkZSAiaTk2NV9kcnZfdmlkZW8uaCIKI2luY2x1ZGUgImk5NjVfZGVmaW5lcy5oIgoKI2RlZmluZSBDT05GSUdfSURfT0ZGU0VUICAgICAgICAgICAgICAgIDB4MDEwMDAwMDAKI2RlZmluZSBDT05URVhUX0lEX09GRlNFVCAgICAgICAgICAgICAgIDB4MDIwMDAwMDAKI2RlZmluZSBTVVJGQUNFX0lEX09GRlNFVCAgICAgICAgICAgICAgIDB4MDQwMDAwMDAKI2RlZmluZSBCVUZGRVJfSURfT0ZGU0VUICAgICAgICAgICAgICAgIDB4MDgwMDAwMDAKI2RlZmluZSBJTUFHRV9JRF9PRkZTRVQgICAgICAgICAgICAgICAgIDB4MGEwMDAwMDAKI2RlZmluZSBTVUJQSUNfSURfT0ZGU0VUICAgICAgICAgICAgICAgIDB4MTAwMDAwMDAKCmVudW0gewogICAgSTk2NV9TVVJGQUNFVFlQRV9SR0JBID0gMSwKICAgIEk5NjVfU1VSRkFDRVRZUEVfWVVWLAogICAgSTk2NV9TVVJGQUNFVFlQRV9JTkRFWEVECn07CgovKiBMaXN0IG9mIHN1cHBvcnRlZCBzdWJwaWN0dXJlIGZvcm1hdHMgKi8KdHlwZWRlZiBzdHJ1Y3QgewogICAgdW5zaWduZWQgaW50ICAgICAgICB0eXBlOwogICAgdW5zaWduZWQgaW50ICAgICAgICBmb3JtYXQ7CiAgICBWQUltYWdlRm9ybWF0ICAgICAgIHZhX2Zvcm1hdDsKICAgIHVuc2lnbmVkIGludCAgICAgICAgdmFfZmxhZ3M7Cn0gaTk2NV9zdWJwaWNfZm9ybWF0X21hcF90OwoKc3RhdGljIGNvbnN0IGk5NjVfc3VicGljX2Zvcm1hdF9tYXBfdAppOTY1X3N1YnBpY19mb3JtYXRzX21hcFtJOTY1X01BWF9TVUJQSUNfRk9STUFUUyArIDFdID0gewogICAgeyBJOTY1X1NVUkZBQ0VUWVBFX0lOREVYRUQsIEk5NjVfU1VSRkFDRUZPUk1BVF9QNEE0X1VOT1JNLAogICAgICB7IFZBX0ZPVVJDQygnSScsJ0EnLCc0JywnNCcpLCBWQV9NU0JfRklSU1QsIDgsIH0sCiAgICAgIDAgfSwKICAgIHsgSTk2NV9TVVJGQUNFVFlQRV9JTkRFWEVELCBJOTY1X1NVUkZBQ0VGT1JNQVRfQTRQNF9VTk9STSwKICAgICAgeyBWQV9GT1VSQ0MoJ0EnLCdJJywnNCcsJzQnKSwgVkFfTVNCX0ZJUlNULCA4LCB9LAogICAgICAwIH0sCn07CgpzdGF0aWMgY29uc3QgaTk2NV9zdWJwaWNfZm9ybWF0X21hcF90ICoKZ2V0X3N1YnBpY19mb3JtYXQoY29uc3QgVkFJbWFnZUZvcm1hdCAqdmFfZm9ybWF0KQp7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIGZvciAoaSA9IDA7IGkgPCBzaXplb2YoaTk2NV9zdWJwaWNfZm9ybWF0c19tYXApL3NpemVvZihpOTY1X3N1YnBpY19mb3JtYXRzX21hcFswXSk7IGkrKykgewogICAgICAgIGNvbnN0IGk5NjVfc3VicGljX2Zvcm1hdF9tYXBfdCAqIGNvbnN0IG0gPSAmaTk2NV9zdWJwaWNfZm9ybWF0c19tYXBbaV07CiAgICAgICAgaWYgKG0tPnZhX2Zvcm1hdC5mb3VyY2MgPT0gdmFfZm9ybWF0LT5mb3VyY2MgJiYKICAgICAgICAgICAgKG0tPnR5cGUgPT0gSTk2NV9TVVJGQUNFVFlQRV9SR0JBID8KICAgICAgICAgICAgIChtLT52YV9mb3JtYXQuYnl0ZV9vcmRlciA9PSB2YV9mb3JtYXQtPmJ5dGVfb3JkZXIgJiYKICAgICAgICAgICAgICBtLT52YV9mb3JtYXQucmVkX21hc2sgICA9PSB2YV9mb3JtYXQtPnJlZF9tYXNrICAgJiYKICAgICAgICAgICAgICBtLT52YV9mb3JtYXQuZ3JlZW5fbWFzayA9PSB2YV9mb3JtYXQtPmdyZWVuX21hc2sgJiYKICAgICAgICAgICAgICBtLT52YV9mb3JtYXQuYmx1ZV9tYXNrICA9PSB2YV9mb3JtYXQtPmJsdWVfbWFzayAgJiYKICAgICAgICAgICAgICBtLT52YV9mb3JtYXQuYWxwaGFfbWFzayA9PSB2YV9mb3JtYXQtPmFscGhhX21hc2spIDogMSkpCiAgICAgICAgICAgIHJldHVybiBtOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KClZBU3RhdHVzIAppOTY1X1F1ZXJ5Q29uZmlnUHJvZmlsZXMoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICBWQVByb2ZpbGUgKnByb2ZpbGVfbGlzdCwgICAgICAgLyogb3V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKm51bV9wcm9maWxlcykgICAgICAgICAgICAgLyogb3V0ICovCnsKICAgIGludCBpID0gMDsKCiAgICBwcm9maWxlX2xpc3RbaSsrXSA9IFZBUHJvZmlsZU1QRUcyU2ltcGxlOwogICAgcHJvZmlsZV9saXN0W2krK10gPSBWQVByb2ZpbGVNUEVHMk1haW47CgogICAgLyogSWYgdGhlIGFzc2VydCBmYWlscyB0aGVuIEk5NjVfTUFYX1BST0ZJTEVTIG5lZWRzIHRvIGJlIGJpZ2dlciAqLwogICAgYXNzZXJ0KGkgPD0gSTk2NV9NQVhfUFJPRklMRVMpOwogICAgKm51bV9wcm9maWxlcyA9IGk7CgogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgpWQVN0YXR1cyAKaTk2NV9RdWVyeUNvbmZpZ0VudHJ5cG9pbnRzKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFQcm9maWxlIHByb2ZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUVudHJ5cG9pbnQgKmVudHJ5cG9pbnRfbGlzdCwgICAgICAvKiBvdXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqbnVtX2VudHJ5cG9pbnRzKSAgICAgICAgICAgICAgIC8qIG91dCAqLwp7CiAgICBWQVN0YXR1cyB2YVN0YXR1cyA9IFZBX1NUQVRVU19TVUNDRVNTOwoKICAgIHN3aXRjaCAocHJvZmlsZSkgewogICAgY2FzZSBWQVByb2ZpbGVNUEVHMlNpbXBsZToKICAgIGNhc2UgVkFQcm9maWxlTVBFRzJNYWluOgogICAgICAgICpudW1fZW50cnlwb2ludHMgPSAxOwogICAgICAgIGVudHJ5cG9pbnRfbGlzdFswXSA9IFZBRW50cnlwb2ludFZMRDsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHZhU3RhdHVzID0gVkFfU1RBVFVTX0VSUk9SX1VOU1VQUE9SVEVEX1BST0ZJTEU7CiAgICAgICAgKm51bV9lbnRyeXBvaW50cyA9IDA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyogSWYgdGhlIGFzc2VydCBmYWlscyB0aGVuIEk5NjVfTUFYX0VOVFJZUE9JTlRTIG5lZWRzIHRvIGJlIGJpZ2dlciAqLwogICAgYXNzZXJ0KCpudW1fZW50cnlwb2ludHMgPD0gSTk2NV9NQVhfRU5UUllQT0lOVFMpOwoKICAgIHJldHVybiB2YVN0YXR1czsKfQoKVkFTdGF0dXMgCmk5NjVfR2V0Q29uZmlnQXR0cmlidXRlcyhWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgIFZBUHJvZmlsZSBwcm9maWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgVkFFbnRyeXBvaW50IGVudHJ5cG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICBWQUNvbmZpZ0F0dHJpYiAqYXR0cmliX2xpc3QsICAvKiBpbi9vdXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1fYXR0cmlicykKewogICAgaW50IGk7CgogICAgLyogT3RoZXIgYXR0cmlidXRlcyBkb24ndCBzZWVtIHRvIGJlIGRlZmluZWQgKi8KICAgIC8qIFdoYXQgdG8gZG8gaWYgd2UgZG9uJ3Qga25vdyB0aGUgYXR0cmlidXRlPyAqLwogICAgZm9yIChpID0gMDsgaSA8IG51bV9hdHRyaWJzOyBpKyspIHsKICAgICAgICBzd2l0Y2ggKGF0dHJpYl9saXN0W2ldLnR5cGUpIHsKICAgICAgICBjYXNlIFZBQ29uZmlnQXR0cmliUlRGb3JtYXQ6CiAgICAgICAgICAgIGF0dHJpYl9saXN0W2ldLnZhbHVlID0gVkFfUlRfRk9STUFUX1lVVjQyMDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIERvIG5vdGhpbmcgKi8KICAgICAgICAgICAgYXR0cmliX2xpc3RbaV0udmFsdWUgPSBWQV9BVFRSSUJfTk9UX1NVUFBPUlRFRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKc3RhdGljIHZvaWQgCmk5NjVfZGVzdHJveV9jb25maWcoc3RydWN0IG9iamVjdF9oZWFwICpoZWFwLCBzdHJ1Y3Qgb2JqZWN0X2Jhc2UgKm9iaikKewogICAgb2JqZWN0X2hlYXBfZnJlZShoZWFwLCBvYmopOwp9CgpzdGF0aWMgVkFTdGF0dXMgCmk5NjVfdXBkYXRlX2F0dHJpYnV0ZShzdHJ1Y3Qgb2JqZWN0X2NvbmZpZyAqb2JqX2NvbmZpZywgVkFDb25maWdBdHRyaWIgKmF0dHJpYikKewogICAgaW50IGk7CgogICAgLyogQ2hlY2sgZXhpc3RpbmcgYXR0cmJpdXRlcyAqLwogICAgZm9yIChpID0gMDsgb2JqX2NvbmZpZy0+bnVtX2F0dHJpYnMgPCBpOyBpKyspIHsKICAgICAgICBpZiAob2JqX2NvbmZpZy0+YXR0cmliX2xpc3RbaV0udHlwZSA9PSBhdHRyaWItPnR5cGUpIHsKICAgICAgICAgICAgLyogVXBkYXRlIGV4aXN0aW5nIGF0dHJpYnV0ZSAqLwogICAgICAgICAgICBvYmpfY29uZmlnLT5hdHRyaWJfbGlzdFtpXS52YWx1ZSA9IGF0dHJpYi0+dmFsdWU7CiAgICAgICAgICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICB9CiAgICB9CgogICAgaWYgKG9ial9jb25maWctPm51bV9hdHRyaWJzIDwgSTk2NV9NQVhfQ09ORklHX0FUVFJJQlVURVMpIHsKICAgICAgICBpID0gb2JqX2NvbmZpZy0+bnVtX2F0dHJpYnM7CiAgICAgICAgb2JqX2NvbmZpZy0+YXR0cmliX2xpc3RbaV0udHlwZSA9IGF0dHJpYi0+dHlwZTsKICAgICAgICBvYmpfY29uZmlnLT5hdHRyaWJfbGlzdFtpXS52YWx1ZSA9IGF0dHJpYi0+dmFsdWU7CiAgICAgICAgb2JqX2NvbmZpZy0+bnVtX2F0dHJpYnMrKzsKICAgICAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9NQVhfTlVNX0VYQ0VFREVEOwp9CgpWQVN0YXR1cyAKaTk2NV9DcmVhdGVDb25maWcoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgIFZBUHJvZmlsZSBwcm9maWxlLAogICAgICAgICAgICAgICAgICBWQUVudHJ5cG9pbnQgZW50cnlwb2ludCwKICAgICAgICAgICAgICAgICAgVkFDb25maWdBdHRyaWIgKmF0dHJpYl9saXN0LAogICAgICAgICAgICAgICAgICBpbnQgbnVtX2F0dHJpYnMsCiAgICAgICAgICAgICAgICAgIFZBQ29uZmlnSUQgKmNvbmZpZ19pZCkJCS8qIG91dCAqLwp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsKICAgIHN0cnVjdCBvYmplY3RfY29uZmlnICpvYmpfY29uZmlnOwogICAgaW50IGNvbmZpZ0lEOwogICAgaW50IGk7CiAgICBWQVN0YXR1cyB2YVN0YXR1czsKCiAgICAvKiBWYWxpZGF0ZSBwcm9maWxlICYgZW50cnlwb2ludCAqLwogICAgc3dpdGNoIChwcm9maWxlKSB7CiAgICBjYXNlIFZBUHJvZmlsZU1QRUcyU2ltcGxlOgogICAgY2FzZSBWQVByb2ZpbGVNUEVHMk1haW46CiAgICAgICAgaWYgKFZBRW50cnlwb2ludFZMRCA9PSBlbnRyeXBvaW50KSB7CiAgICAgICAgICAgIHZhU3RhdHVzID0gVkFfU1RBVFVTX1NVQ0NFU1M7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfRVJST1JfVU5TVVBQT1JURURfRU5UUllQT0lOVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICB2YVN0YXR1cyA9IFZBX1NUQVRVU19FUlJPUl9VTlNVUFBPUlRFRF9QUk9GSUxFOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChWQV9TVEFUVVNfU1VDQ0VTUyAhPSB2YVN0YXR1cykgewogICAgICAgIHJldHVybiB2YVN0YXR1czsKICAgIH0KCiAgICBjb25maWdJRCA9IE5FV19DT05GSUdfSUQoKTsKICAgIG9ial9jb25maWcgPSBDT05GSUcoY29uZmlnSUQpOwoKICAgIGlmIChOVUxMID09IG9ial9jb25maWcpIHsKICAgICAgICB2YVN0YXR1cyA9IFZBX1NUQVRVU19FUlJPUl9BTExPQ0FUSU9OX0ZBSUxFRDsKICAgICAgICByZXR1cm4gdmFTdGF0dXM7CiAgICB9CgogICAgb2JqX2NvbmZpZy0+cHJvZmlsZSA9IHByb2ZpbGU7CiAgICBvYmpfY29uZmlnLT5lbnRyeXBvaW50ID0gZW50cnlwb2ludDsKICAgIG9ial9jb25maWctPmF0dHJpYl9saXN0WzBdLnR5cGUgPSBWQUNvbmZpZ0F0dHJpYlJURm9ybWF0OwogICAgb2JqX2NvbmZpZy0+YXR0cmliX2xpc3RbMF0udmFsdWUgPSBWQV9SVF9GT1JNQVRfWVVWNDIwOwogICAgb2JqX2NvbmZpZy0+bnVtX2F0dHJpYnMgPSAxOwoKICAgIGZvcihpID0gMDsgaSA8IG51bV9hdHRyaWJzOyBpKyspIHsKICAgICAgICB2YVN0YXR1cyA9IGk5NjVfdXBkYXRlX2F0dHJpYnV0ZShvYmpfY29uZmlnLCAmKGF0dHJpYl9saXN0W2ldKSk7CgogICAgICAgIGlmIChWQV9TVEFUVVNfU1VDQ0VTUyAhPSB2YVN0YXR1cykgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgLyogRXJyb3IgcmVjb3ZlcnkgKi8KICAgIGlmIChWQV9TVEFUVVNfU1VDQ0VTUyAhPSB2YVN0YXR1cykgewogICAgICAgIGk5NjVfZGVzdHJveV9jb25maWcoJmk5NjUtPmNvbmZpZ19oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX2NvbmZpZyk7CiAgICB9IGVsc2UgewogICAgICAgICpjb25maWdfaWQgPSBjb25maWdJRDsKICAgIH0KCiAgICByZXR1cm4gdmFTdGF0dXM7Cn0KClZBU3RhdHVzIAppOTY1X0Rlc3Ryb3lDb25maWcoVkFEcml2ZXJDb250ZXh0UCBjdHgsIFZBQ29uZmlnSUQgY29uZmlnX2lkKQp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsKICAgIHN0cnVjdCBvYmplY3RfY29uZmlnICpvYmpfY29uZmlnID0gQ09ORklHKGNvbmZpZ19pZCk7CiAgICBWQVN0YXR1cyB2YVN0YXR1czsKCiAgICBpZiAoTlVMTCA9PSBvYmpfY29uZmlnKSB7CiAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfRVJST1JfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgcmV0dXJuIHZhU3RhdHVzOwogICAgfQoKICAgIGk5NjVfZGVzdHJveV9jb25maWcoJmk5NjUtPmNvbmZpZ19oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX2NvbmZpZyk7CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIGk5NjVfUXVlcnlDb25maWdBdHRyaWJ1dGVzKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUNvbmZpZ0lEIGNvbmZpZ19pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFQcm9maWxlICpwcm9maWxlLCAgICAgICAgICAgICAgICAgLyogb3V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBRW50cnlwb2ludCAqZW50cnlwb2ludCwgICAgICAgICAgIC8qIG91dCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUNvbmZpZ0F0dHJpYiAqYXR0cmliX2xpc3QsICAgICAgICAvKiBvdXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpudW1fYXR0cmlicykgICAgICAgICAgICAgICAgICAgLyogb3V0ICovCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgc3RydWN0IG9iamVjdF9jb25maWcgKm9ial9jb25maWcgPSBDT05GSUcoY29uZmlnX2lkKTsKICAgIFZBU3RhdHVzIHZhU3RhdHVzID0gVkFfU1RBVFVTX1NVQ0NFU1M7CiAgICBpbnQgaTsKCiAgICBhc3NlcnQob2JqX2NvbmZpZyk7CiAgICAqcHJvZmlsZSA9IG9ial9jb25maWctPnByb2ZpbGU7CiAgICAqZW50cnlwb2ludCA9IG9ial9jb25maWctPmVudHJ5cG9pbnQ7CiAgICAqbnVtX2F0dHJpYnMgPSBvYmpfY29uZmlnLT5udW1fYXR0cmliczsKCiAgICBmb3IoaSA9IDA7IGkgPCBvYmpfY29uZmlnLT5udW1fYXR0cmliczsgaSsrKSB7CiAgICAgICAgYXR0cmliX2xpc3RbaV0gPSBvYmpfY29uZmlnLT5hdHRyaWJfbGlzdFtpXTsKICAgIH0KCiAgICByZXR1cm4gdmFTdGF0dXM7Cn0KCnN0YXRpYyB2b2lkIAppOTY1X2Rlc3Ryb3lfc3VyZmFjZShzdHJ1Y3Qgb2JqZWN0X2hlYXAgKmhlYXAsIHN0cnVjdCBvYmplY3RfYmFzZSAqb2JqKQp7CiAgICBzdHJ1Y3Qgb2JqZWN0X3N1cmZhY2UgKm9ial9zdXJmYWNlID0gKHN0cnVjdCBvYmplY3Rfc3VyZmFjZSAqKW9iajsKCiAgICBkcmlfYm9fdW5yZWZlcmVuY2Uob2JqX3N1cmZhY2UtPmJvKTsKICAgIG9ial9zdXJmYWNlLT5ibyA9IE5VTEw7CiAgICBvYmplY3RfaGVhcF9mcmVlKGhlYXAsIG9iaik7Cn0KClZBU3RhdHVzIAppOTY1X0NyZWF0ZVN1cmZhY2VzKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgIGludCB3aWR0aCwKICAgICAgICAgICAgICAgICAgICBpbnQgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgIGludCBmb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgaW50IG51bV9zdXJmYWNlcywKICAgICAgICAgICAgICAgICAgICBWQVN1cmZhY2VJRCAqc3VyZmFjZXMpICAgICAgLyogb3V0ICovCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgaW50IGk7CiAgICBWQVN0YXR1cyB2YVN0YXR1cyA9IFZBX1NUQVRVU19TVUNDRVNTOwoKICAgIC8qIFdlIG9ubHkgc3VwcG9ydCBvbmUgZm9ybWF0ICovCiAgICBpZiAoVkFfUlRfRk9STUFUX1lVVjQyMCAhPSBmb3JtYXQpIHsKICAgICAgICByZXR1cm4gVkFfU1RBVFVTX0VSUk9SX1VOU1VQUE9SVEVEX1JUX0ZPUk1BVDsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtX3N1cmZhY2VzOyBpKyspIHsKICAgICAgICBpbnQgc3VyZmFjZUlEID0gTkVXX1NVUkZBQ0VfSUQoKTsKICAgICAgICBzdHJ1Y3Qgb2JqZWN0X3N1cmZhY2UgKm9ial9zdXJmYWNlID0gU1VSRkFDRShzdXJmYWNlSUQpOwoKICAgICAgICBpZiAoTlVMTCA9PSBvYmpfc3VyZmFjZSkgewogICAgICAgICAgICB2YVN0YXR1cyA9IFZBX1NUQVRVU19FUlJPUl9BTExPQ0FUSU9OX0ZBSUxFRDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBzdXJmYWNlc1tpXSA9IHN1cmZhY2VJRDsKICAgICAgICBvYmpfc3VyZmFjZS0+c3RhdHVzID0gVkFTdXJmYWNlUmVhZHk7CiAgICAgICAgb2JqX3N1cmZhY2UtPnN1YnBpYyA9IFZBX0lOVkFMSURfSUQ7CiAgICAgICAgb2JqX3N1cmZhY2UtPndpZHRoID0gd2lkdGg7CiAgICAgICAgb2JqX3N1cmZhY2UtPmhlaWdodCA9IGhlaWdodDsKICAgICAgICBvYmpfc3VyZmFjZS0+c2l6ZSA9IFNJWkVfWVVWNDIwKHdpZHRoLCBoZWlnaHQpOwogICAgICAgIG9ial9zdXJmYWNlLT5ibyA9IGRyaV9ib19hbGxvYyhpOTY1LT5pbnRlbC5idWZtZ3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ2YWFwaSBzdXJmYWNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqX3N1cmZhY2UtPnNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDY0KTsKCiAgICAgICAgYXNzZXJ0KG9ial9zdXJmYWNlLT5ibyk7CiAgICAgICAgaWYgKE5VTEwgPT0gb2JqX3N1cmZhY2UtPmJvKSB7CiAgICAgICAgICAgIHZhU3RhdHVzID0gVkFfU1RBVFVTX0VSUk9SX1VOS05PV047CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBFcnJvciByZWNvdmVyeSAqLwogICAgaWYgKFZBX1NUQVRVU19TVUNDRVNTICE9IHZhU3RhdHVzKSB7CiAgICAgICAgLyogc3VyZmFjZXNbaS0xXSB3YXMgdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBhbGxvY2F0aW9uICovCiAgICAgICAgZm9yICg7IGktLTsgKSB7CiAgICAgICAgICAgIHN0cnVjdCBvYmplY3Rfc3VyZmFjZSAqb2JqX3N1cmZhY2UgPSBTVVJGQUNFKHN1cmZhY2VzW2ldKTsKCiAgICAgICAgICAgIHN1cmZhY2VzW2ldID0gVkFfSU5WQUxJRF9TVVJGQUNFOwogICAgICAgICAgICBhc3NlcnQob2JqX3N1cmZhY2UpOwogICAgICAgICAgICBpOTY1X2Rlc3Ryb3lfc3VyZmFjZSgmaTk2NS0+c3VyZmFjZV9oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX3N1cmZhY2UpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gdmFTdGF0dXM7Cn0KClZBU3RhdHVzIAppOTY1X0Rlc3Ryb3lTdXJmYWNlcyhWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgICAgVkFTdXJmYWNlSUQgKnN1cmZhY2VfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgaW50IG51bV9zdXJmYWNlcykKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBpbnQgaTsKCiAgICBmb3IgKGkgPSBudW1fc3VyZmFjZXM7IGktLTsgKSB7CiAgICAgICAgc3RydWN0IG9iamVjdF9zdXJmYWNlICpvYmpfc3VyZmFjZSA9IFNVUkZBQ0Uoc3VyZmFjZV9saXN0W2ldKTsKCiAgICAgICAgYXNzZXJ0KG9ial9zdXJmYWNlKTsKICAgICAgICBpOTY1X2Rlc3Ryb3lfc3VyZmFjZSgmaTk2NS0+c3VyZmFjZV9oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX3N1cmZhY2UpOwogICAgfQoKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKVkFTdGF0dXMgCmk5NjVfUXVlcnlJbWFnZUZvcm1hdHMoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgVkFJbWFnZUZvcm1hdCAqZm9ybWF0X2xpc3QsICAgICAgLyogb3V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgaW50ICpudW1fZm9ybWF0cykgICAgICAgICAgICAgICAgLyogb3V0ICovCnsKICAgIGlmIChudW1fZm9ybWF0cykKICAgICAgICAqbnVtX2Zvcm1hdHMgPSAwOwoKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKVkFTdGF0dXMgCmk5NjVfUHV0SW1hZ2UoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEIHN1cmZhY2UsCiAgICAgICAgICAgICAgIFZBSW1hZ2VJRCBpbWFnZSwKICAgICAgICAgICAgICAgaW50IHNyY194LAogICAgICAgICAgICAgICBpbnQgc3JjX3ksCiAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBzcmNfd2lkdGgsCiAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBzcmNfaGVpZ2h0LAogICAgICAgICAgICAgICBpbnQgZGVzdF94LAogICAgICAgICAgICAgICBpbnQgZGVzdF95LAogICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgZGVzdF93aWR0aCwKICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGRlc3RfaGVpZ2h0KQp7CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X1F1ZXJ5U3VicGljdHVyZUZvcm1hdHMoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQUltYWdlRm9ybWF0ICpmb3JtYXRfbGlzdCwgICAgICAgICAvKiBvdXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCAqZmxhZ3MsICAgICAgICAgICAgICAgIC8qIG91dCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50ICpudW1fZm9ybWF0cykgICAgICAgICAgLyogb3V0ICovCnsKICAgIGludCBuOwoKICAgIGZvciAobiA9IDA7IGk5NjVfc3VicGljX2Zvcm1hdHNfbWFwW25dLnZhX2Zvcm1hdC5mb3VyY2MgIT0gMDsgbisrKSB7CiAgICAgICAgY29uc3QgaTk2NV9zdWJwaWNfZm9ybWF0X21hcF90ICogY29uc3QgbSA9ICZpOTY1X3N1YnBpY19mb3JtYXRzX21hcFtuXTsKICAgICAgICBpZiAoZm9ybWF0X2xpc3QpCiAgICAgICAgICAgIGZvcm1hdF9saXN0W25dID0gbS0+dmFfZm9ybWF0OwogICAgICAgIGlmIChmbGFncykKICAgICAgICAgICAgZmxhZ3Nbbl0gPSBtLT52YV9mbGFnczsKICAgIH0KCiAgICBpZiAobnVtX2Zvcm1hdHMpCiAgICAgICAgKm51bV9mb3JtYXRzID0gbjsKCiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KCnN0YXRpYyB2b2lkIAppOTY1X2Rlc3Ryb3lfc3VicGljKHN0cnVjdCBvYmplY3RfaGVhcCAqaGVhcCwgc3RydWN0IG9iamVjdF9iYXNlICpvYmopCnsKLy8gICAgc3RydWN0IG9iamVjdF9zdWJwaWMgKm9ial9zdWJwaWMgPSAoc3RydWN0IG9iamVjdF9zdWJwaWMgKilvYmo7CgogICAgb2JqZWN0X2hlYXBfZnJlZShoZWFwLCBvYmopOwp9CgpWQVN0YXR1cyAKaTk2NV9DcmVhdGVTdWJwaWN0dXJlKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgVkFJbWFnZUlEIGltYWdlLAogICAgICAgICAgICAgICAgICAgICAgVkFTdWJwaWN0dXJlSUQgKnN1YnBpY3R1cmUpICAgICAgICAgLyogb3V0ICovCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgVkFTdWJwaWN0dXJlSUQgc3VicGljSUQgPSBORVdfU1VCUElDX0lEKCkKCQogICAgc3RydWN0IG9iamVjdF9zdWJwaWMgKm9ial9zdWJwaWMgPSBTVUJQSUMoc3VicGljSUQpOwogICAgaWYgKCFvYmpfc3VicGljKQogICAgICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfQUxMT0NBVElPTl9GQUlMRUQ7CgogICAgc3RydWN0IG9iamVjdF9pbWFnZSAqb2JqX2ltYWdlID0gSU1BR0UoaW1hZ2UpOwogICAgaWYgKCFvYmpfaW1hZ2UpCiAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9JTlZBTElEX0lNQUdFOwoKICAgIGNvbnN0IGk5NjVfc3VicGljX2Zvcm1hdF9tYXBfdCAqIGNvbnN0IG0gPSBnZXRfc3VicGljX2Zvcm1hdCgmb2JqX2ltYWdlLT5pbWFnZS5mb3JtYXQpOwogICAgaWYgKCFtKQogICAgICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfVU5LTk9XTjsgLyogWFhYOiBWQV9TVEFUVVNfRVJST1JfVU5TVVBQT1JURURfRk9STUFUPyAqLwoKICAgICpzdWJwaWN0dXJlID0gc3VicGljSUQ7CiAgICBvYmpfc3VicGljLT5pbWFnZSAgPSBpbWFnZTsKICAgIG9ial9zdWJwaWMtPmZvcm1hdCA9IG0tPmZvcm1hdDsKICAgIG9ial9zdWJwaWMtPndpZHRoICA9IG9ial9pbWFnZS0+aW1hZ2Uud2lkdGg7CiAgICBvYmpfc3VicGljLT5oZWlnaHQgPSBvYmpfaW1hZ2UtPmltYWdlLmhlaWdodDsKICAgIG9ial9zdWJwaWMtPmJvICAgICA9IG9ial9pbWFnZS0+Ym87CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X0Rlc3Ryb3lTdWJwaWN0dXJlKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgIFZBU3VicGljdHVyZUlEIHN1YnBpY3R1cmUpCnsKCQogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X3N1YnBpYyAqb2JqX3N1YnBpYyA9IFNVQlBJQyhzdWJwaWN0dXJlKTsKICAgIGk5NjVfZGVzdHJveV9zdWJwaWMoJmk5NjUtPnN1YnBpY19oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX3N1YnBpYyk7CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X1NldFN1YnBpY3R1cmVJbWFnZShWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgVkFTdWJwaWN0dXJlSUQgc3VicGljdHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgVkFJbWFnZUlEIGltYWdlKQp7CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X1NldFN1YnBpY3R1cmVDaHJvbWFrZXkoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQVN1YnBpY3R1cmVJRCBzdWJwaWN0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IGNocm9tYWtleV9taW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgY2hyb21ha2V5X21heCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBjaHJvbWFrZXlfbWFzaykKewogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgpWQVN0YXR1cyAKaTk2NV9TZXRTdWJwaWN0dXJlR2xvYmFsQWxwaGEoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBU3VicGljdHVyZUlEIHN1YnBpY3R1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsb2F0IGdsb2JhbF9hbHBoYSkKewogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgpWQVN0YXR1cyAKaTk2NV9Bc3NvY2lhdGVTdWJwaWN0dXJlKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgVkFTdWJwaWN0dXJlSUQgc3VicGljdHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEICp0YXJnZXRfc3VyZmFjZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtX3N1cmZhY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgc3JjX3gsIC8qIHVwcGVyIGxlZnQgb2Zmc2V0IGluIHN1YnBpY3R1cmUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHNyY195LAogICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgc3JjX3dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgc3JjX2hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGRlc3RfeCwgLyogdXBwZXIgbGVmdCBvZmZzZXQgaW4gc3VyZmFjZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgZGVzdF95LAogICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgZGVzdF93aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IGRlc3RfaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICAqIHdoZXRoZXIgdG8gZW5hYmxlIGNocm9tYS1rZXlpbmcgb3IgZ2xvYmFsLWFscGhhCiAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzZWUgVkFfU1VCUElDVFVSRV9YWFggdmFsdWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncykKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X3N1YnBpYyAqb2JqX3N1YnBpYyA9IFNVQlBJQyhzdWJwaWN0dXJlKTsKICAgIGludCBpOwoKICAgIG9ial9zdWJwaWMtPnNyY19yZWN0LnggICAgICA9IHNyY194OwogICAgb2JqX3N1YnBpYy0+c3JjX3JlY3QueSAgICAgID0gc3JjX3k7CiAgICBvYmpfc3VicGljLT5zcmNfcmVjdC53aWR0aCAgPSBzcmNfd2lkdGg7CiAgICBvYmpfc3VicGljLT5zcmNfcmVjdC5oZWlnaHQgPSBzcmNfaGVpZ2h0OwogICAgb2JqX3N1YnBpYy0+ZHN0X3JlY3QueCAgICAgID0gZGVzdF94OwogICAgb2JqX3N1YnBpYy0+ZHN0X3JlY3QueSAgICAgID0gZGVzdF95OwogICAgb2JqX3N1YnBpYy0+ZHN0X3JlY3Qud2lkdGggID0gZGVzdF93aWR0aDsKICAgIG9ial9zdWJwaWMtPmRzdF9yZWN0LmhlaWdodCA9IGRlc3RfaGVpZ2h0OwoKICAgIGZvciAoaSA9IDA7IGkgPCBudW1fc3VyZmFjZXM7IGkrKykgewogICAgICAgIHN0cnVjdCBvYmplY3Rfc3VyZmFjZSAqb2JqX3N1cmZhY2UgPSBTVVJGQUNFKHRhcmdldF9zdXJmYWNlc1tpXSk7CiAgICAgICAgaWYgKCFvYmpfc3VyZmFjZSkKICAgICAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9JTlZBTElEX1NVUkZBQ0U7CiAgICAgICAgb2JqX3N1cmZhY2UtPnN1YnBpYyA9IHN1YnBpY3R1cmU7CiAgICB9CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KCgpWQVN0YXR1cyAKaTk2NV9EZWFzc29jaWF0ZVN1YnBpY3R1cmUoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBU3VicGljdHVyZUlEIHN1YnBpY3R1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEICp0YXJnZXRfc3VyZmFjZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1fc3VyZmFjZXMpCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8IG51bV9zdXJmYWNlczsgaSsrKSB7CiAgICAgICAgc3RydWN0IG9iamVjdF9zdXJmYWNlICpvYmpfc3VyZmFjZSA9IFNVUkZBQ0UodGFyZ2V0X3N1cmZhY2VzW2ldKTsKICAgICAgICBpZiAoIW9ial9zdXJmYWNlKQogICAgICAgICAgICByZXR1cm4gVkFfU1RBVFVTX0VSUk9SX0lOVkFMSURfU1VSRkFDRTsKICAgICAgICBpZiAob2JqX3N1cmZhY2UtPnN1YnBpYyA9PSBzdWJwaWN0dXJlKQogICAgICAgICAgICBvYmpfc3VyZmFjZS0+c3VicGljID0gVkFfSU5WQUxJRF9JRDsKICAgIH0KICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKc3RhdGljIHZvaWQKaTk2NV9yZWZlcmVuY2VfYnVmZmVyX3N0b3JlKHN0cnVjdCBidWZmZXJfc3RvcmUgKipwdHIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IGJ1ZmZlcl9zdG9yZSAqYnVmZmVyX3N0b3JlKQp7CiAgICBhc3NlcnQoKnB0ciA9PSBOVUxMKTsKCiAgICBpZiAoYnVmZmVyX3N0b3JlKSB7CiAgICAgICAgYnVmZmVyX3N0b3JlLT5yZWZfY291bnQrKzsKICAgICAgICAqcHRyID0gYnVmZmVyX3N0b3JlOwogICAgfQp9CgpzdGF0aWMgdm9pZCAKaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZShzdHJ1Y3QgYnVmZmVyX3N0b3JlICoqcHRyKQp7CiAgICBzdHJ1Y3QgYnVmZmVyX3N0b3JlICpidWZmZXJfc3RvcmUgPSAqcHRyOwoKICAgIGlmIChidWZmZXJfc3RvcmUgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgYXNzZXJ0KGJ1ZmZlcl9zdG9yZS0+Ym8gfHwgYnVmZmVyX3N0b3JlLT5idWZmZXIpOwogICAgYXNzZXJ0KCEoYnVmZmVyX3N0b3JlLT5ibyAmJiBidWZmZXJfc3RvcmUtPmJ1ZmZlcikpOwogICAgYnVmZmVyX3N0b3JlLT5yZWZfY291bnQtLTsKICAgIAogICAgaWYgKGJ1ZmZlcl9zdG9yZS0+cmVmX2NvdW50ID09IDApIHsKICAgICAgICBkcmlfYm9fdW5yZWZlcmVuY2UoYnVmZmVyX3N0b3JlLT5ibyk7CiAgICAgICAgZnJlZShidWZmZXJfc3RvcmUtPmJ1ZmZlcik7CiAgICAgICAgYnVmZmVyX3N0b3JlLT5ibyA9IE5VTEw7CiAgICAgICAgYnVmZmVyX3N0b3JlLT5idWZmZXIgPSBOVUxMOwogICAgICAgIGZyZWUoYnVmZmVyX3N0b3JlKTsKICAgIH0KCiAgICAqcHRyID0gTlVMTDsKfQoKc3RhdGljIHZvaWQgCmk5NjVfZGVzdHJveV9jb250ZXh0KHN0cnVjdCBvYmplY3RfaGVhcCAqaGVhcCwgc3RydWN0IG9iamVjdF9iYXNlICpvYmopCnsKICAgIHN0cnVjdCBvYmplY3RfY29udGV4dCAqb2JqX2NvbnRleHQgPSAoc3RydWN0IG9iamVjdF9jb250ZXh0ICopb2JqOwoKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUucGljX3BhcmFtKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuc2xpY2VfcGFyYW0pOwogICAgaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5pcV9tYXRyaXgpOwogICAgaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5iaXRfcGxhbmUpOwogICAgaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5zbGljZV9kYXRhKTsKICAgIGZyZWUob2JqX2NvbnRleHQtPnJlbmRlcl90YXJnZXRzKTsKICAgIG9iamVjdF9oZWFwX2ZyZWUoaGVhcCwgb2JqKTsKfQoKVkFTdGF0dXMgCmk5NjVfQ3JlYXRlQ29udGV4dChWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgIFZBQ29uZmlnSUQgY29uZmlnX2lkLAogICAgICAgICAgICAgICAgICAgaW50IHBpY3R1cmVfd2lkdGgsCiAgICAgICAgICAgICAgICAgICBpbnQgcGljdHVyZV9oZWlnaHQsCiAgICAgICAgICAgICAgICAgICBpbnQgZmxhZywKICAgICAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEICpyZW5kZXJfdGFyZ2V0cywKICAgICAgICAgICAgICAgICAgIGludCBudW1fcmVuZGVyX3RhcmdldHMsCiAgICAgICAgICAgICAgICAgICBWQUNvbnRleHRJRCAqY29udGV4dCkgICAgICAgICAgICAgICAgLyogb3V0ICovCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgc3RydWN0IG9iamVjdF9jb25maWcgKm9ial9jb25maWcgPSBDT05GSUcoY29uZmlnX2lkKTsKICAgIHN0cnVjdCBvYmplY3RfY29udGV4dCAqb2JqX2NvbnRleHQgPSBOVUxMOwogICAgVkFTdGF0dXMgdmFTdGF0dXMgPSBWQV9TVEFUVVNfU1VDQ0VTUzsKICAgIGludCBjb250ZXh0SUQ7CiAgICBpbnQgaTsKCiAgICBpZiAoTlVMTCA9PSBvYmpfY29uZmlnKSB7CiAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfRVJST1JfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgcmV0dXJuIHZhU3RhdHVzOwogICAgfQoKICAgIC8qIFZhbGlkYXRlIGZsYWcgKi8KICAgIC8qIFZhbGlkYXRlIHBpY3R1cmUgZGltZW5zaW9ucyAqLwogICAgY29udGV4dElEID0gTkVXX0NPTlRFWFRfSUQoKTsKICAgIG9ial9jb250ZXh0ID0gQ09OVEVYVChjb250ZXh0SUQpOwoKICAgIGlmIChOVUxMID09IG9ial9jb250ZXh0KSB7CiAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfRVJST1JfQUxMT0NBVElPTl9GQUlMRUQ7CiAgICAgICAgcmV0dXJuIHZhU3RhdHVzOwogICAgfQoKICAgIG9ial9jb250ZXh0LT5jb250ZXh0X2lkID0gY29udGV4dElEOwogICAgKmNvbnRleHQgPSBjb250ZXh0SUQ7CiAgICBtZW1zZXQoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUsIDAsIHNpemVvZihvYmpfY29udGV4dC0+ZGVjb2RlX3N0YXRlKSk7CiAgICBvYmpfY29udGV4dC0+ZGVjb2RlX3N0YXRlLmN1cnJlbnRfcmVuZGVyX3RhcmdldCA9IC0xOwogICAgb2JqX2NvbnRleHQtPmNvbmZpZ19pZCA9IGNvbmZpZ19pZDsKICAgIG9ial9jb250ZXh0LT5waWN0dXJlX3dpZHRoID0gcGljdHVyZV93aWR0aDsKICAgIG9ial9jb250ZXh0LT5waWN0dXJlX2hlaWdodCA9IHBpY3R1cmVfaGVpZ2h0OwogICAgb2JqX2NvbnRleHQtPm51bV9yZW5kZXJfdGFyZ2V0cyA9IG51bV9yZW5kZXJfdGFyZ2V0czsKICAgIG9ial9jb250ZXh0LT5yZW5kZXJfdGFyZ2V0cyA9IAogICAgICAgIChWQVN1cmZhY2VJRCAqKWNhbGxvYyhudW1fcmVuZGVyX3RhcmdldHMsIHNpemVvZihWQVN1cmZhY2VJRCkpOwoKICAgIGZvcihpID0gMDsgaSA8IG51bV9yZW5kZXJfdGFyZ2V0czsgaSsrKSB7CiAgICAgICAgaWYgKE5VTEwgPT0gU1VSRkFDRShyZW5kZXJfdGFyZ2V0c1tpXSkpIHsKICAgICAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfRVJST1JfSU5WQUxJRF9TVVJGQUNFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIG9ial9jb250ZXh0LT5yZW5kZXJfdGFyZ2V0c1tpXSA9IHJlbmRlcl90YXJnZXRzW2ldOwogICAgfQoKICAgIG9ial9jb250ZXh0LT5mbGFncyA9IGZsYWc7CgogICAgLyogRXJyb3IgcmVjb3ZlcnkgKi8KICAgIGlmIChWQV9TVEFUVVNfU1VDQ0VTUyAhPSB2YVN0YXR1cykgewogICAgICAgIGk5NjVfZGVzdHJveV9jb250ZXh0KCZpOTY1LT5jb250ZXh0X2hlYXAsIChzdHJ1Y3Qgb2JqZWN0X2Jhc2UgKilvYmpfY29udGV4dCk7CiAgICB9CgogICAgcmV0dXJuIHZhU3RhdHVzOwp9CgpWQVN0YXR1cyAKaTk2NV9EZXN0cm95Q29udGV4dChWQURyaXZlckNvbnRleHRQIGN0eCwgVkFDb250ZXh0SUQgY29udGV4dCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2NvbnRleHQgKm9ial9jb250ZXh0ID0gQ09OVEVYVChjb250ZXh0KTsKCiAgICBhc3NlcnQob2JqX2NvbnRleHQpOwogICAgaTk2NV9kZXN0cm95X2NvbnRleHQoJmk5NjUtPmNvbnRleHRfaGVhcCwgKHN0cnVjdCBvYmplY3RfYmFzZSAqKW9ial9jb250ZXh0KTsKCiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KCnN0YXRpYyB2b2lkIAppOTY1X2Rlc3Ryb3lfYnVmZmVyKHN0cnVjdCBvYmplY3RfaGVhcCAqaGVhcCwgc3RydWN0IG9iamVjdF9iYXNlICpvYmopCnsKICAgIHN0cnVjdCBvYmplY3RfYnVmZmVyICpvYmpfYnVmZmVyID0gKHN0cnVjdCBvYmplY3RfYnVmZmVyICopb2JqOwoKICAgIGFzc2VydChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUpOwogICAgaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZSgmb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlKTsKICAgIG9iamVjdF9oZWFwX2ZyZWUoaGVhcCwgb2JqKTsKfQoKVkFTdGF0dXMgCmk5NjVfQ3JlYXRlQnVmZmVyKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICBWQUNvbnRleHRJRCBjb250ZXh0LCAgICAgICAgICAvKiBpbiAqLwogICAgICAgICAgICAgICAgICBWQUJ1ZmZlclR5cGUgdHlwZSwgICAgICAgICAgICAvKiBpbiAqLwogICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgc2l6ZSwgICAgICAgICAgICAvKiBpbiAqLwogICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgbnVtX2VsZW1lbnRzLCAgICAvKiBpbiAqLwogICAgICAgICAgICAgICAgICB2b2lkICpkYXRhLCAgICAgICAgICAgICAgICAgICAvKiBpbiAqLwogICAgICAgICAgICAgICAgICBWQUJ1ZmZlcklEICpidWZfaWQpICAgICAgICAgICAvKiBvdXQgKi8KewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2J1ZmZlciAqb2JqX2J1ZmZlciA9IE5VTEw7CiAgICBzdHJ1Y3QgYnVmZmVyX3N0b3JlICpidWZmZXJfc3RvcmUgPSBOVUxMOwogICAgaW50IGJ1ZmZlcklEOwoKICAgIC8qIFZhbGlkYXRlIHR5cGUgKi8KICAgIHN3aXRjaCAodHlwZSkgewogICAgY2FzZSBWQVBpY3R1cmVQYXJhbWV0ZXJCdWZmZXJUeXBlOgogICAgY2FzZSBWQUlRTWF0cml4QnVmZmVyVHlwZToKICAgIGNhc2UgVkFCaXRQbGFuZUJ1ZmZlclR5cGU6CiAgICBjYXNlIFZBU2xpY2VHcm91cE1hcEJ1ZmZlclR5cGU6CiAgICBjYXNlIFZBU2xpY2VQYXJhbWV0ZXJCdWZmZXJUeXBlOgogICAgY2FzZSBWQVNsaWNlRGF0YUJ1ZmZlclR5cGU6CiAgICBjYXNlIFZBTWFjcm9ibG9ja1BhcmFtZXRlckJ1ZmZlclR5cGU6CiAgICBjYXNlIFZBUmVzaWR1YWxEYXRhQnVmZmVyVHlwZToKICAgIGNhc2UgVkFEZWJsb2NraW5nUGFyYW1ldGVyQnVmZmVyVHlwZToKICAgIGNhc2UgVkFJbWFnZUJ1ZmZlclR5cGU6CiAgICAgICAgLyogT2sgKi8KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfVU5TVVBQT1JURURfQlVGRkVSVFlQRTsKICAgIH0KCiAgICBidWZmZXJJRCA9IE5FV19CVUZGRVJfSUQoKTsKICAgIG9ial9idWZmZXIgPSBCVUZGRVIoYnVmZmVySUQpOwoKICAgIGlmIChOVUxMID09IG9ial9idWZmZXIpIHsKICAgICAgICByZXR1cm4gVkFfU1RBVFVTX0VSUk9SX0FMTE9DQVRJT05fRkFJTEVEOwogICAgfQoKICAgIG9ial9idWZmZXItPm1heF9udW1fZWxlbWVudHMgPSBudW1fZWxlbWVudHM7CiAgICBvYmpfYnVmZmVyLT5udW1fZWxlbWVudHMgPSBudW1fZWxlbWVudHM7CiAgICBvYmpfYnVmZmVyLT5zaXplX2VsZW1lbnQgPSBzaXplOwogICAgb2JqX2J1ZmZlci0+dHlwZSA9IHR5cGU7CiAgICBvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUgPSBOVUxMOwogICAgYnVmZmVyX3N0b3JlID0gY2FsbG9jKDEsIHNpemVvZihzdHJ1Y3QgYnVmZmVyX3N0b3JlKSk7CiAgICBhc3NlcnQoYnVmZmVyX3N0b3JlKTsKICAgIGJ1ZmZlcl9zdG9yZS0+cmVmX2NvdW50ID0gMTsKCiAgICBpZiAodHlwZSA9PSBWQVNsaWNlRGF0YUJ1ZmZlclR5cGUgfHwgdHlwZSA9PSBWQUltYWdlQnVmZmVyVHlwZSkgewogICAgICAgIGJ1ZmZlcl9zdG9yZS0+Ym8gPSBkcmlfYm9fYWxsb2MoaTk2NS0+aW50ZWwuYnVmbWdyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQnVmZmVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSAqIG51bV9lbGVtZW50cywgNjQpOwogICAgICAgIGFzc2VydChidWZmZXJfc3RvcmUtPmJvKTsKCiAgICAgICAgaWYgKGRhdGEpCiAgICAgICAgICAgIGRyaV9ib19zdWJkYXRhKGJ1ZmZlcl9zdG9yZS0+Ym8sIDAsIHNpemUgKiBudW1fZWxlbWVudHMsIGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgICBidWZmZXJfc3RvcmUtPmJ1ZmZlciA9IG1hbGxvYyhzaXplICogbnVtX2VsZW1lbnRzKTsKICAgICAgICBhc3NlcnQoYnVmZmVyX3N0b3JlLT5idWZmZXIpOwoKICAgICAgICBpZiAoZGF0YSkKICAgICAgICAgICAgbWVtY3B5KGJ1ZmZlcl9zdG9yZS0+YnVmZmVyLCBkYXRhLCBzaXplICogbnVtX2VsZW1lbnRzKTsKICAgIH0KCiAgICBpOTY1X3JlZmVyZW5jZV9idWZmZXJfc3RvcmUoJm9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZSwgYnVmZmVyX3N0b3JlKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJmJ1ZmZlcl9zdG9yZSk7CiAgICAqYnVmX2lkID0gYnVmZmVySUQ7CgogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgoKVkFTdGF0dXMgCmk5NjVfQnVmZmVyU2V0TnVtRWxlbWVudHMoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVkFCdWZmZXJJRCBidWZfaWQsICAgICAgICAgICAvKiBpbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBudW1fZWxlbWVudHMpICAgLyogaW4gKi8KewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2J1ZmZlciAqb2JqX2J1ZmZlciA9IEJVRkZFUihidWZfaWQpOwogICAgVkFTdGF0dXMgdmFTdGF0dXMgPSBWQV9TVEFUVVNfU1VDQ0VTUzsKCiAgICBhc3NlcnQob2JqX2J1ZmZlcik7CgogICAgaWYgKChudW1fZWxlbWVudHMgPCAwKSB8fCAKICAgICAgICAobnVtX2VsZW1lbnRzID4gb2JqX2J1ZmZlci0+bWF4X251bV9lbGVtZW50cykpIHsKICAgICAgICB2YVN0YXR1cyA9IFZBX1NUQVRVU19FUlJPUl9VTktOT1dOOwogICAgfSBlbHNlIHsKICAgICAgICBvYmpfYnVmZmVyLT5udW1fZWxlbWVudHMgPSBudW1fZWxlbWVudHM7CiAgICB9CgogICAgcmV0dXJuIHZhU3RhdHVzOwp9CgpWQVN0YXR1cyAKaTk2NV9NYXBCdWZmZXIoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgIFZBQnVmZmVySUQgYnVmX2lkLCAgICAgICAvKiBpbiAqLwogICAgICAgICAgICAgICB2b2lkICoqcGJ1ZikgICAgICAgICAgICAgLyogb3V0ICovCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgc3RydWN0IG9iamVjdF9idWZmZXIgKm9ial9idWZmZXIgPSBCVUZGRVIoYnVmX2lkKTsKICAgIFZBU3RhdHVzIHZhU3RhdHVzID0gVkFfU1RBVFVTX0VSUk9SX1VOS05PV047CgogICAgYXNzZXJ0KG9ial9idWZmZXIgJiYgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlKTsKICAgIGFzc2VydChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvIHx8IG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyKTsKICAgIGFzc2VydCghKG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+Ym8gJiYgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlLT5idWZmZXIpKTsKCiAgICBpZiAoTlVMTCAhPSBvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvKSB7CiAgICAgICAgZHJpX2JvX21hcChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvLCAxKTsKICAgICAgICBhc3NlcnQob2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlLT5iby0+dmlydHVhbCk7CiAgICAgICAgKnBidWYgPSBvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvLT52aXJ0dWFsOwogICAgICAgIHZhU3RhdHVzID0gVkFfU1RBVFVTX1NVQ0NFU1M7CiAgICB9IGVsc2UgaWYgKE5VTEwgIT0gb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlLT5idWZmZXIpIHsKICAgICAgICAqcGJ1ZiA9IG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyOwogICAgICAgIHZhU3RhdHVzID0gVkFfU1RBVFVTX1NVQ0NFU1M7CiAgICB9CgogICAgcmV0dXJuIHZhU3RhdHVzOwp9CgpWQVN0YXR1cyAKaTk2NV9Vbm1hcEJ1ZmZlcihWQURyaXZlckNvbnRleHRQIGN0eCwgVkFCdWZmZXJJRCBidWZfaWQpCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOwogICAgc3RydWN0IG9iamVjdF9idWZmZXIgKm9ial9idWZmZXIgPSBCVUZGRVIoYnVmX2lkKTsKICAgIFZBU3RhdHVzIHZhU3RhdHVzID0gVkFfU1RBVFVTX0VSUk9SX1VOS05PV047CgogICAgYXNzZXJ0KG9ial9idWZmZXIgJiYgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlKTsKICAgIGFzc2VydChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvIHx8IG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyKTsKICAgIGFzc2VydCghKG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+Ym8gJiYgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlLT5idWZmZXIpKTsKCiAgICBpZiAoTlVMTCAhPSBvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvKSB7CiAgICAgICAgZHJpX2JvX3VubWFwKG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+Ym8pOwogICAgICAgIHZhU3RhdHVzID0gVkFfU1RBVFVTX1NVQ0NFU1M7CiAgICB9IGVsc2UgaWYgKE5VTEwgIT0gb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlLT5idWZmZXIpIHsKICAgICAgICAvKiBEbyBub3RoaW5nICovCiAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfU1VDQ0VTUzsKICAgIH0KCiAgICByZXR1cm4gdmFTdGF0dXM7ICAgIAp9CgpWQVN0YXR1cyAKaTk2NV9EZXN0cm95QnVmZmVyKFZBRHJpdmVyQ29udGV4dFAgY3R4LCBWQUJ1ZmZlcklEIGJ1ZmZlcl9pZCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2J1ZmZlciAqb2JqX2J1ZmZlciA9IEJVRkZFUihidWZmZXJfaWQpOwoKICAgIGFzc2VydChvYmpfYnVmZmVyKTsKICAgIGk5NjVfZGVzdHJveV9idWZmZXIoJmk5NjUtPmJ1ZmZlcl9oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX2J1ZmZlcik7CgogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgpWQVN0YXR1cyAKaTk2NV9CZWdpblBpY3R1cmUoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgIFZBQ29udGV4dElEIGNvbnRleHQsCiAgICAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEIHJlbmRlcl90YXJnZXQpCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOyAKICAgIHN0cnVjdCBvYmplY3RfY29udGV4dCAqb2JqX2NvbnRleHQgPSBDT05URVhUKGNvbnRleHQpOwogICAgc3RydWN0IG9iamVjdF9zdXJmYWNlICpvYmpfc3VyZmFjZSA9IFNVUkZBQ0UocmVuZGVyX3RhcmdldCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2NvbmZpZyAqb2JqX2NvbmZpZzsKICAgIFZBQ29udGV4dElEIGNvbmZpZzsKICAgIFZBU3RhdHVzIHZhU3RhdHVzOwoKICAgIGFzc2VydChvYmpfY29udGV4dCk7CiAgICBhc3NlcnQob2JqX3N1cmZhY2UpOwoKICAgIGNvbmZpZyA9IG9ial9jb250ZXh0LT5jb25maWdfaWQ7CiAgICBvYmpfY29uZmlnID0gQ09ORklHKGNvbmZpZyk7CiAgICBhc3NlcnQob2JqX2NvbmZpZyk7CgogICAgc3dpdGNoIChvYmpfY29uZmlnLT5wcm9maWxlKSB7CiAgICBjYXNlIFZBUHJvZmlsZU1QRUcyU2ltcGxlOgogICAgY2FzZSBWQVByb2ZpbGVNUEVHMk1haW46CiAgICAgICAgdmFTdGF0dXMgPSBWQV9TVEFUVVNfU1VDQ0VTUzsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIGFzc2VydCgwKTsKICAgICAgICB2YVN0YXR1cyA9IFZBX1NUQVRVU19FUlJPUl9VTlNVUFBPUlRFRF9QUk9GSUxFOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIG9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuY3VycmVudF9yZW5kZXJfdGFyZ2V0ID0gcmVuZGVyX3RhcmdldDsKCiAgICByZXR1cm4gdmFTdGF0dXM7Cn0KCnN0YXRpYyBWQVN0YXR1cwppOTY1X3JlbmRlcl9waWN0dXJlX3BhcmFtZXRlcl9idWZmZXIoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgb2JqZWN0X2NvbnRleHQgKm9ial9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IG9iamVjdF9idWZmZXIgKm9ial9idWZmZXIpCnsKICAgIGFzc2VydChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvID09IE5VTEwpOwogICAgYXNzZXJ0KG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUucGljX3BhcmFtKTsKICAgIGk5NjVfcmVmZXJlbmNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5waWNfcGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlKTsKCiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KCnN0YXRpYyBWQVN0YXR1cwppOTY1X3JlbmRlcl9pcV9tYXRyaXhfYnVmZmVyKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBvYmplY3RfY29udGV4dCAqb2JqX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IG9iamVjdF9idWZmZXIgKm9ial9idWZmZXIpCnsKICAgIGFzc2VydChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvID09IE5VTEwpOwogICAgYXNzZXJ0KG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuaXFfbWF0cml4KTsKICAgIGk5NjVfcmVmZXJlbmNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5pcV9tYXRyaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlKTsKCiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KCnN0YXRpYyBWQVN0YXR1cwppOTY1X3JlbmRlcl9iaXRfcGxhbmVfYnVmZmVyKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBvYmplY3RfY29udGV4dCAqb2JqX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IG9iamVjdF9idWZmZXIgKm9ial9idWZmZXIpCnsKICAgIGFzc2VydChvYmpfYnVmZmVyLT5idWZmZXJfc3RvcmUtPmJvID09IE5VTEwpOwogICAgYXNzZXJ0KG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuYml0X3BsYW5lKTsKICAgIGk5NjVfcmVmZXJlbmNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5iaXRfcGxhbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZSk7CiAgICAKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKc3RhdGljIFZBU3RhdHVzCmk5NjVfcmVuZGVyX3NsaWNlX3BhcmFtZXRlcl9idWZmZXIoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IG9iamVjdF9jb250ZXh0ICpvYmpfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgb2JqZWN0X2J1ZmZlciAqb2JqX2J1ZmZlcikKewogICAgYXNzZXJ0KG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+Ym8gPT0gTlVMTCk7CiAgICBhc3NlcnQob2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlLT5idWZmZXIpOwogICAgaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5zbGljZV9wYXJhbSk7CiAgICBpOTY1X3JlZmVyZW5jZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuc2xpY2VfcGFyYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqX2J1ZmZlci0+YnVmZmVyX3N0b3JlKTsKICAgIG9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUubnVtX3NsaWNlcyA9IG9ial9idWZmZXItPm51bV9lbGVtZW50czsgICAgCiAgICAKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKc3RhdGljIFZBU3RhdHVzCmk5NjVfcmVuZGVyX3NsaWNlX2RhdGFfYnVmZmVyKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgb2JqZWN0X2NvbnRleHQgKm9ial9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3Qgb2JqZWN0X2J1ZmZlciAqb2JqX2J1ZmZlcikKewogICAgYXNzZXJ0KG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+YnVmZmVyID09IE5VTEwpOwogICAgYXNzZXJ0KG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZS0+Ym8pOwogICAgaTk2NV9yZWxlYXNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5zbGljZV9kYXRhKTsKICAgIGk5NjVfcmVmZXJlbmNlX2J1ZmZlcl9zdG9yZSgmb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5zbGljZV9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ial9idWZmZXItPmJ1ZmZlcl9zdG9yZSk7CiAgICAKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKVkFTdGF0dXMgCmk5NjVfUmVuZGVyUGljdHVyZShWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgIFZBQ29udGV4dElEIGNvbnRleHQsCiAgICAgICAgICAgICAgICAgICBWQUJ1ZmZlcklEICpidWZmZXJzLAogICAgICAgICAgICAgICAgICAgaW50IG51bV9idWZmZXJzKQp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsKICAgIHN0cnVjdCBvYmplY3RfY29udGV4dCAqb2JqX2NvbnRleHQ7CiAgICBpbnQgaTsKICAgIFZBU3RhdHVzIHZhU3RhdHVzID0gVkFfU1RBVFVTX0VSUk9SX1VOS05PV047CgogICAgb2JqX2NvbnRleHQgPSBDT05URVhUKGNvbnRleHQpOwogICAgYXNzZXJ0KG9ial9jb250ZXh0KTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtX2J1ZmZlcnM7IGkrKykgewogICAgICAgIHN0cnVjdCBvYmplY3RfYnVmZmVyICpvYmpfYnVmZmVyID0gQlVGRkVSKGJ1ZmZlcnNbaV0pOwogICAgICAgIGFzc2VydChvYmpfYnVmZmVyKTsKCiAgICAgICAgc3dpdGNoIChvYmpfYnVmZmVyLT50eXBlKSB7CiAgICAgICAgY2FzZSBWQVBpY3R1cmVQYXJhbWV0ZXJCdWZmZXJUeXBlOgogICAgICAgICAgICB2YVN0YXR1cyA9IGk5NjVfcmVuZGVyX3BpY3R1cmVfcGFyYW1ldGVyX2J1ZmZlcihjdHgsIG9ial9jb250ZXh0LCBvYmpfYnVmZmVyKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgICAgIGNhc2UgVkFJUU1hdHJpeEJ1ZmZlclR5cGU6CiAgICAgICAgICAgIHZhU3RhdHVzID0gaTk2NV9yZW5kZXJfaXFfbWF0cml4X2J1ZmZlcihjdHgsIG9ial9jb250ZXh0LCBvYmpfYnVmZmVyKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgVkFCaXRQbGFuZUJ1ZmZlclR5cGU6CiAgICAgICAgICAgIHZhU3RhdHVzID0gaTk2NV9yZW5kZXJfYml0X3BsYW5lX2J1ZmZlcihjdHgsIG9ial9jb250ZXh0LCBvYmpfYnVmZmVyKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgVkFTbGljZVBhcmFtZXRlckJ1ZmZlclR5cGU6CiAgICAgICAgICAgIHZhU3RhdHVzID0gaTk2NV9yZW5kZXJfc2xpY2VfcGFyYW1ldGVyX2J1ZmZlcihjdHgsIG9ial9jb250ZXh0LCBvYmpfYnVmZmVyKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgVkFTbGljZURhdGFCdWZmZXJUeXBlOgogICAgICAgICAgICB2YVN0YXR1cyA9IGk5NjVfcmVuZGVyX3NsaWNlX2RhdGFfYnVmZmVyKGN0eCwgb2JqX2NvbnRleHQsIG9ial9idWZmZXIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiB2YVN0YXR1czsKfQoKVkFTdGF0dXMgCmk5NjVfRW5kUGljdHVyZShWQURyaXZlckNvbnRleHRQIGN0eCwgVkFDb250ZXh0SUQgY29udGV4dCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7IAogICAgc3RydWN0IG9iamVjdF9jb250ZXh0ICpvYmpfY29udGV4dCA9IENPTlRFWFQoY29udGV4dCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2NvbmZpZyAqb2JqX2NvbmZpZzsKICAgIFZBQ29udGV4dElEIGNvbmZpZzsKCiAgICBhc3NlcnQob2JqX2NvbnRleHQpOwogICAgYXNzZXJ0KG9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUucGljX3BhcmFtKTsKICAgIGFzc2VydChvYmpfY29udGV4dC0+ZGVjb2RlX3N0YXRlLnNsaWNlX3BhcmFtKTsKICAgIGFzc2VydChvYmpfY29udGV4dC0+ZGVjb2RlX3N0YXRlLnNsaWNlX2RhdGEpOwoKICAgIGNvbmZpZyA9IG9ial9jb250ZXh0LT5jb25maWdfaWQ7CiAgICBvYmpfY29uZmlnID0gQ09ORklHKGNvbmZpZyk7CiAgICBhc3NlcnQob2JqX2NvbmZpZyk7CiAgICBpOTY1X21lZGlhX2RlY29kZV9waWN0dXJlKGN0eCwgb2JqX2NvbmZpZy0+cHJvZmlsZSwgJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUpOwogICAgb2JqX2NvbnRleHQtPmRlY29kZV9zdGF0ZS5jdXJyZW50X3JlbmRlcl90YXJnZXQgPSAtMTsKICAgIG9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUubnVtX3NsaWNlcyA9IDA7CiAgICBpOTY1X3JlbGVhc2VfYnVmZmVyX3N0b3JlKCZvYmpfY29udGV4dC0+ZGVjb2RlX3N0YXRlLnBpY19wYXJhbSk7CiAgICBpOTY1X3JlbGVhc2VfYnVmZmVyX3N0b3JlKCZvYmpfY29udGV4dC0+ZGVjb2RlX3N0YXRlLnNsaWNlX3BhcmFtKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuaXFfbWF0cml4KTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuYml0X3BsYW5lKTsKICAgIGk5NjVfcmVsZWFzZV9idWZmZXJfc3RvcmUoJm9ial9jb250ZXh0LT5kZWNvZGVfc3RhdGUuc2xpY2VfZGF0YSk7CgogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgpWQVN0YXR1cyAKaTk2NV9TeW5jU3VyZmFjZShWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICBWQVN1cmZhY2VJRCByZW5kZXJfdGFyZ2V0KQp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsgCiAgICBzdHJ1Y3Qgb2JqZWN0X3N1cmZhY2UgKm9ial9zdXJmYWNlID0gU1VSRkFDRShyZW5kZXJfdGFyZ2V0KTsKCiAgICBhc3NlcnQob2JqX3N1cmZhY2UpOwoKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKVkFTdGF0dXMgCmk5NjVfUXVlcnlTdXJmYWNlU3RhdHVzKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICBWQVN1cmZhY2VJRCByZW5kZXJfdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICBWQVN1cmZhY2VTdGF0dXMgKnN0YXR1cykgICAgICAgIC8qIG91dCAqLwp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsgCiAgICBzdHJ1Y3Qgb2JqZWN0X3N1cmZhY2UgKm9ial9zdXJmYWNlID0gU1VSRkFDRShyZW5kZXJfdGFyZ2V0KTsKCiAgICBhc3NlcnQob2JqX3N1cmZhY2UpOwogICAgKnN0YXR1cyA9IG9ial9zdXJmYWNlLT5zdGF0dXM7CgogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgoKLyogCiAqIFF1ZXJ5IGRpc3BsYXkgYXR0cmlidXRlcyAKICogVGhlIGNhbGxlciBtdXN0IHByb3ZpZGUgYSAiYXR0cl9saXN0IiBhcnJheSB0aGF0IGNhbiBob2xkIGF0CiAqIGxlYXN0IHZhTWF4TnVtRGlzcGxheUF0dHJpYnV0ZXMoKSBlbnRyaWVzLiBUaGUgYWN0dWFsIG51bWJlciBvZiBhdHRyaWJ1dGVzCiAqIHJldHVybmVkIGluICJhdHRyX2xpc3QiIGlzIHJldHVybmVkIGluICJudW1fYXR0cmlidXRlcyIuCiAqLwpWQVN0YXR1cyAKaTk2NV9RdWVyeURpc3BsYXlBdHRyaWJ1dGVzKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFEaXNwbGF5QXR0cmlidXRlICphdHRyX2xpc3QsCS8qIG91dCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpudW1fYXR0cmlidXRlcykJCS8qIG91dCAqLwp7CiAgICBpZiAobnVtX2F0dHJpYnV0ZXMpCiAgICAgICAgKm51bV9hdHRyaWJ1dGVzID0gMDsKCiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qIAogKiBHZXQgZGlzcGxheSBhdHRyaWJ1dGVzIAogKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgdGhlIGN1cnJlbnQgYXR0cmlidXRlIHZhbHVlcyBpbiAiYXR0cl9saXN0Ii4KICogT25seSBhdHRyaWJ1dGVzIHJldHVybmVkIHdpdGggVkFfRElTUExBWV9BVFRSSUJfR0VUVEFCTEUgc2V0IGluIHRoZSAiZmxhZ3MiIGZpZWxkCiAqIGZyb20gdmFRdWVyeURpc3BsYXlBdHRyaWJ1dGVzKCkgY2FuIGhhdmUgdGhlaXIgdmFsdWVzIHJldHJpZXZlZC4gIAogKi8KVkFTdGF0dXMgCmk5NjVfR2V0RGlzcGxheUF0dHJpYnV0ZXMoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVkFEaXNwbGF5QXR0cmlidXRlICphdHRyX2xpc3QsCS8qIGluL291dCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgIGludCBudW1fYXR0cmlidXRlcykKewogICAgLyogVE9ETyAqLwogICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9VTktOT1dOOwp9CgovKiAKICogU2V0IGRpc3BsYXkgYXR0cmlidXRlcyAKICogT25seSBhdHRyaWJ1dGVzIHJldHVybmVkIHdpdGggVkFfRElTUExBWV9BVFRSSUJfU0VUVEFCTEUgc2V0IGluIHRoZSAiZmxhZ3MiIGZpZWxkCiAqIGZyb20gdmFRdWVyeURpc3BsYXlBdHRyaWJ1dGVzKCkgY2FuIGJlIHNldC4gIElmIHRoZSBhdHRyaWJ1dGUgaXMgbm90IHNldHRhYmxlIG9yIAogKiB0aGUgdmFsdWUgaXMgb3V0IG9mIHJhbmdlLCB0aGUgZnVuY3Rpb24gcmV0dXJucyBWQV9TVEFUVVNfRVJST1JfQVRUUl9OT1RfU1VQUE9SVEVECiAqLwpWQVN0YXR1cyAKaTk2NV9TZXREaXNwbGF5QXR0cmlidXRlcyhWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICBWQURpc3BsYXlBdHRyaWJ1dGUgKmF0dHJfbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbnVtX2F0dHJpYnV0ZXMpCnsKICAgIC8qIFRPRE8gKi8KICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfVU5LTk9XTjsKfQoKVkFTdGF0dXMgCmk5NjVfRGJnQ29weVN1cmZhY2VUb0J1ZmZlcihWQURyaXZlckNvbnRleHRQIGN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEIHN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqYnVmZmVyLCAgICAgICAgICAgICAgLyogb3V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgKnN0cmlkZSkgICAgICAgLyogb3V0ICovCnsKICAgIC8qIFRPRE8gKi8KICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfVU5LTk9XTjsKfQoKc3RhdGljIFZBU3RhdHVzIAppOTY1X0luaXQoVkFEcml2ZXJDb250ZXh0UCBjdHgpCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1ID0gaTk2NV9kcml2ZXJfZGF0YShjdHgpOyAKCiAgICBpZiAoaW50ZWxfZHJpdmVyX2luaXQoY3R4KSA9PSBGYWxzZSkKICAgICAgICByZXR1cm4gVkFfU1RBVFVTX0VSUk9SX1VOS05PV047CgogICAgaWYgKCFJU19HNFgoaTk2NS0+aW50ZWwuZGV2aWNlX2lkKSAmJgogICAgICAgICFJU19JR0RORyhpOTY1LT5pbnRlbC5kZXZpY2VfaWQpKQogICAgICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfVU5LTk9XTjsKCiAgICBpZiAoaTk2NV9tZWRpYV9pbml0KGN0eCkgPT0gRmFsc2UpCiAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9VTktOT1dOOwoKICAgIGlmIChpOTY1X3JlbmRlcl9pbml0KGN0eCkgPT0gRmFsc2UpCiAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9VTktOT1dOOwoKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKc3RhdGljIHZvaWQKaTk2NV9kZXN0cm95X2hlYXAoc3RydWN0IG9iamVjdF9oZWFwICpoZWFwLCAKICAgICAgICAgICAgICAgICAgdm9pZCAoKmZ1bmMpKHN0cnVjdCBvYmplY3RfaGVhcCAqaGVhcCwgc3RydWN0IG9iamVjdF9iYXNlICpvYmplY3QpKQp7CiAgICBzdHJ1Y3Qgb2JqZWN0X2Jhc2UgKm9iamVjdDsKICAgIG9iamVjdF9oZWFwX2l0ZXJhdG9yIGl0ZXI7ICAgIAoKICAgIG9iamVjdCA9IG9iamVjdF9oZWFwX2ZpcnN0KGhlYXAsICZpdGVyKTsKCiAgICB3aGlsZSAob2JqZWN0KSB7CiAgICAgICAgaWYgKGZ1bmMpCiAgICAgICAgICAgIGZ1bmMoaGVhcCwgb2JqZWN0KTsKCiAgICAgICAgb2JqZWN0ID0gb2JqZWN0X2hlYXBfbmV4dChoZWFwLCAmaXRlcik7CiAgICB9CgogICAgb2JqZWN0X2hlYXBfZGVzdHJveShoZWFwKTsKfQoKClZBU3RhdHVzIAppOTY1X0Rlc3Ryb3lJbWFnZShWQURyaXZlckNvbnRleHRQIGN0eCwgVkFJbWFnZUlEIGltYWdlKTsKClZBU3RhdHVzIAppOTY1X0NyZWF0ZUltYWdlKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgIFZBSW1hZ2VGb3JtYXQgKmZvcm1hdCwKICAgICAgICAgICAgICAgICBpbnQgd2lkdGgsCiAgICAgICAgICAgICAgICAgaW50IGhlaWdodCwKICAgICAgICAgICAgICAgICBWQUltYWdlICpvdXRfaW1hZ2UpICAgICAgICAvKiBvdXQgKi8KewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICBzdHJ1Y3Qgb2JqZWN0X2ltYWdlICpvYmpfaW1hZ2U7CiAgICBWQVN0YXR1cyB2YV9zdGF0dXMgPSBWQV9TVEFUVVNfRVJST1JfT1BFUkFUSU9OX0ZBSUxFRDsKICAgIFZBSW1hZ2VJRCBpbWFnZV9pZDsKICAgIHVuc2lnbmVkIGludCB3aWR0aDIsIGhlaWdodDIsIHNpemUyLCBzaXplOwoKICAgIG91dF9pbWFnZS0+aW1hZ2VfaWQgPSBWQV9JTlZBTElEX0lEOwogICAgb3V0X2ltYWdlLT5idWYgICAgICA9IFZBX0lOVkFMSURfSUQ7CgogICAgaW1hZ2VfaWQgPSBORVdfSU1BR0VfSUQoKTsKICAgIGlmIChpbWFnZV9pZCA9PSBWQV9JTlZBTElEX0lEKQogICAgICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfQUxMT0NBVElPTl9GQUlMRUQ7CgogICAgb2JqX2ltYWdlID0gSU1BR0UoaW1hZ2VfaWQpOwogICAgaWYgKCFvYmpfaW1hZ2UpCiAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9BTExPQ0FUSU9OX0ZBSUxFRDsKICAgIG9ial9pbWFnZS0+Ym8gICAgICAgICA9IE5VTEw7CiAgICBvYmpfaW1hZ2UtPnBhbGV0dGUgICAgPSBOVUxMOwoKICAgIFZBSW1hZ2UgKiBjb25zdCBpbWFnZSA9ICZvYmpfaW1hZ2UtPmltYWdlOwogICAgaW1hZ2UtPmltYWdlX2lkICAgICAgID0gaW1hZ2VfaWQ7CiAgICBpbWFnZS0+YnVmICAgICAgICAgICAgPSBWQV9JTlZBTElEX0lEOwoKICAgIHNpemUgICAgPSB3aWR0aCAqIGhlaWdodDsKICAgIHdpZHRoMiAgPSAod2lkdGggICsgMSkgLyAyOwogICAgaGVpZ2h0MiA9IChoZWlnaHQgKyAxKSAvIDI7CiAgICBzaXplMiAgID0gd2lkdGgyICogaGVpZ2h0MjsKCiAgICBpbWFnZS0+bnVtX3BhbGV0dGVfZW50cmllcyA9IDA7CiAgICBpbWFnZS0+ZW50cnlfYnl0ZXMgICAgICAgICA9IDA7CiAgICBtZW1zZXQoaW1hZ2UtPmNvbXBvbmVudF9vcmRlciwgMCwgc2l6ZW9mKGltYWdlLT5jb21wb25lbnRfb3JkZXIpKTsKCiAgICBzd2l0Y2ggKGZvcm1hdC0+Zm91cmNjKSB7CiAgICBjYXNlIFZBX0ZPVVJDQygnSScsJ0EnLCc0JywnNCcpOgogICAgY2FzZSBWQV9GT1VSQ0MoJ0EnLCdJJywnNCcsJzQnKToKICAgICAgICBpbWFnZS0+bnVtX3BsYW5lcyA9IDE7CiAgICAgICAgaW1hZ2UtPnBpdGNoZXNbMF0gPSB3aWR0aDsKICAgICAgICBpbWFnZS0+b2Zmc2V0c1swXSA9IDA7CiAgICAgICAgaW1hZ2UtPmRhdGFfc2l6ZSAgPSBpbWFnZS0+b2Zmc2V0c1swXSArIGltYWdlLT5waXRjaGVzWzBdICogaGVpZ2h0OwogICAgICAgIGltYWdlLT5udW1fcGFsZXR0ZV9lbnRyaWVzID0gMTY7CiAgICAgICAgaW1hZ2UtPmVudHJ5X2J5dGVzICAgICAgICAgPSAzOwogICAgICAgIGltYWdlLT5jb21wb25lbnRfb3JkZXJbMF0gID0gJ1InOwogICAgICAgIGltYWdlLT5jb21wb25lbnRfb3JkZXJbMV0gID0gJ0cnOwogICAgICAgIGltYWdlLT5jb21wb25lbnRfb3JkZXJbMl0gID0gJ0InOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIHZhX3N0YXR1cyA9IGk5NjVfQ3JlYXRlQnVmZmVyKGN0eCwgMCwgVkFJbWFnZUJ1ZmZlclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZS0+ZGF0YV9zaXplLCAxLCBOVUxMLCAmaW1hZ2UtPmJ1Zik7CiAgICBpZiAodmFfc3RhdHVzICE9IFZBX1NUQVRVU19TVUNDRVNTKQogICAgICAgIGdvdG8gZXJyb3I7CgogICAgb2JqX2ltYWdlLT5ibyA9IEJVRkZFUihpbWFnZS0+YnVmKS0+YnVmZmVyX3N0b3JlLT5ibzsKCiAgICBpZiAoaW1hZ2UtPm51bV9wYWxldHRlX2VudHJpZXMgPiAwICYmIGltYWdlLT5lbnRyeV9ieXRlcyA+IDApIHsKICAgICAgICBvYmpfaW1hZ2UtPnBhbGV0dGUgPSBtYWxsb2MoaW1hZ2UtPm51bV9wYWxldHRlX2VudHJpZXMgKiBzaXplb2Yob2JqX2ltYWdlLT5wYWxldHRlKSk7CiAgICAgICAgaWYgKCFvYmpfaW1hZ2UtPnBhbGV0dGUpCiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaW1hZ2UtPmltYWdlX2lkICAgICAgICAgICAgID0gaW1hZ2VfaWQ7CiAgICBpbWFnZS0+Zm9ybWF0ICAgICAgICAgICAgICAgPSAqZm9ybWF0OwogICAgaW1hZ2UtPndpZHRoICAgICAgICAgICAgICAgID0gd2lkdGg7CiAgICBpbWFnZS0+aGVpZ2h0ICAgICAgICAgICAgICAgPSBoZWlnaHQ7CgogICAgKm91dF9pbWFnZSAgICAgICAgICAgICAgICAgID0gKmltYWdlOwogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwoKIGVycm9yOgogICAgaTk2NV9EZXN0cm95SW1hZ2UoY3R4LCBpbWFnZV9pZCk7CiAgICByZXR1cm4gdmFfc3RhdHVzOwp9CgpWQVN0YXR1cyBpOTY1X0Rlcml2ZUltYWdlKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgICAgICAgICAgICAgIFZBU3VyZmFjZUlEIHN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVkFJbWFnZSAqaW1hZ2UpICAgICAgICAvKiBvdXQgKi8KewogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgpzdGF0aWMgdm9pZCAKaTk2NV9kZXN0cm95X2ltYWdlKHN0cnVjdCBvYmplY3RfaGVhcCAqaGVhcCwgc3RydWN0IG9iamVjdF9iYXNlICpvYmopCnsKICAgIG9iamVjdF9oZWFwX2ZyZWUoaGVhcCwgb2JqKTsKfQoKClZBU3RhdHVzIAppOTY1X0Rlc3Ryb3lJbWFnZShWQURyaXZlckNvbnRleHRQIGN0eCwgVkFJbWFnZUlEIGltYWdlKQp7CiAgICBzdHJ1Y3QgaTk2NV9kcml2ZXJfZGF0YSAqaTk2NSA9IGk5NjVfZHJpdmVyX2RhdGEoY3R4KTsKICAgIHN0cnVjdCBvYmplY3RfaW1hZ2UgKm9ial9pbWFnZSA9IElNQUdFKGltYWdlKTsgCgogICAgaWYgKCFvYmpfaW1hZ2UpCiAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwoKICAgIGlmIChvYmpfaW1hZ2UtPmltYWdlLmJ1ZiAhPSBWQV9JTlZBTElEX0lEKSB7CiAgICAgICAgaTk2NV9EZXN0cm95QnVmZmVyKGN0eCwgb2JqX2ltYWdlLT5pbWFnZS5idWYpOwogICAgICAgIG9ial9pbWFnZS0+aW1hZ2UuYnVmID0gVkFfSU5WQUxJRF9JRDsKICAgIH0KCiAgICBpZiAob2JqX2ltYWdlLT5wYWxldHRlKSB7CiAgICAgICAgZnJlZShvYmpfaW1hZ2UtPnBhbGV0dGUpOwogICAgICAgIG9ial9pbWFnZS0+cGFsZXR0ZSA9IE5VTEw7CiAgICB9CgogICAgaTk2NV9kZXN0cm95X2ltYWdlKCZpOTY1LT5pbWFnZV9oZWFwLCAoc3RydWN0IG9iamVjdF9iYXNlICopb2JqX2ltYWdlKTsKCQogICAgcmV0dXJuIFZBX1NUQVRVU19TVUNDRVNTOwp9CgovKgogKiBwb2ludGVyIHRvIGFuIGFycmF5IGhvbGRpbmcgdGhlIHBhbGV0dGUgZGF0YS4gIFRoZSBzaXplIG9mIHRoZSBhcnJheSBpcwogKiBudW1fcGFsZXR0ZV9lbnRyaWVzICogZW50cnlfYnl0ZXMgaW4gc2l6ZS4gIFRoZSBvcmRlciBvZiB0aGUgY29tcG9uZW50cwogKiBpbiB0aGUgcGFsZXR0ZSBpcyBkZXNjcmliZWQgYnkgdGhlIGNvbXBvbmVudF9vcmRlciBpbiBWQVN1YnBpY3R1cmUgc3RydWN0CiAqLwpWQVN0YXR1cyAKaTk2NV9TZXRJbWFnZVBhbGV0dGUoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICAgICAgIFZBSW1hZ2VJRCBpbWFnZSwKICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcGFsZXR0ZSkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CiAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICBzdHJ1Y3Qgb2JqZWN0X2ltYWdlICpvYmpfaW1hZ2UgPSBJTUFHRShpbWFnZSk7CiAgICBpZiAoIW9ial9pbWFnZSkKICAgICAgICByZXR1cm4gVkFfU1RBVFVTX0VSUk9SX0lOVkFMSURfSU1BR0U7CgogICAgaWYgKCFvYmpfaW1hZ2UtPnBhbGV0dGUpCiAgICAgICAgcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9BTExPQ0FUSU9OX0ZBSUxFRDsgLyogWFhYOiB1bnBhbGV0dGVkL2Vycm9yICovCgogICAgZm9yIChpID0gMDsgaSA8IG9ial9pbWFnZS0+aW1hZ2UubnVtX3BhbGV0dGVfZW50cmllczsgaSsrKQogICAgICAgIG9ial9pbWFnZS0+cGFsZXR0ZVtpXSA9ICgoKHVuc2lnbmVkIGludClwYWxldHRlWzMqaSArIDBdIDw8IDE2KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgodW5zaWduZWQgaW50KXBhbGV0dGVbMyppICsgMV0gPDwgIDgpIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpcGFsZXR0ZVszKmkgKyAyXSk7CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X0dldEltYWdlKFZBRHJpdmVyQ29udGV4dFAgY3R4LAogICAgICAgICAgICAgIFZBU3VyZmFjZUlEIHN1cmZhY2UsCiAgICAgICAgICAgICAgaW50IHgsICAgLyogY29vcmRpbmF0ZXMgb2YgdGhlIHVwcGVyIGxlZnQgc291cmNlIHBpeGVsICovCiAgICAgICAgICAgICAgaW50IHksCiAgICAgICAgICAgICAgdW5zaWduZWQgaW50IHdpZHRoLCAgICAgIC8qIHdpZHRoIGFuZCBoZWlnaHQgb2YgdGhlIHJlZ2lvbiAqLwogICAgICAgICAgICAgIHVuc2lnbmVkIGludCBoZWlnaHQsCiAgICAgICAgICAgICAgVkFJbWFnZUlEIGltYWdlKQp7CiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X1B1dFN1cmZhY2UoVkFEcml2ZXJDb250ZXh0UCBjdHgsCiAgICAgICAgICAgICAgICBWQVN1cmZhY2VJRCBzdXJmYWNlLAogICAgICAgICAgICAgICAgRHJhd2FibGUgZHJhdywgLyogWCBEcmF3YWJsZSAqLwogICAgICAgICAgICAgICAgc2hvcnQgc3JjeCwKICAgICAgICAgICAgICAgIHNob3J0IHNyY3ksCiAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBzcmN3LAogICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgc3JjaCwKICAgICAgICAgICAgICAgIHNob3J0IGRlc3R4LAogICAgICAgICAgICAgICAgc2hvcnQgZGVzdHksCiAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBkZXN0dywKICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IGRlc3RoLAogICAgICAgICAgICAgICAgVkFSZWN0YW5nbGUgKmNsaXByZWN0cywgLyogY2xpZW50IHN1cHBsaWVkIGNsaXAgbGlzdCAqLwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50IG51bWJlcl9jbGlwcmVjdHMsIC8qIG51bWJlciBvZiBjbGlwIHJlY3RzIGluIHRoZSBjbGlwIGxpc3QgKi8KICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBmbGFncykgLyogZGUtaW50ZXJsYWNpbmcgZmxhZ3MgKi8KewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7IAogICAgc3RydWN0IGRyaV9zdGF0ZSAqZHJpX3N0YXRlID0gKHN0cnVjdCBkcmlfc3RhdGUgKiljdHgtPmRyaV9zdGF0ZTsKICAgIHN0cnVjdCBpOTY1X3JlbmRlcl9zdGF0ZSAqcmVuZGVyX3N0YXRlID0gJmk5NjUtPnJlbmRlcl9zdGF0ZTsKICAgIHN0cnVjdCBkcmlfZHJhd2FibGUgKmRyaV9kcmF3YWJsZTsKICAgIHVuaW9uIGRyaV9idWZmZXIgKmJ1ZmZlcjsKICAgIHN0cnVjdCBpbnRlbF9yZWdpb24gKmRlc3RfcmVnaW9uOwogICAgc3RydWN0IG9iamVjdF9zdXJmYWNlICpvYmpfc3VyZmFjZTsgCglpbnQgcmV0OwogICAgdWludDMyX3QgbmFtZTsKICAgIEJvb2wgbmV3X3JlZ2lvbiA9IEZhbHNlOwogICAgLyogQ3VycmVudGx5IGRvbid0IHN1cHBvcnQgRFJJMSAqLwogICAgaWYgKGRyaV9zdGF0ZS0+ZHJpQ29ubmVjdGVkRmxhZyAhPSBWQV9EUkkyKQogICAgICAgIHJldHVybiBWQV9TVEFUVVNfRVJST1JfVU5LTk9XTjsKCiAgICBkcmlfZHJhd2FibGUgPSBkcmlfZ2V0X2RyYXdhYmxlKGN0eCwgZHJhdyk7CiAgICBhc3NlcnQoZHJpX2RyYXdhYmxlKTsKCiAgICBidWZmZXIgPSBkcmlfZ2V0X3JlbmRlcmluZ19idWZmZXIoY3R4LCBkcmlfZHJhd2FibGUpOwogICAgYXNzZXJ0KGJ1ZmZlcik7CiAgICAKICAgIGRlc3RfcmVnaW9uID0gcmVuZGVyX3N0YXRlLT5kcmF3X3JlZ2lvbjsKCiAgICBpZiAoZGVzdF9yZWdpb24pIHsKICAgICAgICBhc3NlcnQoZGVzdF9yZWdpb24tPmJvKTsKICAgICAgICBkcmlfYm9fZmxpbmsoZGVzdF9yZWdpb24tPmJvLCAmbmFtZSk7CiAgICAgICAgCiAgICAgICAgaWYgKGJ1ZmZlci0+ZHJpMi5uYW1lICE9IG5hbWUpIHsKICAgICAgICAgICAgbmV3X3JlZ2lvbiA9IFRydWU7CiAgICAgICAgICAgIGRyaV9ib191bnJlZmVyZW5jZShkZXN0X3JlZ2lvbi0+Ym8pOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgZGVzdF9yZWdpb24gPSAoc3RydWN0IGludGVsX3JlZ2lvbiAqKWNhbGxvYygxLCBzaXplb2YoKmRlc3RfcmVnaW9uKSk7CiAgICAgICAgYXNzZXJ0KGRlc3RfcmVnaW9uKTsKICAgICAgICByZW5kZXJfc3RhdGUtPmRyYXdfcmVnaW9uID0gZGVzdF9yZWdpb247CiAgICAgICAgbmV3X3JlZ2lvbiA9IFRydWU7CiAgICB9CgogICAgaWYgKG5ld19yZWdpb24pIHsKICAgICAgICBkZXN0X3JlZ2lvbi0+eCA9IGRyaV9kcmF3YWJsZS0+eDsKICAgICAgICBkZXN0X3JlZ2lvbi0+eSA9IGRyaV9kcmF3YWJsZS0+eTsKICAgICAgICBkZXN0X3JlZ2lvbi0+d2lkdGggPSBkcmlfZHJhd2FibGUtPndpZHRoOwogICAgICAgIGRlc3RfcmVnaW9uLT5oZWlnaHQgPSBkcmlfZHJhd2FibGUtPmhlaWdodDsKICAgICAgICBkZXN0X3JlZ2lvbi0+Y3BwID0gYnVmZmVyLT5kcmkyLmNwcDsKICAgICAgICBkZXN0X3JlZ2lvbi0+cGl0Y2ggPSBidWZmZXItPmRyaTIucGl0Y2g7CgogICAgICAgIGRlc3RfcmVnaW9uLT5ibyA9IGludGVsX2JvX2dlbV9jcmVhdGVfZnJvbV9uYW1lKGk5NjUtPmludGVsLmJ1Zm1nciwgInJlbmRlcmluZyBidWZmZXIiLCBidWZmZXItPmRyaTIubmFtZSk7CiAgICAgICAgYXNzZXJ0KGRlc3RfcmVnaW9uLT5ibyk7CgogICAgICAgIHJldCA9IGRyaV9ib19nZXRfdGlsaW5nKGRlc3RfcmVnaW9uLT5ibywgJihkZXN0X3JlZ2lvbi0+dGlsaW5nKSwgJihkZXN0X3JlZ2lvbi0+c3dpenpsZSkpOwogICAgICAgIGFzc2VydChyZXQgPT0gMCk7CiAgICB9CgogICAgaTk2NV9yZW5kZXJfcHV0X3N1cmZhY2UoY3R4LCBzdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjeCwgc3JjeSwgc3Jjdywgc3JjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3R4LCBkZXN0eSwgZGVzdHcsIGRlc3RoKTsKICAgIG9ial9zdXJmYWNlID0gU1VSRkFDRShzdXJmYWNlKTsKICAgIGlmKG9ial9zdXJmYWNlLT5zdWJwaWMgIT0gVkFfSU5WQUxJRF9JRCkgewkKCWk5NjVfcmVuZGVyX3B1dF9zdWJwaWMoY3R4LCBzdXJmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzcmN4LCBzcmN5LCBzcmN3LCBzcmNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0eCwgZGVzdHksIGRlc3R3LCBkZXN0aCk7CiAgICB9IAogICAgZHJpX3N3YXBfYnVmZmVyKGN0eCwgZHJpX2RyYXdhYmxlKTsKCiAgICByZXR1cm4gVkFfU1RBVFVTX1NVQ0NFU1M7Cn0KClZBU3RhdHVzIAppOTY1X1Rlcm1pbmF0ZShWQURyaXZlckNvbnRleHRQIGN0eCkKewogICAgc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKmk5NjUgPSBpOTY1X2RyaXZlcl9kYXRhKGN0eCk7CgogICAgaWYgKGk5NjVfcmVuZGVyX3Rlcm1pbmF0ZShjdHgpID09IEZhbHNlKQoJcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9VTktOT1dOOwoKICAgIGlmIChpOTY1X21lZGlhX3Rlcm1pbmF0ZShjdHgpID09IEZhbHNlKQoJcmV0dXJuIFZBX1NUQVRVU19FUlJPUl9VTktOT1dOOwoKICAgIGlmIChpbnRlbF9kcml2ZXJfdGVybWluYXRlKGN0eCkgPT0gRmFsc2UpCglyZXR1cm4gVkFfU1RBVFVTX0VSUk9SX1VOS05PV047CgogICAgaTk2NV9kZXN0cm95X2hlYXAoJmk5NjUtPmJ1ZmZlcl9oZWFwLCBpOTY1X2Rlc3Ryb3lfYnVmZmVyKTsKICAgIGk5NjVfZGVzdHJveV9oZWFwKCZpOTY1LT5pbWFnZV9oZWFwLCBpOTY1X2Rlc3Ryb3lfaW1hZ2UpOwogICAgaTk2NV9kZXN0cm95X2hlYXAoJmk5NjUtPnN1YnBpY19oZWFwLCBpOTY1X2Rlc3Ryb3lfc3VicGljKTsKICAgIGk5NjVfZGVzdHJveV9oZWFwKCZpOTY1LT5zdXJmYWNlX2hlYXAsIGk5NjVfZGVzdHJveV9zdXJmYWNlKTsKICAgIGk5NjVfZGVzdHJveV9oZWFwKCZpOTY1LT5jb250ZXh0X2hlYXAsIGk5NjVfZGVzdHJveV9jb250ZXh0KTsKICAgIGk5NjVfZGVzdHJveV9oZWFwKCZpOTY1LT5jb25maWdfaGVhcCwgaTk2NV9kZXN0cm95X2NvbmZpZyk7CgogICAgZnJlZShjdHgtPnBEcml2ZXJEYXRhKTsKICAgIGN0eC0+cERyaXZlckRhdGEgPSBOVUxMOwoKICAgIHJldHVybiBWQV9TVEFUVVNfU1VDQ0VTUzsKfQoKVkFTdGF0dXMgCl9fdmFEcml2ZXJJbml0XzBfMzEoICBWQURyaXZlckNvbnRleHRQIGN0eCApCnsKICAgIHN0cnVjdCBpOTY1X2RyaXZlcl9kYXRhICppOTY1OwogICAgaW50IHJlc3VsdDsKCiAgICBjdHgtPnZlcnNpb25fbWFqb3IgPSBWQV9NQUpPUl9WRVJTSU9OOwogICAgY3R4LT52ZXJzaW9uX21pbm9yID0gVkFfTUlOT1JfVkVSU0lPTjsKICAgIGN0eC0+bWF4X3Byb2ZpbGVzID0gSTk2NV9NQVhfUFJPRklMRVM7CiAgICBjdHgtPm1heF9lbnRyeXBvaW50cyA9IEk5NjVfTUFYX0VOVFJZUE9JTlRTOwogICAgY3R4LT5tYXhfYXR0cmlidXRlcyA9IEk5NjVfTUFYX0NPTkZJR19BVFRSSUJVVEVTOwogICAgY3R4LT5tYXhfaW1hZ2VfZm9ybWF0cyA9IEk5NjVfTUFYX0lNQUdFX0ZPUk1BVFM7CiAgICBjdHgtPm1heF9zdWJwaWNfZm9ybWF0cyA9IEk5NjVfTUFYX1NVQlBJQ19GT1JNQVRTOwogICAgY3R4LT5tYXhfZGlzcGxheV9hdHRyaWJ1dGVzID0gSTk2NV9NQVhfRElTUExBWV9BVFRSSUJVVEVTOwogICAgY3R4LT5zdHJfdmVuZG9yID0gSTk2NV9TVFJfVkVORE9SOwoKICAgIGN0eC0+dnRhYmxlLnZhVGVybWluYXRlID0gaTk2NV9UZXJtaW5hdGU7CiAgICBjdHgtPnZ0YWJsZS52YVF1ZXJ5Q29uZmlnRW50cnlwb2ludHMgPSBpOTY1X1F1ZXJ5Q29uZmlnRW50cnlwb2ludHM7CiAgICBjdHgtPnZ0YWJsZS52YVF1ZXJ5Q29uZmlnUHJvZmlsZXMgPSBpOTY1X1F1ZXJ5Q29uZmlnUHJvZmlsZXM7CiAgICBjdHgtPnZ0YWJsZS52YVF1ZXJ5Q29uZmlnRW50cnlwb2ludHMgPSBpOTY1X1F1ZXJ5Q29uZmlnRW50cnlwb2ludHM7CiAgICBjdHgtPnZ0YWJsZS52YVF1ZXJ5Q29uZmlnQXR0cmlidXRlcyA9IGk5NjVfUXVlcnlDb25maWdBdHRyaWJ1dGVzOwogICAgY3R4LT52dGFibGUudmFDcmVhdGVDb25maWcgPSBpOTY1X0NyZWF0ZUNvbmZpZzsKICAgIGN0eC0+dnRhYmxlLnZhRGVzdHJveUNvbmZpZyA9IGk5NjVfRGVzdHJveUNvbmZpZzsKICAgIGN0eC0+dnRhYmxlLnZhR2V0Q29uZmlnQXR0cmlidXRlcyA9IGk5NjVfR2V0Q29uZmlnQXR0cmlidXRlczsKICAgIGN0eC0+dnRhYmxlLnZhQ3JlYXRlU3VyZmFjZXMgPSBpOTY1X0NyZWF0ZVN1cmZhY2VzOwogICAgY3R4LT52dGFibGUudmFEZXN0cm95U3VyZmFjZXMgPSBpOTY1X0Rlc3Ryb3lTdXJmYWNlczsKICAgIGN0eC0+dnRhYmxlLnZhQ3JlYXRlQ29udGV4dCA9IGk5NjVfQ3JlYXRlQ29udGV4dDsKICAgIGN0eC0+dnRhYmxlLnZhRGVzdHJveUNvbnRleHQgPSBpOTY1X0Rlc3Ryb3lDb250ZXh0OwogICAgY3R4LT52dGFibGUudmFDcmVhdGVCdWZmZXIgPSBpOTY1X0NyZWF0ZUJ1ZmZlcjsKICAgIGN0eC0+dnRhYmxlLnZhQnVmZmVyU2V0TnVtRWxlbWVudHMgPSBpOTY1X0J1ZmZlclNldE51bUVsZW1lbnRzOwogICAgY3R4LT52dGFibGUudmFNYXBCdWZmZXIgPSBpOTY1X01hcEJ1ZmZlcjsKICAgIGN0eC0+dnRhYmxlLnZhVW5tYXBCdWZmZXIgPSBpOTY1X1VubWFwQnVmZmVyOwogICAgY3R4LT52dGFibGUudmFEZXN0cm95QnVmZmVyID0gaTk2NV9EZXN0cm95QnVmZmVyOwogICAgY3R4LT52dGFibGUudmFCZWdpblBpY3R1cmUgPSBpOTY1X0JlZ2luUGljdHVyZTsKICAgIGN0eC0+dnRhYmxlLnZhUmVuZGVyUGljdHVyZSA9IGk5NjVfUmVuZGVyUGljdHVyZTsKICAgIGN0eC0+dnRhYmxlLnZhRW5kUGljdHVyZSA9IGk5NjVfRW5kUGljdHVyZTsKICAgIGN0eC0+dnRhYmxlLnZhU3luY1N1cmZhY2UgPSBpOTY1X1N5bmNTdXJmYWNlOwogICAgY3R4LT52dGFibGUudmFRdWVyeVN1cmZhY2VTdGF0dXMgPSBpOTY1X1F1ZXJ5U3VyZmFjZVN0YXR1czsKICAgIGN0eC0+dnRhYmxlLnZhUHV0U3VyZmFjZSA9IGk5NjVfUHV0U3VyZmFjZTsKICAgIGN0eC0+dnRhYmxlLnZhUXVlcnlJbWFnZUZvcm1hdHMgPSBpOTY1X1F1ZXJ5SW1hZ2VGb3JtYXRzOwogICAgY3R4LT52dGFibGUudmFDcmVhdGVJbWFnZSA9IGk5NjVfQ3JlYXRlSW1hZ2U7CiAgICBjdHgtPnZ0YWJsZS52YURlcml2ZUltYWdlID0gaTk2NV9EZXJpdmVJbWFnZTsKICAgIGN0eC0+dnRhYmxlLnZhRGVzdHJveUltYWdlID0gaTk2NV9EZXN0cm95SW1hZ2U7CiAgICBjdHgtPnZ0YWJsZS52YVNldEltYWdlUGFsZXR0ZSA9IGk5NjVfU2V0SW1hZ2VQYWxldHRlOwogICAgY3R4LT52dGFibGUudmFHZXRJbWFnZSA9IGk5NjVfR2V0SW1hZ2U7CiAgICBjdHgtPnZ0YWJsZS52YVB1dEltYWdlID0gaTk2NV9QdXRJbWFnZTsKICAgIGN0eC0+dnRhYmxlLnZhUXVlcnlTdWJwaWN0dXJlRm9ybWF0cyA9IGk5NjVfUXVlcnlTdWJwaWN0dXJlRm9ybWF0czsKICAgIGN0eC0+dnRhYmxlLnZhQ3JlYXRlU3VicGljdHVyZSA9IGk5NjVfQ3JlYXRlU3VicGljdHVyZTsKICAgIGN0eC0+dnRhYmxlLnZhRGVzdHJveVN1YnBpY3R1cmUgPSBpOTY1X0Rlc3Ryb3lTdWJwaWN0dXJlOwogICAgY3R4LT52dGFibGUudmFTZXRTdWJwaWN0dXJlSW1hZ2UgPSBpOTY1X1NldFN1YnBpY3R1cmVJbWFnZTsKICAgIGN0eC0+dnRhYmxlLnZhU2V0U3VicGljdHVyZUNocm9tYWtleSA9IGk5NjVfU2V0U3VicGljdHVyZUNocm9tYWtleTsKICAgIGN0eC0+dnRhYmxlLnZhU2V0U3VicGljdHVyZUdsb2JhbEFscGhhID0gaTk2NV9TZXRTdWJwaWN0dXJlR2xvYmFsQWxwaGE7CiAgICBjdHgtPnZ0YWJsZS52YUFzc29jaWF0ZVN1YnBpY3R1cmUgPSBpOTY1X0Fzc29jaWF0ZVN1YnBpY3R1cmU7CiAgICBjdHgtPnZ0YWJsZS52YURlYXNzb2NpYXRlU3VicGljdHVyZSA9IGk5NjVfRGVhc3NvY2lhdGVTdWJwaWN0dXJlOwogICAgY3R4LT52dGFibGUudmFRdWVyeURpc3BsYXlBdHRyaWJ1dGVzID0gaTk2NV9RdWVyeURpc3BsYXlBdHRyaWJ1dGVzOwogICAgY3R4LT52dGFibGUudmFHZXREaXNwbGF5QXR0cmlidXRlcyA9IGk5NjVfR2V0RGlzcGxheUF0dHJpYnV0ZXM7CiAgICBjdHgtPnZ0YWJsZS52YVNldERpc3BsYXlBdHRyaWJ1dGVzID0gaTk2NV9TZXREaXNwbGF5QXR0cmlidXRlczsKLy8gICAgY3R4LT52dGFibGUudmFEYmdDb3B5U3VyZmFjZVRvQnVmZmVyID0gaTk2NV9EYmdDb3B5U3VyZmFjZVRvQnVmZmVyOwoKICAgIGk5NjUgPSAoc3RydWN0IGk5NjVfZHJpdmVyX2RhdGEgKiljYWxsb2MoMSwgc2l6ZW9mKCppOTY1KSk7CiAgICBhc3NlcnQoaTk2NSk7CiAgICBjdHgtPnBEcml2ZXJEYXRhID0gKHZvaWQgKilpOTY1OwoKICAgIHJlc3VsdCA9IG9iamVjdF9oZWFwX2luaXQoJmk5NjUtPmNvbmZpZ19oZWFwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvYmplY3RfY29uZmlnKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTkZJR19JRF9PRkZTRVQpOwogICAgYXNzZXJ0KHJlc3VsdCA9PSAwKTsKCiAgICByZXN1bHQgPSBvYmplY3RfaGVhcF9pbml0KCZpOTY1LT5jb250ZXh0X2hlYXAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3RydWN0IG9iamVjdF9jb250ZXh0KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlRFWFRfSURfT0ZGU0VUKTsKICAgIGFzc2VydChyZXN1bHQgPT0gMCk7CgogICAgcmVzdWx0ID0gb2JqZWN0X2hlYXBfaW5pdCgmaTk2NS0+c3VyZmFjZV9oZWFwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvYmplY3Rfc3VyZmFjZSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVVJGQUNFX0lEX09GRlNFVCk7CiAgICBhc3NlcnQocmVzdWx0ID09IDApOwoKICAgIHJlc3VsdCA9IG9iamVjdF9oZWFwX2luaXQoJmk5NjUtPmJ1ZmZlcl9oZWFwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvYmplY3RfYnVmZmVyKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJVRkZFUl9JRF9PRkZTRVQpOwogICAgYXNzZXJ0KHJlc3VsdCA9PSAwKTsKCiAgICByZXN1bHQgPSBvYmplY3RfaGVhcF9pbml0KCZpOTY1LT5pbWFnZV9oZWFwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvYmplY3RfaW1hZ2UpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU1BR0VfSURfT0ZGU0VUKTsKICAgIGFzc2VydChyZXN1bHQgPT0gMCk7CgkKICAgIHJlc3VsdCA9IG9iamVjdF9oZWFwX2luaXQoJmk5NjUtPnN1YnBpY19oZWFwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBvYmplY3Rfc3VicGljKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNVQlBJQ19JRF9PRkZTRVQpOwogICAgYXNzZXJ0KHJlc3VsdCA9PSAwKTsKCiAgICByZXR1cm4gaTk2NV9Jbml0KGN0eCk7Cn0K