LyoKICogc25tcF9hZ2VudC5jCiAqCiAqIFNpbXBsZSBOZXR3b3JrIE1hbmFnZW1lbnQgUHJvdG9jb2wgKFJGQyAxMDY3KS4KICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodHMuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCUNvcHlyaWdodCAxOTg4LCAxOTg5IGJ5IENhcm5lZ2llIE1lbGxvbiBVbml2ZXJzaXR5CgogICAgICAgICAgICAgICAgICAgICAgQWxsIFJpZ2h0cyBSZXNlcnZlZAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzIApkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBhbmQgd2l0aG91dCBmZWUgaXMgaGVyZWJ5IGdyYW50ZWQsIApwcm92aWRlZCB0aGF0IHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0CmJvdGggdGhhdCBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiAKc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBDTVUgbm90IGJlCnVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZQpzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICAKCkNNVSBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwgSU5DTFVESU5HCkFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTyBFVkVOVCBTSEFMTApDTVUgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SCkFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywKV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIgVE9SVElPVVMgQUNUSU9OLApBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTClNPRlRXQVJFLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIAogKiByZXNlcnZlZC4gIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSAKICogQ09QWUlORyBmaWxlIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwovKiogQGRlZmdyb3VwIHNubXBfYWdlbnQgbmV0LXNubXAgYWdlbnQgcmVsYXRlZCBwcm9jZXNzaW5nIAogKiAgQGluZ3JvdXAgYWdlbnQKICoKICogQHsKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmZGVmIEhBVkVfTElNSVRTX0gKI2luY2x1ZGUgPGxpbWl0cy5oPgojZW5kaWYKI2lmZGVmIEhBVkVfU1RETElCX0gKI2luY2x1ZGUgPHN0ZGxpYi5oPgojZW5kaWYKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZW5kaWYKI2lmIFRJTUVfV0lUSF9TWVNfVElNRQojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9TWVNfU0VMRUNUX0gKI2luY2x1ZGUgPHN5cy9zZWxlY3QuaD4KI2VuZGlmCiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPGVycm5vLmg+CgojZGVmaW5lIFNOTVBfTkVFRF9SRVFVRVNUX0xJU1QKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2Fzc2VydC5oPgoKI2lmIEhBVkVfU1lTTE9HX0gKI2luY2x1ZGUgPHN5c2xvZy5oPgojZW5kaWYKCiNpZmRlZiBORVRTTk1QX1VTRV9MSUJXUkFQCiNpbmNsdWRlIDx0Y3BkLmg+CmludCAgICAgICAgICAgICBhbGxvd19zZXZlcml0eSA9IExPR19JTkZPOwppbnQgICAgICAgICAgICAgZGVueV9zZXZlcml0eSA9IExPR19XQVJOSU5HOwojZW5kaWYKCiNpbmNsdWRlICJzbm1wZC5oIgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbWliX21vZHVsZV9jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L21pYl9tb2R1bGVzLmg+CgojaWZkZWYgVVNJTkdfQUdFTlRYX1BST1RPQ09MX01PRFVMRQojaW5jbHVkZSAiYWdlbnR4L3Byb3RvY29sLmgiCiNlbmRpZgoKI2lmZGVmIFVTSU5HX0FHRU5UWF9NQVNURVJfTU9EVUxFCiNpbmNsdWRlICJhZ2VudHgvbWFzdGVyLmgiCiNlbmRpZgoKI2lmZGVmIFVTSU5HX1NNVVhfTU9EVUxFCiNpbmNsdWRlICJzbXV4L3NtdXguaCIKI2VuZGlmCgpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfYWdlbnRfYWRkX2xpc3RfZGF0YShuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqYXJpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kYXRhX2xpc3QgKm5vZGUpCnsKICAgIGlmIChhcmkpIHsKCWlmIChhcmktPmFnZW50X2RhdGEpIHsKICAgICAgICAgICAgbmV0c25tcF9hZGRfbGlzdF9kYXRhKCZhcmktPmFnZW50X2RhdGEsIG5vZGUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGFyaS0+YWdlbnRfZGF0YSA9IG5vZGU7Cgl9CiAgICB9Cn0KCk5FVFNOTVBfSU5MSU5FIGludApuZXRzbm1wX2FnZW50X3JlbW92ZV9saXN0X2RhdGEobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKiBuYW1lKQp7CiAgICBpZiAoKE5VTEwgPT0gYXJpKSB8fCAoTlVMTCA9PSBhcmktPmFnZW50X2RhdGEpKQogICAgICAgIHJldHVybiAxOwoKICAgIHJldHVybiBuZXRzbm1wX3JlbW92ZV9saXN0X25vZGUoJmFyaS0+YWdlbnRfZGF0YSwgbmFtZSk7Cn0KCk5FVFNOTVBfSU5MSU5FIHZvaWQgICAgKgpuZXRzbm1wX2FnZW50X2dldF9saXN0X2RhdGEobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIGlmIChhcmkpIHsKICAgICAgICByZXR1cm4gbmV0c25tcF9nZXRfbGlzdF9kYXRhKGFyaS0+YWdlbnRfZGF0YSwgbmFtZSk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfYWdlbnRfZGF0YV9zZXQobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSkKewogICAgaWYgKGFyaSkgewogICAgICAgIG5ldHNubXBfZnJlZV9saXN0X2RhdGEoYXJpLT5hZ2VudF9kYXRhKTsKICAgIH0KfQoKTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2ZyZWVfYWdlbnRfZGF0YV9zZXRzKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICphcmkpCnsKICAgIGlmIChhcmkpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfYWxsX2xpc3RfZGF0YShhcmktPmFnZW50X2RhdGEpOwogICAgfQp9CgpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfZnJlZV9hZ2VudF9yZXF1ZXN0X2luZm8obmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKmFyaSkKewogICAgaWYgKGFyaSkgewogICAgICAgIGlmIChhcmktPmFnZW50X2RhdGEpIHsKICAgICAgICAgICAgbmV0c25tcF9mcmVlX2FsbF9saXN0X2RhdGEoYXJpLT5hZ2VudF9kYXRhKTsKCX0KICAgICAgICBTTk1QX0ZSRUUoYXJpKTsKICAgIH0KfQoKb2lkICAgICAgdmVyc2lvbl9zeXNvaWRbXSA9IHsgTkVUU05NUF9TWVNURU1fTUlCIH07CmludCAgICAgIHZlcnNpb25fc3lzb2lkX2xlbiA9IE9JRF9MRU5HVEgodmVyc2lvbl9zeXNvaWQpOwoKI2RlZmluZSBTTk1QX0FERFJDQUNIRV9TSVpFIDEwCiNkZWZpbmUgU05NUF9BRERSQ0FDSEVfTUFYQUdFIDMwMCAvKiBpbiBzZWNvbmRzICovCgplbnVtIHsKICAgIFNOTVBfQUREUkNBQ0hFX1VOVVNFRCA9IDAsCiAgICBTTk1QX0FERFJDQUNIRV9VU0VEID0gMQp9OwoKc3RydWN0IGFkZHJDYWNoZSB7CiAgICBjaGFyICAgICAgICAgICAqYWRkcjsKICAgIGludCAgICAgICAgICAgIHN0YXR1czsKICAgIHN0cnVjdCB0aW1ldmFsIGxhc3RIaXQ7Cn07CgpzdGF0aWMgc3RydWN0IGFkZHJDYWNoZSBhZGRyQ2FjaGVbU05NUF9BRERSQ0FDSEVfU0laRV07CmludCAgICAgICAgICAgICBsb2dfYWRkcmVzc2VzID0gMDsKCgoKdHlwZWRlZiBzdHJ1Y3QgX2FnZW50X25zYXAgewogICAgaW50ICAgICAgICAgICAgIGhhbmRsZTsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0OwogICAgdm9pZCAgICAgICAgICAgKnM7ICAgICAgICAgIC8qICBPcGFxdWUgaW50ZXJuYWwgc2Vzc2lvbiBwb2ludGVyLiAgKi8KICAgIHN0cnVjdCBfYWdlbnRfbnNhcCAqbmV4dDsKfSBhZ2VudF9uc2FwOwoKc3RhdGljIGFnZW50X25zYXAgKmFnZW50X25zYXBfbGlzdCA9IE5VTEw7CnN0YXRpYyBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFnZW50X3Nlc3Npb25fbGlzdCA9IE5VTEw7Cm5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqbmV0c25tcF9wcm9jZXNzaW5nX3NldCA9IE5VTEw7Cm5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBOVUxMOwpuZXRzbm1wX2FnZW50X3Nlc3Npb24gKm5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QgPSBOVUxMOwoKCmludCAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X2NoZWNrX3BhY2tldChuZXRzbm1wX3Nlc3Npb24gKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBuZXRzbm1wX3RyYW5zcG9ydF9zICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICosIGludCk7CmludCAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X2NoZWNrX3BhcnNlKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQpOwp2b2lkICAgICAgICAgICAgZGVsZXRlX3N1Ym5ldHNubXBfdHJlZV9jYWNoZShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBoYW5kbGVfcGR1KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKTsKaW50ICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzdGF0dXMpOwppbnQgICAgICAgICAgICAgbmV0c25tcF93cmFwX3VwX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdHVzKTsKaW50ICAgICAgICAgICAgIGNoZWNrX2RlbGF5ZWRfcmVxdWVzdChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBoYW5kbGVfZ2V0bmV4dF9sb29wKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKTsKaW50ICAgICAgICAgICAgIGhhbmRsZV9zZXRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CgppbnQgICAgICAgICAgICAgbmV0c25tcF9jaGVja19xdWV1ZWRfY2hhaW5fZm9yKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKTsKaW50ICAgICAgICAgICAgIG5ldHNubXBfYWRkX3F1ZXVlZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CmludCAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9mcm9tX2RlbGVnYXRlZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCk7CgoKc3RhdGljIGludCAgICAgIGN1cnJlbnRfZ2xvYmFsaWQgPSAwOwoKaW50ICAgICAgbmV0c25tcF9ydW5uaW5nID0gMTsKCmludApuZXRzbm1wX2FsbG9jYXRlX2dsb2JhbGNhY2hlaWQodm9pZCkKewogICAgcmV0dXJuICsrY3VycmVudF9nbG9iYWxpZDsKfQoKaW50Cm5ldHNubXBfZ2V0X2xvY2FsX2NhY2hpZChuZXRzbm1wX2NhY2hlbWFwICpjYWNoZV9zdG9yZSwgaW50IGdsb2JhbGlkKQp7CiAgICB3aGlsZSAoY2FjaGVfc3RvcmUgIT0gTlVMTCkgewogICAgICAgIGlmIChjYWNoZV9zdG9yZS0+Z2xvYmFsaWQgPT0gZ2xvYmFsaWQpCiAgICAgICAgICAgIHJldHVybiBjYWNoZV9zdG9yZS0+Y2FjaGVpZDsKICAgICAgICBjYWNoZV9zdG9yZSA9IGNhY2hlX3N0b3JlLT5uZXh0OwogICAgfQogICAgcmV0dXJuIC0xOwp9CgpuZXRzbm1wX2NhY2hlbWFwICoKbmV0c25tcF9nZXRfb3JfYWRkX2xvY2FsX2NhY2hpZChuZXRzbm1wX2NhY2hlbWFwICoqY2FjaGVfc3RvcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGdsb2JhbGlkLCBpbnQgbG9jYWxpZCkKewogICAgbmV0c25tcF9jYWNoZW1hcCAqdG1wcDsKCiAgICB0bXBwID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2NhY2hlbWFwKTsKICAgIGlmICh0bXBwICE9IE5VTEwpIHsKICAgICAgICBpZiAoKmNhY2hlX3N0b3JlKSB7CiAgICAgICAgICAgIHRtcHAtPm5leHQgPSAqY2FjaGVfc3RvcmU7CiAgICAgICAgICAgICpjYWNoZV9zdG9yZSA9IHRtcHA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgKmNhY2hlX3N0b3JlID0gdG1wcDsKICAgICAgICB9CgogICAgICAgIHRtcHAtPmdsb2JhbGlkID0gZ2xvYmFsaWQ7CiAgICAgICAgdG1wcC0+Y2FjaGVpZCA9IGxvY2FsaWQ7CiAgICB9CiAgICByZXR1cm4gdG1wcDsKfQoKdm9pZApuZXRzbm1wX2ZyZWVfY2FjaGVtYXAobmV0c25tcF9jYWNoZW1hcCAqY2FjaGVfc3RvcmUpCnsKICAgIG5ldHNubXBfY2FjaGVtYXAgKnRtcHA7CiAgICB3aGlsZSAoY2FjaGVfc3RvcmUpIHsKICAgICAgICB0bXBwID0gY2FjaGVfc3RvcmU7CiAgICAgICAgY2FjaGVfc3RvcmUgPSBjYWNoZV9zdG9yZS0+bmV4dDsKICAgICAgICBTTk1QX0ZSRUUodG1wcCk7CiAgICB9Cn0KCgp0eXBlZGVmIHN0cnVjdCBhZ2VudF9zZXRfY2FjaGVfcyB7CiAgICAvKgogICAgICogbWF0Y2ggb24gdGhlc2UgMiAKICAgICAqLwogICAgaW50ICAgICAgICAgICAgIHRyYW5zSUQ7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNlc3M7CgogICAgLyoKICAgICAqIHN0b3JlIHRoaXMgaW5mbyAKICAgICAqLwogICAgbmV0c25tcF90cmVlX2NhY2hlICp0cmVlY2FjaGU7CiAgICBpbnQgICAgICAgICAgICAgdHJlZWNhY2hlX2xlbjsKICAgIGludCAgICAgICAgICAgICB0cmVlY2FjaGVfbnVtOwoKICAgIGludCAgICAgICAgICAgICB2YmNvdW50OwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpzYXZlZF92YXJzOwogICAgbmV0c25tcF9kYXRhX2xpc3QgKmFnZW50X2RhdGE7CgogICAgLyoKICAgICAqIGxpc3QgCiAgICAgKi8KICAgIHN0cnVjdCBhZ2VudF9zZXRfY2FjaGVfcyAqbmV4dDsKfSBhZ2VudF9zZXRfY2FjaGU7CgpzdGF0aWMgYWdlbnRfc2V0X2NhY2hlICpTZXRzID0gTlVMTDsKCmFnZW50X3NldF9jYWNoZSAqCnNhdmVfc2V0X2NhY2hlKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBhZ2VudF9zZXRfY2FjaGUgKnB0cjsKCiAgICBpZiAoIWFzcCB8fCAhYXNwLT5yZXFpbmZvIHx8ICFhc3AtPnBkdSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBTTk1QX01BTExPQ19UWVBFREVGKGFnZW50X3NldF9jYWNoZSk7CiAgICBpZiAocHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyoKICAgICAqIFNhdmUgdGhlIGltcG9ydGFudCBpbmZvcm1hdGlvbiAKICAgICAqLwogICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIHNhdmVkIGluIGNhY2hlIChtb2RlICVkKVxuIiwKICAgICAgICAgICAgICAgIGFzcCwgYXNwLT5yZXFpbmZvLCBhc3AtPnBkdS0+Y29tbWFuZCkpOwogICAgcHRyLT50cmFuc0lEID0gYXNwLT5wZHUtPnRyYW5zaWQ7CiAgICBwdHItPnNlc3MgPSBhc3AtPnNlc3Npb247CiAgICBwdHItPnRyZWVjYWNoZSA9IGFzcC0+dHJlZWNhY2hlOwogICAgcHRyLT50cmVlY2FjaGVfbGVuID0gYXNwLT50cmVlY2FjaGVfbGVuOwogICAgcHRyLT50cmVlY2FjaGVfbnVtID0gYXNwLT50cmVlY2FjaGVfbnVtOwogICAgcHRyLT5hZ2VudF9kYXRhID0gYXNwLT5yZXFpbmZvLT5hZ2VudF9kYXRhOwogICAgcHRyLT5yZXF1ZXN0cyA9IGFzcC0+cmVxdWVzdHM7CiAgICBwdHItPnNhdmVkX3ZhcnMgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyAvKiByZXF1ZXN0cyBjb250YWlucyBwb2ludGVycyB0byB2YXJpYWJsZXMgKi8KICAgIHB0ci0+dmJjb3VudCA9IGFzcC0+dmJjb3VudDsKCiAgICAvKgogICAgICogbWFrZSB0aGUgYWdlbnQgZm9yZ2V0IGFib3V0IHdoYXQgd2UndmUgc2F2ZWQgCiAgICAgKi8KICAgIGFzcC0+dHJlZWNhY2hlID0gTlVMTDsKICAgIGFzcC0+cmVxaW5mby0+YWdlbnRfZGF0YSA9IE5VTEw7CiAgICBhc3AtPnBkdS0+dmFyaWFibGVzID0gTlVMTDsKICAgIGFzcC0+cmVxdWVzdHMgPSBOVUxMOwoKICAgIHB0ci0+bmV4dCA9IFNldHM7CiAgICBTZXRzID0gcHRyOwoKICAgIHJldHVybiBwdHI7Cn0KCmludApnZXRfc2V0X2NhY2hlKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBhZ2VudF9zZXRfY2FjaGUgKnB0ciwgKnByZXYgPSBOVUxMOwoKICAgIGZvciAocHRyID0gU2V0czsgcHRyICE9IE5VTEw7IHB0ciA9IHB0ci0+bmV4dCkgewogICAgICAgIGlmIChwdHItPnNlc3MgPT0gYXNwLT5zZXNzaW9uICYmIHB0ci0+dHJhbnNJRCA9PSBhc3AtPnBkdS0+dHJhbnNpZCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZW1vdmUgdGhpcyBpdGVtIGZyb20gbGlzdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHByZXYpCiAgICAgICAgICAgICAgICBwcmV2LT5uZXh0ID0gcHRyLT5uZXh0OwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBTZXRzID0gcHRyLT5uZXh0OwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZm91bmQgaXQuICBHZXQgdGhlIG5lZWRlZCBkYXRhIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYXNwLT50cmVlY2FjaGUgPSBwdHItPnRyZWVjYWNoZTsKICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVfbGVuID0gcHRyLT50cmVlY2FjaGVfbGVuOwogICAgICAgICAgICBhc3AtPnRyZWVjYWNoZV9udW0gPSBwdHItPnRyZWVjYWNoZV9udW07CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGcmVlIHByZXZpb3VzbHkgYWxsb2NhdGVkIHJlcXVlc3RzIGJlZm9yZSBvdmVyd3JpdGluZyBieQogICAgICAgICAgICAgKiBjYWNoZWQgb25lcywgb3RoZXJ3aXNlIG1lbW9yeSBsZWFrcyEKICAgICAgICAgICAgICovCgkgICAgaWYgKGFzcC0+cmVxdWVzdHMpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBJIGRvbid0IHRoaW5rIHRoaXMgY2FzZSBzaG91bGQgZXZlciBoYXBwZW4uIFBsZWFzZSBlbWFpbAogICAgICAgICAgICAgICAgICogdGhlIG5ldC1zbm1wLWNvZGVyc0BsaXN0cy5zb3VyY2Vmb3JnZS5uZXQgaWYgeW91IGhhdmUKICAgICAgICAgICAgICAgICAqIGEgdGVzdCBjYXNlIHRoYXQgaGl0cyB0aGlzIGNvbmRpdGlvbi4gLS0gcnN0b3J5CiAgICAgICAgICAgICAgICAgKi8KCQlpbnQgaTsKICAgICAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgPT0gYXNwLT5yZXF1ZXN0cyk7IC8qIHNlZSBub3RlIGFib3ZlICovCgkJZm9yIChpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgaSsrKSB7CgkJICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cygmYXNwLT5yZXF1ZXN0c1tpXSk7CgkJfQoJCWZyZWUoYXNwLT5yZXF1ZXN0cyk7CgkgICAgfQoJICAgIC8qCgkgICAgICogSWYgd2UgcmVwbGFjZSBhc3AtPnJlcXVlc3RzIHdpdGggdGhlIGluZm8gZnJvbSB0aGUgc2V0IGNhY2hlLAoJICAgICAqIHdlIHNob3VsZCByZXBsYWNlIGFzcC0+cGR1LT52YXJpYWJsZXMgYWxzbyB3aXRoIHRoZSBjYWNoZWQKCSAgICAgKiBpbmZvLCBhcyBhc3AtPnJlcXVlc3RzIGNvbnRhaW5zIHBvaW50ZXJzIHRvIHRoZW0uICBBbmQgd2UKCSAgICAgKiBzaG91bGQgYWxzbyBmcmVlIHRoZSBjdXJyZW50IGFzcC0+cGR1LT52YXJpYWJsZXMgbGlzdC4uLgoJICAgICAqLwoJICAgIGlmIChwdHItPnNhdmVkX3ZhcnMpIHsKCQlpZiAoYXNwLT5wZHUtPnZhcmlhYmxlcykKCQkgICAgc25tcF9mcmVlX3ZhcmJpbmQoYXNwLT5wZHUtPnZhcmlhYmxlcyk7CgkJYXNwLT5wZHUtPnZhcmlhYmxlcyA9IHB0ci0+c2F2ZWRfdmFyczsKICAgICAgICAgICAgICAgIGFzcC0+dmJjb3VudCA9IHB0ci0+dmJjb3VudDsKCSAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHdoZW4gd291bGQgd2Ugbm90IGhhdmUgc2F2ZWQgdmFyaWFibGVzPyBzb21lb25lCiAgICAgICAgICAgICAgICAgKiBsZXQgbWUga25vdyBpZiB0aGV5IGhpdCB0aGlzIGNvbmRpdGlvbi4gLS0gcnN0b3J5CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gcHRyLT5zYXZlZF92YXJzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhc3AtPnJlcXVlc3RzID0gcHRyLT5yZXF1ZXN0czsKCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwgIT0gYXNwLT5yZXFpbmZvKTsKICAgICAgICAgICAgYXNwLT5yZXFpbmZvLT5hc3AgPSBhc3A7CiAgICAgICAgICAgIGFzcC0+cmVxaW5mby0+YWdlbnRfZGF0YSA9IHB0ci0+YWdlbnRfZGF0YTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHVwZGF0ZSByZXF1ZXN0IHJlcWluZm8sIGlmIGl0J3Mgb3V0IG9mIGRhdGUuCiAgICAgICAgICAgICAqIHl5eS1ya3M6IGludmVzdGlnYXRlIHdoZW4vd2h5IHNvbWV0aW1lcyB0aGV5IG1hdGNoLAogICAgICAgICAgICAgKiBzb21ldGltZXMgdGhleSBkb24ndC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKGFzcC0+cmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvICE9IGFzcC0+cmVxaW5mbykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIC0gb25lIGRvbid0IG1hdGNoIGNhc2U6IGFnZW50eCBzdWJhZ2VudHMuIHByZXYgYXNwICYgcmVxaW5mbwogICAgICAgICAgICAgICAgICogICBmcmVlZCwgcmVxdWVzdCByZXFpbmZvIHB0cnMgbm90IGNsZWFyZWQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICp0bXAgPSBhc3AtPnJlcXVlc3RzOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIHJlcWluZm8gJXAgZG9lc24ndCBtYXRjaCBjYWNoZWQgcmVxaW5mbyAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxaW5mbywgYXNwLT5yZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pKTsKICAgICAgICAgICAgICAgIGZvcig7IHRtcDsgdG1wID0gdG1wLT5uZXh0KQogICAgICAgICAgICAgICAgICAgIHRtcC0+YWdlbnRfcmVxX2luZm8gPSBhc3AtPnJlcWluZm87CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogLSBtYXRjaCBjYXNlOiA/CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICByZXFpbmZvICVwIG1hdGNoZXMgY2FjaGVkIHJlcWluZm8gJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnJlcWluZm8sIGFzcC0+cmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFNOTVBfRlJFRShwdHIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CiAgICAgICAgcHJldiA9IHB0cjsKICAgIH0KICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7Cn0KCi8qIEJ1bGtjYWNoZSBob2xkcyB0aGUgdmFsdWVzIGZvciB0aGUgKnJlcGVhdGluZyogdmFyYmluZHMgKG9ubHkpLAogKiAgIGJ1dCBvcmRlcmVkICJieSBjb2x1bW4iIC0gaS5lLiB0aGUgcmVwZXRpdGlvbnMgZm9yIGVhY2gKICogICByZXBlYXRpbmcgdmFyYmluZCBmb2xsb3cgb24gaW1tZWRpYXRlbHkgZnJvbSBvbmUgYW5vdGhlciwKICogICByYXRoZXIgdGhhbiBiZWluZyBpbnRlcmxlYXZlZCwgYXMgcmVxdWlyZWQgYnkgdGhlIHByb3RvY29sLgogKgogKiBTbyB3ZSBuZWVkIHRvIHJlYXJyYW5nZSB0aGUgdmFyYmluZCBsaXN0IHNvIGl0J3Mgb3JkZXJlZCAiYnkgcm93Ii4KICoKICogSW4gdGhlIGZvbGxvd2luZyBjb2RlIGNodW5rOgogKiAgICAgbiAgICAgICAgICAgID0gIyBub24tcmVwZWF0aW5nIHZhcmJpbmRzCiAqICAgICByICAgICAgICAgICAgPSAjIHJlcGVhdGluZyB2YXJiaW5kcwogKiAgICAgYXNwLT52YmNvdW50ID0gIyB2YXJiaW5kcyBpbiB0aGUgaW5jb21pbmcgUERVCiAqICAgICAgICAgKFNvIGFzcC0+dmJjb3VudCA9IG4rcikKICoKICogICAgIHJlcGVhdHMgPSBEZXNpcmVkICMgb2YgcmVwZXRpdGlvbnMgKG9mICdyJyB2YXJiaW5kcykKICovCk5FVFNOTVBfU1RBVElDX0lOTElORSB2b2lkCl9yZW9yZGVyX2dldGJ1bGsobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBpLCBuID0gMCwgciA9IDA7CiAgICBpbnQgICAgICAgICAgICAgcmVwZWF0cyA9IGFzcC0+cGR1LT5lcnJpbmRleDsKICAgIGludCAgICAgICAgICAgICBqLCBrOwogICAgaW50ICAgICAgICAgICAgIGFsbF9lb01pYjsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqcHJldiA9IE5VTEwsICpjdXJyOwogICAgICAgICAgICAKICAgIGlmIChhc3AtPnZiY291bnQgPT0gMCkgIC8qIE5vdGhpbmcgdG8gZG8hICovCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChhc3AtPnBkdS0+ZXJyc3RhdCA8IGFzcC0+dmJjb3VudCkgewogICAgICAgIG4gPSBhc3AtPnBkdS0+ZXJyc3RhdDsKICAgIH0gZWxzZSB7CiAgICAgICAgbiA9IGFzcC0+dmJjb3VudDsKICAgIH0KICAgIGlmICgociA9IGFzcC0+dmJjb3VudCAtIG4pIDwgMCkgewogICAgICAgIHIgPSAwOwogICAgfQoKICAgIC8qIHdlIGRvIG5vdGhpbmcgaWYgdGhlcmUgaXMgbm90aGluZyByZXBlYXRlZCAqLwogICAgaWYgKHIgPT0gMCkKICAgICAgICByZXR1cm47CiAgICAgICAgICAgIAogICAgLyogRml4IGVuZE9mTWliVmlldyBlbnRyaWVzLiAqLwogICAgZm9yIChpID0gMDsgaSA8IHI7IGkrKykgewogICAgICAgIHByZXYgPSBOVUxMOwogICAgICAgIGZvciAoaiA9IDA7IGogPCByZXBlYXRzOyBqKyspIHsKCSAgICBjdXJyID0gYXNwLT5idWxrY2FjaGVbaSAqIHJlcGVhdHMgKyBqXTsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogIElmIHdlIGRvbid0IGhhdmUgYSB2YWxpZCBuYW1lIGZvciBhIGdpdmVuIHJlcGV0aXRpb24KICAgICAgICAgICAgICogICAoYW5kIHByb2JhYmx5IGZvciBhbGwgdGhlIG9uZXMgdGhhdCBmb2xsb3cgYXMgd2VsbCksCiAgICAgICAgICAgICAqICAgZXh0ZW5kIHRoZSBwcmV2aW91cyByZXN1bHQgdG8gaW5kaWNhdGUgJ2VuZE9mTWliVmlldycuCiAgICAgICAgICAgICAqICBPciBpZiB0aGUgcmVwZXRpdGlvbiBhbHJlYWR5IGhhcyB0eXBlIGVuZE9mTWliVmlldyBtYWtlCiAgICAgICAgICAgICAqICAgc3VyZSBpdCBoYXMgdGhlIGNvcnJlY3Qgb2JqaWQgKGkuZS4gdGhhdCBvZiB0aGUgcHJldmlvdXMKICAgICAgICAgICAgICogICBlbnRyeSBvciB0aGF0IG9mIHRoZSBvcmlnaW5hbCByZXF1ZXN0KS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjdXJyLT5uYW1lX2xlbmd0aCA9PSAwIHx8IGN1cnItPnR5cGUgPT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKCQlpZiAocHJldiA9PSBOVUxMKSB7CgkJICAgIC8qIFVzZSBvYmppZCBmcm9tIG9yaWdpbmFsIHBkdS4gKi8KCQkgICAgcHJldiA9IGFzcC0+b3JpZ19wZHUtPnZhcmlhYmxlczsKCQkgICAgZm9yIChrID0gaTsgcHJldiAmJiBrID4gMDsgay0tKQoJCQlwcmV2ID0gcHJldi0+bmV4dF92YXJpYWJsZTsKCQl9CgkJaWYgKHByZXYpIHsKCQkgICAgc25tcF9zZXRfdmFyX29iamlkKGN1cnIsIHByZXYtPm5hbWUsIHByZXYtPm5hbWVfbGVuZ3RoKTsKCQkgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKGN1cnIsIFNOTVBfRU5ET0ZNSUJWSUVXLCBOVUxMLCAwKTsKCQl9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJldiA9IGN1cnI7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBGb3IgZWFjaCBvZiB0aGUgb3JpZ2luYWwgcmVwZWF0aW5nIHZhcmJpbmRzIChleGNlcHQgdGhlIGxhc3QpLAogICAgICogIGdvIHRocm91Z2ggdGhlIGJsb2NrIG9mIHJlc3VsdHMgZm9yIHRoYXQgdmFyYmluZCwKICAgICAqICBhbmQgbGluayBlYWNoIGluc3RhbmNlIHRvIHRoZSBjb3JyZXNwb25kaW5nIGluc3RhbmNlCiAgICAgKiAgaW4gdGhlIG5leHQgYmxvY2suCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCByIC0gMTsgaSsrKSB7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IHJlcGVhdHM7IGorKykgewogICAgICAgICAgICBhc3AtPmJ1bGtjYWNoZVtpICogcmVwZWF0cyArIGpdLT5uZXh0X3ZhcmlhYmxlID0KICAgICAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlWyhpICsgMSkgKiByZXBlYXRzICsgal07CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBGb3IgdGhlIGxhc3Qgb2YgdGhlIG9yaWdpbmFsIHJlcGVhdGluZyB2YXJiaW5kcywKICAgICAqICBnbyB0aHJvdWdoIHRoYXQgYmxvY2sgb2YgcmVzdWx0cywgYW5kIGxpbmsgZWFjaAogICAgICogIGluc3RhbmNlIHRvIHRoZSAqbmV4dCogaW5zdGFuY2UgaW4gdGhlICpmaXJzdCogYmxvY2suCiAgICAgKgogICAgICogVGhlIHZlcnkgbGFzdCBpbnN0YW5jZSBvZiB0aGlzIGJsb2NrIGlzIGxlZnQgdW50b3VjaGVkCiAgICAgKiAgc2luY2UgaXQgKGNvcnJlY3RseSkgcG9pbnRzIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3QuCiAgICAgKi8KICAgIGZvciAoaiA9IDA7IGogPCByZXBlYXRzIC0gMTsgaisrKSB7Cglhc3AtPmJ1bGtjYWNoZVsociAtIDEpICogcmVwZWF0cyArIGpdLT5uZXh0X3ZhcmlhYmxlID0gCgkgICAgYXNwLT5idWxrY2FjaGVbaiArIDFdOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB3ZSd2ZSBnb3QgYSBmdWxsIHJvdyBvZiBlbmRPZk1pYlZpZXdzLCB0aGVuIHdlCiAgICAgKiAgY2FuIHRydW5jYXRlIHRoZSByZXN1bHQgdmFyYmluZCBsaXN0IGFmdGVyIHRoYXQuCiAgICAgKgogICAgICogTG9vayBmb3IgZW5kT2ZNaWJWaWV3IGV4Y2VwdGlvbiB2YWx1ZXMgaW4gdGhlIGxpc3Qgb2YKICAgICAqICByZXBldGl0aW9ucyBmb3IgdGhlIGZpcnN0IHZhcmJpbmQsIGFuZCBjaGVjayB0aGUgCiAgICAgKiAgY29ycmVzcG9uZGluZyBpbnN0YW5jZXMgZm9yIHRoZSBvdGhlciB2YXJiaW5kcwogICAgICogIChmb2xsb3dpbmcgdGhlIG5leHRfdmFyaWFibGUgbGlua3MpLgogICAgICoKICAgICAqIElmIHRoZXkncmUgYWxsIGVuZE9mTWliVmlldyB0b28sIHRoZW4gd2UgY2FuIHRlcm1pbmF0ZQogICAgICogIHRoZSBsaW5rZWQgbGlzdCB0aGVyZSwgYW5kIGZyZWUgYW55IHJlZHVuZGFudCB2YXJiaW5kcy4KICAgICAqLwogICAgYWxsX2VvTWliID0gMDsKICAgIGZvciAoaSA9IDA7IGkgPCByZXBlYXRzOyBpKyspIHsKICAgICAgICBpZiAoYXNwLT5idWxrY2FjaGVbaV0tPnR5cGUgPT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKICAgICAgICAgICAgYWxsX2VvTWliID0gMTsKICAgICAgICAgICAgZm9yIChqID0gMSwgcHJldj1hc3AtPmJ1bGtjYWNoZVtpXTsKICAgICAgICAgICAgICAgICBqIDwgcjsKICAgICAgICAgICAgICAgICBqKyssIHByZXY9cHJldi0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgaWYgKHByZXYtPnR5cGUgIT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKICAgICAgICAgICAgICAgICAgICBhbGxfZW9NaWIgPSAwOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwkvKiBGb3VuZCBhIHJlYWwgdmFsdWUgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoYWxsX2VvTWliKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVGhpcyBpcyBpbmRlZWQgYSBmdWxsIGVuZE9mTWliVmlldyByb3cuCiAgICAgICAgICAgICAgICAgKiBUZXJtaW5hdGUgdGhlIGxpc3QgaGVyZSAmIGZyZWUgdGhlIHJlc3QuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCBwcmV2LT5uZXh0X3ZhcmlhYmxlICk7CiAgICAgICAgICAgICAgICBwcmV2LT5uZXh0X3ZhcmlhYmxlID0gTlVMTDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgoKLyogRW5kT2ZNaWJWaWV3IHJlcGxpZXMgdG8gYSBHRVRORVhUIHJlcXVlc3Qgc2hvdWxkIGFjY29yZGluZyB0byBSRkMzNDE2CiAqICBoYXZlIHRoZSBvYmplY3QgSUQgc2V0IHRvIHRoYXQgb2YgdGhlIHJlcXVlc3QuIE91ciB0cmVlIHNlYXJjaCAKICogIGFsZ29yaXRobSB3aWxsIHNvbWV0aW1lcyBicmVhayB0aGF0IHJlcXVpcmVtZW50LiBUaGlzIGZ1bmN0aW9uIHdpbGwKICogIGZpeCB0aGF0LgogKi8KTkVUU05NUF9TVEFUSUNfSU5MSU5FIHZvaWQKX2ZpeF9lbmRvZm1pYnZpZXcobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmIsICpvdmI7CgogICAgaWYgKGFzcC0+dmJjb3VudCA9PSAwKSAgLyogTm90aGluZyB0byBkbyEgKi8KICAgICAgICByZXR1cm47CgogICAgZm9yICh2YiA9IGFzcC0+cGR1LT52YXJpYWJsZXMsIG92YiA9IGFzcC0+b3JpZ19wZHUtPnZhcmlhYmxlczsKCSB2YiAmJiBvdmI7IHZiID0gdmItPm5leHRfdmFyaWFibGUsIG92YiA9IG92Yi0+bmV4dF92YXJpYWJsZSkgewoJaWYgKHZiLT50eXBlID09IFNOTVBfRU5ET0ZNSUJWSUVXKQoJICAgIHNubXBfc2V0X3Zhcl9vYmppZCh2Yiwgb3ZiLT5uYW1lLCBvdmItPm5hbWVfbGVuZ3RoKTsKICAgIH0KfQoKCmludApnZXROZXh0U2Vzc0lEKHZvaWQpCnsKICAgIHN0YXRpYyBpbnQgICAgICBTZXNzaW9uSUQgPSAwOwoKICAgIHJldHVybiArK1Nlc3Npb25JRDsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gY2hlY2tzIGZvciBwYWNrZXRzIGFycml2aW5nIG9uIHRoZSBTTk1QIHBvcnQgYW5kCiAqIHByb2Nlc3NlcyB0aGVtKHNubXBfcmVhZCkgaWYgc29tZSBhcmUgZm91bmQsIHVzaW5nIHRoZSBzZWxlY3QoKS4gSWYgYmxvY2sKICogaXMgbm9uIHplcm8sIHRoZSBmdW5jdGlvbiBjYWxsIGJsb2NrcyB1bnRpbCBhIHBhY2tldCBhcnJpdmVzCiAqCiAqIEBwYXJhbSBibG9jayB1c2VkIHRvIGNvbnRyb2wgYmxvY2tpbmcgaW4gdGhlIHNlbGVjdCgpIGZ1bmN0aW9uLCAxID0gYmxvY2sKICogICAgICAgIGZvcmV2ZXIsIGFuZCAwID0gZG9uJ3QgYmxvY2sKICoKICogQHJldHVybiAgUmV0dXJucyBhIHBvc2l0aXZlIGludGVnZXIgaWYgcGFja2V0cyB3ZXJlIHByb2Nlc3NlZCwgYW5kIC0xIGlmIGFuCiAqIGVycm9yIHdhcyBmb3VuZC4KICoKICovCmludAphZ2VudF9jaGVja19hbmRfcHJvY2VzcyhpbnQgYmxvY2spCnsKICAgIGludCAgICAgICAgICAgICBudW1mZHM7CiAgICBmZF9zZXQgICAgICAgICAgZmRzZXQ7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdGltZW91dCA9IHsgTE9OR19NQVgsIDAgfSwgKnR2cCA9ICZ0aW1lb3V0OwogICAgaW50ICAgICAgICAgICAgIGNvdW50OwogICAgaW50ICAgICAgICAgICAgIGZha2VibG9jayA9IDA7CgogICAgbnVtZmRzID0gMDsKICAgIEZEX1pFUk8oJmZkc2V0KTsKICAgIHNubXBfc2VsZWN0X2luZm8oJm51bWZkcywgJmZkc2V0LCB0dnAsICZmYWtlYmxvY2spOwogICAgaWYgKGJsb2NrICE9IDAgJiYgZmFrZWJsb2NrICE9IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFRoZXJlIGFyZSBubyBhbGFybXMgcmVnaXN0ZXJlZCwgYW5kIHRoZSBjYWxsZXIgYXNrZWQgZm9yIGJsb2NraW5nLCBzbwogICAgICAgICAqIGxldCBzZWxlY3QoKSBibG9jayBmb3JldmVyLiAgCiAgICAgICAgICovCgogICAgICAgIHR2cCA9IE5VTEw7CiAgICB9IGVsc2UgaWYgKGJsb2NrICE9IDAgJiYgZmFrZWJsb2NrID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFRoZSBjYWxsZXIgYXNrZWQgZm9yIGJsb2NraW5nLCBidXQgdGhlcmUgaXMgYW4gYWxhcm0gZHVlIHNvb25lciB0aGFuCiAgICAgICAgICogTE9OR19NQVggc2Vjb25kcyBmcm9tIG5vdywgc28gdXNlIHRoZSBtb2RpZmllZCB0aW1lb3V0IHJldHVybmVkIGJ5CiAgICAgICAgICogc25tcF9zZWxlY3RfaW5mbyBhcyB0aGUgdGltZW91dCBmb3Igc2VsZWN0KCkuICAKICAgICAgICAgKi8KCiAgICB9IGVsc2UgaWYgKGJsb2NrID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIFRoZSBjYWxsZXIgZG9lcyBub3Qgd2FudCB1cyB0byBibG9jayBhdCBhbGwuICAKICAgICAgICAgKi8KCiAgICAgICAgdGltZXJjbGVhcih0dnApOwogICAgfQoKICAgIGNvdW50ID0gc2VsZWN0KG51bWZkcywgJmZkc2V0LCBOVUxMLCBOVUxMLCB0dnApOwoKICAgIGlmIChjb3VudCA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIHBhY2tldHMgZm91bmQsIHByb2Nlc3MgdGhlbSAKICAgICAgICAgKi8KICAgICAgICBzbm1wX3JlYWQoJmZkc2V0KTsKICAgIH0gZWxzZQogICAgICAgIHN3aXRjaCAoY291bnQpIHsKICAgICAgICBjYXNlIDA6CiAgICAgICAgICAgIHNubXBfdGltZW91dCgpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIC0xOgogICAgICAgICAgICBpZiAoZXJybm8gIT0gRUlOVFIpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nX3BlcnJvcigic2VsZWN0Iik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJzZWxlY3QgcmV0dXJuZWQgJWRcbiIsIGNvdW50KTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZGlmIC0tIGNvdW50PjAgKi8KCiAgICAvKgogICAgICogc2VlIGlmIHBlcnNpc3RlbnQgc3RvcmUgbmVlZHMgdG8gYmUgc2F2ZWQKICAgICAqLwogICAgc25tcF9zdG9yZV9pZl9uZWVkZWQoKTsKCiAgICAvKgogICAgICogUnVuIHJlcXVlc3RlZCBhbGFybXMuICAKICAgICAqLwogICAgcnVuX2FsYXJtcygpOwoKICAgIG5ldHNubXBfY2hlY2tfb3V0c3RhbmRpbmdfYWdlbnRfcmVxdWVzdHMoKTsKCiAgICByZXR1cm4gY291bnQ7Cn0KCgovKgogKiBTZXQgdXAgdGhlIGFkZHJlc3MgY2FjaGUuICAKICovCnZvaWQKbmV0c25tcF9hZGRyY2FjaGVfaW5pdGlhbGlzZSh2b2lkKQp7CiAgICBpbnQgICAgICAgICAgICAgaSA9IDA7CgogICAgZm9yIChpID0gMDsgaSA8IFNOTVBfQUREUkNBQ0hFX1NJWkU7IGkrKykgewogICAgICAgIGFkZHJDYWNoZVtpXS5hZGRyID0gTlVMTDsKICAgICAgICBhZGRyQ2FjaGVbaV0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVU5VU0VEOwogICAgfQp9Cgp2b2lkIG5ldHNubXBfYWRkcmNhY2hlX2Rlc3Ryb3kodm9pZCkKewogICAgaW50ICAgICAgICAgICAgIGkgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBTTk1QX0FERFJDQUNIRV9TSVpFOyBpKyspIHsKICAgICAgICBpZiAoYWRkckNhY2hlW2ldLnN0YXR1cyA9PSBTTk1QX0FERFJDQUNIRV9VU0VEKSB7CiAgICAgICAgICAgIGZyZWUoYWRkckNhY2hlW2ldLmFkZHIpOwogICAgICAgICAgICBhZGRyQ2FjaGVbaV0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVU5VU0VEOwogICAgICAgIH0KICAgIH0KfQoKLyoKICogQWRkcyBhIG5ldyBlbnRyeSB0byB0aGUgY2FjaGUgb2YgYWRkcmVzc2VzIHRoYXQKICogaGF2ZSByZWNlbnRseSBtYWRlIGNvbm5lY3Rpb25zIHRvIHRoZSBhZ2VudC4KICogUmV0dXJucyAwIGlmIHRoZSBlbnRyeSBhbHJlYWR5IGV4aXN0cyAoYnV0IHVwZGF0ZXMKICogdGhlIGVudHJ5IHdpdGggYSBuZXcgdGltZXN0YW1wKSBhbmQgMSBpZiB0aGUKICogZW50cnkgZGlkIG5vdCBwcmV2aW91c2x5IGV4aXN0LgogKgogKiBJbXBsZW1lbnRzIGEgc2ltcGxlIExSVSBjYWNoZSByZXBsYWNlbWVudAogKiBwb2xpY3kuIFVzZXMgYSBsaW5lYXIgc2VhcmNoLCB3aGljaCBzaG91bGQgYmUKICogb2theSwgYXMgbG9uZyBhcyBTTk1QX0FERFJDQUNIRV9TSVpFIHJlbWFpbnMKICogcmVsYXRpdmVseSBzbWFsbC4KICoKICogQHJldHZhbCAwIDogdXBkYXRlZCBleGlzdGluZyBlbnRyeQogKiBAcmV0dmFsIDEgOiBhZGRlZCBuZXcgZW50cnkKICovCmludApuZXRzbm1wX2FkZHJjYWNoZV9hZGQoY29uc3QgY2hhciAqYWRkcikKewogICAgaW50IG9sZGVzdCA9IC0xOyAvKiBJbmRleCBvZiB0aGUgb2xkZXN0IGNhY2hlIGVudHJ5ICovCiAgICBpbnQgdW51c2VkID0gLTE7IC8qIEluZGV4IG9mIHRoZSBmaXJzdCBmcmVlIGNhY2hlIGVudHJ5ICovCiAgICBpbnQgaTsgLyogTG9vcGluZyB2YXJpYWJsZSAqLwogICAgaW50IHJjID0gLTE7CiAgICBzdHJ1Y3QgdGltZXZhbCBub3c7IC8qIFdoYXQgdGltZSBpcyBpdCBub3c/ICovCiAgICBzdHJ1Y3QgdGltZXZhbCBhZ2VkOyAvKiBPbGRlc3QgYWxsb3dhYmxlIGNhY2hlIGVudHJ5ICovCgogICAgLyoKICAgICAqIEZpcnN0IGdldCB0aGUgY3VycmVudCBhbmQgb2xkZXN0IGFsbG93YWJsZSB0aW1lc3RhbXBzCiAgICAgKi8KICAgIGdldHRpbWVvZmRheSgmbm93LCAoc3RydWN0IHRpbWV6b25lKikgTlVMTCk7CiAgICBhZ2VkLnR2X3NlYyA9IG5vdy50dl9zZWMgLSBTTk1QX0FERFJDQUNIRV9NQVhBR0U7CiAgICBhZ2VkLnR2X3VzZWMgPSBub3cudHZfdXNlYzsKCiAgICAvKgogICAgICogTm93IGxvb2sgZm9yIGEgcGxhY2UgdG8gcHV0IHRoaXMgdGhpbmcKICAgICAqLwogICAgZm9yKGkgPSAwOyBpIDwgU05NUF9BRERSQ0FDSEVfU0laRTsgaSsrKSB7CiAgICAgICAgaWYgKGFkZHJDYWNoZVtpXS5zdGF0dXMgPT0gU05NUF9BRERSQ0FDSEVfVU5VU0VEKSB7IC8qIElmIHVudXNlZCAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZW1lbWJlciB0aGlzIGxvY2F0aW9uLCBpbiBjYXNlIGFkZHIgaXNuJ3QgaW4gdGhlIGNhY2hlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAodW51c2VkIDwgMCkKICAgICAgICAgICAgICAgIHVudXNlZCA9IGk7CiAgICAgICAgfQogICAgICAgIGVsc2UgeyAvKiBJZiB1c2VkICovCiAgICAgICAgICAgIGlmICgoTlVMTCAhPSBhZGRyKSAmJiAoc3RyY21wKGFkZHJDYWNoZVtpXS5hZGRyLCBhZGRyKSA9PSAwKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZvdW5kIGEgbWF0Y2gKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgYWRkckNhY2hlW2ldLmxhc3RIaXQgPSBub3c7CiAgICAgICAgICAgICAgICBpZiAodGltZXJjbXAoJmFkZHJDYWNoZVtpXS5sYXN0SGl0LCAmYWdlZCwgPCkpCgkJICAgIHJjID0gMTsgLyogc2hvdWxkIGhhdmUgZXhwaXJlZCwgc28gaXMgbmV3ICovCgkJZWxzZQoJCSAgICByYyA9IDA7IC8qIG5vdCBleHBpcmVkLCBzbyBpcyBleGlzdGluZyBlbnRyeSAqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogVXNlZCwgYnV0IG5vdCB0aGlzIGFkZHJlc3MuIGNoZWNrIGlmIGl0J3Mgc3RhbGUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0aW1lcmNtcCgmYWRkckNhY2hlW2ldLmxhc3RIaXQsICZhZ2VkLCA8KSkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogU3RhbGUsIHJldXNlCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKGFkZHJDYWNoZVtpXS5hZGRyKTsKICAgICAgICAgICAgICAgICAgICBhZGRyQ2FjaGVbaV0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVU5VU0VEOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogcmVtZW1iZXIgdGhpcyBsb2NhdGlvbiwgaW4gY2FzZSBhZGRyIGlzbid0IGluIHRoZSBjYWNoZQogICAgICAgICAgICAgICAgICAgICAqLwoJCSAgICBpZiAodW51c2VkIDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgdW51c2VkID0gaTsKICAgICAgICAgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBTdGlsbCBmcmVzaCwgYnV0IGEgY2FuZGlkYXRlIGZvciBMUlUgcmVwbGFjZW1lbnQKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAob2xkZXN0IDwgMCkKICAgICAgICAgICAgICAgICAgICAgICAgb2xkZXN0ID0gaTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh0aW1lcmNtcCgmYWRkckNhY2hlW2ldLmxhc3RIaXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFkZHJDYWNoZVtvbGRlc3RdLmxhc3RIaXQsIDwpKQogICAgICAgICAgICAgICAgICAgICAgICBvbGRlc3QgPSBpOwogICAgICAgICAgICAgICAgfSAvKiBmcmVzaCAqLwogICAgICAgICAgICB9IC8qIHVzZWQsIG5vIG1hdGNoICovCiAgICAgICAgfSAvKiB1c2VkICovCiAgICB9IC8qIGZvciBsb29wICovCgogICAgaWYgKCgtMSA9PSByYykgJiYgKE5VTEwgIT0gYWRkcikpIHsKICAgICAgICAvKgogICAgICAgICAqIFdlIGRpZG4ndCBmaW5kIHRoZSBlbnRyeSBpbiB0aGUgY2FjaGUKICAgICAgICAgKi8KICAgICAgICBpZiAodW51c2VkID49IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSWYgd2UgaGF2ZSBhIHNsb3QgZnJlZSBhbnl3YXksIHVzZSBpdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYWRkckNhY2hlW3VudXNlZF0uYWRkciA9IHN0cmR1cChhZGRyKTsKICAgICAgICAgICAgYWRkckNhY2hlW3VudXNlZF0uc3RhdHVzID0gU05NUF9BRERSQ0FDSEVfVVNFRDsKICAgICAgICAgICAgYWRkckNhY2hlW3VudXNlZF0ubGFzdEhpdCA9IG5vdzsKICAgICAgICB9CiAgICAgICAgZWxzZSB7IC8qIE90aGVyd2lzZSwgcmVwbGFjZSBvbGRlc3QgZW50cnkgKi8KICAgICAgICAgICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9WRVJCT1NFKSkKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19JTkZPLCAiUHVyZ2luZyBhZGRyZXNzIGZyb20gYWRkcmVzcyBjYWNoZTogJXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgYWRkckNhY2hlW29sZGVzdF0uYWRkcik7CiAgICAgICAgICAgIAogICAgICAgICAgICBmcmVlKGFkZHJDYWNoZVtvbGRlc3RdLmFkZHIpOwogICAgICAgICAgICBhZGRyQ2FjaGVbb2xkZXN0XS5hZGRyID0gc3RyZHVwKGFkZHIpOwogICAgICAgICAgICBhZGRyQ2FjaGVbb2xkZXN0XS5sYXN0SGl0ID0gbm93OwogICAgICAgIH0KICAgICAgICByYyA9IDE7CiAgICB9CiAgICBpZiAoKGxvZ19hZGRyZXNzZXMgJiYgKDEgPT0gcmMpKSB8fAogICAgICAgIG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfVkVSQk9TRSkpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywgIlJlY2VpdmVkIFNOTVAgcGFja2V0KHMpIGZyb20gJXNcbiIsIGFkZHIpOwogICAgIH0KCiAgICByZXR1cm4gcmM7Cn0KCi8qCiAqIEFnZSB0aGUgZW50cmllcyBpbiB0aGUgYWRkcmVzcyBjYWNoZS4gIAogKgogKiBiYWNrd2FyZHMgY29tcGF0YWJpbGl0eTsgbm90IHVzZWQgYW55d2hlcmUKICovCnZvaWQKbmV0c25tcF9hZGRyY2FjaGVfYWdlKHZvaWQpCnsKICAgICh2b2lkKW5ldHNubXBfYWRkcmNhY2hlX2FkZChOVUxMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiotby0qKioqKioKICogbmV0c25tcF9hZ2VudF9jaGVja19wYWNrZXQKICoKICogUGFyYW1ldGVyczoKICoJc2Vzc2lvbiwgdHJhbnNwb3J0LCB0cmFuc3BvcnRfZGF0YSwgdHJhbnNwb3J0X2RhdGFfbGVuZ3RoCiAqICAgICAgCiAqIFJldHVybnM6CiAqCTEJT24gc3VjY2Vzcy4KICoJMAlPbiBlcnJvci4KICoKICogSGFuZGxlciBmb3IgYWxsIGluY29taW5nIG1lc3NhZ2VzIChhLmsuYS4gcGFja2V0cykgZm9yIHRoZSBhZ2VudC4gIElmIHVzaW5nCiAqIHRoZSBsaWJ3cmFwIHV0aWxpdHksIGxvZyB0aGUgY29ubmVjdGlvbiBhbmQgZGVueS9hbGxvdyB0aGUgYWNjZXNzLiBQcmludAogKiBvdXRwdXQgd2hlbiBhcHByb3ByaWF0ZSwgYW5kIGluY3JlbWVudCB0aGUgaW5jb21pbmcgY291bnRlci4KICoKICovCgppbnQKbmV0c25tcF9hZ2VudF9jaGVja19wYWNrZXQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqdHJhbnNwb3J0X2RhdGEsIGludCB0cmFuc3BvcnRfZGF0YV9sZW5ndGgpCnsKICAgIGNoYXIgICAgICAgICAgICphZGRyX3N0cmluZyA9IE5VTEw7CiNpZmRlZiAgTkVUU05NUF9VU0VfTElCV1JBUAogICAgY2hhciAqdGNwdWRwYWRkciA9IE5VTEwsICpuYW1lOwogICAgc2hvcnQgbm90X2xvZ19jb25uZWN0aW9uOwoKICAgIG5hbWUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKTsKCiAgICAvKiBub3RfbG9nX2Nvbm5lY3Rpb24gd2lsbCBiZSAxIGlmIHdlIHNob3VsZCBza2lwIHRoZSBtZXNzYWdlcyAqLwogICAgbm90X2xvZ19jb25uZWN0aW9uID0gbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX0RPTlRfTE9HX1RDUFdSQVBQRVJTX0NPTk5FQ1RTKTsKCiAgICAvKgogICAgICogaGFuZGxlIHRoZSBlcnJvciBjYXNlCiAgICAgKiBkZWZhdWx0IHRvIGxvZ2dpbmcgdGhlIG1lc3NhZ2VzCiAgICAgKi8KICAgIGlmIChub3RfbG9nX2Nvbm5lY3Rpb24gPT0gU05NUEVSUl9HRU5FUlIpIG5vdF9sb2dfY29ubmVjdGlvbiA9IDA7CiNlbmRpZgoKICAgIC8qCiAgICAgKiBMb2cgdGhlIG1lc3NhZ2UgYW5kL29yIGR1bXAgdGhlIG1lc3NhZ2UuCiAgICAgKiBPcHRpb25hbGx5IGNhY2hlIHRoZSBuZXR3b3JrIGFkZHJlc3Mgb2YgdGhlIHNlbmRlci4KICAgICAqLwoKICAgIGlmICh0cmFuc3BvcnQgIT0gTlVMTCAmJiB0cmFuc3BvcnQtPmZfZm10YWRkciAhPSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBPa2F5IEkgZG8ga25vdyBob3cgdG8gZm9ybWF0IHRoaXMgYWRkcmVzcyBmb3IgbG9nZ2luZy4gIAogICAgICAgICAqLwogICAgICAgIGFkZHJfc3RyaW5nID0gdHJhbnNwb3J0LT5mX2ZtdGFkZHIodHJhbnNwb3J0LCB0cmFuc3BvcnRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydF9kYXRhX2xlbmd0aCk7CiAgICAgICAgLyoKICAgICAgICAgKiBEb24ndCBmb3JnZXQgdG8gZnJlZSgpIGl0LiAgCiAgICAgICAgICovCiAgICB9CiNpZmRlZiAgTkVUU05NUF9VU0VfTElCV1JBUAogICAgLyogQ2F0Y2ggdWRwLHVkcDYsdGNwLHRjcDYgdHJhbnNwb3J0cyB1c2luZyAiWyIgKi8KICAgIGlmIChhZGRyX3N0cmluZykKICAgICAgICB0Y3B1ZHBhZGRyID0gc3Ryc3RyKGFkZHJfc3RyaW5nLCAiWyIpOwogICAgaWYgKCB0Y3B1ZHBhZGRyICE9IDAgKSB7CiAgICAgICAgY2hhciBzYnVmWzY0XTsKICAgICAgICBjaGFyICp4cDsKCiAgICAgICAgc3RybGNweShzYnVmLCB0Y3B1ZHBhZGRyICsgMSwgc2l6ZW9mKHNidWYpKTsKICAgICAgICB4cCA9IHN0cnN0cihzYnVmLCAiXSIpOwogICAgICAgIGlmICh4cCkKICAgICAgICAgICAgKnhwID0gJ1wwJzsKIAogICAgICAgIGlmIChob3N0c19jdGwobmFtZSwgU1RSSU5HX1VOS05PV04sIHNidWYsIFNUUklOR19VTktOT1dOKSkgewogICAgICAgICAgICBpZiAoIW5vdF9sb2dfY29ubmVjdGlvbikgewogICAgICAgICAgICAgICAgc25tcF9sb2coYWxsb3dfc2V2ZXJpdHksICJDb25uZWN0aW9uIGZyb20gJXNcbiIsIGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNubXBfbG9nKGRlbnlfc2V2ZXJpdHksICJDb25uZWN0aW9uIGZyb20gJXMgUkVGVVNFRFxuIiwKICAgICAgICAgICAgICAgICAgICAgYWRkcl9zdHJpbmcpOwogICAgICAgICAgICBTTk1QX0ZSRUUoYWRkcl9zdHJpbmcpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogZG9uJ3QgbG9nIGNhbGxiYWNrIGNvbm5lY3Rpb25zLgogICAgICAgICAqIFdoYXQgYWJvdXQgJ0xvY2FsIElQQycsICdJUFgnIGFuZCAnQUFMNSBQVkMnPwogICAgICAgICAqLwogICAgICAgIGlmICgwID09IHN0cm5jbXAoYWRkcl9zdHJpbmcsICJjYWxsYmFjayIsIDgpKQogICAgICAgICAgICA7CiAgICAgICAgZWxzZSBpZiAoaG9zdHNfY3RsKG5hbWUsIFNUUklOR19VTktOT1dOLCBTVFJJTkdfVU5LTk9XTiwgU1RSSU5HX1VOS05PV04pKXsKICAgICAgICAgICAgaWYgKCFub3RfbG9nX2Nvbm5lY3Rpb24pIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKGFsbG93X3NldmVyaXR5LCAiQ29ubmVjdGlvbiBmcm9tIDxVTktOT1dOPiAoJXMpXG4iLCBhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIH07CiAgICAgICAgICAgIFNOTVBfRlJFRShhZGRyX3N0cmluZyk7CiAgICAgICAgICAgIGFkZHJfc3RyaW5nID0gc3RyZHVwKCI8VU5LTk9XTj4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzbm1wX2xvZyhkZW55X3NldmVyaXR5LCAiQ29ubmVjdGlvbiBmcm9tIDxVTktOT1dOPiAoJXMpIFJFRlVTRURcbiIsIGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgU05NUF9GUkVFKGFkZHJfc3RyaW5nKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qTkVUU05NUF9VU0VfTElCV1JBUCAqLwoKICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlBLVFMpOwoKICAgIGlmIChhZGRyX3N0cmluZyAhPSBOVUxMKSB7CiAgICAgICAgbmV0c25tcF9hZGRyY2FjaGVfYWRkKGFkZHJfc3RyaW5nKTsKICAgICAgICBTTk1QX0ZSRUUoYWRkcl9zdHJpbmcpOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgppbnQKbmV0c25tcF9hZ2VudF9jaGVja19wYXJzZShuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZXN1bHQpCnsKICAgIGlmIChyZXN1bHQgPT0gMCkgewogICAgICAgIGlmIChzbm1wX2dldF9kb19sb2dnaW5nKCkgJiYKCSAgICBuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkJICAgTkVUU05NUF9EU19BR0VOVF9WRVJCT1NFKSkgewogICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcl9wdHI7CgogICAgICAgICAgICBzd2l0Y2ggKHBkdS0+Y29tbWFuZCkgewogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgR0VUIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgR0VUTkVYVCBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBSRVNQT05TRSBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgU0VUIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDoKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgVFJBUCBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIEdFVEJVTEsgbWVzc2FnZSwgbm9uLXJlcD0lbGQsIG1heF9yZXA9JWxkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5lcnJzdGF0LCBwZHUtPmVycmluZGV4KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lORk9STToKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIiAgSU5GT1JNIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIFRSQVAyIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfUkVQT1JUOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBSRVBPUlQgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBSRVNFUlZFMSBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfUkVTRVJWRTI6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIFJFU0VSVkUyIG1lc3NhZ2VcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9BQ1RJT046CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIEFDVElPTiBtZXNzYWdlXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQ09NTUlUOgogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0RFQlVHLCAiICBJTlRFUk5BTCBDT01NSVQgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0ZSRUU6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIEZSRUUgbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1VORE86CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIElOVEVSTkFMIFVORE8gbWVzc2FnZVxuIik7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgIFVOS05PV04gbWVzc2FnZSwgdHlwZT0lMDJYXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tYW5kKTsKICAgICAgICAgICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yICh2YXJfcHRyID0gcGR1LT52YXJpYWJsZXM7IHZhcl9wdHIgIT0gTlVMTDsKICAgICAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIGNfb2lkbGVuID0gMjU2LCBjX291dGxlbiA9IDA7CiAgICAgICAgICAgICAgICB1X2NoYXIgICAgICAgICAqY19vaWQgPSAodV9jaGFyICopIG1hbGxvYyhjX29pZGxlbik7CgogICAgICAgICAgICAgICAgaWYgKGNfb2lkKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFzcHJpbnRfcmVhbGxvY19vYmppZAogICAgICAgICAgICAgICAgICAgICAgICAoJmNfb2lkLCAmY19vaWRsZW4sICZjX291dGxlbiwgMSwgdmFyX3B0ci0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHZhcl9wdHItPm5hbWVfbGVuZ3RoKSkgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgICAgLS0gJXMgW1RSVU5DQVRFRF1cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNfb2lkKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICIgICAgLS0gJXNcbiIsIGNfb2lkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKGNfb2lkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOyAgICAgICAgICAgICAgICAgICAvKiBYWFg6IGRvZXMgaXQgbWF0dGVyIHdoYXQgdGhlIHJldHVybiB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIGlzPyAgWWVzOiBpZiB3ZSByZXR1cm4gMCwgdGhlbiB0aGUgUERVIGlzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogZHVtcGVkLiAgKi8KfQoKCi8qCiAqIEdsb2JhbCBhY2Nlc3MgdG8gdGhlIHByaW1hcnkgc2Vzc2lvbiBzdHJ1Y3R1cmUgZm9yIHRoaXMgYWdlbnQuCiAqIGZvciBJbmRleCBBbGxvY2F0aW9uIHVzZSBpbml0aWFsbHkuIAogKi8KCi8qCiAqIEkgZG9uJ3QgdW5kZXJzdGFuZCB3aGF0IHRoaXMgaXMgZm9yIGF0IHRoZSBtb21lbnQuICBBRkFJQ1MgYXMgbG9uZyBhcyBpdAogKiBnZXRzIHNldCBhbmQgcG9pbnRzIGF0IGEgc2Vzc2lvbiwgdGhhdCdzIGZpbmUuICA/Pz8gIAogKi8KCm5ldHNubXBfc2Vzc2lvbiAqbWFpbl9zZXNzaW9uID0gTlVMTDsKCgoKLyoKICogU2V0IHVwIGFuIGFnZW50IHNlc3Npb24gb24gdGhlIGdpdmVuIHRyYW5zcG9ydC4gIFJldHVybiBhIGhhbmRsZQogKiB3aGljaCBtYXkgbGF0ZXIgYmUgdXNlZCB0byBkZS1yZWdpc3RlciB0aGlzIHRyYW5zcG9ydC4gIEEgcmV0dXJuCiAqIHZhbHVlIG9mIC0xIGluZGljYXRlcyBhbiBlcnJvci4gIAogKi8KCmludApuZXRzbm1wX3JlZ2lzdGVyX2FnZW50X25zYXAobmV0c25tcF90cmFuc3BvcnQgKnQpCnsKICAgIG5ldHNubXBfc2Vzc2lvbiAqcywgKnNwID0gTlVMTDsKICAgIGFnZW50X25zYXAgICAgICphID0gTlVMTCwgKm4gPSBOVUxMLCAqKnByZXZOZXh0ID0gJmFnZW50X25zYXBfbGlzdDsKICAgIGludCAgICAgICAgICAgICBoYW5kbGUgPSAwOwogICAgdm9pZCAgICAgICAgICAgKmlzcCA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgcmM7CgogICAgaWYgKHQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgibmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwIiwgImZkICVkXG4iLCB0LT5zb2NrKSk7CgogICAgbiA9IChhZ2VudF9uc2FwICopIG1hbGxvYyhzaXplb2YoYWdlbnRfbnNhcCkpOwogICAgaWYgKG4gPT0gTlVMTCkgewogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIHMgPSAobmV0c25tcF9zZXNzaW9uICopIG1hbGxvYyhzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBpZiAocyA9PSBOVUxMKSB7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIG1lbXNldChzLCAwLCBzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBzbm1wX3Nlc3NfaW5pdChzKTsKCiAgICAvKgogICAgICogU2V0IHVwIHRoZSBzZXNzaW9uIGFwcHJvcHJpYXRlbHkgZm9yIGFuIGFnZW50LiAgCiAgICAgKi8KCiAgICBzLT52ZXJzaW9uID0gU05NUF9ERUZBVUxUX1ZFUlNJT047CiAgICBzLT5jYWxsYmFjayA9IGhhbmRsZV9zbm1wX3BhY2tldDsKICAgIHMtPmF1dGhlbnRpY2F0b3IgPSBOVUxMOwogICAgcy0+ZmxhZ3MgPSBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwgCgkJCQkgIE5FVFNOTVBfRFNfQUdFTlRfRkxBR1MpOwogICAgcy0+aXNBdXRob3JpdGF0aXZlID0gU05NUF9TRVNTX0FVVEhPUklUQVRJVkU7CgogICAgLyogT3B0aW9uYWwgc3VwcGxpbWVudGFsIHRyYW5zcG9ydCBjb25maWd1cmF0aW9uIGluZm9ybWF0aW9uIGFuZAogICAgICAgZmluYWwgY2FsbCB0byBhY3R1YWxseSBvcGVuIHRoZSB0cmFuc3BvcnQgKi8KICAgIGlmICgocmMgPSBuZXRzbm1wX3Nlc3NfY29uZmlnX3RyYW5zcG9ydChzLT50cmFuc3BvcnRfY29uZmlndXJhdGlvbiwgdCkpCiAgICAgICAgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgU05NUF9GUkVFKHMpOwogICAgICAgIFNOTVBfRlJFRShuKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgoKICAgIGlmICh0LT5mX29wZW4pCiAgICAgICAgdCA9IHQtPmZfb3Blbih0KTsKCiAgICBpZiAoTlVMTCA9PSB0KSB7CiAgICAgICAgU05NUF9GUkVFKHMpOwogICAgICAgIFNOTVBfRlJFRShuKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgdC0+ZmxhZ3MgfD0gTkVUU05NUF9UUkFOU1BPUlRfRkxBR19PUEVORUQ7CgogICAgc3AgPSBzbm1wX2FkZChzLCB0LCBuZXRzbm1wX2FnZW50X2NoZWNrX3BhY2tldCwKICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9jaGVja19wYXJzZSk7CiAgICBpZiAoc3AgPT0gTlVMTCkgewogICAgICAgIFNOTVBfRlJFRShzKTsKICAgICAgICBTTk1QX0ZSRUUobik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGlzcCA9IHNubXBfc2Vzc19wb2ludGVyKHNwKTsKICAgIGlmIChpc3AgPT0gTlVMTCkgeyAgICAgICAgICAvKiAgb3Zlci1jYXV0aW91cyAgKi8KICAgICAgICBTTk1QX0ZSRUUocyk7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBuLT5zID0gaXNwOwogICAgbi0+dCA9IHQ7CgogICAgaWYgKG1haW5fc2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgbWFpbl9zZXNzaW9uID0gc25tcF9zZXNzX3Nlc3Npb24oaXNwKTsKICAgIH0KCiAgICBmb3IgKGEgPSBhZ2VudF9uc2FwX2xpc3Q7IGEgIT0gTlVMTCAmJiBoYW5kbGUgKyAxID49IGEtPmhhbmRsZTsKICAgICAgICAgYSA9IGEtPm5leHQpIHsKICAgICAgICBoYW5kbGUgPSBhLT5oYW5kbGU7CiAgICAgICAgcHJldk5leHQgPSAmKGEtPm5leHQpOwogICAgfQoKICAgIGlmIChoYW5kbGUgPCBJTlRfTUFYKSB7CiAgICAgICAgbi0+aGFuZGxlID0gaGFuZGxlICsgMTsKICAgICAgICBuLT5uZXh0ID0gYTsKICAgICAgICAqcHJldk5leHQgPSBuOwogICAgICAgIFNOTVBfRlJFRShzKTsKICAgICAgICByZXR1cm4gbi0+aGFuZGxlOwogICAgfSBlbHNlIHsKICAgICAgICBTTk1QX0ZSRUUocyk7CiAgICAgICAgU05NUF9GUkVFKG4pOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KfQoKdm9pZApuZXRzbm1wX2RlcmVnaXN0ZXJfYWdlbnRfbnNhcChpbnQgaGFuZGxlKQp7CiAgICBhZ2VudF9uc2FwICAgICAqYSA9IE5VTEwsICoqcHJldk5leHQgPSAmYWdlbnRfbnNhcF9saXN0OwogICAgaW50ICAgICAgICAgICAgIG1haW5fc2Vzc2lvbl9kZXJlZ2lzdGVyZWQgPSAwOwoKICAgIERFQlVHTVNHVEwoKCJuZXRzbm1wX2RlcmVnaXN0ZXJfYWdlbnRfbnNhcCIsICJoYW5kbGUgJWRcbiIsIGhhbmRsZSkpOwoKICAgIGZvciAoYSA9IGFnZW50X25zYXBfbGlzdDsgYSAhPSBOVUxMICYmIGEtPmhhbmRsZSA8IGhhbmRsZTsgYSA9IGEtPm5leHQpIHsKICAgICAgICBwcmV2TmV4dCA9ICYoYS0+bmV4dCk7CiAgICB9CgogICAgaWYgKGEgIT0gTlVMTCAmJiBhLT5oYW5kbGUgPT0gaGFuZGxlKSB7CiAgICAgICAgKnByZXZOZXh0ID0gYS0+bmV4dDsKCWlmIChzbm1wX3Nlc3Nfc2Vzc2lvbl9sb29rdXAoYS0+cykpIHsKICAgICAgICAgICAgaWYgKG1haW5fc2Vzc2lvbiA9PSBzbm1wX3Nlc3Nfc2Vzc2lvbihhLT5zKSkgewogICAgICAgICAgICAgICAgbWFpbl9zZXNzaW9uX2RlcmVnaXN0ZXJlZCA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9jbG9zZShzbm1wX3Nlc3Nfc2Vzc2lvbihhLT5zKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoZSBhYm92ZSBmcmVlKClzIHRoZSB0cmFuc3BvcnQgYW5kIHNlc3Npb24gcG9pbnRlcnMuICAKICAgICAgICAgICAgICovCiAgICAgICAgfQogICAgICAgIFNOTVBfRlJFRShhKTsKICAgIH0KCiAgICAvKgogICAgICogSWYgd2UndmUgZGVyZWdpc3RlcmVkIHRoZSBzZXNzaW9uIHRoYXQgbWFpbl9zZXNzaW9uIHVzZWQgdG8gcG9pbnQgdG8sCiAgICAgKiB0aGVuIG1ha2UgaXQgcG9pbnQgdG8gYW5vdGhlciBvbmUsIG9yIGluIHRoZSBsYXN0IHJlc29ydCwgbWFrZSBpdCBlcXVhbAogICAgICogdG8gTlVMTC4gIEJhc2ljYWxseSB0aGlzIHNob3VsZG4ndCBldmVyIGhhcHBlbiBpbiBub3JtYWwgb3BlcmF0aW9uCiAgICAgKiBiZWNhdXNlIG1haW5fc2Vzc2lvbiBzdGFydHMgb2ZmIHBvaW50aW5nIGF0IHRoZSBmaXJzdCBzZXNzaW9uIGFkZGVkIGJ5CiAgICAgKiBpbml0X21hc3Rlcl9hZ2VudCgpLCB3aGljaCB0aGVuIGRpc2NhcmRzIHRoZSBoYW5kbGUuICAKICAgICAqLwoKICAgIGlmIChtYWluX3Nlc3Npb25fZGVyZWdpc3RlcmVkKSB7CiAgICAgICAgaWYgKGFnZW50X25zYXBfbGlzdCAhPSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKCQkJIldBUk5JTkc6IG1haW5fc2Vzc2lvbiBwdHIgY2hhbmdlZCBmcm9tICVwIHRvICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBtYWluX3Nlc3Npb24sIHNubXBfc2Vzc19zZXNzaW9uKGFnZW50X25zYXBfbGlzdC0+cykpKTsKICAgICAgICAgICAgbWFpbl9zZXNzaW9uID0gc25tcF9zZXNzX3Nlc3Npb24oYWdlbnRfbnNhcF9saXN0LT5zKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCgkJCSJXQVJOSU5HOiBtYWluX3Nlc3Npb24gcHRyIGNoYW5nZWQgZnJvbSAlcCB0byBOVUxMXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBtYWluX3Nlc3Npb24pKTsKICAgICAgICAgICAgbWFpbl9zZXNzaW9uID0gTlVMTDsKICAgICAgICB9CiAgICB9Cn0KCgoKLyoKICogCiAqIFRoaXMgZnVuY3Rpb24gaGFzIGJlZW4gbW9kaWZpZWQgdG8gdXNlIHRoZSBleHBlcmltZW50YWwKICogbmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwIGludGVyZmFjZS4gIFRoZSBtYWpvciByZXNwb25zaWJpbGl0eSBvZiB0aGlzCiAqIGZ1bmN0aW9uIG5vdyBpcyB0byBpbnRlcnByZXQgYSBzdHJpbmcgc3BlY2lmaWVkIHRvIHRoZSBhZ2VudCAodmlhIC1wIG9uIHRoZQogKiBjb21tYW5kIGxpbmUsIG9yIGZyb20gYSBjb25maWd1cmF0aW9uIGZpbGUpIGFzIGEgbGlzdCBvZiBhZ2VudCBOU0FQcyBvbgogKiB3aGljaCB0byBsaXN0ZW4gZm9yIFNOTVAgcGFja2V0cy4gIFR5cGljYWxseSwgd2hlbiB5b3UgYWRkIGEgbmV3IHRyYW5zcG9ydAogKiBkb21haW4gImZvbyIsIHlvdSBhZGQgY29kZSBoZXJlIHN1Y2ggdGhhdCBpZiB0aGUgImZvbyIgY29kZSBpcyBjb21waWxlZAogKiBpbnRvIHRoZSBhZ2VudCAoU05NUF9UUkFOU1BPUlRfRk9PX0RPTUFJTiBpcyBkZWZpbmVkKSwgdGhlbiBhIHRva2VuIG9mIHRoZQogKiBmb3JtICJmb286YmxldGNoLTNhMDA1NGVmJXdvYiZ3b2IiIGdldHMgdHVybmVkIGludG8gdGhlIGFwcHJvcHJpYXRlCiAqIHRyYW5zcG9ydCBkZXNjcmlwdG9yLiAgbmV0c25tcF9yZWdpc3Rlcl9hZ2VudF9uc2FwIGlzIHRoZW4gY2FsbGVkIHdpdGggdGhhdAogKiB0cmFuc3BvcnQgZGVzY3JpcHRvciBhbmQgc2V0cyB1cCBhIGxpc3RlbmluZyBhZ2VudCBzZXNzaW9uIG9uIGl0LgogKiAKICogRXZlcnl0aGluZyB0aGVuIHdvcmtzIG11Y2ggYXMgbm9ybWFsOiB0aGUgYWdlbnQgcnVucyBpbiBhbiBpbmZpbml0ZSBsb29wCiAqIChpbiB0aGUgc25tcGQuYy9yZWNlaXZlKClyb3V0aW5lKSwgd2hpY2ggY2FsbHMgc25tcF9yZWFkKCkgd2hlbiBhIHJlcXVlc3QKICogaXMgcmVhZGFibGUgb24gYW55IG9mIHRoZSBnaXZlbiB0cmFuc3BvcnRzLiAgVGhpcyByb3V0aW5lIHRoZW4gdHJhdmVyc2VzCiAqIHRoZSBsaWJyYXJ5ICdTZXNzaW9ucycgbGlzdCB0byBpZGVudGlmeSB0aGUgcmVsZXZhbnQgc2Vzc2lvbiBhbmQgZXZlbnR1YWxseQogKiBpbnZva2VzICdfc2Vzc19yZWFkJy4gIFRoaXMgdGhlbiBwcm9jZXNzZXMgdGhlIGluY29taW5nIHBhY2tldCwgY2FsbGluZyB0aGUKICogcHJlX3BhcnNlLCBwYXJzZSwgcG9zdF9wYXJzZSBhbmQgY2FsbGJhY2sgcm91dGluZXMgaW4gdHVybi4KICogCiAqIEpCUE4gMjAwMDExMTcKICovCgppbnQKaW5pdF9tYXN0ZXJfYWdlbnQodm9pZCkKewogICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydDsKICAgIGNoYXIgICAgICAgICAgICpjcHRyOwogICAgY2hhciAgICAgICAgICAgKmJ1ZiA9IE5VTEw7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CgogICAgLyogZGVmYXVsdCB0byBhIGRlZmF1bHQgY2FjaGUgc2l6ZSAqLwogICAgbmV0c25tcF9zZXRfbG9va3VwX2NhY2hlX3NpemUoLTEpOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkgICAgICAgTkVUU05NUF9EU19BR0VOVF9ST0xFKSAhPSBNQVNURVJfQUdFTlQpIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsCiAgICAgICAgICAgICAgICAgICAgImluaXRfbWFzdGVyX2FnZW50OyBub3QgbWFzdGVyIGFnZW50XG4iKSk7CgogICAgICAgIG5ldHNubXBfYXNzZXJ0KCJhZ2VudCByb2xlICFtYXN0ZXIgJiYgIXN1Yl9hZ2VudCIpOwogICAgICAgIAogICAgICAgIHJldHVybiAwOyAgICAgICAgICAgICAgIC8qICBObyBlcnJvciBpZiAhIE1BU1RFUl9BR0VOVCAgKi8KICAgIH0KCiAgICAvKgogICAgICogSGF2ZSBzcGVjaWZpYyBhZ2VudCBwb3J0cyBiZWVuIHNwZWNpZmllZD8gIAogICAgICovCiAgICBjcHRyID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIAoJCQkJIE5FVFNOTVBfRFNfQUdFTlRfUE9SVFMpOwoKICAgIGlmIChjcHRyKSB7CiAgICAgICAgYnVmID0gc3RyZHVwKGNwdHIpOwogICAgICAgIGlmICghYnVmKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJFcnJvciBwcm9jZXNzaW5nIHRyYW5zcG9ydCBcIiVzXCJcbiIsIGNwdHIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogTm8sIHNvIGp1c3Qgc3BlY2lmeSB0aGUgZGVmYXVsdCBwb3J0LiAgCiAgICAgICAgICovCiAgICAgICAgYnVmID0gc3RyZHVwKCIiKTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJmaW5hbCBwb3J0IHNwZWM6IFwiJXNcIlxuIiwgYnVmKSk7CiAgICBzdCA9IGJ1ZjsKICAgIGRvIHsKICAgICAgICAvKgogICAgICAgICAqIFNwZWNpZmljYXRpb24gZm9ybWF0OiAKICAgICAgICAgKiAKICAgICAgICAgKiBOT05FOiAgICAgICAgICAgICAgICAgICAgICAoYSBwc2V1ZG8tdHJhbnNwb3J0KQogICAgICAgICAqIFVEUDpbYWRkcmVzczpdcG9ydCAgICAgICAgKGFsc28gZGVmYXVsdCBpZiBubyB0cmFuc3BvcnQgaXMgc3BlY2lmaWVkKQogICAgICAgICAqIFRDUDpbYWRkcmVzczpdcG9ydCAgICAgICAgIChpZiBzdXBwb3J0ZWQpCiAgICAgICAgICogVW5peDpwYXRobmFtZSAgICAgICAgICAgICAgKGlmIHN1cHBvcnRlZCkKICAgICAgICAgKiBBQUw1UFZDOml0Zi52cGkudmNpICAgICAgICAoaWYgc3VwcG9ydGVkKQogICAgICAgICAqIElQWDpbbmV0d29ya106bm9kZVsvcG9ydF0gKGlmIHN1cHBvcnRlZCkKICAgICAgICAgKiAKICAgICAgICAgKi8KCgljcHRyID0gc3Q7CglzdCA9IHN0cmNocihzdCwgJywnKTsKCWlmIChzdCkKCSAgICAqc3QrKyA9ICdcMCc7CgogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImluc3RhbGxpbmcgbWFzdGVyIGFnZW50IG9uIHBvcnQgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgY3B0cikpOwoKICAgICAgICBpZiAoc3RybmNhc2VjbXAoY3B0ciwgIm5vbmUiLCA0KSA9PSAwKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgImluaXRfbWFzdGVyX2FnZW50OyBwc2V1ZG8tdHJhbnNwb3J0IFwibm9uZVwiICIKCQkJInJlcXVlc3RlZFxuIikpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgdHJhbnNwb3J0ID0gbmV0c25tcF90cmFuc3BvcnRfb3Blbl9zZXJ2ZXIoInNubXAiLCBjcHRyKTsKCiAgICAgICAgaWYgKHRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJFcnJvciBvcGVuaW5nIHNwZWNpZmllZCBlbmRwb2ludCBcIiVzXCJcbiIsCiAgICAgICAgICAgICAgICAgICAgIGNwdHIpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIGlmIChuZXRzbm1wX3JlZ2lzdGVyX2FnZW50X25zYXAodHJhbnNwb3J0KSA9PSAwKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJFcnJvciByZWdpc3RlcmluZyBzcGVjaWZpZWQgdHJhbnNwb3J0IFwiJXNcIiBhcyBhbiAiCgkJICAgICAiYWdlbnQgTlNBUFxuIiwgY3B0cik7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgImluaXRfbWFzdGVyX2FnZW50OyBcIiVzXCIgcmVnaXN0ZXJlZCBhcyBhbiBhZ2VudCAiCgkJCSJOU0FQXG4iLCBjcHRyKSk7CiAgICAgICAgfQogICAgfSB3aGlsZShzdCAmJiAqc3QgIT0gJ1wwJyk7CiAgICBTTk1QX0ZSRUUoYnVmKTsKCiNpZmRlZiBVU0lOR19BR0VOVFhfTUFTVEVSX01PRFVMRQogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwgCgkJCSAgICAgICBORVRTTk1QX0RTX0FHRU5UX0FHRU5UWF9NQVNURVIpID09IDEpCiAgICAgICAgcmVhbF9pbml0X21hc3RlcigpOwojZW5kaWYKI2lmZGVmIFVTSU5HX1NNVVhfTU9EVUxFCiAgICBpZihzaG91bGRfaW5pdCgic211eCIpKQogICAgcmVhbF9pbml0X3NtdXgoKTsKI2VuZGlmCgogICAgcmV0dXJuIDA7Cn0KCnZvaWQKY2xlYXJfbnNhcF9saXN0KHZvaWQpCnsKICAgIERFQlVHTVNHVEwoKCJjbGVhcl9uc2FwX2xpc3QiLCAiY2xlYXIgdGhlIG5zYXAgbGlzdFxuIikpOwoKICAgIHdoaWxlIChhZ2VudF9uc2FwX2xpc3QgIT0gTlVMTCkKCW5ldHNubXBfZGVyZWdpc3Rlcl9hZ2VudF9uc2FwKGFnZW50X25zYXBfbGlzdC0+aGFuZGxlKTsKfQoKdm9pZApzaHV0ZG93bl9tYXN0ZXJfYWdlbnQodm9pZCkKewogICAgY2xlYXJfbnNhcF9saXN0KCk7Cn0KCgpuZXRzbm1wX2FnZW50X3Nlc3Npb24gKgppbml0X2FnZW50X3NubXBfc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1KQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCA9IChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKikKICAgICAgICBjYWxsb2MoMSwgc2l6ZW9mKG5ldHNubXBfYWdlbnRfc2Vzc2lvbikpOwoKICAgIGlmIChhc3AgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwiYWdlbnRfc2VzaW9uICU4cCBjcmVhdGVkXG4iLCBhc3ApKTsKICAgIGFzcC0+c2Vzc2lvbiA9IHNlc3Npb247CiAgICBhc3AtPnBkdSA9IHNubXBfY2xvbmVfcGR1KHBkdSk7CiAgICBhc3AtPm9yaWdfcGR1ID0gc25tcF9jbG9uZV9wZHUocGR1KTsKICAgIGFzcC0+cncgPSBSRUFEOwogICAgYXNwLT5leGFjdCA9IFRSVUU7CiAgICBhc3AtPm5leHQgPSBOVUxMOwogICAgYXNwLT5tb2RlID0gUkVTRVJWRTE7CiAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBhc3AtPmluZGV4ID0gMDsKICAgIGFzcC0+b2xkbW9kZSA9IDA7CiAgICBhc3AtPnRyZWVjYWNoZV9udW0gPSAtMTsKICAgIGFzcC0+dHJlZWNhY2hlX2xlbiA9IDA7CiAgICBhc3AtPnJlcWluZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvKTsKICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsICJhc3AgJXAgcmVxaW5mbyAlcCBjcmVhdGVkXG4iLAogICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKCiAgICByZXR1cm4gYXNwOwp9Cgp2b2lkCmZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpZiAoIWFzcCkKICAgICAgICByZXR1cm47CgogICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCJhZ2VudF9zZXNzaW9uICU4cCByZWxlYXNlZFxuIiwgYXNwKSk7CgogICAgbmV0c25tcF9yZW1vdmVfZnJvbV9kZWxlZ2F0ZWQoYXNwKTsKICAgIAogICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIGZyZWVkXG4iLAogICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKICAgIGlmIChhc3AtPm9yaWdfcGR1KQogICAgICAgIHNubXBfZnJlZV9wZHUoYXNwLT5vcmlnX3BkdSk7CiAgICBpZiAoYXNwLT5wZHUpCiAgICAgICAgc25tcF9mcmVlX3BkdShhc3AtPnBkdSk7CiAgICBpZiAoYXNwLT5yZXFpbmZvKQogICAgICAgIG5ldHNubXBfZnJlZV9hZ2VudF9yZXF1ZXN0X2luZm8oYXNwLT5yZXFpbmZvKTsKICAgIGlmIChhc3AtPnRyZWVjYWNoZSkgewogICAgICAgIFNOTVBfRlJFRShhc3AtPnRyZWVjYWNoZSk7CiAgICB9CiAgICBpZiAoYXNwLT5idWxrY2FjaGUpIHsKICAgICAgICBTTk1QX0ZSRUUoYXNwLT5idWxrY2FjaGUpOwogICAgfQogICAgaWYgKGFzcC0+cmVxdWVzdHMpIHsKICAgICAgICBpbnQgICAgICAgICAgICAgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYXNwLT52YmNvdW50OyBpKyspIHsKICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKCZhc3AtPnJlcXVlc3RzW2ldKTsKICAgICAgICB9CiAgICAgICAgU05NUF9GUkVFKGFzcC0+cmVxdWVzdHMpOwogICAgfQogICAgaWYgKGFzcC0+Y2FjaGVfc3RvcmUpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfY2FjaGVtYXAoYXNwLT5jYWNoZV9zdG9yZSk7CiAgICAgICAgYXNwLT5jYWNoZV9zdG9yZSA9IE5VTEw7CiAgICB9CiAgICBTTk1QX0ZSRUUoYXNwKTsKfQoKaW50Cm5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIGk7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKCiAgICBpZiAoTlVMTCA9PSBhc3AtPnRyZWVjYWNoZSkKICAgICAgICByZXR1cm4gMDsKICAgIAogICAgZm9yIChpID0gMDsgaSA8PSBhc3AtPnRyZWVjYWNoZV9udW07IGkrKykgewogICAgICAgIGZvciAocmVxdWVzdCA9IGFzcC0+dHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luOyByZXF1ZXN0OwogICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKHJlcXVlc3QtPmRlbGVnYXRlZCkKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9CgppbnQKbmV0c25tcF9jaGVja19kZWxlZ2F0ZWRfY2hhaW5fZm9yKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcHRtcDsKICAgIGZvciAoYXNwdG1wID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGFzcHRtcDsgYXNwdG1wID0gYXNwdG1wLT5uZXh0KSB7CiAgICAgICAgaWYgKGFzcHRtcCA9PSBhc3ApCiAgICAgICAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCmludApuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWRfYW5kX2FkZChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaWYgKG5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChhc3ApKSB7CiAgICAgICAgaWYgKCFuZXRzbm1wX2NoZWNrX2RlbGVnYXRlZF9jaGFpbl9mb3IoYXNwKSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhZGQgdG8gZGVsZWdhdGVkIHJlcXVlc3QgY2hhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBhc3AtPm5leHQgPSBhZ2VudF9kZWxlZ2F0ZWRfbGlzdDsKICAgICAgICAgICAgYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBhc3A7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImRlbGVnYXRlIHNlc3Npb24gPT0gJThwXG4iLCBhc3ApKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKaW50Cm5ldHNubXBfcmVtb3ZlX2Zyb21fZGVsZWdhdGVkKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmN1cnIsICpwcmV2ID0gTlVMTDsKICAgIAogICAgZm9yIChjdXJyID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGN1cnI7IHByZXYgPSBjdXJyLCBjdXJyID0gY3Vyci0+bmV4dCkgewogICAgICAgIC8qCiAgICAgICAgICogaXMgdGhpcyB1cz8KICAgICAgICAgKi8KICAgICAgICBpZiAoY3VyciAhPSBhc3ApCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIAogICAgICAgIC8qCiAgICAgICAgICogcmVtb3ZlIGZyb20gcXVldWUgCiAgICAgICAgICovCiAgICAgICAgaWYgKHByZXYgIT0gTlVMTCkKICAgICAgICAgICAgcHJldi0+bmV4dCA9IGFzcC0+bmV4dDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGFnZW50X2RlbGVnYXRlZF9saXN0ID0gYXNwLT5uZXh0OwoKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJyZW1vdmUgZGVsZWdhdGVkIHNlc3Npb24gPT0gJThwXG4iLCBhc3ApKTsKCiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIG5ldHNubXBfcmVtb3ZlX2RlbGVnYXRlZF9yZXF1ZXN0c19mb3Jfc2Vzc2lvbgogKgogKiBjYWxsZWQgd2hlbiBhIHNlc3Npb24gaXMgYmVpbmcgY2xvc2VkLiBDaGVjayBhbGwgZGVsZWdhdGVkIHJlcXVlc3RzIHRvCiAqIHNlZSBpZiB0aGUgYXJlIHdhaXRpbmcgb24gdGhpcyBzZXNzaW9uLCBhbmQgaWYgc2V0LCBzZXQgdGhlIHN0YXR1cyBmb3IKICogdGhhdCByZXF1ZXN0IHRvIEdFTkVSUi4KICovCmludApuZXRzbm1wX3JlbW92ZV9kZWxlZ2F0ZWRfcmVxdWVzdHNfZm9yX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICpzZXNzKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKICAgIGludCBjb3VudCA9IDA7CiAgICAKICAgIGZvciAoYXNwID0gYWdlbnRfZGVsZWdhdGVkX2xpc3Q7IGFzcDsgYXNwID0gYXNwLT5uZXh0KSB7CiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayBlYWNoIHJlcXVlc3QKICAgICAgICAgKi8KICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgICAgICBmb3IocmVxdWVzdCA9IGFzcC0+cmVxdWVzdHM7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNoZWNrIHNlc3Npb24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KE5VTEwhPXJlcXVlc3QtPnN1YnRyZWUpOwogICAgICAgICAgICBpZihyZXF1ZXN0LT5zdWJ0cmVlLT5zZXNzaW9uICE9IHNlc3MpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG1hdGNoZWQhIG1hcmsgcmVxdWVzdCBhcyBkb25lCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgICAgICsrY291bnQ7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBpZiB3ZSBmb3VuZCBhbnksIHRoYXQgcmVxdWVzdCBtYXkgYmUgZmluaXNoZWQgbm93CiAgICAgKi8KICAgIGlmKGNvdW50KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAicmVtb3ZlZCAlZCBkZWxlZ2F0ZWQgcmVxdWVzdChzKSBmb3Igc2Vzc2lvbiAiCiAgICAgICAgICAgICAgICAgICAgIiU4cFxuIiwgY291bnQsIHNlc3MpKTsKICAgICAgICBuZXRzbm1wX2NoZWNrX291dHN0YW5kaW5nX2FnZW50X3JlcXVlc3RzKCk7CiAgICB9CiAgICAKICAgIHJldHVybiBjb3VudDsKfQoKaW50Cm5ldHNubXBfY2hlY2tfcXVldWVkX2NoYWluX2ZvcihuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3B0bXA7CiAgICBmb3IgKGFzcHRtcCA9IG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3Q7IGFzcHRtcDsgYXNwdG1wID0gYXNwdG1wLT5uZXh0KSB7CiAgICAgICAgaWYgKGFzcHRtcCA9PSBhc3ApCiAgICAgICAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCmludApuZXRzbm1wX2FkZF9xdWV1ZWQobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwX3RtcDsKCiAgICAvKgogICAgICogZmlyc3QgaXRlbT8KICAgICAqLwogICAgaWYgKE5VTEwgPT0gbmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdCkgewogICAgICAgIG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QgPSBhc3A7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgoKICAgIC8qCiAgICAgKiBhZGQgdG8gZW5kIG9mIHF1ZXVlZCByZXF1ZXN0IGNoYWluIAogICAgICovCiAgICBhc3BfdG1wID0gbmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdDsKICAgIGZvciAoOyBhc3BfdG1wOyBhc3BfdG1wID0gYXNwX3RtcC0+bmV4dCkgewogICAgICAgIC8qCiAgICAgICAgICogYWxyZWFkeSBpbiBxdWV1ZT8KICAgICAgICAgKi8KICAgICAgICBpZiAoYXNwX3RtcCA9PSBhc3ApCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAvKgogICAgICAgICAqIGVuZCBvZiBxdWV1ZT8KICAgICAgICAgKi8KICAgICAgICBpZiAoTlVMTCA9PSBhc3BfdG1wLT5uZXh0KQogICAgICAgICAgICBhc3BfdG1wLT5uZXh0ID0gYXNwOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCgppbnQKbmV0c25tcF93cmFwX3VwX3JlcXVlc3QobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsIGludCBzdGF0dXMpCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyX3B0cjsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIC8qCiAgICAgKiBpZiB0aGlzIHJlcXVlc3Qgd2FzIGEgc2V0LCBjbGVhciB0aGUgZ2xvYmFsIG5vdyB0aGF0IHdlIGFyZQogICAgICogZG9uZS4KICAgICAqLwogICAgaWYgKGFzcCA9PSBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiU0VUIHJlcXVlc3QgY29tcGxldGUsIGFzcCA9ICU4cFxuIiwKICAgICAgICAgICAgICAgICAgICBhc3ApKTsKICAgICAgICBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ID0gTlVMTDsKICAgIH0KCiAgICBpZiAoYXNwLT5wZHUpIHsKICAgICAgICAvKgogICAgICAgICAqIElmIHdlJ3ZlIGdvdCBhbiBlcnJvciBzdGF0dXMsIHRoZW4gdGhpcyBuZWVkcyB0byBiZQogICAgICAgICAqICBwYXNzZWQgYmFjayB1cCB0byB0aGUgaGlnaGVyIGxldmVscy4uLi4KICAgICAgICAgKi8KICAgICAgICBpZiAoIHN0YXR1cyAhPSAwICAmJiBhc3AtPnN0YXR1cyA9PSAwICkKICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CgogICAgICAgIHN3aXRjaCAoYXNwLT5wZHUtPmNvbW1hbmQpIHsKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQkVHSU46CiAgICAgICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgICAgICAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9SRVNFUlZFMjoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQUNUSU9OOgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHNvbWUgc3R1ZmYgbmVlZHMgdG8gYmUgc2F2ZWQgaW4gc3BlY2lhbCBzdWJhZ2VudCBjYXNlcyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc2F2ZV9zZXRfY2FjaGUoYXNwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgICAgICAgICAgX2ZpeF9lbmRvZm1pYnZpZXcoYXNwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZvciBhIEdFVEJVTEsgcmVzcG9uc2Ugd2UgbmVlZCB0byByZWFycmFuZ2UgdGhlIHZhcmJpbmRzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBfcmVvcmRlcl9nZXRidWxrKGFzcCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogTWF5IG5lZWQgdG8gImR1bWIgZG93biIgYSBTRVQgZXJyb3Igc3RhdHVzIGZvciBhCiAgICAgICAgICogdjEgcXVlcnkuICBTZWUgUkZDMjU3NiAtIHNlY3Rpb24gNC4zCiAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIGlmICgoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfU0VUKSAmJgogICAgICAgICAgICAoYXNwLT5wZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpKSB7CiAgICAgICAgICAgIHN3aXRjaCAoYXNwLT5zdGF0dXMpIHsKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfV1JPTkdWQUxVRToKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfV1JPTkdFTkNPRElORzoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfV1JPTkdUWVBFOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9XUk9OR0xFTkdUSDoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfSU5DT05TSVNURU5UVkFMVUU6CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfQkFEVkFMVUU7CiAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBTTk1QX0VSUl9CQURWQUxVRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfTk9BQ0NFU1M6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX05PVFdSSVRBQkxFOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9OT0NSRUFUSU9OOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9JTkNPTlNJU1RFTlROQU1FOgogICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I6CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgICAgICAgICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEU6CiAgICAgICAgICAgICAgICBjYXNlIFNOTVBfRVJSX0NPTU1JVEZBSUxFRDoKICAgICAgICAgICAgICAgIGNhc2UgU05NUF9FUlJfVU5ET0ZBSUxFRDoKICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBTaW1pbGFybHkgd2UgbWF5IG5lZWQgdG8gImR1bWIgZG93biIgdjIgZXhjZXB0aW9uCiAgICAgICAgICogIHR5cGVzIHRvIHRocm93IGFuIGVycm9yIGZvciBhIHYxIHF1ZXJ5LgogICAgICAgICAqICBTZWUgUkZDMjU3NiAtIHNlY3Rpb24gNC4xLjIuMwogICAgICAgICAqLwogICAgICAgIGlmICgoYXNwLT5wZHUtPmNvbW1hbmQgIT0gU05NUF9NU0dfU0VUKSAmJgogICAgICAgICAgICAoYXNwLT5wZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpKSB7CiAgICAgICAgICAgIGZvciAodmFyX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXMsIGkgPSAxOwogICAgICAgICAgICAgICAgIHZhcl9wdHIgIT0gTlVMTDsgdmFyX3B0ciA9IHZhcl9wdHItPm5leHRfdmFyaWFibGUsIGkrKykgewogICAgICAgICAgICAgICAgc3dpdGNoICh2YXJfcHRyLT50eXBlKSB7CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTTk1QX05PU1VDSE9CSkVDVDoKICAgICAgICAgICAgICAgICAgICBjYXNlIFNOTVBfTk9TVUNISU5TVEFOQ0U6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBTTk1QX0VORE9GTUlCVklFVzoKICAgICAgICAgICAgICAgICAgICBjYXNlIEFTTl9DT1VOVEVSNjQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5pbmRleCA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogc25tcHYxIHN1cHBvcnQgKi8KICAgIH0gLyoqIGlmIGFzcC0+cGR1ICovCgogICAgLyoKICAgICAqIFVwZGF0ZSB0aGUgc25tcCBlcnJvci1jb3VudCBzdGF0aXN0aWNzCiAgICAgKiAgIFhYWCAtIHNob3VsZCB3ZSBpbmNsdWRlIHRoZSBWMiBlcnJvcnMgaW4gdGhpcyBvciBub3Q/CiAgICAgKi8KI2RlZmluZSBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKCiAgICBzd2l0Y2ggKHN0YXR1cykgewojaWZkZWYgSU5DTFVERV9WMkVSUk9SU19JTl9WMVNUQVRTCiAgICBjYXNlIFNOTVBfRVJSX1dST05HVkFMVUU6CiAgICBjYXNlIFNOTVBfRVJSX1dST05HRU5DT0RJTkc6CiAgICBjYXNlIFNOTVBfRVJSX1dST05HVFlQRToKICAgIGNhc2UgU05NUF9FUlJfV1JPTkdMRU5HVEg6CiAgICBjYXNlIFNOTVBfRVJSX0lOQ09OU0lTVEVOVFZBTFVFOgojZW5kaWYKICAgIGNhc2UgU05NUF9FUlJfQkFEVkFMVUU6CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVEJBRFZBTFVFUyk7CiAgICAgICAgYnJlYWs7CiNpZmRlZiBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKICAgIGNhc2UgU05NUF9FUlJfTk9BQ0NFU1M6CiAgICBjYXNlIFNOTVBfRVJSX05PVFdSSVRBQkxFOgogICAgY2FzZSBTTk1QX0VSUl9OT0NSRUFUSU9OOgogICAgY2FzZSBTTk1QX0VSUl9JTkNPTlNJU1RFTlROQU1FOgogICAgY2FzZSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I6CiNlbmRpZgogICAgY2FzZSBTTk1QX0VSUl9OT1NVQ0hOQU1FOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVROT1NVQ0hOQU1FUyk7CiAgICAgICAgYnJlYWs7CiNpZmRlZiBJTkNMVURFX1YyRVJST1JTX0lOX1YxU1RBVFMKICAgIGNhc2UgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRToKICAgIGNhc2UgU05NUF9FUlJfQ09NTUlURkFJTEVEOgogICAgY2FzZSBTTk1QX0VSUl9VTkRPRkFJTEVEOgojZW5kaWYKICAgIGNhc2UgU05NUF9FUlJfR0VORVJSOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRHRU5FUlJTKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfRVJSX1RPT0JJRzoKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUVE9PQklHUyk7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKChzdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUikgJiYgKGFzcC0+cGR1KSkgewogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpY19ieSgoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfU0VUID8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRfU05NUElOVE9UQUxTRVRWQVJTIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNUQVRfU05NUElOVE9UQUxSRVFWQVJTKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRfdmFyYmluZHMoYXNwLT5wZHUtPnZhcmlhYmxlcykpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIFVzZSBhIGNvcHkgb2YgdGhlIG9yaWdpbmFsIHJlcXVlc3QKICAgICAgICAgKiAgIHRvIHJlcG9ydCBmYWlsdXJlcy4KICAgICAgICAgKi8KICAgICAgICBzbm1wX2ZyZWVfcGR1KGFzcC0+cGR1KTsKICAgICAgICBhc3AtPnBkdSA9IGFzcC0+b3JpZ19wZHU7CiAgICAgICAgYXNwLT5vcmlnX3BkdSA9IE5VTEw7CiAgICB9CiAgICBpZiAoYXNwLT5wZHUpIHsKICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1JFU1BPTlNFOwogICAgICAgIGFzcC0+cGR1LT5lcnJzdGF0ID0gYXNwLT5zdGF0dXM7CiAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4ID0gYXNwLT5pbmRleDsKICAgICAgICBpZiAoIXNubXBfc2VuZChhc3AtPnNlc3Npb24sIGFzcC0+cGR1KSAmJgogICAgICAgICAgICAgYXNwLT5zZXNzaW9uLT5zX3NubXBfZXJybm8gIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyX3B0cjsKICAgICAgICAgICAgc25tcF9wZXJyb3IoInNlbmQgcmVzcG9uc2UiKTsKICAgICAgICAgICAgZm9yICh2YXJfcHRyID0gYXNwLT5wZHUtPnZhcmlhYmxlczsgdmFyX3B0ciAhPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICB2YXJfcHRyID0gdmFyX3B0ci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgc2l6ZV90ICBjX29pZGxlbiA9IDI1NiwgY19vdXRsZW4gPSAwOwogICAgICAgICAgICAgICAgdV9jaGFyICpjX29pZCA9ICh1X2NoYXIgKikgbWFsbG9jKGNfb2lkbGVuKTsKCiAgICAgICAgICAgICAgICBpZiAoY19vaWQpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIXNwcmludF9yZWFsbG9jX29iamlkICgmY19vaWQsICZjX29pZGxlbiwgJmNfb3V0bGVuLCAxLAogCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyX3B0ci0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJfcHRyLT5uYW1lX2xlbmd0aCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIiAgICAtLSAlcyBbVFJVTkNBVEVEXVxuIiwgY19vaWQpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICIgICAgLS0gJXNcbiIsIGNfb2lkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKGNfb2lkKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KGFzcC0+cGR1KTsKICAgICAgICAgICAgYXNwLT5wZHUgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QT1VUUEtUUyk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVEdFVFJFU1BPTlNFUyk7CiAgICAgICAgYXNwLT5wZHUgPSBOVUxMOyAvKiB5eXktcmtzOiByZWR1bmRhbnQsIG5vPyAqLwogICAgICAgIG5ldHNubXBfcmVtb3ZlX2FuZF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhc3ApOwogICAgfQogICAgcmV0dXJuIDE7Cn0KCnZvaWQKZHVtcF9zZXNzX2xpc3Qodm9pZCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIkRVTVAgYWdlbnRfc2Vzc19saXN0IC0+ICIpKTsKICAgIGZvciAoYSA9IGFnZW50X3Nlc3Npb25fbGlzdDsgYSAhPSBOVUxMOyBhID0gYS0+bmV4dCkgewogICAgICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICIlOHBbc2Vzc2lvbiAlOHBdIC0+ICIsIGEsIGEtPnNlc3Npb24pKTsKICAgIH0KICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICJbTklMXVxuIikpOwp9Cgp2b2lkCm5ldHNubXBfcmVtb3ZlX2FuZF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbihuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphLCAqKnByZXZOZXh0ID0gJmFnZW50X3Nlc3Npb25fbGlzdDsKCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJSRU1PVkUgc2Vzc2lvbiA9PSAlOHBcbiIsIGFzcCkpOwoKICAgIGZvciAoYSA9IGFnZW50X3Nlc3Npb25fbGlzdDsgYSAhPSBOVUxMOyBhID0gKnByZXZOZXh0KSB7CiAgICAgICAgaWYgKGEgPT0gYXNwKSB7CiAgICAgICAgICAgICpwcmV2TmV4dCA9IGEtPm5leHQ7CiAgICAgICAgICAgIGEtPm5leHQgPSBOVUxMOwogICAgICAgICAgICBmcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhKTsKICAgICAgICAgICAgYXNwID0gTlVMTDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJldk5leHQgPSAmKGEtPm5leHQpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoYSA9PSBOVUxMICYmIGFzcCAhPSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBXZSBjb3VsbmQndCBmaW5kIGl0IG9uIHRoZSBsaXN0LCBzbyBmcmVlIGl0IGFueXdheS4gIAogICAgICAgICAqLwogICAgICAgIGZyZWVfYWdlbnRfc25tcF9zZXNzaW9uKGFzcCk7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbl9ieV9zZXNzaW9uKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqZnJlZV9yZXF1ZXN0KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5ldHNubXBfcmVxdWVzdF9saXN0ICopKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmEsICpuZXh0LCAqKnByZXZOZXh0ID0gJmFnZW50X3Nlc3Npb25fbGlzdDsKCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJSRU1PVkUgc2Vzc2lvbiA9PSAlOHBcbiIsIHNlc3MpKTsKCiAgICBmb3IgKGEgPSBhZ2VudF9zZXNzaW9uX2xpc3Q7IGEgIT0gTlVMTDsgYSA9IG5leHQpIHsKICAgICAgICBpZiAoYS0+c2Vzc2lvbiA9PSBzZXNzKSB7CiAgICAgICAgICAgICpwcmV2TmV4dCA9IGEtPm5leHQ7CiAgICAgICAgICAgIG5leHQgPSBhLT5uZXh0OwogICAgICAgICAgICBmcmVlX2FnZW50X3NubXBfc2Vzc2lvbihhKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcmV2TmV4dCA9ICYoYS0+bmV4dCk7CiAgICAgICAgICAgIG5leHQgPSBhLT5uZXh0OwogICAgICAgIH0KICAgIH0KfQoKLyoqIGhhbmRsZXMgYW4gaW5jb21pbmcgU05NUCBwYWNrZXQgaW50byB0aGUgYWdlbnQgKi8KaW50CmhhbmRsZV9zbm1wX3BhY2tldChpbnQgb3AsIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sIGludCByZXFpZCwKICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICpwZHUsIHZvaWQgKm1hZ2ljKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcDsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMsIGFjY2Vzc19yZXQsIHJjOwoKICAgIC8qCiAgICAgKiBXZSBvbmx5IHN1cHBvcnQgcmVjZWl2aW5nIGhlcmUuICAKICAgICAqLwogICAgaWYgKG9wICE9IE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRSkgewogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIC8qCiAgICAgKiBSRVNQT05TRSBtZXNzYWdlcyB3b24ndCBnZXQgdGhpcyBmYXIsIGJ1dCBUUkFQLWxpa2UgbWVzc2FnZXMKICAgICAqIG1pZ2h0LiAgCiAgICAgKi8KICAgIGlmIChwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfVFJBUCB8fCBwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfSU5GT1JNIHx8CiAgICAgICAgcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVAyKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAicmVjZWl2ZWQgdHJhcC1saWtlIFBEVSAoJTAyeClcbiIsCiAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tYW5kKSk7CiAgICAgICAgcGR1LT5jb21tYW5kID0gU05NUF9NU0dfVFJBUDI7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUFVOS05PV05QRFVIQU5ETEVSUyk7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgLyoKICAgICAqIHNlbmQgc25tcHYzIGF1dGhmYWlsIHRyYXAuCiAgICAgKi8KICAgIGlmIChwZHUtPnZlcnNpb24gID09IFNOTVBfVkVSU0lPTl8zICYmIAogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9PSBTTk1QRVJSX1VTTV9BVVRIRU5USUNBVElPTkZBSUxVUkUpIHsKICAgICAgICAgICBzZW5kX2Vhc3lfdHJhcChTTk1QX1RSQVBfQVVUSEZBSUwsIDApOwogICAgICAgICAgIHJldHVybiAxOwogICAgfSAKCQogICAgaWYgKG1hZ2ljID09IE5VTEwpIHsKICAgICAgICBhc3AgPSBpbml0X2FnZW50X3NubXBfc2Vzc2lvbihzZXNzaW9uLCBwZHUpOwogICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICB9IGVsc2UgewogICAgICAgIGFzcCA9IChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKikgbWFnaWM7CiAgICAgICAgc3RhdHVzID0gYXNwLT5zdGF0dXM7CiAgICB9CgogICAgaWYgKChhY2Nlc3NfcmV0ID0gY2hlY2tfYWNjZXNzKGFzcC0+cGR1KSkgIT0gMCkgewogICAgICAgIGlmIChhY2Nlc3NfcmV0ID09IFZBQ01fTk9TVUNIQ09OVEVYVCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByZmMzNDEzIHNlY3Rpb24gMy4yLCBzdGVwIDUgc2F5cyB0aGF0IHdlIGluY3JlbWVudCB0aGUKICAgICAgICAgICAgICogY291bnRlciBidXQgZG9uJ3QgcmV0dXJuIGEgcmVzcG9uc2Ugb2YgYW55IGtpbmQgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgY3VycmVudGx5IGRvbid0IHN1cHBvcnQgdW5hdmFpbGFibGUgY29udGV4dHMsIGFzCiAgICAgICAgICAgICAqIHRoZXJlIGlzIG5vIHJlYXNvbiB0byB0aGF0IEkgY3VycmVudGx5IGtub3cgb2YgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QVU5LTk9XTkNPTlRFWFRTKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRyb3AgdGhlIHJlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWNjZXNzIGNvbnRyb2wgc2V0dXAgaXMgaW5jb3JyZWN0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2VuZF9lYXN5X3RyYXAoU05NUF9UUkFQX0FVVEhGQUlMLCAwKTsKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQojaWYgZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKQogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzJjKSB7CiNlbHNlCiNpZiBkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPnZlcnNpb24gIT0gU05NUF9WRVJTSU9OXzEpIHsKI2Vsc2UKICAgICAgICAgICAgaWYgKGFzcC0+cGR1LT52ZXJzaW9uICE9IFNOTVBfVkVSU0lPTl8xCiAgICAgICAgICAgICAgICAmJiBhc3AtPnBkdS0+dmVyc2lvbiAhPSBTTk1QX1ZFUlNJT05fMmMpIHsKI2VuZGlmCiNlbmRpZgogICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycnN0YXQgPSBTTk1QX0VSUl9BVVRIT1JJWkFUSU9ORVJST1I7CiAgICAgICAgICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1JFU1BPTlNFOwogICAgICAgICAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFBLVFMpOwogICAgICAgICAgICAgICAgaWYgKCFzbm1wX3NlbmQoYXNwLT5zZXNzaW9uLCBhc3AtPnBkdSkpCiAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdShhc3AtPnBkdSk7CiAgICAgICAgICAgICAgICBhc3AtPnBkdSA9IE5VTEw7CiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgICAgICB9IGVsc2UgewojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBkcm9wIHRoZSByZXF1ZXN0IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlbW92ZV9hbmRfZnJlZV9hZ2VudF9zbm1wX3Nlc3Npb24oYXNwKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICAgICAgICAgIH0KI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCiAgICAgICAgfQogICAgfQoKICAgIHJjID0gbmV0c25tcF9oYW5kbGVfcmVxdWVzdChhc3AsIHN0YXR1cyk7CgogICAgLyoKICAgICAqIGRvbmUgCiAgICAgKi8KICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImVuZCBvZiBoYW5kbGVfc25tcF9wYWNrZXQsIGFzcCA9ICU4cFxuIiwKICAgICAgICAgICAgICAgIGFzcCkpOwogICAgcmV0dXJuIHJjOwp9CgpuZXRzbm1wX3JlcXVlc3RfaW5mbyAqCm5ldHNubXBfYWRkX3ZhcmJpbmRfdG9fY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3AsIGludCB2YmNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcmJpbmRfcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfc3VidHJlZSAqdHApCnsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0ID0gTlVMTDsKICAgIGludCAgICAgICAgICAgICBjYWNoZWlkOwoKICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgImFkZF92Yl90b19jYWNoZSglOHAsICVkLCAiLCBhc3AsIHZiY291bnQpKTsKICAgIERFQlVHTVNHT0lEKCgic25tcF9hZ2VudCIsIHZhcmJpbmRfcHRyLT5uYW1lLAogICAgICAgICAgICAgICAgIHZhcmJpbmRfcHRyLT5uYW1lX2xlbmd0aCkpOwogICAgREVCVUdNU0coKCJzbm1wX2FnZW50IiwgIiwgJThwKVxuIiwgdHApKTsKCiAgICBpZiAodHAgJiYKICAgICAgICAoYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUTkVYVCB8fAogICAgICAgICBhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSkgewogICAgICAgIGludCByZXN1bHQ7CiAgICAgICAgaW50IHByZWZpeF9sZW47CgogICAgICAgIHByZWZpeF9sZW4gPSBuZXRzbm1wX29pZF9maW5kX3ByZWZpeCh0cC0+c3RhcnRfYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPnN0YXJ0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPmVuZF9hLCB0cC0+ZW5kX2xlbik7CiAgICAgICAgaWYgKHByZWZpeF9sZW4gPCAxKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IFZBQ01fTk9USU5WSUVXOyAvKiBhY2suLi4gIGJhZCBiYWQgdGhpbmcgaGFwcGVuZWQgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXN1bHQgPQogICAgICAgICAgICAgICAgbmV0c25tcF9hY21fY2hlY2tfc3VidHJlZShhc3AtPnBkdSwgdHAtPnN0YXJ0X2EsIHByZWZpeF9sZW4pOwogICAgICAgIH0KCiAgICAgICAgd2hpbGUgKHJlc3VsdCA9PSBWQUNNX05PVElOVklFVykgewogICAgICAgICAgICAvKiB0aGUgZW50aXJlIHN1YnRyZWUgaXMgbm90IGluIHZpZXcuIFNraXAgaXQuICovCiAgICAgICAgICAgIC8qKiBAdG9kbyBtYWtlIHRoaXMgYmUgbW9yZSBpbnRlbGxpZ2VudCBhYm91dCByYW5nZXMuCiAgICAgICAgICAgICAgICBSaWdodCBub3cgd2UgbWVyZWx5IHRha2UgdGhlIGhpZ2hlc3QgbGV2ZWwKICAgICAgICAgICAgICAgIGNvbW1vbmFsaXR5IG9mIGEgcmVnaXN0cmF0aW9uIHJhbmdlIGFuZCB1c2UgdGhhdC4KICAgICAgICAgICAgICAgIEF0IHRpbWVzIHdlIG1pZ2h0IGJlIGFibGUgdG8gYmUgc21hcnRlciBhYm91dAogICAgICAgICAgICAgICAgY2hlY2tpbmcgdGhlIHJhbmdlIGl0c2VsZiBhcyBvcHBvc2VkIHRvIHRoZSBub2RlCiAgICAgICAgICAgICAgICBhYm92ZSB3aGVyZSB0aGUgcmFuZ2UgZXhpc3RzLCBidXQgSSBkb3VidCB0aGlzIHdpbGwKICAgICAgICAgICAgICAgIGNvbWUgdXAgYWxsIHRoYXQgZnJlcXVlbnRseS4gKi8KICAgICAgICAgICAgdHAgPSB0cC0+bmV4dDsKICAgICAgICAgICAgaWYgKHRwKSB7CiAgICAgICAgICAgICAgICBwcmVmaXhfbGVuID0gbmV0c25tcF9vaWRfZmluZF9wcmVmaXgodHAtPnN0YXJ0X2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPnN0YXJ0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cC0+ZW5kX2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPmVuZF9sZW4pOwogICAgICAgICAgICAgICAgaWYgKHByZWZpeF9sZW4gPCAxKSB7CiAgICAgICAgICAgICAgICAgICAgLyogYWNrLi4uICBiYWQgYmFkIHRoaW5nIGhhcHBlbmVkICovCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gVkFDTV9OT1RJTlZJRVc7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWNtX2NoZWNrX3N1YnRyZWUoYXNwLT5wZHUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHAtPnN0YXJ0X2EsIHByZWZpeF9sZW4pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGlmICh0cCA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBubyBhcHByb3ByaWF0ZSByZWdpc3RyYXRpb24gZm91bmQgCiAgICAgICAgICovCiAgICAgICAgLyoKICAgICAgICAgKiBtYWtlIHVwIHRoZSByZXNwb25zZSBvdXJzZWx2ZXMgCiAgICAgICAgICovCiAgICAgICAgc3dpdGNoIChhc3AtPnBkdS0+Y29tbWFuZCkgewogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgICAgIHZhcmJpbmRfcHRyLT50eXBlID0gU05NUF9FTkRPRk1JQlZJRVc7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAgICAgdmFyYmluZF9wdHItPnR5cGUgPSBTTk1QX05PU1VDSE9CSkVDVDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBOVUxMOyAgICAgICAgLyogc2hvdWxkbid0IGdldCBoZXJlICovCiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJ0cC0+c3RhcnQgIikpOwogICAgICAgIERFQlVHTVNHT0lEKCgic25tcF9hZ2VudCIsIHRwLT5zdGFydF9hLCB0cC0+c3RhcnRfbGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJzbm1wX2FnZW50IiwgIiwgdHAtPmVuZCAiKSk7CiAgICAgICAgREVCVUdNU0dPSUQoKCJzbm1wX2FnZW50IiwgdHAtPmVuZF9hLCB0cC0+ZW5kX2xlbikpOwogICAgICAgIERFQlVHTVNHKCgic25tcF9hZ2VudCIsICIsIFxuIikpOwoKICAgICAgICAvKgogICAgICAgICAqIG1hbGxvYyB0aGUgcmVxdWVzdCBzdHJ1Y3R1cmUgCiAgICAgICAgICovCiAgICAgICAgcmVxdWVzdCA9ICYoYXNwLT5yZXF1ZXN0c1t2YmNvdW50IC0gMV0pOwogICAgICAgIHJlcXVlc3QtPmluZGV4ID0gdmJjb3VudDsKICAgICAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQgPSAwOwogICAgICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IDA7CiAgICAgICAgcmVxdWVzdC0+c3RhdHVzID0gMDsKICAgICAgICByZXF1ZXN0LT5zdWJ0cmVlID0gdHA7CiAgICAgICAgcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8gPSBhc3AtPnJlcWluZm87CiAgICAgICAgaWYgKHJlcXVlc3QtPnBhcmVudF9kYXRhKSB7CiAgICAgICAgICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXF1ZXN0KTsKICAgICAgICB9CiAgICAgICAgREVCVUdNU0dUTCgoInZlcmJvc2U6YXNwIiwgImFzcCAlcCByZXFpbmZvICVwIGFzc2lnbmVkIHRvIHJlcXVlc3RcbiIsCiAgICAgICAgICAgICAgICAgICAgYXNwLCBhc3AtPnJlcWluZm8pKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBmb3Igbm9uLVNFVCBtb2Rlcywgc2V0IHRoZSB0eXBlIHRvIE5VTEwgCiAgICAgICAgICovCiAgICAgICAgaWYgKCFNT0RFX0lTX1NFVChhc3AtPnBkdS0+Y29tbWFuZCkpIHsKICAgICAgICBERUJVR01TR1RMKCgidmVyYm9zZTphc3AiLCAiYXNwICVwIHJlcWluZm8gJXAgYXNzaWduZWQgdG8gcmVxdWVzdFxuIiwKICAgICAgICAgICAgICAgICAgICBhc3AsIGFzcC0+cmVxaW5mbykpOwogICAgICAgICAgICBpZiAodmFyYmluZF9wdHItPnR5cGUgPT0gQVNOX1BSSVZfSU5DTF9SQU5HRSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAidmFyYmluZCAlZCBpcyBpbmNsdXNpdmVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmRleCkpOwogICAgICAgICAgICAgICAgcmVxdWVzdC0+aW5jbHVzaXZlID0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXJiaW5kX3B0ci0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBwbGFjZSB0aGVtIGluIGEgY2FjaGUgCiAgICAgICAgICovCiAgICAgICAgaWYgKHRwLT5nbG9iYWxfY2FjaGVpZCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB3ZSBuZWVkIHRvIG1lcmdlIGFsbCBtYXJrZWQgc3VidHJlZXMgdG9nZXRoZXIgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoYXNwLT5jYWNoZV9zdG9yZSAmJiAtMSAhPQogICAgICAgICAgICAgICAgKGNhY2hlaWQgPSBuZXRzbm1wX2dldF9sb2NhbF9jYWNoaWQoYXNwLT5jYWNoZV9zdG9yZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5nbG9iYWxfY2FjaGVpZCkpKSB7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjYWNoZWlkID0gKysoYXNwLT50cmVlY2FjaGVfbnVtKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfZ2V0X29yX2FkZF9sb2NhbF9jYWNoaWQoJmFzcC0+Y2FjaGVfc3RvcmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT5nbG9iYWxfY2FjaGVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FjaGVpZCk7CiAgICAgICAgICAgICAgICBnb3RvIG1hbGxvY3Nsb3Q7ICAgICAgICAvKiBYWFg6IGljayAqLwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICh0cC0+Y2FjaGVpZCA+IC0xICYmIHRwLT5jYWNoZWlkIDw9IGFzcC0+dHJlZWNhY2hlX251bSAmJgogICAgICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbdHAtPmNhY2hlaWRdLnN1YnRyZWUgPT0gdHApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgaGF2ZSBhbHJlYWR5IGFkZGVkIGEgcmVxdWVzdCB0byB0aGlzIHRyZWUKICAgICAgICAgICAgICogcG9pbnRlciBiZWZvcmUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjYWNoZWlkID0gdHAtPmNhY2hlaWQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgY2FjaGVpZCA9ICsrKGFzcC0+dHJlZWNhY2hlX251bSk7CiAgICAgICAgICBtYWxsb2NzbG90OgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBuZXcgc2xvdCBuZWVkZWQgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoYXNwLT50cmVlY2FjaGVfbnVtID49IGFzcC0+dHJlZWNhY2hlX2xlbikgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGV4YXBhbmQgY2FjaGUgYXJyYXkgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBXV1c6IG5vbi1saW5lYXIgZXhwYW5zaW9uIG5lZWRlZCAod2l0aCBjYXApIAogICAgICAgICAgICAgICAgICovCiNkZWZpbmUgQ0FDSEVfR1JPV19TSVpFIDE2CiAgICAgICAgICAgICAgICBhc3AtPnRyZWVjYWNoZV9sZW4gPQogICAgICAgICAgICAgICAgICAgIChhc3AtPnRyZWVjYWNoZV9sZW4gKyBDQUNIRV9HUk9XX1NJWkUpOwogICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGUgPQogICAgICAgICAgICAgICAgICAgIChuZXRzbm1wX3RyZWVfY2FjaGUgKilyZWFsbG9jKGFzcC0+dHJlZWNhY2hlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG5ldHNubXBfdHJlZV9jYWNoZSkgKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVfbGVuKTsKICAgICAgICAgICAgICAgIGlmIChhc3AtPnRyZWVjYWNoZSA9PSBOVUxMKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgbWVtc2V0KCYoYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0pLCAweDAwLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihuZXRzbm1wX3RyZWVfY2FjaGUpICogKENBQ0hFX0dST1dfU0laRSkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnN1YnRyZWUgPSB0cDsKICAgICAgICAgICAgYXNwLT50cmVlY2FjaGVbY2FjaGVpZF0ucmVxdWVzdHNfYmVnaW4gPSByZXF1ZXN0OwogICAgICAgICAgICB0cC0+Y2FjaGVpZCA9IGNhY2hlaWQ7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGlmIHRoaXMgaXMgYSBzZWFyY2ggdHlwZSwgZ2V0IHRoZSBlbmRpbmcgcmFuZ2Ugb2lkIGFzIHdlbGwgCiAgICAgICAgICovCiAgICAgICAgaWYgKGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX0dFVE5FWFQgfHwKICAgICAgICAgICAgYXNwLT5wZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfR0VUQlVMSykgewogICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmQgPSB0cC0+ZW5kX2E7CiAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4gPSB0cC0+ZW5kX2xlbjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmQgPSBOVUxMOwogICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuID0gMDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbGluayBpbnRvIGNoYWluIAogICAgICAgICAqLwogICAgICAgIGlmIChhc3AtPnRyZWVjYWNoZVtjYWNoZWlkXS5yZXF1ZXN0c19lbmQpCiAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnJlcXVlc3RzX2VuZC0+bmV4dCA9IHJlcXVlc3Q7CiAgICAgICAgcmVxdWVzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgcmVxdWVzdC0+cHJldiA9IGFzcC0+dHJlZWNhY2hlW2NhY2hlaWRdLnJlcXVlc3RzX2VuZDsKICAgICAgICBhc3AtPnRyZWVjYWNoZVtjYWNoZWlkXS5yZXF1ZXN0c19lbmQgPSByZXF1ZXN0OwoKICAgICAgICAvKgogICAgICAgICAqIGFkZCB0aGUgZ2l2ZW4gcmVxdWVzdCB0byB0aGUgbGlzdCBvZiByZXF1ZXN0cyB0aGV5IG5lZWQKICAgICAgICAgKiB0byBoYW5kbGUgcmVzdWx0cyBmb3IgCiAgICAgICAgICovCiAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiID0gcmVxdWVzdC0+cmVxdWVzdHZiX3N0YXJ0ID0gdmFyYmluZF9wdHI7CiAgICB9CiAgICByZXR1cm4gcmVxdWVzdDsKfQoKLyoKICogY2hlY2sgdGhlIEFDTShzKSBmb3IgdGhlIHJlc3VsdHMgb24gZWFjaCBvZiB0aGUgdmFyYmluZHMuCiAqIElmIEFDTSBkaXNhbGxvd3MgaXQsIHJlcGxhY2UgdGhlIHZhbHVlIHdpdGggdHlwZQogKiAKICogUmV0dXJucyBudW1iZXIgb2YgdmFyYmluZHMgd2l0aCBBQ00gZXJyb3JzCiAqLwppbnQKY2hlY2tfYWNtKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLCB1X2NoYXIgdHlwZSkKewogICAgaW50ICAgICAgICAgICAgIHZpZXc7CiAgICBpbnQgICAgICAgICAgICAgaSwgaiwgazsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwogICAgaW50ICAgICAgICAgICAgIHJldCA9IDA7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZiLCAqdmIyLCAqdmJjOwogICAgaW50ICAgICAgICAgICAgIGVhcmxpZXN0ID0gMDsKCiAgICBmb3IgKGkgPSAwOyBpIDw9IGFzcC0+dHJlZWNhY2hlX251bTsgaSsrKSB7CiAgICAgICAgZm9yIChyZXF1ZXN0ID0gYXNwLT50cmVlY2FjaGVbaV0ucmVxdWVzdHNfYmVnaW47CiAgICAgICAgICAgICByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBmb3IgZWFjaCByZXF1ZXN0LCBydW4gaXQgdGhyb3VnaCBpbl9hX3ZpZXcoKSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVhcmxpZXN0ID0gMDsKICAgICAgICAgICAgZm9yKGogPSByZXF1ZXN0LT5yZXBlYXQsIHZiID0gcmVxdWVzdC0+cmVxdWVzdHZiX3N0YXJ0OwogICAgICAgICAgICAgICAgdmIgJiYgaiA+IC0xOwogICAgICAgICAgICAgICAgai0tLCB2YiA9IHZiLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICBpZiAodmItPnR5cGUgIT0gQVNOX05VTEwgJiYKICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSAhPSBBU05fUFJJVl9SRVRSWSkgeyAvKiBub3QgeWV0IHByb2Nlc3NlZCAqLwogICAgICAgICAgICAgICAgICAgIHZpZXcgPQogICAgICAgICAgICAgICAgICAgICAgICBpbl9hX3ZpZXcodmItPm5hbWUsICZ2Yi0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnBkdSwgdmItPnR5cGUpOwoKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGlmIGEgQUNNIGVycm9yIG9jY3VycywgbWFyayBpdCBhcyB0eXBlIHBhc3NlZCBpbiAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAodmlldyAhPSBWQUNNX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0Kys7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXBlYXQgPCByZXF1ZXN0LT5vcmlnX3JlcGVhdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYmFzaWNhbGx5IHRoaXMgbWVhbnMgYSBHRVRCVUxLICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXBlYXQrKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghZWFybGllc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmIgPSB2YjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlYXJsaWVzdCA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdWdoLiAgaWYgYSB3aG9sZSBub3cgZXhpc3RzLCB3ZSBuZWVkIHRvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3ZlIHRoZSBjb250ZW50cyB1cCB0aGUgY2hhaW4gYW5kIGZpbGwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluIGF0IHRoZSBlbmQgZWxzZSB3ZSB3b24ndCBlbmQgdXAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxleG9ncmFwaGljYWxseSBzb3J0ZWQgcHJvcGVybHkgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChqID4gLTEgJiYgdmItPm5leHRfdmFyaWFibGUgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+bmV4dF92YXJpYWJsZS0+dHlwZSAhPSBBU05fTlVMTCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT5uZXh0X3ZhcmlhYmxlLT50eXBlICE9IEFTTl9QUklWX1JFVFJZKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGsgPSBqLCB2YmMgPSB2YiwgdmIyID0gdmItPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGsgPiAtMiAmJiB2YmMgJiYgdmIyOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrLS0sIHZiYyA9IHZiMiwgdmIyID0gdmIyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNsb25lIG5leHQgaW50byB0aGUgY3VycmVudCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2Nsb25lX3Zhcih2YjIsIHZiYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiYy0+bmV4dF92YXJpYWJsZSA9IHZiMjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHZiLCB0eXBlLCBOVUxMLCAwKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgoKaW50Cm5ldHNubXBfY3JlYXRlX3N1YnRyZWVfY2FjaGUobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIG5ldHNubXBfc3VidHJlZSAqdHA7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcmJpbmRfcHRyLCAqdmJzYXZlLCAqdmJwdHIsICoqcHJldk5leHQ7CiAgICBpbnQgICAgICAgICAgICAgdmlldzsKICAgIGludCAgICAgICAgICAgICB2YmNvdW50ID0gMDsKICAgIGludCAgICAgICAgICAgICBidWxrY291bnQgPSAwLCBidWxrcmVwID0gMDsKICAgIGludCAgICAgICAgICAgICBpID0gMCwgbiA9IDAsIHIgPSAwOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CgogICAgaWYgKGFzcC0+dHJlZWNhY2hlID09IE5VTEwgJiYgYXNwLT50cmVlY2FjaGVfbGVuID09IDApIHsKICAgICAgICBhc3AtPnRyZWVjYWNoZV9sZW4gPSBTTk1QX01BWCgxICsgYXNwLT52YmNvdW50IC8gNCwgMTYpOwogICAgICAgIGFzcC0+dHJlZWNhY2hlID0KICAgICAgICAgICAgKG5ldHNubXBfdHJlZV9jYWNoZSAqKWNhbGxvYyhhc3AtPnRyZWVjYWNoZV9sZW4sIHNpemVvZihuZXRzbm1wX3RyZWVfY2FjaGUpKTsKICAgICAgICBpZiAoYXNwLT50cmVlY2FjaGUgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KICAgIGFzcC0+dHJlZWNhY2hlX251bSA9IC0xOwoKICAgIGlmIChhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBnZXRidWxrIHByZXAgCiAgICAgICAgICovCiAgICAgICAgaW50ICAgICAgICAgICAgIGNvdW50ID0gY291bnRfdmFyYmluZHMoYXNwLT5wZHUtPnZhcmlhYmxlcyk7CiAgICAgICAgaWYgKGFzcC0+cGR1LT5lcnJzdGF0IDwgMCkgewogICAgICAgICAgICBhc3AtPnBkdS0+ZXJyc3RhdCA9IDA7CiAgICAgICAgfQogICAgICAgIGlmIChhc3AtPnBkdS0+ZXJyaW5kZXggPCAwKSB7CiAgICAgICAgICAgIGFzcC0+cGR1LT5lcnJpbmRleCA9IDA7CiAgICAgICAgfQoKICAgICAgICBpZiAoYXNwLT5wZHUtPmVycnN0YXQgPCBjb3VudCkgewogICAgICAgICAgICBuID0gYXNwLT5wZHUtPmVycnN0YXQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbiA9IGNvdW50OwogICAgICAgIH0KICAgICAgICBpZiAoKHIgPSBjb3VudCAtIG4pIDw9IDApIHsKICAgICAgICAgICAgciA9IDA7CiAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlID0gTlVMTDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgICAgICAgICAgIG1heGJ1bGsgPQogICAgICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9NQVhfR0VUQlVMS1JFUEVBVFMpOwogICAgICAgICAgICBpbnQgbWF4cmVzcG9uc2VzID0KICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfTUFYX0dFVEJVTEtSRVNQT05TRVMpOwoKICAgICAgICAgICAgaWYgKG1heHJlc3BvbnNlcyA9PSAwKQogICAgICAgICAgICAgICAgbWF4cmVzcG9uc2VzID0gMTAwOyAgIC8qIG1vcmUgdGhhbiByZWFzb25hYmxlIGRlZmF1bHQgKi8KCiAgICAgICAgICAgIC8qIGVuc3VyZSB0aGF0IHRoZSB0b3RhbCBudW1iZXIgb2YgcmVzcG9uc2VzIGZpdHMgaW4gYSBtYWxsb2NhYmxlCiAgICAgICAgICAgICAqIHJlc3VsdCB2ZWN0b3IKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChtYXhyZXNwb25zZXMgPCAwIHx8CiAgICAgICAgICAgICAgICBtYXhyZXNwb25zZXMgPiAoaW50KShJTlRfTUFYIC8gc2l6ZW9mKHN0cnVjdCB2YXJiaW5kX2xpc3QgKikpKQogICAgICAgICAgICAgICAgbWF4cmVzcG9uc2VzID0gKGludCkoSU5UX01BWCAvIHNpemVvZihzdHJ1Y3QgdmFyYmluZF9saXN0ICopKTsKCiAgICAgICAgICAgIC8qIGVuc3VyZSB0aGF0IHRoZSBtYXhpbXVtIG51bWJlciBvZiByZXBldGl0aW9ucyB3aWxsIGZpdCBpbiB0aGUKICAgICAgICAgICAgICogcmVzdWx0IHZlY3RvcgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKG1heGJ1bGsgPD0gMCB8fCBtYXhidWxrID4gbWF4cmVzcG9uc2VzIC8gcikKICAgICAgICAgICAgICAgIG1heGJ1bGsgPSBtYXhyZXNwb25zZXMgLyByOwoKICAgICAgICAgICAgLyogbGltaXQgZ2V0YnVsayBudW1iZXIgb2YgcmVwZWF0cyB0byBhIGNvbmZpZ3VyZWQgc2l6ZSAqLwogICAgICAgICAgICBpZiAoYXNwLT5wZHUtPmVycmluZGV4ID4gbWF4YnVsaykgewogICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4ID0gbWF4YnVsazsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cnVuY2F0aW5nIG51bWJlciBvZiBnZXRidWxrIHJlcGVhdHMgdG8gJWxkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5wZHUtPmVycmluZGV4KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGFzcC0+YnVsa2NhY2hlID0KICAgICAgICAgICAgICAgIChuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiopIG1hbGxvYygKICAgICAgICAgICAgICAgICAgICAobiArIGFzcC0+cGR1LT5lcnJpbmRleCAqIHIpICogc2l6ZW9mKHN0cnVjdCB2YXJiaW5kX2xpc3QgKikpOwoKICAgICAgICAgICAgaWYgKCFhc3AtPmJ1bGtjYWNoZSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiQnVsa2NhY2hlIG1hbGxvYyBmYWlsZWRcbiIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiR0VUQlVMSyBOID0gJWQsIE0gPSAlbGQsIFIgPSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICBuLCBhc3AtPnBkdS0+ZXJyaW5kZXgsIHIpKTsKICAgIH0KCiAgICAvKgogICAgICogY29sbGVjdCB2YXJiaW5kcyBpbnRvIHRoZWlyIHJlZ2lzdGVyZWQgdHJlZXMgCiAgICAgKi8KICAgIHByZXZOZXh0ID0gJihhc3AtPnBkdS0+dmFyaWFibGVzKTsKICAgIGZvciAodmFyYmluZF9wdHIgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyB2YXJiaW5kX3B0cjsKICAgICAgICAgdmFyYmluZF9wdHIgPSB2YnNhdmUpIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBnZXRidWxrIG1lc3Mgd2l0aCB0aGlzIHBvaW50ZXIsIHNvIHNhdmUgaXQgCiAgICAgICAgICovCiAgICAgICAgdmJzYXZlID0gdmFyYmluZF9wdHItPm5leHRfdmFyaWFibGU7CgogICAgICAgIGlmIChhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSB7CiAgICAgICAgICAgIGlmIChuID4gMCkgewogICAgICAgICAgICAgICAgbi0tOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHJlcGVhdGUgcmVxdWVzdCB2YXJiaW5kcyBvbiBHRVRCVUxLLiAgVGhlc2Ugd2lsbAogICAgICAgICAgICAgICAgICogaGF2ZSB0byBiZSBwcm9wZXJseSByZWFycmFuZ2VkIGxhdGVyIHRob3VnaCBhcwogICAgICAgICAgICAgICAgICogcmVzcG9uc2VzIGFyZSBzdXBwb3NlZCB0byBhY3R1YWxseSBiZSBpbnRlcmxhY2VkCiAgICAgICAgICAgICAgICAgKiB3aXRoIGVhY2ggb3RoZXIuICBUaGlzIGlzIGRvbmUgd2l0aCB0aGUgYXNwLT5idWxrY2FjaGUuIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBidWxrcmVwID0gYXNwLT5wZHUtPmVycmluZGV4IC0gMTsKICAgICAgICAgICAgICAgIGlmIChhc3AtPnBkdS0+ZXJyaW5kZXggPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgdmJwdHIgPSB2YXJiaW5kX3B0cjsKICAgICAgICAgICAgICAgICAgICBhc3AtPmJ1bGtjYWNoZVtidWxrY291bnQrK10gPSB2YnB0cjsKCiAgICAgICAgICAgICAgICAgICAgZm9yIChpID0gMTsgaSA8IGFzcC0+cGR1LT5lcnJpbmRleDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHZicHRyLT5uZXh0X3ZhcmlhYmxlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTUFMTE9DX1NUUlVDVCh2YXJpYWJsZV9saXN0KTsKICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICogZG9uJ3QgY2xvbmUgdGhlIG9pZCBhcyBpdCdzIGdvdCB0byBiZQogICAgICAgICAgICAgICAgICAgICAgICAgKiBvdmVyd3JpdHRlbiBhbnl3YXkgCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXZicHRyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogWFhYV1dXOiBhY2shISEgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwgIk5leHRWYXIgbWFsbG9jIGZhaWxlZFxuIikpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmJwdHIgPSB2YnB0ci0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZicHRyLT5uYW1lX2xlbmd0aCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YnB0ci0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5idWxrY2FjaGVbYnVsa2NvdW50KytdID0gdmJwdHI7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgdmJwdHItPm5leHRfdmFyaWFibGUgPSB2YnNhdmU7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogMCByZXBlYXRzIHJlcXVlc3RlZCBmb3IgdGhpcyB2YXJiaW5kLCBzbyB0YWtlIGl0IG9mZgogICAgICAgICAgICAgICAgICAgICAqIHRoZSBsaXN0LiAgCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdmJwdHIgPSB2YXJiaW5kX3B0cjsKICAgICAgICAgICAgICAgICAgICAqcHJldk5leHQgPSB2YnB0ci0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgICAgICAgICB2YnB0ci0+bmV4dF92YXJpYWJsZSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmJwdHIpOwogICAgICAgICAgICAgICAgICAgIGFzcC0+dmJjb3VudC0tOwogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGNvdW50IHRoZSB2YXJiaW5kcyAKICAgICAgICAgKi8KICAgICAgICArK3ZiY291bnQ7CgogICAgICAgIC8qCiAgICAgICAgICogZmluZCB0aGUgb3duaW5nIHRyZWUgCiAgICAgICAgICovCiAgICAgICAgdHAgPSBuZXRzbm1wX3N1YnRyZWVfZmluZCh2YXJiaW5kX3B0ci0+bmFtZSwgdmFyYmluZF9wdHItPm5hbWVfbGVuZ3RoLAoJCQkJICBOVUxMLCBhc3AtPnBkdS0+Y29udGV4dE5hbWUpOwoKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIGFjY2VzcyBjb250cm9sIAogICAgICAgICAqLwogICAgICAgIHN3aXRjaCAoYXNwLT5wZHUtPmNvbW1hbmQpIHsKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICAgICAgdmlldyA9IGluX2Ffdmlldyh2YXJiaW5kX3B0ci0+bmFtZSwgJnZhcmJpbmRfcHRyLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnBkdSwgdmFyYmluZF9wdHItPnR5cGUpOwogICAgICAgICAgICBpZiAodmlldyAhPSBWQUNNX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUodmFyYmluZF9wdHIsIFNOTVBfTk9TVUNIT0JKRUNULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDApOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgICAgIHZpZXcgPSBpbl9hX3ZpZXcodmFyYmluZF9wdHItPm5hbWUsICZ2YXJiaW5kX3B0ci0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5wZHUsIHZhcmJpbmRfcHRyLT50eXBlKTsKICAgICAgICAgICAgaWYgKHZpZXcgIT0gVkFDTV9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICBhc3AtPmluZGV4ID0gdmJjb3VudDsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0FDQ0VTUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUQlVMSzoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB2aWV3ID0gVkFDTV9TVUNDRVNTOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBYWFhXV1c6IGNoZWNrIFZBQ00gaGVyZSB0byBzZWUgaWYgInRwIiBpcyBldmVuIHdvcnRod2hpbGUgCiAgICAgICAgICAgICAqLwogICAgICAgIH0KICAgICAgICBpZiAodmlldyA9PSBWQUNNX1NVQ0NFU1MpIHsKICAgICAgICAgICAgcmVxdWVzdCA9IG5ldHNubXBfYWRkX3ZhcmJpbmRfdG9fY2FjaGUoYXNwLCB2YmNvdW50LCB2YXJiaW5kX3B0ciwKCQkJCQkJICAgdHApOwogICAgICAgICAgICBpZiAocmVxdWVzdCAmJiBhc3AtPnBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19HRVRCVUxLKSB7CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXBlYXQgPSByZXF1ZXN0LT5vcmlnX3JlcGVhdCA9IGJ1bGtyZXA7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHByZXZOZXh0ID0gJih2YXJiaW5kX3B0ci0+bmV4dF92YXJpYWJsZSk7CiAgICB9CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoKICogdGhpcyBmdW5jdGlvbiBpcyBvbmx5IGFwcGxpY2FibGUgaW4gZ2V0bmV4dCBsaWtlIGNvbnRleHRzIAogKi8KaW50Cm5ldHNubXBfcmVhc3NpZ25fcmVxdWVzdHMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIC8qCiAgICAgKiBhc3N1bWUgYWxsIHRoZSByZXF1ZXN0cyBoYXZlIGJlZW4gZmlsbGVkIG9yIHJlamVjdGVkIGJ5IHRoZQogICAgICogc3VidHJlZXMsIHNvIHJlYXNzaWduIHRoZSByZWplY3RlZCBvbmVzIHRvIHRoZSBuZXh0IHN1YnRyZWUgaW4KICAgICAqIHRoZSBjaGFpbiAKICAgICAqLwoKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIC8qCiAgICAgKiBnZXQgb2xkIGluZm8gCiAgICAgKi8KICAgIG5ldHNubXBfdHJlZV9jYWNoZSAqb2xkX3RyZWVjYWNoZSA9IGFzcC0+dHJlZWNhY2hlOwoKICAgIC8qCiAgICAgKiBtYWxsb2MgbmV3IHNwYWNlIAogICAgICovCiAgICBhc3AtPnRyZWVjYWNoZSA9CiAgICAgICAgKG5ldHNubXBfdHJlZV9jYWNoZSAqKSBjYWxsb2MoYXNwLT50cmVlY2FjaGVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihuZXRzbm1wX3RyZWVfY2FjaGUpKTsKCiAgICBpZiAoYXNwLT50cmVlY2FjaGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwoKICAgIGFzcC0+dHJlZWNhY2hlX251bSA9IC0xOwogICAgaWYgKGFzcC0+Y2FjaGVfc3RvcmUpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfY2FjaGVtYXAoYXNwLT5jYWNoZV9zdG9yZSk7CiAgICAgICAgYXNwLT5jYWNoZV9zdG9yZSA9IE5VTEw7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgaSsrKSB7CiAgICAgICAgaWYgKGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogT2NjdXJzIHdoZW4gdGhlcmUncyBhIG1peHR1cmUgb2Ygc3RpbGwgYWN0aXZlCiAgICAgICAgICAgICAqICAgYW5kICJlbmRPZk1pYlZpZXciIHJlcGV0aXRpb25zCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgaWYgKGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLT50eXBlID09IEFTTl9OVUxMKSB7CiAgICAgICAgICAgIGlmICghbmV0c25tcF9hZGRfdmFyYmluZF90b19jYWNoZShhc3AsIGFzcC0+cmVxdWVzdHNbaV0uaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3AtPnJlcXVlc3RzW2ldLnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxdWVzdHNbaV0uc3VidHJlZS0+bmV4dCkpIHsKICAgICAgICAgICAgICAgIGlmIChvbGRfdHJlZWNhY2hlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUob2xkX3RyZWVjYWNoZSk7CiAgICAgICAgICAgICAgICAgICAgb2xkX3RyZWVjYWNoZSA9IE5VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLT50eXBlID09IEFTTl9QUklWX1JFVFJZKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHJlLWFkZCB0aGUgc2FtZSBzdWJ0cmVlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5yZXF1ZXN0dmItPnR5cGUgPSBBU05fTlVMTDsKICAgICAgICAgICAgaWYgKCFuZXRzbm1wX2FkZF92YXJiaW5kX3RvX2NhY2hlKGFzcCwgYXNwLT5yZXF1ZXN0c1tpXS5pbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+cmVxdWVzdHNbaV0ucmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5zdWJ0cmVlKSkgewogICAgICAgICAgICAgICAgaWYgKG9sZF90cmVlY2FjaGUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvbGRfdHJlZWNhY2hlKTsKICAgICAgICAgICAgICAgICAgICBvbGRfdHJlZWNhY2hlID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAob2xkX3RyZWVjYWNoZSAhPSBOVUxMKSB7CiAgICAgICAgU05NUF9GUkVFKG9sZF90cmVlY2FjaGUpOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCnZvaWQKbmV0c25tcF9kZWxldGVfcmVxdWVzdF9pbmZvcyhuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxbGlzdCkKewogICAgd2hpbGUgKHJlcWxpc3QpIHsKICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxbGlzdCk7CiAgICAgICAgcmVxbGlzdCA9IHJlcWxpc3QtPm5leHQ7CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9kZWxldGVfc3VidHJlZV9jYWNoZShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgd2hpbGUgKGFzcC0+dHJlZWNhY2hlX251bSA+PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkb24ndCBkZWxldGUgc3VidHJlZXMgCiAgICAgICAgICovCiAgICAgICAgbmV0c25tcF9kZWxldGVfcmVxdWVzdF9pbmZvcyhhc3AtPnRyZWVjYWNoZVthc3AtPnRyZWVjYWNoZV9udW1dLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHNfYmVnaW4pOwogICAgICAgIGFzcC0+dHJlZWNhY2hlX251bS0tOwogICAgfQp9CgovKgogKiBjaGVjayBhbGwgcmVxdWVzdHMgZm9yIGVycm9ycwogKgogKiBATm90ZToKICogVGhpcyBmdW5jdGlvbiBpcyBhIGxpdHRsZSBkaWZmZXJlbnQgZnJvbSB0aGUgb3RoZXJzIGluIHRoYXQKICogaXQgZG9lcyBub3QgdXNlIGFueSBsaW5rZWQgbGlzdHMsIGluc3RlYWQgdXNpbmcgdGhlIG9yaWdpbmFsCiAqIGFzcCByZXF1ZXN0cyBhcnJheS4gVGhpcyBpcyBvZiBwYXJ0aWN1bGFyIGltcG9ydGFuY2UgZm9yCiAqIGNhc2VzIHdoZXJlIHRoZSBsaW5rZWQgbGlzdHMgYXJlIHVucmVsaWFibGUuIE9uZSBrbm93biBpbnN0YW5jZQogKiBvZiB0aGlzIHNjZW5hcmlvIG9jY3VycyB3aGVuIHRoZSByb3dfbWVyZ2UgaGVscGVyIGlzIHVzZWQsIHdoaWNoCiAqIG1heSB0ZW1wb3JhcmlseSBkaXNydXB0cyBsaW5rZWQgbGlzdHMgZHVyaW5nIGl0cyAoYW5kIGl0cyBjaGlsZHJlbnMpCiAqIGhhbmRsaW5nIG9mIHJlcXVlc3RzLgogKi8KaW50Cm5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX2Vycm9yKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbG9va19mb3Jfc3BlY2lmaWMpCnsKICAgIGludCBpOwoKICAgIC8qCiAgICAgKiBmaW5kIGFueSBlcnJvcnMgbWFya2VkIGluIHRoZSByZXF1ZXN0cyAKICAgICAqLwogICAgZm9yKCBpID0gMDsgaSA8IGFzcC0+dmJjb3VudDsgKytpICkgewogICAgICAgIGlmICgoU05NUF9FUlJfTk9FUlJPUiAhPSBhc3AtPnJlcXVlc3RzW2ldLnN0YXR1cykgJiYKICAgICAgICAgICAgKCFsb29rX2Zvcl9zcGVjaWZpYyB8fAogICAgICAgICAgICAgYXNwLT5yZXF1ZXN0c1tpXS5zdGF0dXMgPT0gbG9va19mb3Jfc3BlY2lmaWMpKQogICAgICAgICAgICByZXR1cm4gYXNwLT5yZXF1ZXN0c1tpXS5zdGF0dXM7CiAgICB9CgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX2Vycm9yKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgLyoKICAgICAqIGZpbmQgYW55IGVycm9ycyBtYXJrZWQgaW4gdGhlIHJlcXVlc3RzIAogICAgICovCiAgICBmb3IgKDtyZXF1ZXN0cztyZXF1ZXN0cyA9IHJlcXVlc3RzLT5uZXh0KSB7CiAgICAgICAgaWYgKHJlcXVlc3RzLT5zdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgcmV0dXJuIHJlcXVlc3RzLT5zdGF0dXM7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKaW50Cm5ldHNubXBfY2hlY2tfcmVxdWVzdHNfc3RhdHVzKG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb29rX2Zvcl9zcGVjaWZpYykKewogICAgLyoKICAgICAqIGZpbmQgYW55IGVycm9ycyBtYXJrZWQgaW4gdGhlIHJlcXVlc3RzIAogICAgICovCiAgICB3aGlsZSAocmVxdWVzdHMpIHsKICAgICAgICBpZihyZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8gIT0gYXNwLT5yZXFpbmZvKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ2ZXJib3NlOmFzcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICIqKnJlcWluZm8gJXAgZG9lc24ndCBtYXRjaCBjYWNoZWQgcmVxaW5mbyAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYXNwLT5yZXFpbmZvLCByZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pKTsKICAgICAgICB9CiAgICAgICAgaWYgKHJlcXVlc3RzLT5zdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUiAmJgogICAgICAgICAgICAoIWxvb2tfZm9yX3NwZWNpZmljIHx8IHJlcXVlc3RzLT5zdGF0dXMgPT0gbG9va19mb3Jfc3BlY2lmaWMpCiAgICAgICAgICAgICYmIChsb29rX2Zvcl9zcGVjaWZpYyB8fCBhc3AtPmluZGV4ID09IDAKICAgICAgICAgICAgICAgIHx8IHJlcXVlc3RzLT5pbmRleCA8IGFzcC0+aW5kZXgpKSB7CiAgICAgICAgICAgIGFzcC0+aW5kZXggPSByZXF1ZXN0cy0+aW5kZXg7CiAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gcmVxdWVzdHMtPnN0YXR1czsKICAgICAgICB9CiAgICAgICAgcmVxdWVzdHMgPSByZXF1ZXN0cy0+bmV4dDsKICAgIH0KICAgIHJldHVybiBhc3AtPnN0YXR1czsKfQoKaW50Cm5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX3N0YXR1cyhuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBsb29rX2Zvcl9zcGVjaWZpYykKewogICAgaW50ICAgICAgICAgICAgIGk7CiAgICBmb3IgKGkgPSAwOyBpIDw9IGFzcC0+dHJlZWNhY2hlX251bTsgaSsrKSB7CiAgICAgICAgbmV0c25tcF9jaGVja19yZXF1ZXN0c19zdGF0dXMoYXNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2tfZm9yX3NwZWNpZmljKTsKICAgIH0KICAgIHJldHVybiBhc3AtPnN0YXR1czsKfQoKaW50CmhhbmRsZV92YXJfcmVxdWVzdHMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIGludCAgICAgICAgICAgICBpLCByZXRzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SLAogICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1IsIGZpbmFsX3N0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvOwoKICAgIGFzcC0+cmVxaW5mby0+YXNwID0gYXNwOwogICAgYXNwLT5yZXFpbmZvLT5tb2RlID0gYXNwLT5tb2RlOwoKICAgIC8qCiAgICAgKiBub3csIGhhdmUgdGhlIHN1YnRyZWVzIGluIHRoZSBjYWNoZSBnbyBzZWFyY2ggZm9yIHRoZWlyIHJlc3VsdHMgCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IGkgPD0gYXNwLT50cmVlY2FjaGVfbnVtOyBpKyspIHsKICAgICAgICAvKgogICAgICAgICAqIGRvbid0IGNhbGwgaGFuZGxlcnMgdy9udWxsIHJlZ2luZm8uCiAgICAgICAgICogLSB3aGVuIGlzIHRoaXM/IHN1YiBhZ2VudCBkaXNjb25uZWN0ZWQgd2hpbGUgcmVxdWVzdCBwcm9jZXNzaW5nPwogICAgICAgICAqIC0gc2hvdWxkIHRoaXMgY2FzZSBlbmNvbXBhc3MgbW9yZSBvZiB0aGlzIHN1YnJvdXRpbmU/CiAgICAgICAgICogICAtIGRvZXMgY2hlY2tfcmVxdWVzdF9zdGF0dXMgbWFrZSBzZW5kIGlmIGhhbmRsZXJzIHdlcmVuJ3QgY2FsbGVkPwogICAgICAgICAqLwogICAgICAgIGlmKE5VTEwgIT0gYXNwLT50cmVlY2FjaGVbaV0uc3VidHJlZS0+cmVnaW5mbykgewogICAgICAgICAgICByZWdpbmZvID0gYXNwLT50cmVlY2FjaGVbaV0uc3VidHJlZS0+cmVnaW5mbzsKICAgICAgICAgICAgc3RhdHVzID0gbmV0c25tcF9jYWxsX2hhbmRsZXJzKHJlZ2luZm8sIGFzcC0+cmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLnJlcXVlc3RzX2JlZ2luKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9HRU5FUlI7CgogICAgICAgIC8qCiAgICAgICAgICogZmluZCBhbnkgZXJyb3JzIG1hcmtlZCBpbiB0aGUgcmVxdWVzdHMuICBGb3IgbGF0ZXIgcGFydHMgb2YKICAgICAgICAgKiBTRVQgcHJvY2Vzc2luZywgb25seSBjaGVjayBmb3IgbmV3IGVycm9ycyBzcGVjaWZpYyB0byB0aGF0CiAgICAgICAgICogc2V0IHByb2Nlc3NpbmcgZGlyZWN0aXZlICh3aGljaCBtdXN0IHN1cGVyY2VlZCB0aGUgcHJldmlvdXMKICAgICAgICAgKiBlcnJvcnMpLgogICAgICAgICAqLwogICAgICAgIHN3aXRjaCAoYXNwLT5tb2RlKSB7CiAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgIHJldHN0YXR1cyA9IG5ldHNubXBfY2hlY2tfcmVxdWVzdHNfc3RhdHVzKGFzcCwKCQkJCQkJICAgICAgYXNwLT50cmVlY2FjaGVbaV0uCgkJCQkJCSAgICAgIHJlcXVlc3RzX2JlZ2luLAoJCQkJCQkgICAgICBTTk1QX0VSUl9DT01NSVRGQUlMRUQpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICAgICByZXRzdGF0dXMgPSBuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX3N0YXR1cyhhc3AsCgkJCQkJCSAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLgoJCQkJCQkgICAgICByZXF1ZXN0c19iZWdpbiwKCQkJCQkJICAgICAgU05NUF9FUlJfVU5ET0ZBSUxFRCk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXRzdGF0dXMgPSBuZXRzbm1wX2NoZWNrX3JlcXVlc3RzX3N0YXR1cyhhc3AsCgkJCQkJCSAgICAgIGFzcC0+dHJlZWNhY2hlW2ldLgoJCQkJCQkgICAgICByZXF1ZXN0c19iZWdpbiwgMCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBhbHdheXMgdGFrZSBsb3dlc3QgdmFyYmluZCBpZiBwb3NzaWJsZSAKICAgICAgICAgKi8KICAgICAgICBpZiAocmV0c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgc3RhdHVzID0gcmV0c3RhdHVzOwoJfQoKICAgICAgICAvKgogICAgICAgICAqIG90aGVyIHRoaW5ncyB3ZSBrbm93IGxlc3MgYWJvdXQgKG5vIGluZGV4KSAKICAgICAgICAgKi8KICAgICAgICAvKgogICAgICAgICAqIFdXVzogZHJvcCBzdXBwb3J0IGZvciB0aGlzPyAKICAgICAgICAgKi8KICAgICAgICBpZiAoZmluYWxfc3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IgJiYgc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogd2UgY2FuJ3QgYnJlYWsgaGVyZSwgc2luY2Ugc29tZSBwcm9jZXNzaW5nIG5lZWRzIHRvIGJlCiAgICAgICAgICAgICAqIGRvbmUgZm9yIGFsbCByZXF1ZXN0cyBhbnl3YXkgKElFLCBTRVQgaGFuZGxpbmcgZm9yIFVORE8KICAgICAgICAgICAgICogbmVlZHMgdG8gYmUgY2FsbGVkIHJlZ2FyZGxlc3Mgb2YgcHJldmlvdXMgc3RhdHVzCiAgICAgICAgICAgICAqIHJlc3VsdHMuCiAgICAgICAgICAgICAqIFdXVzogIFRoaXMgc2hvdWxkIGJlIHByZWRpY3RhYmxlIHRob3VnaCBhbmQKICAgICAgICAgICAgICogYnJlYWtpbmcgc2hvdWxkIGJlIHBvc3NpYmxlIGluIHNvbWUgY2FzZXMgKGVnIEdFVCwKICAgICAgICAgICAgICogR0VUTkVYVCwgLi4uKSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsX3N0YXR1cyA9IHN0YXR1czsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGZpbmFsX3N0YXR1czsKfQoKLyoKICogbG9vcCB0aHJvdWdoIG91ciBzZXNzaW9ucyBrbm93biBkZWxlZ2F0ZWQgc2Vzc2lvbnMgYW5kIGNoZWNrIHRvIHNlZQogKiBpZiB0aGV5J3ZlIGNvbXBsZXRlZCB5ZXQuIElmIHRoZXJlIGFyZSBubyBtb3JlIGRlbGVnYXRlZCBzZXNzaW9ucywKICogY2hlY2sgZm9yIGFuZCBwcm9jZXNzIGFueSBxdWV1ZWQgcmVxdWVzdHMKICovCnZvaWQKbmV0c25tcF9jaGVja19vdXRzdGFuZGluZ19hZ2VudF9yZXF1ZXN0cyh2b2lkKQp7CiAgICBuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCwgKnByZXZfYXNwID0gTlVMTCwgKm5leHRfYXNwID0gTlVMTDsKCiAgICAvKgogICAgICogZGVhbCB3aXRoIGRlbGVnYXRlZCByZXF1ZXN0cwogICAgICovCiAgICBmb3IgKGFzcCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OyBhc3A7IGFzcCA9IG5leHRfYXNwKSB7CiAgICAgICAgbmV4dF9hc3AgPSBhc3AtPm5leHQ7ICAgLyogc2F2ZSBpbiBjYXNlIHdlIGNsZWFuIHVwIGFzcCAqLwogICAgICAgIGlmICghbmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkKGFzcCkpIHsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHdlJ3JlIGRvbmUgd2l0aCB0aGlzIG9uZSwgcmVtb3ZlIGZyb20gcXVldWUgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocHJldl9hc3AgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHByZXZfYXNwLT5uZXh0ID0gYXNwLT5uZXh0OwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhZ2VudF9kZWxlZ2F0ZWRfbGlzdCA9IGFzcC0+bmV4dDsKICAgICAgICAgICAgYXNwLT5uZXh0ID0gTlVMTDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNoZWNrIHJlcXVlc3Qgc3RhdHVzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBuZXRzbm1wX2NoZWNrX2FsbF9yZXF1ZXN0c19zdGF0dXMoYXNwLCAwKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNvbnRpbnVlIHByb2Nlc3Npbmcgb3IgZmluaXNoIHVwIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2hlY2tfZGVsYXllZF9yZXF1ZXN0KGFzcCk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiBoZWFkIHdhcyByZW1vdmVkLCBkb24ndCBkcm9wIGl0IGlmIGl0CiAgICAgICAgICAgICAqIHdhcyBpdCByZS1xdWV1ZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgocHJldl9hc3AgPT0gTlVMTCkgJiYgKGFnZW50X2RlbGVnYXRlZF9saXN0ID09IGFzcCkpIHsKICAgICAgICAgICAgICAgIHByZXZfYXNwID0gYXNwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFzcCBpcyBzdGlsbCBvbiB0aGUgcXVldWUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHByZXZfYXNwID0gYXNwOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogaWYgd2UgYXJlIHByb2Nlc3NpbmcgYSBzZXQgYW5kIHRoZXJlIGFyZSBtb3JlIGRlbGVnYXRlZAogICAgICogcmVxdWVzdHMsIGtlZXAgd2FpdGluZyBiZWZvcmUgZ2V0dGluZyB0byBxdWV1ZWQgcmVxdWVzdHMuCiAgICAgKi8KICAgIGlmIChuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ICYmIChOVUxMICE9IGFnZW50X2RlbGVnYXRlZF9saXN0KSkKICAgICAgICByZXR1cm47CgogICAgd2hpbGUgKG5ldHNubXBfYWdlbnRfcXVldWVkX2xpc3QpIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBpZiB3ZSBhcmUgcHJvY2Vzc2luZyBhIHNldCwgdGhlIGZpcnN0IGl0ZW0gYmV0dGVyIGJlCiAgICAgICAgICogdGhlIHNldCBiZWluZyAob3Igd2FpdGluZyB0byBiZSkgcHJvY2Vzc2VkLgogICAgICAgICAqLwogICAgICAgIG5ldHNubXBfYXNzZXJ0KCghbmV0c25tcF9wcm9jZXNzaW5nX3NldCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAobmV0c25tcF9wcm9jZXNzaW5nX3NldCA9PSBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0KSk7CgogICAgICAgIC8qCiAgICAgICAgICogaWYgdGhlIHRvcCByZXF1ZXN0IGlzIGEgc2V0LCBkb24ndCBwb3AgaXQKICAgICAgICAgKiBvZmYgaWYgdGhlcmUgYXJlIGRlbGVnYXRlZCByZXF1ZXN0cwogICAgICAgICAqLwogICAgICAgIGlmICgobmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1NFVCkgJiYKICAgICAgICAgICAgKGFnZW50X2RlbGVnYXRlZF9saXN0KSkgewoKICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQobmV0c25tcF9wcm9jZXNzaW5nX3NldCA9PSBOVUxMKTsKCiAgICAgICAgICAgIG5ldHNubXBfcHJvY2Vzc2luZ19zZXQgPSBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0OwogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJTRVQgcmVxdWVzdCByZW1haW5zIHF1ZXVlZCB3aGlsZSAiCiAgICAgICAgICAgICAgICAgICAgICAgICJkZWxlZ2F0ZWQgcmVxdWVzdHMgZmluaXNoLCBhc3AgPSAlOHBcbiIsIGFzcCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogcG9wIHRoZSBmaXJzdCByZXF1ZXN0IGFuZCBwcm9jZXNzIGl0CiAgICAgICAgICovCiAgICAgICAgYXNwID0gbmV0c25tcF9hZ2VudF9xdWV1ZWRfbGlzdDsKICAgICAgICBuZXRzbm1wX2FnZW50X3F1ZXVlZF9saXN0ID0gYXNwLT5uZXh0OwogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAicHJvY2Vzc2luZyBxdWV1ZWQgcmVxdWVzdCwgYXNwID0gJThwXG4iLCBhc3ApKTsKCiAgICAgICAgbmV0c25tcF9oYW5kbGVfcmVxdWVzdChhc3AsIGFzcC0+c3RhdHVzKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBpZiB3ZSBoaXQgYSBzZXQsIHN0b3AKICAgICAgICAgKi8KICAgICAgICBpZiAoTlVMTCAhPSBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0KQogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKLyoqIERlY2lkZSBpZiB0aGUgcmVxdWVzdGVkIHRyYW5zYWN0aW9uX2lkIGlzIHN0aWxsIGJlaW5nIHByb2Nlc3NlZAogICB3aXRoaW4gdGhlIGFnZW50LiAgVGhpcyBpcyB1c2VkIHRvIHZhbGlkYXRlIHdoZXRoZXIgYSBkZWxheWVkIGNhY2hlCiAgIChjb250YWluaW5nIHBvc3NpYmx5IGZyZWVkIHBvaW50ZXJzKSBpcyBzdGlsbCB1c2FibGUuCgogICByZXR1cm5zIFNOTVBFUlJfU1VDQ0VTUyBpZiBpdCdzIHN0aWxsIHZhbGlkLCBvciBTTk1QRVJSX0dFTkVSUiBpZiBub3QuICovCmludApuZXRzbm1wX2NoZWNrX3RyYW5zYWN0aW9uX2lkKGludCB0cmFuc2FjdGlvbl9pZCkKewogICAgbmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3A7CgogICAgZm9yIChhc3AgPSBhZ2VudF9kZWxlZ2F0ZWRfbGlzdDsgYXNwOyBhc3AgPSBhc3AtPm5leHQpIHsKICAgICAgICBpZiAoYXNwLT5wZHUtPnRyYW5zaWQgPT0gdHJhbnNhY3Rpb25faWQpCiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7CiAgICB9CiAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7Cn0KCgovKgogKiBjaGVja19kZWxheWVkX3JlcXVlc3QoYXNwKQogKgogKiBDYWxsZWQgdG8gcmV4YW1pbmUgYSBzZXQgb2YgcmVxdWVzdHMgYW5kIGNvbnRpbnVlIHByb2Nlc3NpbmcgdGhlbQogKiBvbmNlIGFsbCB0aGUgcHJldmlvdXMgKGRlbGF5ZWQpIHJlcXVlc3RzIGhhdmUgYmVlbiBoYW5kbGVkIG9uZSB3YXkKICogb3IgYW5vdGhlci4KICovCgppbnQKY2hlY2tfZGVsYXllZF9yZXF1ZXN0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJwcm9jZXNzaW5nIGRlbGVnYXRlZCByZXF1ZXN0LCBhc3AgPSAlOHBcbiIsCiAgICAgICAgICAgICAgICBhc3ApKTsKCiAgICBzd2l0Y2ggKGFzcC0+bW9kZSkgewogICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOgogICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgICAgIG5ldHNubXBfY2hlY2tfYWxsX3JlcXVlc3RzX3N0YXR1cyhhc3AsIDApOwogICAgICAgIGhhbmRsZV9nZXRuZXh0X2xvb3AoYXNwKTsKICAgICAgICBpZiAobmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkKGFzcCkgJiYKICAgICAgICAgICAgbmV0c25tcF9jaGVja190cmFuc2FjdGlvbl9pZChhc3AtPnBkdS0+dHJhbnNpZCkgIT0KICAgICAgICAgICAgU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFkZCB0byBkZWxlZ2F0ZWQgcmVxdWVzdCBjaGFpbiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICghbmV0c25tcF9jaGVja19kZWxlZ2F0ZWRfY2hhaW5fZm9yKGFzcCkpIHsKICAgICAgICAgICAgICAgIGFzcC0+bmV4dCA9IGFnZW50X2RlbGVnYXRlZF9saXN0OwogICAgICAgICAgICAgICAgYWdlbnRfZGVsZWdhdGVkX2xpc3QgPSBhc3A7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfc3RhdHVzKGFzcCwgU05NUF9FUlJfQ09NTUlURkFJTEVEKTsKICAgICAgICBnb3RvIHNldHRvcDsKCiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgbmV0c25tcF9jaGVja19hbGxfcmVxdWVzdHNfc3RhdHVzKGFzcCwgU05NUF9FUlJfVU5ET0ZBSUxFRCk7CiAgICAgICAgZ290byBzZXR0b3A7CgogICAgY2FzZSBNT0RFX1NFVF9CRUdJTjoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgIHNldHRvcDoKICAgICAgICAvKiBJZiB3ZSBzaG91bGQgZG8gb25seSBvbmUgcGFzcywgdGhpcyBtZWFuIHdlICovCiAgICAgICAgLyogc2hvdWxkIG5vdCByZWVudGVyIHRoaXMgZnVuY3Rpb24gKi8KICAgICAgICBpZiAoKGFzcC0+cGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19PTkVfUEFTU19PTkxZKSkgewogICAgICAgICAgICAvKiBXZSBzaG91bGQgaGF2ZSBmaW5pc2hlZCB0aGUgcHJvY2Vzc2luZyBhZnRlciB0aGUgZmlyc3QgKi8KICAgICAgICAgICAgLyogaGFuZGxlX3NldF9sb29wLCBzbyBqdXN0IHdyYXAgdXAgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGhhbmRsZV9zZXRfbG9vcChhc3ApOwogICAgICAgIGlmIChhc3AtPm1vZGUgIT0gRklOSVNIRURfU1VDQ0VTUyAmJiBhc3AtPm1vZGUgIT0gRklOSVNIRURfRkFJTFVSRSkgewoKICAgICAgICAgICAgaWYgKG5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZF9hbmRfYWRkKGFzcCkpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBhZGQgdG8gZGVsZWdhdGVkIHJlcXVlc3QgY2hhaW4gCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICghYXNwLT5zdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgYXNwLT5zdGF0dXMgPSBzdGF0dXM7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qCiAgICAgKiBpZiB3ZSBkb24ndCBoYXZlIGFueXRoaW5nIG91dHN0YW5kaW5nIChkZWxlZ2F0ZWQpLCB3cmFwIHVwIAogICAgICovCiAgICBpZiAoIW5ldHNubXBfY2hlY2tfZm9yX2RlbGVnYXRlZChhc3ApKQogICAgICAgIHJldHVybiBuZXRzbm1wX3dyYXBfdXBfcmVxdWVzdChhc3AsIHN0YXR1cyk7CgogICAgcmV0dXJuIDE7Cn0KCi8qKiByZXR1cm5zIDEgaWYgdGhlcmUgYXJlIHZhbGlkIEdFVE5FWFQgcmVxdWVzdHMgbGVmdC4gIFJldHVybnMgMCBpZiBub3QuICovCmludApjaGVja19nZXRuZXh0X3Jlc3VsdHMobmV0c25tcF9hZ2VudF9zZXNzaW9uICphc3ApCnsKICAgIC8qCiAgICAgKiBnZXQgb2xkIGluZm8gCiAgICAgKi8KICAgIG5ldHNubXBfdHJlZV9jYWNoZSAqb2xkX3RyZWVjYWNoZSA9IGFzcC0+dHJlZWNhY2hlOwogICAgaW50ICAgICAgICAgICAgIG9sZF90cmVlY2FjaGVfbnVtID0gYXNwLT50cmVlY2FjaGVfbnVtOwogICAgaW50ICAgICAgICAgICAgIGNvdW50ID0gMDsKICAgIGludCAgICAgICAgICAgICBpLCBzcGVjaWFsID0gMDsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwoKICAgIGlmIChhc3AtPm1vZGUgPT0gU05NUF9NU0dfR0VUKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBTcGVjaWFsIGNhc2UgZm9yIGRvaW5nIElOQ0xVU0lWRSBnZXROZXh0IG9wZXJhdGlvbnMgaW4KICAgICAgICAgKiBBZ2VudFggc3ViYWdlbnRzLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLAogICAgICAgICAgICAgICAgICAgICJhc3AtPm1vZGUgPT0gU05NUF9NU0dfR0VUIGluIGNoX2dldG5leHRcbiIpKTsKICAgICAgICBhc3AtPm1vZGUgPSBhc3AtPm9sZG1vZGU7CiAgICAgICAgc3BlY2lhbCA9IDE7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8PSBvbGRfdHJlZWNhY2hlX251bTsgaSsrKSB7CiAgICAgICAgZm9yIChyZXF1ZXN0ID0gb2xkX3RyZWVjYWNoZVtpXS5yZXF1ZXN0c19iZWdpbjsgcmVxdWVzdDsKICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJZiB3ZSBoYXZlIGp1c3QgZG9uZSB0aGUgc3BlY2lhbCBjYXNlIEFnZW50WCBHRVQsIHRoZW4gYW55CiAgICAgICAgICAgICAqIHJlcXVlc3RzIHdoaWNoIHdlcmUgbm90IElOQ0xVU0lWRSB3aWxsIG5vdyBoYXZlIGEgd3JvbmcKICAgICAgICAgICAgICogcmVzcG9uc2UsIHNvIGp1bmsgdGhlbSBhbmQgcmV0cnkgZnJvbSB0aGUgc2FtZSBwbGFjZSAoZXhjZXB0CiAgICAgICAgICAgICAqIHRoYXQgdGhpcyB0aW1lIHRoZSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIGluICJpbmV4YWN0IgogICAgICAgICAgICAgKiBtb2RlKS4gIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChzcGVjaWFsKSB7CiAgICAgICAgICAgICAgICBpZiAoIXJlcXVlc3QtPmluY2x1c2l2ZSkgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVxdWVzdCAlZCB3YXNuJ3QgaW5jbHVzaXZlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluZGV4KSk7CiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX1BSSVZfUkVUUlksIE5VTEwsIDApOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IFNOTVBfTk9TVUNISU5TVEFOQ0UgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IFNOTVBfTk9TVUNIT0JKRUNUKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBpdCB3YXMgaW5jbHVzaXZlLCBidXQgbm8gcmVzdWx0cy4gIFN0aWxsIHJldHJ5IHRoaXMKICAgICAgICAgICAgICAgICAgICAgKiBzZWFyY2guIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9QUklWX1JFVFJZLCBOVUxMLCAwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb3V0IG9mIHJhbmdlPyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChzbm1wX29pZF9jb21wYXJlKHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKSA+PSAwKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogYWNrLCBpdCdzIGJleW9uZCB0aGUgYWNjZXB0ZWQgZW5kIG9mIHJhbmdlLiAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGZpeCBpdCBieSBzZXR0aW5nIHRoZSBvaWQgdG8gdGhlIGVuZCBvZiByYW5nZSBvaWQgaW5zdGVhZCAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImNoZWNrX2dldG5leHRfcmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVxdWVzdCByZXNwb25zZSAlZCBvdXQgb2YgcmFuZ2VcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmRleCkpOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEknbSBub3Qgc3VyZSB3aHkgaW5jbHVzaXZlIGlzIHNldCB1bmNvbmRpdGlvbmFsbHkgaGVyZSAoc2VlCiAgICAgICAgICAgICAgICAgKiBjb21tZW50cyBmb3IgcmV2aXNpb24gMS4xNjEpLCBidXQgaXQgY2F1c2VzIGEgcHJvYmxlbSBmb3IKICAgICAgICAgICAgICAgICAqIEdFVEJVTEsgb3ZlciBhbiBvdmVycmlkZGVuIHZhcmlhYmxlLiBUaGUgYnVsay10by1uZXh0CiAgICAgICAgICAgICAgICAgKiBoYW5kbGVyIHJlLXVzZXMgdGhlIHNhbWUgcmVxdWVzdCBmb3IgbXVsdGlwbGUgdmFyYmluZHMsCiAgICAgICAgICAgICAgICAgKiBhbmQgb25jZSBpbmNsdXNpdmUgd2FzIHNldCwgaXQgd2FzIG5ldmVyIGNsZWFyZWQuIFNvLCBhCiAgICAgICAgICAgICAgICAgKiBoYWNrLiBJbnN0ZWFkIG9mIHNldHRpbmcgaXQgdG8gMSwgc2V0IGl0IHRvIDIsIHNvIGJ1bGstdG8KICAgICAgICAgICAgICAgICAqIG5leHQgY2FuIGNsZWFyIGl0IGxhdGVyLiBBcyBvZiB0aGUgdGltZSBvZiB0aGlzIGhhY2ssIGFsbAogICAgICAgICAgICAgICAgICogY2hlY2tzIG9mIHRoaXMgdmFyIGFyZSBib29sZWFuIGNoZWNrcyAobm90ID09IDEpLCBzbyB0aGlzCiAgICAgICAgICAgICAgICAgKiBzaG91bGQgYmUgc2FmZS4gQ3Jvc3MgeW91ciBmaW5nZXJzLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmNsdXNpdmUgPSAyOwogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFhYWDogc2hvdWxkIHNldCB0aGlzIHRvIHRoZSBvcmlnaW5hbCBPSUQ/IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdC0+cmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKTsKICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0LT5yZXF1ZXN0dmIsIEFTTl9OVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBtYXJrIGFueSBleGlzdGVudCByZXF1ZXN0cyB3aXRoIGlsbGVnYWwgcmVzdWx0cyBhcyBOVUxMIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGlsbGVnYWwgcmVzcG9uc2UgZnJvbSBhIHN1YmFnZW50LiAgQ2hhbmdlIGl0IGJhY2sgdG8gTlVMTCAKICAgICAgICAgICAgICAgICAqICB4eHgtcmtzOiBlcnIsIGhvdyBkbyB3ZSBrbm93IHRoaXMgaXMgYSBzdWJhZ2VudD8KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX05VTEw7CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5pbmNsdXNpdmUgPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IEFTTl9OVUxMIHx8CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX1BSSVZfUkVUUlkgfHwKICAgICAgICAgICAgICAgIChhc3AtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLCiAgICAgICAgICAgICAgICAgJiYgcmVxdWVzdC0+cmVwZWF0ID4gMCkpCiAgICAgICAgICAgICAgICBjb3VudCsrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBjb3VudDsKfQoKLyoqIHJlcGVhdGVkbHkgY2FsbHMgZ2V0bmV4dCBoYW5kbGVycyBsb29raW5nIGZvciBhbiBhbnN3ZXIgdGlsbCBhbGwKICAgcmVxdWVzdHMgYXJlIHNhdGlzaWZpZWQuICBJdCdzIGV4cGVjdGVkIHRoYXQgb25lIHBhc3MgaGFzIGJlZW4gbWFkZQogICBiZWZvcmUgZW50ZXJpbmcgdGhpcyBmdW5jdGlvbiAqLwppbnQKaGFuZGxlX2dldG5leHRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIHN0YXR1czsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyX3B0cjsKCiAgICAvKgogICAgICogbG9vcCAKICAgICAqLwogICAgd2hpbGUgKG5ldHNubXBfcnVubmluZykgewoKICAgICAgICAvKgogICAgICAgICAqIGJhaWwgZm9yIG5vdyBpZiBhbnl0aGluZyBpcyBkZWxlZ2F0ZWQuIAogICAgICAgICAqLwogICAgICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSkgewogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgdmFjbSBhZ2FpbnN0IHJlc3VsdHMgCiAgICAgICAgICovCiAgICAgICAgY2hlY2tfYWNtKGFzcCwgQVNOX1BSSVZfUkVUUlkpOwoKICAgICAgICAvKgogICAgICAgICAqIG5lZWQgdG8ga2VlcCBnb2luZyB3ZSdyZSBub3QgZG9uZSB5ZXQuIAogICAgICAgICAqLwogICAgICAgIGlmICghY2hlY2tfZ2V0bmV4dF9yZXN1bHRzKGFzcCkpCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG5vdGhpbmcgbGVmdCwgcXVpdCBub3cgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgLyoKICAgICAgICAgKiBuZXZlciBoYWQgYSByZXF1ZXN0IChlbXB0eSBwZHUpLCBxdWl0IG5vdyAKICAgICAgICAgKi8KICAgICAgICAvKgogICAgICAgICAqIFhYWFdXVzogaHVoPyAgdGhpcyB3b3VsZCBiZSB0b28gbGF0ZSwgbm8/ICBzaG91bGRuJ3Qgd2UKICAgICAgICAgKiBjYXRjaCB0aGlzIGVhcmxpZXI/IAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogaWYgKGNvdW50ID09IDApCiAgICAgICAgICogYnJlYWs7IAogICAgICAgICAqLwoKICAgICAgICBERUJVR0lGKCJyZXN1bHRzIikgewogICAgICAgICAgICBERUJVR01TR1RMKCgicmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICJnZXRuZXh0IHJlc3VsdHMsIGJlZm9yZSBuZXh0IHBhc3M6XG4iKSk7CiAgICAgICAgICAgIGZvciAodmFyX3B0ciA9IGFzcC0+cGR1LT52YXJpYWJsZXM7IHZhcl9wdHI7CiAgICAgICAgICAgICAgICAgdmFyX3B0ciA9IHZhcl9wdHItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJyZXN1bHRzIiwgIlx0IikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dWQVIoKCJyZXN1bHRzIiwgdmFyX3B0cikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJyZXN1bHRzIiwgIlxuIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBuZXRzbm1wX3JlYXNzaWduX3JlcXVlc3RzKGFzcCk7CiAgICAgICAgc3RhdHVzID0gaGFuZGxlX3Zhcl9yZXF1ZXN0cyhhc3ApOwogICAgICAgIGlmIChzdGF0dXMgIT0gU05NUF9FUlJfTk9FUlJPUikgewogICAgICAgICAgICByZXR1cm4gc3RhdHVzOyAgICAgIC8qIHNob3VsZCBuZXZlciByZWFsbHkgaGFwcGVuICovCiAgICAgICAgfQogICAgfQogICAgaWYgKCFuZXRzbm1wX3J1bm5pbmcpIHsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCmludApoYW5kbGVfc2V0KG5ldHNubXBfYWdlbnRfc2Vzc2lvbiAqYXNwKQp7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwogICAgLyoKICAgICAqIFNFVFMgcmVxdWlyZSAzLTQgcGFzc2VzIHRocm91Z2ggdGhlIHZhcl9vcF9saXN0LgogICAgICogVGhlIGZpcnN0IHR3bwogICAgICogcGFzc2VzIHZlcmlmeSB0aGF0IGFsbCB0eXBlcywgbGVuZ3RocywgYW5kIHZhbHVlcyBhcmUgdmFsaWQKICAgICAqIGFuZCBtYXkgcmVzZXJ2ZSByZXNvdXJjZXMgYW5kIHRoZSB0aGlyZCBkb2VzIHRoZSBzZXQgYW5kIGEKICAgICAqIGZvdXJ0aCBleGVjdXRlcyBhbnkgYWN0aW9ucy4gIFRoZW4gdGhlIGlkZW50aWNhbCBHRVQgUkVTUE9OU0UKICAgICAqIHBhY2tldCBpcyByZXR1cm5lZC4KICAgICAqIElmIGVpdGhlciBvZiB0aGUgZmlyc3QgdHdvIHBhc3NlcyByZXR1cm5zIGFuIGVycm9yLCBhbm90aGVyCiAgICAgKiBwYXNzIGlzIG1hZGUgc28gdGhhdCBhbnkgcmVzZXJ2ZWQgcmVzb3VyY2VzIGNhbiBiZSBmcmVlZC4KICAgICAqIElmIHRoZSB0aGlyZCBwYXNzIHJldHVybnMgYW4gZXJyb3IsIGFub3RoZXIgcGFzcyBpcwogICAgICogbWFkZSBzbyB0aGF0CiAgICAgKiBhbnkgY2hhbmdlcyBjYW4gYmUgcmV2ZXJzZWQuCiAgICAgKiBJZiB0aGUgZm91cnRoIHBhc3MgKG9yIGFueSBvZiB0aGUgZXJyb3IgaGFuZGxpbmcgcGFzc2VzKQogICAgICogcmV0dXJuIGFuIGVycm9yLCB3ZSdkIHJhdGhlciBub3Qga25vdyBhYm91dCBpdCEKICAgICAqLwogICAgaWYgKCEoYXNwLT5wZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFkpKSB7CiAgICAgICAgc3dpdGNoIChhc3AtPm1vZGUpIHsKICAgICAgICBjYXNlIE1PREVfU0VUX0JFR0lOOgogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5TRVRSRVFVRVNUUyk7CiAgICAgICAgICAgIGFzcC0+cncgPSBXUklURTsgICAgLyogV1dXOiBzdGlsbCBuZWVkZWQ/ICovCiAgICAgICAgICAgIGFzcC0+bW9kZSA9IE1PREVfU0VUX1JFU0VSVkUxOwogICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgoKICAgICAgICAgICAgaWYgKGFzcC0+c3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9GUkVFOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9SRVNFUlZFMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgICAgIGlmIChhc3AtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfRlJFRTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfQUNUSU9OOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgICAgIGlmIChhc3AtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfVU5ETzsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gTU9ERV9TRVRfQ09NTUlUOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgIGlmIChhc3AtPnN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAgICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9GQUlMVVJFOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXNwLT5tb2RlID0gRklOSVNIRURfU1VDQ0VTUzsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgICAgICBhc3AtPm1vZGUgPSBGSU5JU0hFRF9GQUlMVVJFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9TVUNDRVNTICYmIGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9GQUlMVVJFKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50X3NldCIsICJkb2luZyBzZXQgbW9kZSA9ICVkICglcylcbiIsIGFzcC0+bW9kZSwKICAgICAgICAgICAgICAgICAgICBzZV9maW5kX2xhYmVsX2luX3NsaXN0KCJhZ2VudF9tb2RlIiwgYXNwLT5tb2RlKSkpOwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV92YXJfcmVxdWVzdHMoYXNwKTsKICAgICAgICBERUJVR01TR1RMKCgiYWdlbnRfc2V0IiwgImRpZCBzZXQgbW9kZSA9ICVkLCBzdGF0dXMgPSAlZFxuIiwKICAgICAgICAgICAgICAgICAgICBhc3AtPm1vZGUsIHN0YXR1cykpOwogICAgICAgIGlmICgoc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IgJiYgYXNwLT5zdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUikgfHwKCSAgICBzdGF0dXMgPT0gU05NUF9FUlJfQ09NTUlURkFJTEVEIHx8IAoJICAgIHN0YXR1cyA9PSBTTk1QX0VSUl9VTkRPRkFJTEVEKSB7CiAgICAgICAgICAgIGFzcC0+c3RhdHVzID0gc3RhdHVzOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBhc3AtPnN0YXR1czsKfQoKaW50CmhhbmRsZV9zZXRfbG9vcChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgd2hpbGUgKGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9GQUlMVVJFICYmIGFzcC0+bW9kZSAhPSBGSU5JU0hFRF9TVUNDRVNTKSB7CiAgICAgICAgaGFuZGxlX3NldChhc3ApOwogICAgICAgIGlmIChuZXRzbm1wX2NoZWNrX2Zvcl9kZWxlZ2F0ZWQoYXNwKSkgewogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCX0KICAgICAgICBpZiAoYXNwLT5wZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX09ORV9QQVNTX09OTFkpIHsKICAgICAgICAgICAgcmV0dXJuIGFzcC0+c3RhdHVzOwoJfQogICAgfQogICAgcmV0dXJuIGFzcC0+c3RhdHVzOwp9CgppbnQKbmV0c25tcF9oYW5kbGVfcmVxdWVzdChuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCwgaW50IHN0YXR1cykKewogICAgLyoKICAgICAqIGlmIHRoaXMgaXNuJ3QgYSBkZWxlZ2F0ZWQgcmVxdWVzdCB0cnlpbmcgdG8gZmluaXNoLAogICAgICogcHJvY2Vzc2luZyBvZiBhIHNldCByZXF1ZXN0IHNob3VsZCBub3Qgc3RhcnQgdW50aWwgYWxsCiAgICAgKiBkZWxlZ2F0ZWQgcmVxdWVzdHMgaGF2ZSBjb21wbGV0ZWQsIGFuZCBubyBvdGhlciBuZXcgcmVxdWVzdHMKICAgICAqIHNob3VsZCBiZSBwcm9jZXNzZWQgdW50aWwgdGhlIHNldCByZXF1ZXN0IGNvbXBsZXRlcy4KICAgICAqLwogICAgaWYgKCgwID09IG5ldHNubXBfY2hlY2tfZGVsZWdhdGVkX2NoYWluX2Zvcihhc3ApKSAmJgogICAgICAgIChhc3AgIT0gbmV0c25tcF9wcm9jZXNzaW5nX3NldCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGlmIHdlIGFyZSBwcm9jZXNzaW5nIGEgc2V0IGFuZCB0aGlzIGlzIG5vdCBhIGRlbGVnYXRlZAogICAgICAgICAqIHJlcXVlc3QsIHF1ZXVlIHRoZSByZXF1ZXN0CiAgICAgICAgICovCiAgICAgICAgaWYgKG5ldHNubXBfcHJvY2Vzc2luZ19zZXQpIHsKICAgICAgICAgICAgbmV0c25tcF9hZGRfcXVldWVkKGFzcCk7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FnZW50IiwKICAgICAgICAgICAgICAgICAgICAgICAgInJlcXVlc3QgcXVldWVkIHdoaWxlIHByb2Nlc3Npbmcgc2V0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICJhc3AgPSAlOHBcbiIsIGFzcCkpOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgZm9yIHNldCByZXF1ZXN0CiAgICAgICAgICovCiAgICAgICAgaWYgKGFzcC0+cGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1NFVCkgewogICAgICAgICAgICBuZXRzbm1wX3Byb2Nlc3Npbmdfc2V0ID0gYXNwOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgdGhlcmUgYXJlIGRlbGVnYXRlZCByZXF1ZXN0cywgd2UgbXVzdCB3YWl0IGZvciB0aGVtCiAgICAgICAgICAgICAqIHRvIGZpbmlzaC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChhZ2VudF9kZWxlZ2F0ZWRfbGlzdCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYWdlbnQiLCAiU0VUIHJlcXVlc3QgcXVldWVkIHdoaWxlICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZWxlZ2F0ZWQgcmVxdWVzdHMgZmluaXNoLCBhc3AgPSAlOHBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3ApKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfYWRkX3F1ZXVlZChhc3ApOwogICAgICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIHByb2Nlc3MgdGhlIHJlcXVlc3QgCiAgICAgKi8KICAgIHN0YXR1cyA9IGhhbmRsZV9wZHUoYXNwKTsKCiAgICAvKgogICAgICogcHJpbnQgdGhlIHJlc3VsdHMgaW4gYXBwcm9wcmlhdGUgZGVidWdnaW5nIG1vZGUgCiAgICAgKi8KICAgIERFQlVHSUYoInJlc3VsdHMiKSB7CiAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJfcHRyOwogICAgICAgIERFQlVHTVNHVEwoKCJyZXN1bHRzIiwgInJlcXVlc3QgcmVzdWx0cyAoc3RhdHVzID0gJWQpOlxuIiwKICAgICAgICAgICAgICAgICAgICBzdGF0dXMpKTsKICAgICAgICBmb3IgKHZhcl9wdHIgPSBhc3AtPnBkdS0+dmFyaWFibGVzOyB2YXJfcHRyOwogICAgICAgICAgICAgdmFyX3B0ciA9IHZhcl9wdHItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInJlc3VsdHMiLCAiXHQiKSk7CiAgICAgICAgICAgIERFQlVHTVNHVkFSKCgicmVzdWx0cyIsIHZhcl9wdHIpKTsKICAgICAgICAgICAgREVCVUdNU0coKCJyZXN1bHRzIiwgIlxuIikpOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogY2hlY2sgZm9yIHVuY29tcGxldGVkIHJlcXVlc3RzIAogICAgICovCiAgICBpZiAobmV0c25tcF9jaGVja19mb3JfZGVsZWdhdGVkX2FuZF9hZGQoYXNwKSkgewogICAgICAgIC8qCiAgICAgICAgICogYWRkIHRvIGRlbGVnYXRlZCByZXF1ZXN0IGNoYWluIAogICAgICAgICAqLwogICAgICAgIGFzcC0+c3RhdHVzID0gc3RhdHVzOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIGlmIHdlIGRvbid0IGhhdmUgYW55dGhpbmcgb3V0c3RhbmRpbmcgKGRlbGVnYXRlZCksIHdyYXAgdXAKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gbmV0c25tcF93cmFwX3VwX3JlcXVlc3QoYXNwLCBzdGF0dXMpOwogICAgfQoKICAgIHJldHVybiAxOwp9CgppbnQKaGFuZGxlX3BkdShuZXRzbm1wX2FnZW50X3Nlc3Npb24gKmFzcCkKewogICAgaW50ICAgICAgICAgICAgIHN0YXR1cywgaW5jbHVzaXZlcyA9IDA7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnYgPSBOVUxMOwoKICAgIC8qCiAgICAgKiBmb3IgaWxsZWdhbCByZXF1ZXN0cywgbWFyayBhbGwgbm9kZXMgYXMgQVNOX05VTEwgCiAgICAgKi8KICAgIHN3aXRjaCAoYXNwLT5wZHUtPmNvbW1hbmQpIHsKCiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9SRVNFUlZFMjoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0FDVElPTjoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0NPTU1JVDoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX0ZSRUU6CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9VTkRPOgogICAgICAgIHN0YXR1cyA9IGdldF9zZXRfY2FjaGUoYXNwKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgZm9yICh2ID0gYXNwLT5wZHUtPnZhcmlhYmxlczsgdiAhPSBOVUxMOyB2ID0gdi0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICBpZiAodi0+dHlwZSA9PSBBU05fUFJJVl9JTkNMX1JBTkdFKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogTGVhdmUgdGhlIHR5cGUgZm9yIG5vdyAoaXQgZ2V0cyBzZXQgdG8KICAgICAgICAgICAgICAgICAqIEFTTl9OVUxMIGluIG5ldHNubXBfYWRkX3ZhcmJpbmRfdG9fY2FjaGUsCiAgICAgICAgICAgICAgICAgKiBjYWxsZWQgYnkgY3JlYXRlX3N1Ym5ldHNubXBfdHJlZV9jYWNoZSBiZWxvdykuCiAgICAgICAgICAgICAgICAgKiBJZiB3ZSBzZXQgaXQgdG8gQVNOX05VTEwgbm93LCB3ZSB3b3VsZG4ndCBiZQogICAgICAgICAgICAgICAgICogYWJsZSB0byBkaXN0aW5ndWlzaCBJTkNMVVNJVkUgc2VhcmNoCiAgICAgICAgICAgICAgICAgKiByYW5nZXMuICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaW5jbHVzaXZlcysrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHYsIEFTTl9OVUxMLCBOVUxMLCAwKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIGZhbGwgdGhyb3VnaCAKICAgICAgICAgKi8KCiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9CRUdJTjoKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgZGVmYXVsdDoKICAgICAgICBhc3AtPnZiY291bnQgPSBjb3VudF92YXJiaW5kcyhhc3AtPnBkdS0+dmFyaWFibGVzKTsKICAgICAgICBpZiAoYXNwLT52YmNvdW50KSAvKiBlZmVuY2UgZG9lc24ndCBsaWtlIDAgc2l6ZSBhbGxvY3MgKi8KICAgICAgICAgICAgYXNwLT5yZXF1ZXN0cyA9IChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqKQogICAgICAgICAgICAgICAgY2FsbG9jKGFzcC0+dmJjb3VudCwgc2l6ZW9mKG5ldHNubXBfcmVxdWVzdF9pbmZvKSk7CiAgICAgICAgLyoKICAgICAgICAgKiBjb2xsZWN0IHZhcmJpbmRzIAogICAgICAgICAqLwogICAgICAgIHN0YXR1cyA9IG5ldHNubXBfY3JlYXRlX3N1YnRyZWVfY2FjaGUoYXNwKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFNOTVBfRVJSX05PRVJST1IpCiAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CgogICAgYXNwLT5tb2RlID0gYXNwLT5wZHUtPmNvbW1hbmQ7CiAgICBzd2l0Y2ggKGFzcC0+bW9kZSkgewogICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICAgICAgLyoKICAgICAgICAgKiBpbmNyZW1lbnQgdGhlIG1lc3NhZ2UgdHlwZSBjb3VudGVyIAogICAgICAgICAqLwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkdFVFJFUVVFU1RTKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayB2YWNtIGFoZWFkIG9mIHRpbWUgCiAgICAgICAgICovCiAgICAgICAgY2hlY2tfYWNtKGFzcCwgU05NUF9OT1NVQ0hPQkpFQ1QpOwoKICAgICAgICAvKgogICAgICAgICAqIGdldCB0aGUgcmVzdWx0cyAKICAgICAgICAgKi8KICAgICAgICBzdGF0dXMgPSBoYW5kbGVfdmFyX3JlcXVlc3RzKGFzcCk7CgogICAgICAgIC8qCiAgICAgICAgICogRGVhbCB3aXRoIHVuaGFuZGxlZCByZXN1bHRzIC0+IG5vU3VjaEluc3RhbmNlIChyYXRoZXIKICAgICAgICAgKiB0aGFuIG5vU3VjaE9iamVjdCAtLSBpbiB0aGF0IGNhc2UsIHRoZSB0eXBlIHdpbGwKICAgICAgICAgKiBhbHJlYWR5IGhhdmUgYmVlbiBzZXQgdG8gbm9TdWNoT2JqZWN0IHdoZW4gd2UgcmVhbGlzZWQKICAgICAgICAgKiB3ZSBjb3VsZG4ndCBmaW5kIGFuIGFwcHJvcHJpYXRlIHRyZWUpLiAgCiAgICAgICAgICovCiAgICAgICAgaWYgKHN0YXR1cyA9PSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICBzbm1wX3JlcGxhY2VfdmFyX3R5cGVzKGFzcC0+cGR1LT52YXJpYWJsZXMsIEFTTl9OVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTk9TVUNISU5TVEFOQ0UpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5HRVRORVhUUyk7CiAgICAgICAgLyoKICAgICAgICAgKiBmYWxsIHRocm91Z2ggCiAgICAgICAgICovCgogICAgY2FzZSBTTk1QX01TR19HRVRCVUxLOiAgICAgLyogbm90ZTogdGhlcmUgaXMgbm8gZ2V0YnVsayBzdGF0ICovCiAgICAgICAgLyoKICAgICAgICAgKiBsb29wIHRocm91Z2ggb3VyIG1pYiB0cmVlIHRpbGwgd2UgZmluZCBhbgogICAgICAgICAqIGFwcHJvcHJpYXRlIHJlc3BvbnNlIHRvIHJldHVybiB0byB0aGUgY2FsbGVyLiAKICAgICAgICAgKi8KCiAgICAgICAgaWYgKGluY2x1c2l2ZXMpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBmb3IgQWdlbnRYIElOQ0xVU0lWRSBnZXROZXh0CiAgICAgICAgICAgICAqIHJlcXVlc3RzIHdoZXJlIGEgcmVzdWx0IGxleGktZXF1YWwgdG8gdGhlIHJlcXVlc3QgaXMgb2theQogICAgICAgICAgICAgKiBidXQgaWYgc3VjaCBhIHJlc3VsdCBkb2VzIG5vdCBleGlzdCwgd2Ugc3RpbGwgd2FudCB0aGUKICAgICAgICAgICAgICogbGV4aS1uZXh0IG9uZS4gIFNvIGJhc2ljYWxseSB3ZSBkbyBhIEdFVCBmaXJzdCwgYW5kIGlmIGFueQogICAgICAgICAgICAgKiBvZiB0aGUgSU5DTFVTSVZFIHJlcXVlc3RzIGFyZSBzYXRpc2ZpZWQsIHdlIHVzZSB0aGF0CiAgICAgICAgICAgICAqIHZhbHVlLiAgVGhlbiwgdW5zYXRpc2ZpZWQgSU5DTFVTSVZFIHJlcXVlc3RzLCBhbmQKICAgICAgICAgICAgICogbm9uLUlOQ0xVU0lWRSByZXF1ZXN0cyBnZXQgZG9uZSBhcyBub3JtYWwuICAKICAgICAgICAgICAgICovCgogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hZ2VudCIsICJpbmNsdXNpdmUgcmFuZ2UocykgaW4gZ2V0TmV4dFxuIikpOwogICAgICAgICAgICBhc3AtPm9sZG1vZGUgPSBhc3AtPm1vZGU7CiAgICAgICAgICAgIGFzcC0+bW9kZSA9IFNOTVBfTVNHX0dFVDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZmlyc3QgcGFzcyAKICAgICAgICAgKi8KICAgICAgICBzdGF0dXMgPSBoYW5kbGVfdmFyX3JlcXVlc3RzKGFzcCk7CiAgICAgICAgaWYgKHN0YXR1cyAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAgICAgICAgIGlmICghaW5jbHVzaXZlcykKICAgICAgICAgICAgICAgIHJldHVybiBzdGF0dXM7ICAvKiBzaG91bGQgbmV2ZXIgcmVhbGx5IGhhcHBlbiAqLwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBhc3AtPnN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGxvb3AgdGhyb3VnaCBvdXIgbWliIHRyZWUgdGlsbCB3ZSBmaW5kIGFuCiAgICAgICAgICogYXBwcm9wcmlhdGUgcmVzcG9uc2UgdG8gcmV0dXJuIHRvIHRoZSBjYWxsZXIuIAogICAgICAgICAqLwoKICAgICAgICBzdGF0dXMgPSBoYW5kbGVfZ2V0bmV4dF9sb29wKGFzcCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19TRVQ6CiNpZmRlZiBORVRTTk1QX0RJU0FCTEVfU0VUX1NVUFBPUlQKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiNlbHNlCiAgICAgICAgLyoKICAgICAgICAgKiBjaGVjayBhY2Nlc3MgcGVybWlzc2lvbnMgZmlyc3QgCiAgICAgICAgICovCiAgICAgICAgaWYgKGNoZWNrX2FjbShhc3AsIFNOTVBfTk9TVUNIT0JKRUNUKSkKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PVFdSSVRBQkxFOwoKICAgICAgICBhc3AtPm1vZGUgPSBNT0RFX1NFVF9CRUdJTjsKICAgICAgICBzdGF0dXMgPSBoYW5kbGVfc2V0X2xvb3AoYXNwKTsKI2VuZGlmCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQkVHSU46CiAgICBjYXNlIFNOTVBfTVNHX0lOVEVSTkFMX1NFVF9SRVNFUlZFMToKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUyOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQUNUSU9OOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfQ09NTUlUOgogICAgY2FzZSBTTk1QX01TR19JTlRFUk5BTF9TRVRfRlJFRToKICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1VORE86CiAgICAgICAgYXNwLT5wZHUtPmZsYWdzIHw9IFVDRF9NU0dfRkxBR19PTkVfUEFTU19PTkxZOwogICAgICAgIHN0YXR1cyA9IGhhbmRsZV9zZXRfbG9vcChhc3ApOwogICAgICAgIC8qCiAgICAgICAgICogYXNwIHJlbGF0ZWQgY2FjaGUgaXMgc2F2ZWQgaW4gY2xlYW51cCAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkdFVFJFU1BPTlNFUyk7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CgogICAgY2FzZSBTTk1QX01TR19UUkFQOgogICAgY2FzZSBTTk1QX01TR19UUkFQMjoKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5UUkFQUyk7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CgogICAgZGVmYXVsdDoKICAgICAgICAvKgogICAgICAgICAqIFdXVzogYXJlIHJlcG9ydHMgY291bnRlZCBzb21ld2hlcmUgPyAKICAgICAgICAgKi8KICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsgIC8qIHNob3VsZG4ndCBnZXQgaGVyZSAqLwogICAgICAgIC8qCiAgICAgICAgICogV1dXIAogICAgICAgICAqLwogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKLyoqIHNldCBlcnJvciBmb3IgYSByZXF1ZXN0CiAqIFxpbnRlcm5hbCBleHRlcm5hbCBpbnRlcmZhY2U6IG5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3IKICovCk5FVFNOTVBfU1RBVElDX0lOTElORSBpbnQKX3JlcXVlc3Rfc2V0X2Vycm9yKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgbW9kZSwgaW50IGVycm9yX3ZhbHVlKQp7CiAgICBpZiAoIXJlcXVlc3QpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSAxOwogICAgcmVxdWVzdC0+ZGVsZWdhdGVkID0gUkVRVUVTVF9JU19OT1RfREVMRUdBVEVEOwoKICAgIHN3aXRjaCAoZXJyb3JfdmFsdWUpIHsKICAgIGNhc2UgU05NUF9OT1NVQ0hPQkpFQ1Q6CiAgICBjYXNlIFNOTVBfTk9TVUNISU5TVEFOQ0U6CiAgICBjYXNlIFNOTVBfRU5ET0ZNSUJWSUVXOgogICAgICAgIC8qCiAgICAgICAgICogdGhlc2UgYXJlIGV4Y2VwdGlvbnMgdGhhdCBzaG91bGQgYmUgcHV0IGluIHRoZSB2YXJiaW5kCiAgICAgICAgICogaW4gdGhlIGNhc2Ugb2YgYSBHRVQgYnV0IHNob3VsZCBiZSB0cmFuc2xhdGVkIGZvciBhIFNFVAogICAgICAgICAqIGludG8gYSByZWFsIGVycm9yIHN0YXR1cyBjb2RlIGFuZCBwdXQgaW4gdGhlIHJlcXVlc3QgCiAgICAgICAgICovCiAgICAgICAgc3dpdGNoIChtb2RlKSB7CiAgICAgICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICBjYXNlIE1PREVfR0VUQlVMSzoKICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gZXJyb3JfdmFsdWU7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhlc2UgYXJlIHRlY2huaWNhbGx5IGlsbGVnYWwgdG8gc2V0IGJ5IHRoZQogICAgICAgICAgICAgKiBjbGllbnQgQVBJcyBmb3IgdGhlc2UgbW9kZXMuICBCdXQgYWNjZXB0aW5nCiAgICAgICAgICAgICAqIHRoZW0gaGVyZSBhbGxvd3MgdGhlICdzcGFyc2VfdGFibGUnIGhlbHBlciB0bwogICAgICAgICAgICAgKiBwcm92aWRlIHNvbWUgY29tbW9uIHRhYmxlIGhhbmRsaW5nIHByb2Nlc3NpbmcKICAgICAgICAgICAgICoKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIklsbGVnYWwgZXJyb3JfdmFsdWUgJWQgZm9yIG1vZGUgJWQgaWdub3JlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgZXJyb3JfdmFsdWUsIG1vZGUpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgICovCgogICAgICAgIGNhc2UgU05NUF9NU0dfSU5URVJOQUxfU0VUX1JFU0VSVkUxOgogICAgICAgICAgICByZXF1ZXN0LT5zdGF0dXMgPSBTTk1QX0VSUl9OT0NSRUFUSU9OOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmVxdWVzdC0+c3RhdHVzID0gU05NUF9FUlJfTk9TVUNITkFNRTsgICAgICAvKiBXV1c6IGNvcnJlY3Q/ICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBicmVhazsgICAgICAgICAgICAgICAgICAvKiBuZXZlciBnZXQgaGVyZSAqLwoKICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKGVycm9yX3ZhbHVlIDwgMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpbGxlZ2FsIGxvY2FsIGVycm9yIGNvZGUuICB0cmFuc2xhdGUgdG8gZ2VuZXJyIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogV1dXOiBmdWxsIHRyYW5zbGF0aW9uIG1hcD8gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiSWxsZWdhbCBlcnJvcl92YWx1ZSAlZCB0cmFuc2xhdGVkIHRvICVkXG4iLAogICAgICAgICAgICAgICAgICAgICBlcnJvcl92YWx1ZSwgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICAgICAgcmVxdWVzdC0+c3RhdHVzID0gU05NUF9FUlJfR0VORVJSOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFdXVzogdHJhbnNsYXRpb25zIGFuZCBtb2RlIGNoZWNraW5nPyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlcXVlc3QtPnN0YXR1cyA9IGVycm9yX3ZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdAogKiBAcGFyYW0gcmVxdWVzdCByZXF1ZXN0IHdoaWNoIGhhcyBlcnJvcgogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3QKICovCmludApuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICByZXR1cm4gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3QsIHJlcXVlc3QtPmFnZW50X3JlcV9pbmZvLT5tb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl92YWx1ZSk7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGEgcmVxdWVzdCB3aXRoaW4gYSByZXF1ZXN0IGxpc3QKICogQHBhcmFtIHJlcXVlc3QgaGVhZCBvZiB0aGUgcmVxdWVzdCBsaXN0CiAqIEBwYXJhbSBlcnJvcl92YWx1ZSBlcnJvciB2YWx1ZSBmb3IgcmVxdWVzdAogKiBAcGFyYW0gaWR4IGluZGV4IG9mIHRoZSByZXF1ZXN0IHdoaWNoIGhhcyB0aGUgZXJyb3IKICovCmludApuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yX2lkeChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVycm9yX3ZhbHVlLCBpbnQgaWR4KQp7CiAgICBpbnQgaTsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXEgPSByZXF1ZXN0OwoKICAgIGlmICghcmVxdWVzdCB8fCAhcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKCiAgICAvKgogICAgICogU2tpcCB0byB0aGUgaW5kaWNhdGVkIHZhcmJpbmQKICAgICAqLwogICAgZm9yICggaT0yOyBpPGlkeDsgaSsrKSB7CiAgICAgICAgcmVxID0gcmVxLT5uZXh0OwogICAgICAgIGlmICghcmVxKQogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9OT19WQVJTOwogICAgfQogICAgCiAgICByZXR1cm4gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcSwgcmVxdWVzdC0+YWdlbnRfcmVxX2luZm8tPm1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX3ZhbHVlKTsKfQoKLyoqIHNldCBlcnJvciBmb3IgYWxsIHJlcXVlc3RzCiAqIEBwYXJhbSByZXF1ZXN0cyByZXF1ZXN0IGxpc3QKICogQHBhcmFtIGVycm9yIGVycm9yIHZhbHVlIGZvciByZXF1ZXN0cwogKiBAcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUywgb3IgYW4gZXJyb3IgY29kZQogKi8KTkVUU05NUF9JTkxJTkUgaW50Cm5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3JfYWxsKCBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsIGludCBlcnJvcikKewogICAgaW50IG1vZGUsIHJjLCByZXN1bHQgPSBTTk1QRVJSX1NVQ0NFU1M7CgogICAgaWYoKE5VTEwgPT0gcmVxdWVzdHMpIHx8IChOVUxMID09IHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mbykpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfTk9fVkFSUzsKICAgIAogICAgbW9kZSA9IHJlcXVlc3RzLT5hZ2VudF9yZXFfaW5mby0+bW9kZTsgLyogZXZlcnkgcmVxIGhhcyBzYW1lIG1vZGUgKi8KICAgIAogICAgZm9yKDsgcmVxdWVzdHMgOyByZXF1ZXN0cyA9IHJlcXVlc3RzLT5uZXh0KSB7CgogICAgICAgIC8qKiBwYXJhbm9pZCBzYW5pdHkgY2hlY2tzICovCiAgICAgICAgbmV0c25tcF9hc3NlcnQoTlVMTCAhPSByZXF1ZXN0cy0+YWdlbnRfcmVxX2luZm8pOwogICAgICAgIG5ldHNubXBfYXNzZXJ0KG1vZGUgPT0gcmVxdWVzdHMtPmFnZW50X3JlcV9pbmZvLT5tb2RlKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBzZXQgZXJyb3IgZm9yIHRoaXMgcmVxdWVzdC4gTG9nIGFueSBlcnJvcnMsIHNhdmUgdGhlIGxhc3QKICAgICAgICAgKiB0byByZXR1cm4gdG8gdGhlIHVzZXIuCiAgICAgICAgICovCiAgICAgICAgaWYoKHJjID0gX3JlcXVlc3Rfc2V0X2Vycm9yKHJlcXVlc3RzLCBtb2RlLCBlcnJvcikpKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCJnb3QgJWQgd2hpbGUgc2V0dGluZyByZXF1ZXN0IGVycm9yXG4iLCByYyk7CiAgICAgICAgICAgIHJlc3VsdCA9IHJjOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qKgogKiBSZXR1cm4gdGhlIHZhbHVlIG9mICdzeXNVcFRpbWUnIGF0IHRoZSBnaXZlbiBtYXJrZXIKICoKICogQG5vdGUgVXNlIG5ldHNubXBfZ2V0X2FnZW50X3J1bnRpbWUoKSBpbnN0ZWFkIG9mIHRoaXMgZnVuY3Rpb24gaWYgeW91IG5lZWQKICogICB0byBrbm93IGhvdyBtdWNoIHRpbWUgZWxhcHNlZCBzaW5jZSBuZXRzbm1wX3NldF9hZ2VudF9zdGFydHRpbWUoKSBoYXMgYmVlbgogKiAgIGNhbGxlZC4KICovCnVfbG9uZwpuZXRzbm1wX21hcmtlcl91cHRpbWUobWFya2VyX3QgcG0pCnsKICAgIHVfbG9uZyAgICAgICAgICByZXM7CiAgICBjb25zdF9tYXJrZXJfdCAgc3RhcnQgPSBuZXRzbm1wX2dldF9hZ2VudF9zdGFydHRpbWUoKTsKCiAgICByZXMgPSB1YXRpbWVfaGRpZmYoc3RhcnQsIHBtKTsKICAgIHJldHVybiByZXM7Cn0KCiAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAqIHN0cnVjdCB0aW1ldmFsIGVxdWl2YWxlbnRzIG9mIHRoZXNlIAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KdV9sb25nCm5ldHNubXBfdGltZXZhbF91cHRpbWUoc3RydWN0IHRpbWV2YWwgKiB0dikKewogICAgcmV0dXJuIG5ldHNubXBfbWFya2VyX3VwdGltZSgobWFya2VyX3QpIHR2KTsKfQoKCnN0cnVjdCB0aW1ldmFsICBzdGFydHRpbWU7CgovKioKICogUmV0dXJuIGEgcG9pbnRlciB0byB0aGUgdmFyaWFibGUgaW4gd2hpY2ggdGhlIE5ldC1TTk1QIHN0YXJ0IHRpbWUgaGFzCiAqIGJlZW4gc3RvcmVkLgogKi8KY29uc3RfbWFya2VyX3QgICAgICAgIApuZXRzbm1wX2dldF9hZ2VudF9zdGFydHRpbWUodm9pZCkKewogICAgcmV0dXJuICZzdGFydHRpbWU7Cn0KCi8qKgogKiBSZXBvcnQgdGhlIHRpbWUgdGhhdCBlbGFwc2VkIHNpbmNlIHRoZSBhZ2VudCBzdGFydCB0aW1lIGluIGh1bmRyZWR0aHMgb2YgYQogKiBzZWNvbmQuCiAqCiAqIEBzZWUgU2VlIGFsc28gbmV0c25tcF9zZXRfYWdlbnRfc3RhcnR0aW1lKCkuCiAqLwp1aW50NjRfdApuZXRzbm1wX2dldF9hZ2VudF9ydW50aW1lKHZvaWQpCnsKICAgIHN0cnVjdCB0aW1ldmFsIG5vdywgZGVsdGE7CgogICAgZ2V0dGltZW9mZGF5KCZub3csIE5VTEwpOwogICAgTkVUU05NUF9USU1FUlNVQigmbm93LCAmc3RhcnR0aW1lLCAmZGVsdGEpOwogICAgcmV0dXJuIGRlbHRhLnR2X3NlYyAqICh1aW50NjRfdCkxMDAgKyBkZWx0YS50dl91c2VjIC8gMTAwMDA7Cn0KCi8qKgogKiBTZXQgdGhlIHRpbWUgYXQgd2hpY2ggTmV0LVNOTVAgc3RhcnRlZCBlaXRoZXIgdG8gdGhlIGN1cnJlbnQgdGltZQogKiAoaWYgcyA9PSBOVUxMKSBvciB0byAqcyAoaWYgcyBpcyBub3QgTlVMTCkuCiAqLwp2b2lkICAgICAgICAgICAgCm5ldHNubXBfc2V0X2FnZW50X3N0YXJ0dGltZShtYXJrZXJfdCBzKQp7CiAgICBpZiAocykKICAgICAgICBzdGFydHRpbWUgPSAqKHN0cnVjdCB0aW1ldmFsKilzOwogICAgZWxzZQogICAgICAgIGdldHRpbWVvZmRheSgmc3RhcnR0aW1lLCBOVUxMKTsKfQoKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogUmV0dXJuIHRoZSBjdXJyZW50IHZhbHVlIG9mICdzeXNVcFRpbWUnIAogICAgICAgICAgICAgICAgICovCnVfbG9uZwpuZXRzbm1wX2dldF9hZ2VudF91cHRpbWUodm9pZCkKewogICAgc3RydWN0IHRpbWV2YWwgIG5vdzsKICAgIGdldHRpbWVvZmRheSgmbm93LCBOVUxMKTsKCiAgICByZXR1cm4gbmV0c25tcF90aW1ldmFsX3VwdGltZSgmbm93KTsKfQoKdm9pZApuZXRzbm1wX3NldF9hZ2VudF91cHRpbWUodV9sb25nIGhzZWMpCnsKICAgIHN0cnVjdCB0aW1ldmFsICBub3c7CiAgICBzdHJ1Y3QgdGltZXZhbCAgbmV3X3VwdGltZTsKCiAgICBnZXR0aW1lb2ZkYXkoJm5vdywgTlVMTCk7CiAgICBuZXdfdXB0aW1lLnR2X3NlYyA9IGhzZWMgLyAxMDA7CiAgICBuZXdfdXB0aW1lLnR2X3VzZWMgPSAoaHNlYyAtIG5ld191cHRpbWUudHZfc2VjICogMTAwKSAqIDEwMDAwTDsKICAgIE5FVFNOTVBfVElNRVJTVUIoJm5vdywgJm5ld191cHRpbWUsICZzdGFydHRpbWUpOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogZGVwcmVjYXRlZCBmdW5jdGlvbnMKICoKICovCgovKiogc2V0IGVycm9yIGZvciBhIHJlcXVlc3QKICogXGRlcHJlY2F0ZWQsIHVzZSBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yIGluc3RlYWQKICogQHBhcmFtIHJlcWluZm8gYWdlbnRfcmVxdWVzdF9pbmZvIHBvaW50ZXIgZm9yIHJlcXVlc3QKICogQHBhcmFtIHJlcXVlc3QgcmVxdWVzdF9pbmZvIHBvaW50ZXIKICogQHBhcmFtIGVycm9yX3ZhbHVlIGVycm9yIHZhbHVlIGZvciByZXF1ZXN0cwogKiBAcmV0dXJuIGVycm9yX3ZhbHVlCiAqLwppbnQKbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwgaW50IGVycm9yX3ZhbHVlKQp7CiAgICBpZiAoIXJlcXVlc3QgfHwgIXJlcWluZm8pCiAgICAgICAgcmV0dXJuIGVycm9yX3ZhbHVlOwoKICAgIF9yZXF1ZXN0X3NldF9lcnJvcihyZXF1ZXN0LCByZXFpbmZvLT5tb2RlLCBlcnJvcl92YWx1ZSk7CiAgICAKICAgIHJldHVybiBlcnJvcl92YWx1ZTsKfQoKLyoqIHNldCBlcnJvciBmb3IgYSByZXF1ZXN0CiAqIFxkZXByZWNhdGVkLCB1c2UgbmV0c25tcF9yZXF1ZXN0X3NldF9lcnJvciBpbnN0ZWFkCiAqIEBwYXJhbSBtb2RlIE5ldC1TTk1QIGFnZW50IHByb2Nlc3NpbmcgbW9kZQogKiBAcGFyYW0gcmVxdWVzdCByZXF1ZXN0X2luZm8gcG9pbnRlcgogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3RzCiAqIEByZXR1cm4gZXJyb3JfdmFsdWUKICovCmludApuZXRzbm1wX3NldF9tb2RlX3JlcXVlc3RfZXJyb3IoaW50IG1vZGUsIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVycm9yX3ZhbHVlKQp7CiAgICBfcmVxdWVzdF9zZXRfZXJyb3IocmVxdWVzdCwgbW9kZSwgZXJyb3JfdmFsdWUpOwogICAgCiAgICByZXR1cm4gZXJyb3JfdmFsdWU7Cn0KCi8qKiBzZXQgZXJyb3IgZm9yIGFsbCByZXF1ZXN0CiAqIFxkZXByZWNhdGVkIHVzZSBuZXRzbm1wX3JlcXVlc3Rfc2V0X2Vycm9yX2FsbAogKiBAcGFyYW0gcmVxaW5mbyBhZ2VudF9yZXF1ZXN0X2luZm8gcG9pbnRlciBmb3IgcmVxdWVzdHMKICogQHBhcmFtIHJlcXVlc3RzIHJlcXVlc3QgbGlzdAogKiBAcGFyYW0gZXJyb3JfdmFsdWUgZXJyb3IgdmFsdWUgZm9yIHJlcXVlc3RzCiAqIEByZXR1cm4gZXJyb3JfdmFsdWUKICovCmludApuZXRzbm1wX3NldF9hbGxfcmVxdWVzdHNfZXJyb3IobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZXJyb3JfdmFsdWUpCnsKICAgIG5ldHNubXBfcmVxdWVzdF9zZXRfZXJyb3JfYWxsKHJlcXVlc3RzLCBlcnJvcl92YWx1ZSk7CiAgICByZXR1cm4gZXJyb3JfdmFsdWU7Cn0KLyoqIEB9ICovCg==