LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgovKgogKiB2YWNtLmMKICoKICogU05NUHYzIFZpZXctYmFzZWQgQWNjZXNzIENvbnRyb2wgTW9kZWwKICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCgojaWYgSEFWRV9ETUFMTE9DX0gKI2luY2x1ZGUgPGRtYWxsb2MuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvdHlwZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL291dHB1dF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2NvbmZpZ19hcGkuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3Rvb2xzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3ZhY20uaD4KCnN0YXRpYyBzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKnZpZXdMaXN0ID0gTlVMTCwgKnZpZXdTY2FuUHRyID0gTlVMTDsKc3RhdGljIHN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICphY2Nlc3NMaXN0ID0gTlVMTCwgKmFjY2Vzc1NjYW5QdHIgPSBOVUxMOwpzdGF0aWMgc3RydWN0IHZhY21fZ3JvdXBFbnRyeSAqZ3JvdXBMaXN0ID0gTlVMTCwgKmdyb3VwU2NhblB0ciA9IE5VTEw7CgovKgogKiBNYWNybyB0byBleHRlbmQgdmlldyBtYXNrcyB3aXRoIDEgYml0cyB3aGVuIHNob3J0ZXIgdGhhbiBzdWJ0cmVlIGxlbmd0aHMKICogUkVGOiB2YWNtVmlld1RyZWVGYW1pbHlNYXNrIFtSRkMzNDE1XSwgc25tcE5vdGlmeUZpbHRlck1hc2sgW1JGQzM0MTNdCiAqLwoKI2RlZmluZSBWSUVXX01BU0sodmlld1B0ciwgaWR4LCBtYXNrKSBcCiAgICAoKGlkeCA+PSB2aWV3UHRyLT52aWV3TWFza0xlbikgPyBtYXNrIDogKHZpZXdQdHItPnZpZXdNYXNrW2lkeF0gJiBtYXNrKSkKCi8qKgogKiBJbml0aWxpemVzIHRoZSBWQUNNIGNvZGUuCiAqIFNwZWNpZmljYWxseToKICogIC0gYWRkcyBhIHNldCBvZiBlbnVtcyBtYXBwaW5nIHZpZXcgbnVtYmVycyB0byBodW1hbiByZWFkYWJsZSBuYW1lcwogKi8Kdm9pZAppbml0X3ZhY20odm9pZCkKewogICAgLyogdmlld3MgZm9yIGFjY2VzcyB2aWEgZ2V0L3NldC9zZW5kLW5vdGlmaWNhdGlvbnMgKi8KICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KFZBQ01fVklFV19FTlVNX05BTUUsIHN0cmR1cCgicmVhZCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgVkFDTV9WSUVXX1JFQUQpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoVkFDTV9WSUVXX0VOVU1fTkFNRSwgc3RyZHVwKCJ3cml0ZSIpLAogICAgICAgICAgICAgICAgICAgICAgICAgVkFDTV9WSUVXX1dSSVRFKTsKICAgIHNlX2FkZF9wYWlyX3RvX3NsaXN0KFZBQ01fVklFV19FTlVNX05BTUUsIHN0cmR1cCgibm90aWZ5IiksCiAgICAgICAgICAgICAgICAgICAgICAgICBWQUNNX1ZJRVdfTk9USUZZKTsKCiAgICAvKiB2aWV3cyBmb3IgcGVybWlzc2lvbnMgd2hlbiByZWNlaXZpbmcgbm90aWZpY2F0aW9ucyAqLwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoVkFDTV9WSUVXX0VOVU1fTkFNRSwgc3RyZHVwKCJsb2ciKSwKICAgICAgICAgICAgICAgICAgICAgICAgIFZBQ01fVklFV19MT0cpOwogICAgc2VfYWRkX3BhaXJfdG9fc2xpc3QoVkFDTV9WSUVXX0VOVU1fTkFNRSwgc3RyZHVwKCJleGVjdXRlIiksCiAgICAgICAgICAgICAgICAgICAgICAgICBWQUNNX1ZJRVdfRVhFQ1VURSk7CiAgICBzZV9hZGRfcGFpcl90b19zbGlzdChWQUNNX1ZJRVdfRU5VTV9OQU1FLCBzdHJkdXAoIm5ldCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgVkFDTV9WSUVXX05FVCk7Cn0KCnZvaWQKdmFjbV9zYXZlKGNvbnN0IGNoYXIgKnRva2VuLCBjb25zdCBjaGFyICp0eXBlKQp7CiAgICBzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKnZwdHI7CiAgICBzdHJ1Y3QgdmFjbV9hY2Nlc3NFbnRyeSAqYXB0cjsKICAgIHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKmdwdHI7CiAgICBpbnQgaTsKCiAgICBmb3IgKHZwdHIgPSB2aWV3TGlzdDsgdnB0ciAhPSBOVUxMOyB2cHRyID0gdnB0ci0+bmV4dCkgewogICAgICAgIGlmICh2cHRyLT52aWV3U3RvcmFnZVR5cGUgPT0gU1RfTk9OVk9MQVRJTEUpCiAgICAgICAgICAgIHZhY21fc2F2ZV92aWV3KHZwdHIsIHRva2VuLCB0eXBlKTsKICAgIH0KCiAgICBmb3IgKGFwdHIgPSBhY2Nlc3NMaXN0OyBhcHRyICE9IE5VTEw7IGFwdHIgPSBhcHRyLT5uZXh0KSB7CiAgICAgICAgaWYgKGFwdHItPnN0b3JhZ2VUeXBlID09IFNUX05PTlZPTEFUSUxFKSB7CiAgICAgICAgICAgIC8qIFN0b3JlIHRoZSBzdGFuZGFyZCB2aWV3cyAoaWYgc2V0KSAqLwogICAgICAgICAgICBpZiAoIGFwdHItPnZpZXdzW1ZBQ01fVklFV19SRUFEICBdWzBdIHx8CiAgICAgICAgICAgICAgICAgYXB0ci0+dmlld3NbVkFDTV9WSUVXX1dSSVRFIF1bMF0gfHwKICAgICAgICAgICAgICAgICBhcHRyLT52aWV3c1tWQUNNX1ZJRVdfTk9USUZZXVswXSApCiAgICAgICAgICAgICAgICB2YWNtX3NhdmVfYWNjZXNzKGFwdHIsIHRva2VuLCB0eXBlKTsKICAgICAgICAgICAgLyogU3RvcmUgYW55IG90aGVyICh2YWxpZCkgYWNjZXNzIHZpZXdzICovCiAgICAgICAgICAgIGZvciAoIGk9VkFDTV9WSUVXX05PVElGWSsxOyBpPFZBQ01fTUFYX1ZJRVdTOyBpKysgKSB7CiAgICAgICAgICAgICAgICBpZiAoIGFwdHItPnZpZXdzW2ldWzBdICkKICAgICAgICAgICAgICAgICAgICB2YWNtX3NhdmVfYXV0aF9hY2Nlc3MoYXB0ciwgdG9rZW4sIHR5cGUsIGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGZvciAoZ3B0ciA9IGdyb3VwTGlzdDsgZ3B0ciAhPSBOVUxMOyBncHRyID0gZ3B0ci0+bmV4dCkgewogICAgICAgIGlmIChncHRyLT5zdG9yYWdlVHlwZSA9PSBTVF9OT05WT0xBVElMRSkKICAgICAgICAgICAgdmFjbV9zYXZlX2dyb3VwKGdwdHIsIHRva2VuLCB0eXBlKTsKICAgIH0KfQoKLyoKICogdmFjbV9zYXZlX3ZpZXcoKTogc2F2ZXMgYSB2aWV3IGVudHJ5IHRvIHRoZSBwZXJzaXN0ZW50IGNhY2hlIAogKi8Kdm9pZAp2YWNtX3NhdmVfdmlldyhzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKnZpZXcsIGNvbnN0IGNoYXIgKnRva2VuLAogICAgICAgICAgICAgICBjb25zdCBjaGFyICp0eXBlKQp7CiAgICBjaGFyICAgICAgICAgICAgbGluZVs0MDk2XTsKICAgIGNoYXIgICAgICAgICAgICpjcHRyOwoKICAgIG1lbXNldChsaW5lLCAwLCBzaXplb2YobGluZSkpOwogICAgc25wcmludGYobGluZSwgc2l6ZW9mKGxpbmUpLCAiJXMlcyAlZCAlZCAlZCAiLCB0b2tlbiwgIlZpZXciLAogICAgICAgICAgICB2aWV3LT52aWV3U3RhdHVzLCB2aWV3LT52aWV3U3RvcmFnZVR5cGUsIHZpZXctPnZpZXdUeXBlKTsKICAgIGxpbmVbIHNpemVvZihsaW5lKS0xIF0gPSAwOwogICAgY3B0ciA9ICZsaW5lW3N0cmxlbihsaW5lKV07IC8qIHRoZSBOVUxMICovCgogICAgY3B0ciA9CiAgICAgICAgcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoY3B0ciwgKHVfY2hhciAqKSB2aWV3LT52aWV3TmFtZSArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlldy0+dmlld05hbWVbMF0pOwogICAgKmNwdHIrKyA9ICcgJzsKICAgIGNwdHIgPQogICAgICAgIHJlYWRfY29uZmlnX3NhdmVfb2JqaWQoY3B0ciwgdmlldy0+dmlld1N1YnRyZWUrMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXctPnZpZXdTdWJ0cmVlTGVuLTEpOwogICAgKmNwdHIrKyA9ICcgJzsKICAgIGNwdHIgPSByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjcHRyLCAodV9jaGFyICopIHZpZXctPnZpZXdNYXNrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXctPnZpZXdNYXNrTGVuKTsKCiAgICByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBsaW5lKTsKfQoKdm9pZAp2YWNtX3BhcnNlX2NvbmZpZ192aWV3KGNvbnN0IGNoYXIgKnRva2VuLCBjb25zdCBjaGFyICpsaW5lKQp7CiAgICBzdHJ1Y3QgdmFjbV92aWV3RW50cnkgdmlldzsKICAgIHN0cnVjdCB2YWNtX3ZpZXdFbnRyeSAqdnB0cjsKICAgIGNoYXIgICAgICAgICAgICp2aWV3TmFtZSA9IChjaGFyICopICZ2aWV3LnZpZXdOYW1lOwogICAgb2lkICAgICAgICAgICAgKnZpZXdTdWJ0cmVlID0gKG9pZCAqKSAmIHZpZXcudmlld1N1YnRyZWU7CiAgICB1X2NoYXIgICAgICAgICAqdmlld01hc2s7CiAgICBzaXplX3QgICAgICAgICAgbGVuOwoKICAgIHZpZXcudmlld1N0YXR1cyA9IGF0b2kobGluZSk7CiAgICBsaW5lID0gc2tpcF90b2tlbl9jb25zdChsaW5lKTsKICAgIHZpZXcudmlld1N0b3JhZ2VUeXBlID0gYXRvaShsaW5lKTsKICAgIGxpbmUgPSBza2lwX3Rva2VuX2NvbnN0KGxpbmUpOwogICAgdmlldy52aWV3VHlwZSA9IGF0b2kobGluZSk7CiAgICBsaW5lID0gc2tpcF90b2tlbl9jb25zdChsaW5lKTsKICAgIGxlbiA9IHNpemVvZih2aWV3LnZpZXdOYW1lKTsKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGxpbmUsICh1X2NoYXIgKiopICYgdmlld05hbWUsICZsZW4pOwogICAgdmlldy52aWV3U3VidHJlZUxlbiA9IE1BWF9PSURfTEVOOwogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vYmppZF9jb25zdChsaW5lLCAob2lkICoqKSAmIHZpZXdTdWJ0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZpZXcudmlld1N1YnRyZWVMZW4pOwoKICAgIHZwdHIgPQogICAgICAgIHZhY21fY3JlYXRlVmlld0VudHJ5KHZpZXcudmlld05hbWUsIHZpZXcudmlld1N1YnRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlldy52aWV3U3VidHJlZUxlbik7CiAgICBpZiAoIXZwdHIpIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdnB0ci0+dmlld1N0YXR1cyA9IHZpZXcudmlld1N0YXR1czsKICAgIHZwdHItPnZpZXdTdG9yYWdlVHlwZSA9IHZpZXcudmlld1N0b3JhZ2VUeXBlOwogICAgdnB0ci0+dmlld1R5cGUgPSB2aWV3LnZpZXdUeXBlOwogICAgdmlld01hc2sgPSB2cHRyLT52aWV3TWFzazsKICAgIHZwdHItPnZpZXdNYXNrTGVuID0gc2l6ZW9mKHZwdHItPnZpZXdNYXNrKTsKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGxpbmUsICZ2aWV3TWFzaywgJnZwdHItPnZpZXdNYXNrTGVuKTsKfQoKLyoKICogdmFjbV9zYXZlX2FjY2VzcygpOiBzYXZlcyBhbiBhY2Nlc3MgZW50cnkgdG8gdGhlIHBlcnNpc3RlbnQgY2FjaGUgCiAqLwp2b2lkCnZhY21fc2F2ZV9hY2Nlc3Moc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKmFjY2Vzc19lbnRyeSwgY29uc3QgY2hhciAqdG9rZW4sCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdHlwZSkKewogICAgY2hhciAgICAgICAgICAgIGxpbmVbNDA5Nl07CiAgICBjaGFyICAgICAgICAgICAqY3B0cjsKCiAgICBtZW1zZXQobGluZSwgMCwgc2l6ZW9mKGxpbmUpKTsKICAgIHNucHJpbnRmKGxpbmUsIHNpemVvZihsaW5lKSwgIiVzJXMgJWQgJWQgJWQgJWQgJWQgIiwKICAgICAgICAgICAgdG9rZW4sICJBY2Nlc3MiLCBhY2Nlc3NfZW50cnktPnN0YXR1cywKICAgICAgICAgICAgYWNjZXNzX2VudHJ5LT5zdG9yYWdlVHlwZSwgYWNjZXNzX2VudHJ5LT5zZWN1cml0eU1vZGVsLAogICAgICAgICAgICBhY2Nlc3NfZW50cnktPnNlY3VyaXR5TGV2ZWwsIGFjY2Vzc19lbnRyeS0+Y29udGV4dE1hdGNoKTsKICAgIGxpbmVbIHNpemVvZihsaW5lKS0xIF0gPSAwOwogICAgY3B0ciA9ICZsaW5lW3N0cmxlbihsaW5lKV07IC8qIHRoZSBOVUxMICovCiAgICBjcHRyID0KICAgICAgICByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgYWNjZXNzX2VudHJ5LT5ncm91cE5hbWUgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc19lbnRyeS0+Z3JvdXBOYW1lWzBdICsgMSk7CiAgICAqY3B0cisrID0gJyAnOwogICAgY3B0ciA9CiAgICAgICAgcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIGFjY2Vzc19lbnRyeS0+Y29udGV4dFByZWZpeCArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzX2VudHJ5LT5jb250ZXh0UHJlZml4WzBdICsgMSk7CgogICAgKmNwdHIrKyA9ICcgJzsKICAgIGNwdHIgPSByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjcHRyLCAodV9jaGFyICopIGFjY2Vzc19lbnRyeS0+dmlld3NbVkFDTV9WSUVXX1JFQURdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihhY2Nlc3NfZW50cnktPnZpZXdzW1ZBQ01fVklFV19SRUFEXSkgKyAxKTsKICAgICpjcHRyKysgPSAnICc7CiAgICBjcHRyID0KICAgICAgICByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjcHRyLCAodV9jaGFyICopIGFjY2Vzc19lbnRyeS0+dmlld3NbVkFDTV9WSUVXX1dSSVRFXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oYWNjZXNzX2VudHJ5LT52aWV3c1tWQUNNX1ZJRVdfV1JJVEVdKSArIDEpOwogICAgKmNwdHIrKyA9ICcgJzsKICAgIGNwdHIgPQogICAgICAgIHJlYWRfY29uZmlnX3NhdmVfb2N0ZXRfc3RyaW5nKGNwdHIsICh1X2NoYXIgKikgYWNjZXNzX2VudHJ5LT52aWV3c1tWQUNNX1ZJRVdfTk9USUZZXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW4oYWNjZXNzX2VudHJ5LT52aWV3c1tWQUNNX1ZJRVdfTk9USUZZXSkgKyAxKTsKCiAgICByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBsaW5lKTsKfQoKdm9pZAp2YWNtX3NhdmVfYXV0aF9hY2Nlc3Moc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKmFjY2Vzc19lbnRyeSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRva2VuLCBjb25zdCBjaGFyICp0eXBlLCBpbnQgYXV0aHR5cGUpCnsKICAgIGNoYXIgICAgICAgICAgICBsaW5lWzQwOTZdOwogICAgY2hhciAgICAgICAgICAgKmNwdHI7CgogICAgbWVtc2V0KGxpbmUsIDAsIHNpemVvZihsaW5lKSk7CiAgICBzbnByaW50ZihsaW5lLCBzaXplb2YobGluZSksICIlcyVzICVkICVkICVkICVkICVkICIsCiAgICAgICAgICAgIHRva2VuLCAiQXV0aEFjY2VzcyIsIGFjY2Vzc19lbnRyeS0+c3RhdHVzLAogICAgICAgICAgICBhY2Nlc3NfZW50cnktPnN0b3JhZ2VUeXBlLCBhY2Nlc3NfZW50cnktPnNlY3VyaXR5TW9kZWwsCiAgICAgICAgICAgIGFjY2Vzc19lbnRyeS0+c2VjdXJpdHlMZXZlbCwgYWNjZXNzX2VudHJ5LT5jb250ZXh0TWF0Y2gpOwogICAgbGluZVsgc2l6ZW9mKGxpbmUpLTEgXSA9IDA7CiAgICBjcHRyID0gJmxpbmVbc3RybGVuKGxpbmUpXTsgLyogdGhlIE5VTEwgKi8KICAgIGNwdHIgPQogICAgICAgIHJlYWRfY29uZmlnX3NhdmVfb2N0ZXRfc3RyaW5nKGNwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSBhY2Nlc3NfZW50cnktPmdyb3VwTmFtZSArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzX2VudHJ5LT5ncm91cE5hbWVbMF0gKyAxKTsKICAgICpjcHRyKysgPSAnICc7CiAgICBjcHRyID0KICAgICAgICByZWFkX2NvbmZpZ19zYXZlX29jdGV0X3N0cmluZyhjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgYWNjZXNzX2VudHJ5LT5jb250ZXh0UHJlZml4ICsgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NfZW50cnktPmNvbnRleHRQcmVmaXhbMF0gKyAxKTsKCiAgICBzbnByaW50ZihjcHRyLCBzaXplb2YobGluZSktKGNwdHItbGluZSksICIgJWQgIiwgYXV0aHR5cGUpOwogICAgd2hpbGUgKCAqY3B0ciApCiAgICAgICAgY3B0cisrOwoKICAgICpjcHRyKysgPSAnICc7CiAgICBjcHRyID0gcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKilhY2Nlc3NfZW50cnktPnZpZXdzW2F1dGh0eXBlXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihhY2Nlc3NfZW50cnktPnZpZXdzW2F1dGh0eXBlXSkgKyAxKTsKCiAgICByZWFkX2NvbmZpZ19zdG9yZSh0eXBlLCBsaW5lKTsKfQoKY2hhciAqCl92YWNtX3BhcnNlX2NvbmZpZ19hY2Nlc3NfY29tbW9uKHN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICoqYXB0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbGluZSkKewogICAgc3RydWN0IHZhY21fYWNjZXNzRW50cnkgYWNjZXNzOwogICAgY2hhciAgICAgICAgICAgKmNQcmVmaXggPSAoY2hhciAqKSAmYWNjZXNzLmNvbnRleHRQcmVmaXg7CiAgICBjaGFyICAgICAgICAgICAqZ05hbWUgICA9IChjaGFyICopICZhY2Nlc3MuZ3JvdXBOYW1lOwogICAgc2l6ZV90ICAgICAgICAgIGxlbjsKCiAgICBhY2Nlc3Muc3RhdHVzID0gYXRvaShsaW5lKTsKICAgIGxpbmUgPSBza2lwX3Rva2VuX2NvbnN0KGxpbmUpOwogICAgYWNjZXNzLnN0b3JhZ2VUeXBlID0gYXRvaShsaW5lKTsKICAgIGxpbmUgPSBza2lwX3Rva2VuX2NvbnN0KGxpbmUpOwogICAgYWNjZXNzLnNlY3VyaXR5TW9kZWwgPSBhdG9pKGxpbmUpOwogICAgbGluZSA9IHNraXBfdG9rZW5fY29uc3QobGluZSk7CiAgICBhY2Nlc3Muc2VjdXJpdHlMZXZlbCA9IGF0b2kobGluZSk7CiAgICBsaW5lID0gc2tpcF90b2tlbl9jb25zdChsaW5lKTsKICAgIGFjY2Vzcy5jb250ZXh0TWF0Y2ggPSBhdG9pKGxpbmUpOwogICAgbGluZSA9IHNraXBfdG9rZW5fY29uc3QobGluZSk7CiAgICBsZW4gID0gc2l6ZW9mKGFjY2Vzcy5ncm91cE5hbWUpOwogICAgbGluZSA9IHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGxpbmUsICh1X2NoYXIgKiopICZnTmFtZSwgICAmbGVuKTsKICAgIGxlbiAgPSBzaXplb2YoYWNjZXNzLmNvbnRleHRQcmVmaXgpOwogICAgbGluZSA9IHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGxpbmUsICh1X2NoYXIgKiopICZjUHJlZml4LCAmbGVuKTsKCiAgICAqYXB0ciA9IHZhY21fZ2V0QWNjZXNzRW50cnkoYWNjZXNzLmdyb3VwTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzcy5jb250ZXh0UHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzLnNlY3VyaXR5TW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Muc2VjdXJpdHlMZXZlbCk7CiAgICBpZiAoISphcHRyKQogICAgICAgICphcHRyID0gdmFjbV9jcmVhdGVBY2Nlc3NFbnRyeShhY2Nlc3MuZ3JvdXBOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWNjZXNzLmNvbnRleHRQcmVmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3Muc2VjdXJpdHlNb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzcy5zZWN1cml0eUxldmVsKTsKICAgIGlmICghKmFwdHIpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgKCphcHRyKS0+c3RhdHVzID0gYWNjZXNzLnN0YXR1czsKICAgICgqYXB0ciktPnN0b3JhZ2VUeXBlICAgPSBhY2Nlc3Muc3RvcmFnZVR5cGU7CiAgICAoKmFwdHIpLT5zZWN1cml0eU1vZGVsID0gYWNjZXNzLnNlY3VyaXR5TW9kZWw7CiAgICAoKmFwdHIpLT5zZWN1cml0eUxldmVsID0gYWNjZXNzLnNlY3VyaXR5TGV2ZWw7CiAgICAoKmFwdHIpLT5jb250ZXh0TWF0Y2ggID0gYWNjZXNzLmNvbnRleHRNYXRjaDsKICAgIHJldHVybiBORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyICosIGxpbmUpOwp9Cgp2b2lkCnZhY21fcGFyc2VfY29uZmlnX2FjY2Vzcyhjb25zdCBjaGFyICp0b2tlbiwgY29uc3QgY2hhciAqbGluZSkKewogICAgc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKmFwdHI7CiAgICBjaGFyICAgICAgICAgICAqcmVhZFZpZXcsICp3cml0ZVZpZXcsICpub3RpZnlWaWV3OwogICAgc2l6ZV90ICAgICAgICAgIGxlbjsKCiAgICBsaW5lID0gX3ZhY21fcGFyc2VfY29uZmlnX2FjY2Vzc19jb21tb24oJmFwdHIsIGxpbmUpOwogICAgaWYgKCFsaW5lKQogICAgICAgIHJldHVybjsKCiAgICByZWFkVmlldyA9IChjaGFyICopIGFwdHItPnZpZXdzW1ZBQ01fVklFV19SRUFEXTsKICAgIGxlbiA9IHNpemVvZihhcHRyLT52aWV3c1tWQUNNX1ZJRVdfUkVBRF0pOwogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmcobGluZSwgKHVfY2hhciAqKikgJiByZWFkVmlldywgJmxlbik7CiAgICB3cml0ZVZpZXcgPSAoY2hhciAqKSBhcHRyLT52aWV3c1tWQUNNX1ZJRVdfV1JJVEVdOwogICAgbGVuID0gc2l6ZW9mKGFwdHItPnZpZXdzW1ZBQ01fVklFV19XUklURV0pOwogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vY3RldF9zdHJpbmcobGluZSwgKHVfY2hhciAqKikgJiB3cml0ZVZpZXcsICZsZW4pOwogICAgbm90aWZ5VmlldyA9IChjaGFyICopIGFwdHItPnZpZXdzW1ZBQ01fVklFV19OT1RJRlldOwogICAgbGVuID0gc2l6ZW9mKGFwdHItPnZpZXdzW1ZBQ01fVklFV19OT1RJRlldKTsKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGxpbmUsICh1X2NoYXIgKiopICYgbm90aWZ5VmlldywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKTsKfQoKdm9pZAp2YWNtX3BhcnNlX2NvbmZpZ19hdXRoX2FjY2Vzcyhjb25zdCBjaGFyICp0b2tlbiwgY29uc3QgY2hhciAqbGluZSkKewogICAgc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKmFwdHI7CiAgICBpbnQgICAgICAgICAgICAgYXV0aHR5cGU7CiAgICBjaGFyICAgICAgICAgICAqdmlldzsKICAgIHNpemVfdCAgICAgICAgICBsZW47CgogICAgbGluZSA9IF92YWNtX3BhcnNlX2NvbmZpZ19hY2Nlc3NfY29tbW9uKCZhcHRyLCBsaW5lKTsKICAgIGlmICghbGluZSkKICAgICAgICByZXR1cm47CgogICAgYXV0aHR5cGUgPSBhdG9pKGxpbmUpOwogICAgbGluZSA9IHNraXBfdG9rZW5fY29uc3QobGluZSk7CgogICAgdmlldyA9IChjaGFyICopIGFwdHItPnZpZXdzW2F1dGh0eXBlXTsKICAgIGxlbiAgPSBzaXplb2YoYXB0ci0+dmlld3NbYXV0aHR5cGVdKTsKICAgIGxpbmUgPSByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyhsaW5lLCAodV9jaGFyICoqKSAmIHZpZXcsICZsZW4pOwp9CgovKgogKiB2YWNtX3NhdmVfZ3JvdXAoKTogc2F2ZXMgYSBncm91cCBlbnRyeSB0byB0aGUgcGVyc2lzdGVudCBjYWNoZSAKICovCnZvaWQKdmFjbV9zYXZlX2dyb3VwKHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKmdyb3VwX2VudHJ5LCBjb25zdCBjaGFyICp0b2tlbiwKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIGNoYXIgICAgICAgICAgICBsaW5lWzQwOTZdOwogICAgY2hhciAgICAgICAgICAgKmNwdHI7CgogICAgbWVtc2V0KGxpbmUsIDAsIHNpemVvZihsaW5lKSk7CiAgICBzbnByaW50ZihsaW5lLCBzaXplb2YobGluZSksICIlcyVzICVkICVkICVkICIsCiAgICAgICAgICAgIHRva2VuLCAiR3JvdXAiLCBncm91cF9lbnRyeS0+c3RhdHVzLAogICAgICAgICAgICBncm91cF9lbnRyeS0+c3RvcmFnZVR5cGUsIGdyb3VwX2VudHJ5LT5zZWN1cml0eU1vZGVsKTsKICAgIGxpbmVbIHNpemVvZihsaW5lKS0xIF0gPSAwOwogICAgY3B0ciA9ICZsaW5lW3N0cmxlbihsaW5lKV07IC8qIHRoZSBOVUxMICovCgogICAgY3B0ciA9CiAgICAgICAgcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIGdyb3VwX2VudHJ5LT5zZWN1cml0eU5hbWUgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2VudHJ5LT5zZWN1cml0eU5hbWVbMF0gKyAxKTsKICAgICpjcHRyKysgPSAnICc7CiAgICBjcHRyID0gcmVhZF9jb25maWdfc2F2ZV9vY3RldF9zdHJpbmcoY3B0ciwgKHVfY2hhciAqKSBncm91cF9lbnRyeS0+Z3JvdXBOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbihncm91cF9lbnRyeS0+Z3JvdXBOYW1lKSArIDEpOwoKICAgIHJlYWRfY29uZmlnX3N0b3JlKHR5cGUsIGxpbmUpOwp9Cgp2b2lkCnZhY21fcGFyc2VfY29uZmlnX2dyb3VwKGNvbnN0IGNoYXIgKnRva2VuLCBjb25zdCBjaGFyICpsaW5lKQp7CiAgICBzdHJ1Y3QgdmFjbV9ncm91cEVudHJ5IGdyb3VwOwogICAgc3RydWN0IHZhY21fZ3JvdXBFbnRyeSAqZ3B0cjsKICAgIGNoYXIgICAgICAgICAgICpzZWN1cml0eU5hbWUgPSAoY2hhciAqKSAmZ3JvdXAuc2VjdXJpdHlOYW1lOwogICAgY2hhciAgICAgICAgICAgKmdyb3VwTmFtZTsKICAgIHNpemVfdCAgICAgICAgICBsZW47CgogICAgZ3JvdXAuc3RhdHVzID0gYXRvaShsaW5lKTsKICAgIGxpbmUgPSBza2lwX3Rva2VuX2NvbnN0KGxpbmUpOwogICAgZ3JvdXAuc3RvcmFnZVR5cGUgPSBhdG9pKGxpbmUpOwogICAgbGluZSA9IHNraXBfdG9rZW5fY29uc3QobGluZSk7CiAgICBncm91cC5zZWN1cml0eU1vZGVsID0gYXRvaShsaW5lKTsKICAgIGxpbmUgPSBza2lwX3Rva2VuX2NvbnN0KGxpbmUpOwogICAgbGVuID0gc2l6ZW9mKGdyb3VwLnNlY3VyaXR5TmFtZSk7CiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX29jdGV0X3N0cmluZyhsaW5lLCAodV9jaGFyICoqKSAmIHNlY3VyaXR5TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKTsKCiAgICBncHRyID0gdmFjbV9jcmVhdGVHcm91cEVudHJ5KGdyb3VwLnNlY3VyaXR5TW9kZWwsIGdyb3VwLnNlY3VyaXR5TmFtZSk7CiAgICBpZiAoIWdwdHIpCiAgICAgICAgcmV0dXJuOwoKICAgIGdwdHItPnN0YXR1cyA9IGdyb3VwLnN0YXR1czsKICAgIGdwdHItPnN0b3JhZ2VUeXBlID0gZ3JvdXAuc3RvcmFnZVR5cGU7CiAgICBncm91cE5hbWUgPSAoY2hhciAqKSBncHRyLT5ncm91cE5hbWU7CiAgICBsZW4gPSBzaXplb2YoZ3JvdXAuZ3JvdXBOYW1lKTsKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2N0ZXRfc3RyaW5nKGxpbmUsICh1X2NoYXIgKiopICYgZ3JvdXBOYW1lLCAmbGVuKTsKfQoKc3RydWN0IHZhY21fdmlld0VudHJ5ICoKbmV0c25tcF92aWV3X2dldChzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKmhlYWQsIGNvbnN0IGNoYXIgKnZpZXdOYW1lLAogICAgICAgICAgICAgICAgICBvaWQgKiB2aWV3U3VidHJlZSwgc2l6ZV90IHZpZXdTdWJ0cmVlTGVuLCBpbnQgbW9kZSkKewogICAgc3RydWN0IHZhY21fdmlld0VudHJ5ICp2cCwgKnZwcmV0ID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICB2aWV3W1ZBQ01TVFJJTkdMRU5dOwogICAgaW50ICAgICAgICAgICAgIGZvdW5kLCBnbGVuOwogICAgaW50IGNvdW50PTA7CgogICAgZ2xlbiA9IChpbnQpIHN0cmxlbih2aWV3TmFtZSk7CiAgICBpZiAoZ2xlbiA8IDAgfHwgZ2xlbiA+IFZBQ01fTUFYX1NUUklORykKICAgICAgICByZXR1cm4gTlVMTDsKICAgIHZpZXdbMF0gPSBnbGVuOwogICAgc3RyY3B5KHZpZXcgKyAxLCB2aWV3TmFtZSk7CiAgICBmb3IgKHZwID0gaGVhZDsgdnA7IHZwID0gdnAtPm5leHQpIHsKICAgICAgICBpZiAoIW1lbWNtcCh2aWV3LCB2cC0+dmlld05hbWUsIGdsZW4gKyAxKQogICAgICAgICAgICAmJiB2aWV3U3VidHJlZUxlbiA+PSAodnAtPnZpZXdTdWJ0cmVlTGVuIC0gMSkpIHsKICAgICAgICAgICAgaW50ICAgICAgICAgICAgIG1hc2sgPSAweDgwOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgICAgb2lkcG9zLCBtYXNrcG9zID0gMDsKICAgICAgICAgICAgZm91bmQgPSAxOwoKICAgICAgICAgICAgZm9yIChvaWRwb3MgPSAwOwogICAgICAgICAgICAgICAgIGZvdW5kICYmIG9pZHBvcyA8IHZwLT52aWV3U3VidHJlZUxlbiAtIDE7CiAgICAgICAgICAgICAgICAgb2lkcG9zKyspIHsKICAgICAgICAgICAgICAgIGlmIChtb2RlPT1WQUNNX01PREVfSUdOT1JFX01BU0sgfHwgKFZJRVdfTUFTSyh2cCwgbWFza3BvcywgbWFzaykgIT0gMCkpIHsKICAgICAgICAgICAgICAgICAgICBpZiAodmlld1N1YnRyZWVbb2lkcG9zXSAhPQogICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmlld1N1YnRyZWVbb2lkcG9zICsgMV0pCiAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChtYXNrID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBtYXNrID0gMHg4MDsKICAgICAgICAgICAgICAgICAgICBtYXNrcG9zKys7CiAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBtYXNrID4+PSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZm91bmQpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBtYXRjaCBzdWNjZXNzZnVsLCBrZWVwIHRoaXMgbm9kZSBpZiBpdHMgbG9uZ2VyIHRoYW4KICAgICAgICAgICAgICAgICAqIHRoZSBwcmV2aW91cyBvciAoZXF1YWwgYW5kIGxleGljb2dyYXBoaWNhbGx5IGdyZWF0ZXIKICAgICAgICAgICAgICAgICAqIHRoYW4gdGhlIHByZXZpb3VzKS4gCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGNvdW50Kys7CiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PSBWQUNNX01PREVfQ0hFQ0tfU1VCVFJFRSkgewogICAgICAgICAgICAgICAgICAgIHZwcmV0ID0gdnA7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZwcmV0ID09IE5VTEwKICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgdnAtPnZpZXdTdWJ0cmVlTGVuID4gdnByZXQtPnZpZXdTdWJ0cmVlTGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8ICh2cC0+dmlld1N1YnRyZWVMZW4gPT0gdnByZXQtPnZpZXdTdWJ0cmVlTGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBzbm1wX29pZF9jb21wYXJlKHZwLT52aWV3U3VidHJlZSArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT52aWV3U3VidHJlZUxlbiAtIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwcmV0LT52aWV3U3VidHJlZSArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwcmV0LT52aWV3U3VidHJlZUxlbiAtIDEpID4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApKSB7CiAgICAgICAgICAgICAgICAgICAgdnByZXQgPSB2cDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIERFQlVHTVNHVEwoKCJ2YWNtOmdldFZpZXciLCAiLCAlc1xuIiwgKHZwcmV0KSA/ICJmb3VuZCIgOiAibm9uZSIpKTsKICAgIGlmIChtb2RlID09IFZBQ01fTU9ERV9DSEVDS19TVUJUUkVFICYmIGNvdW50ID4gMSkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgcmV0dXJuIHZwcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKm8tbyoqKioqKgogKiB2YWNtX2NoZWNrU3VidHJlZQogKgogKiBDaGVjayB0byBzZWUgaWYgZXZlcnl0aGluZyB3aXRoaW4gYSBzdWJ0cmVlIGlzIGluIHZpZXcsIG5vdCBpbiB2aWV3LAogKiBvciBwb3NzaWJseSBib3RoLgogKgogKiBQYXJhbWV0ZXJzOgogKiAgICp2aWV3TmFtZSAgICAgICAgICAgLSBOYW1lIG9mIHZpZXcgdG8gY2hlY2sKICogICAqdmlld1N1YnRyZWUgICAgICAgIC0gT0lEIG9mIHN1YnRyZWUKICogICAgdmlld1N1YnRyZWVMZW4gICAgIC0gbGVuZ3RoIG9mIHN1YnRyZWUgT0lECiAqICAgICAgCiAqIFJldHVybnM6CiAqICAgVkFDTV9TVUNDRVNTICAgICAgICAgIFRoZSBPSUQgaXMgaW5jbHVkZWQgaW4gdGhlIHZpZXcuCiAqICAgVkFDTV9OT1RJTlZJRVcgICAgICAgIElmIG5vIGVudHJ5IGluIHRoZSB2aWV3IGxpc3QgaW5jbHVkZXMgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHByb3ZpZGVkIE9JRCwgb3IgdGhlIE9JRCBpcyBleHBsaWNpdGx5IGV4Y2x1ZGVkCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGZyb20gdGhlIHZpZXcuIAogKiAgIFZBQ01fU1VCVFJFRV9VTktOT1dOICBUaGUgZW50aXJlIHN1YnRyZWUgaGFzIGJvdGggYWxsb3dlZCBhbmQgZGlzYWxsb3dlZAogKiAgICAgICAgICAgICAgICAgICAgICAgICBwb3J0aW9ucy4KICovCmludApuZXRzbm1wX3ZpZXdfc3VidHJlZV9jaGVjayhzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKmhlYWQsIGNvbnN0IGNoYXIgKnZpZXdOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiB2aWV3U3VidHJlZSwgc2l6ZV90IHZpZXdTdWJ0cmVlTGVuKQp7CiAgICBzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKnZwLCAqdnBTaG9ydGVyID0gTlVMTCwgKnZwTG9uZ2VyID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICB2aWV3W1ZBQ01TVFJJTkdMRU5dOwogICAgaW50ICAgICAgICAgICAgIGZvdW5kLCBnbGVuOwoKICAgIGdsZW4gPSAoaW50KSBzdHJsZW4odmlld05hbWUpOwogICAgaWYgKGdsZW4gPCAwIHx8IGdsZW4gPiBWQUNNX01BWF9TVFJJTkcpCiAgICAgICAgcmV0dXJuIFZBQ01fTk9USU5WSUVXOwogICAgdmlld1swXSA9IGdsZW47CiAgICBzdHJjcHkodmlldyArIDEsIHZpZXdOYW1lKTsKICAgIERFQlVHTVNHVEwoKCI5OnZhY206Y2hlY2tTdWJ0cmVlIiwgInZpZXcgJXNcbiIsIHZpZXdOYW1lKSk7CiAgICBmb3IgKHZwID0gaGVhZDsgdnA7IHZwID0gdnAtPm5leHQpIHsKICAgICAgICBpZiAoIW1lbWNtcCh2aWV3LCB2cC0+dmlld05hbWUsIGdsZW4gKyAxKSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBJZiB0aGUgc3VidHJlZSBkZWZpbmVkIGluIHRoZSB2aWV3IGlzIHNob3J0ZXIgdGhhbiBvciBlcXVhbAogICAgICAgICAgICAgKiB0byB0aGUgc3VidHJlZSB3ZSBhcmUgY29tcGFyaW5nLCB0aGVuIGl0IG1pZ2h0IGVudmVsb3AgdGhlCiAgICAgICAgICAgICAqIHN1YnRyZWUgd2UgYXJlIGNvbXBhcmluZyBhZ2FpbnN0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHZpZXdTdWJ0cmVlTGVuID49ICh2cC0+dmlld1N1YnRyZWVMZW4gLSAxKSkgewogICAgICAgICAgICAgICAgaW50ICAgICAgICAgICAgIG1hc2sgPSAweDgwOwogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50ICAgIG9pZHBvcywgbWFza3BvcyA9IDA7CiAgICAgICAgICAgICAgICBmb3VuZCA9IDE7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGNoZWNrIHRoZSBtYXNrCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGZvciAob2lkcG9zID0gMDsKICAgICAgICAgICAgICAgICAgICAgZm91bmQgJiYgb2lkcG9zIDwgdnAtPnZpZXdTdWJ0cmVlTGVuIC0gMTsKICAgICAgICAgICAgICAgICAgICAgb2lkcG9zKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoVklFV19NQVNLKHZwLCBtYXNrcG9zLCBtYXNrKSAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2aWV3U3VidHJlZVtvaWRwb3NdICE9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmlld1N1YnRyZWVbb2lkcG9zICsgMV0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3VuZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChtYXNrID09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWFzayA9IDB4ODA7CiAgICAgICAgICAgICAgICAgICAgICAgIG1hc2twb3MrKzsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgbWFzayA+Pj0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZm91bmQpIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIG1hdGNoIHN1Y2Nlc3NmdWwsIGtlZXAgdGhpcyBub2RlIGlmIGl0J3MgbG9uZ2VyIHRoYW4KICAgICAgICAgICAgICAgICAgICAgKiB0aGUgcHJldmlvdXMgb3IgKGVxdWFsIGFuZCBsZXhpY29ncmFwaGljYWxseSBncmVhdGVyCiAgICAgICAgICAgICAgICAgICAgICogdGhhbiB0aGUgcHJldmlvdXMpLiAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiOTp2YWNtOmNoZWNrU3VidHJlZSIsICIgJXMgbWF0Y2hlZD9cbiIsIHZwLT52aWV3TmFtZSkpOwogICAgCiAgICAgICAgICAgICAgICAgICAgaWYgKHZwU2hvcnRlciA9PSBOVUxMCiAgICAgICAgICAgICAgICAgICAgICAgIHx8IHZwLT52aWV3U3VidHJlZUxlbiA+IHZwU2hvcnRlci0+dmlld1N1YnRyZWVMZW4KICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHZwLT52aWV3U3VidHJlZUxlbiA9PSB2cFNob3J0ZXItPnZpZXdTdWJ0cmVlTGVuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICYmIHNubXBfb2lkX2NvbXBhcmUodnAtPnZpZXdTdWJ0cmVlICsgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmlld1N1YnRyZWVMZW4gLSAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwU2hvcnRlci0+dmlld1N1YnRyZWUgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwU2hvcnRlci0+dmlld1N1YnRyZWVMZW4gLSAxKSA+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdnBTaG9ydGVyID0gdnA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIElmIHRoZSBzdWJ0cmVlIGRlZmluZWQgaW4gdGhlIHZpZXcgaXMgbG9uZ2VyIHRoYW4gdGhlCiAgICAgICAgICAgICAqIHN1YnRyZWUgd2UgYXJlIGNvbXBhcmluZywgdGhlbiBpdCBtaWdodCBhbWJpZ3VhdGUgb3VyCiAgICAgICAgICAgICAqIHJlc3BvbnNlLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBpbnQgICAgICAgICAgICAgbWFzayA9IDB4ODA7CiAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgICAgb2lkcG9zLCBtYXNrcG9zID0gMDsKICAgICAgICAgICAgICAgIGZvdW5kID0gMTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogY2hlY2sgdGhlIG1hc2sgdXAgdG8gdGhlIGxlbmd0aCBvZiB0aGUgcHJvdmlkZWQgc3VidHJlZQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBmb3IgKG9pZHBvcyA9IDA7CiAgICAgICAgICAgICAgICAgICAgIGZvdW5kICYmIG9pZHBvcyA8IHZpZXdTdWJ0cmVlTGVuOwogICAgICAgICAgICAgICAgICAgICBvaWRwb3MrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChWSUVXX01BU0sodnAsIG1hc2twb3MsIG1hc2spICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZpZXdTdWJ0cmVlW29pZHBvc10gIT0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT52aWV3U3VidHJlZVtvaWRwb3MgKyAxXSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKG1hc2sgPT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgICBtYXNrID0gMHg4MDsKICAgICAgICAgICAgICAgICAgICAgICAgbWFza3BvcysrOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBtYXNrID4+PSAxOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChmb3VuZCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogbWF0Y2ggc3VjY2Vzc2Z1bC4gIElmIHdlIGFscmVhZHkgZm91bmQgYSBtYXRjaAogICAgICAgICAgICAgICAgICAgICAqIHdpdGggYSBkaWZmZXJlbnQgdmlldyB0eXBlLCB0aGVuIHBhcnRzIG9mIHRoZSBzdWJ0cmVlIAogICAgICAgICAgICAgICAgICAgICAqIGFyZSBpbmNsdWRlZCBhbmQgb3RoZXJzIGFyZSBleGNsdWRlZCwgc28gcmV0dXJuIFVOS05PV04uCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoIjk6dmFjbTpjaGVja1N1YnRyZWUiLCAiICVzIG1hdGNoZWQ/XG4iLCB2cC0+dmlld05hbWUpKTsKICAgICAgICAgICAgICAgICAgICBpZiAodnBMb25nZXIgIT0gTlVMTAogICAgICAgICAgICAgICAgICAgICAgICAmJiAodnBMb25nZXItPnZpZXdUeXBlICE9IHZwLT52aWV3VHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInZhY206Y2hlY2tTdWJ0cmVlIiwgIiwgJXNcbiIsICJ1bmtub3duIikpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gVkFDTV9TVUJUUkVFX1VOS05PV047CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHZwTG9uZ2VyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdnBMb25nZXIgPSB2cDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBERUJVR01TR1RMKCgiOTp2YWNtOmNoZWNrU3VidHJlZSIsICIgJXMgbWF0Y2hlZFxuIiwgdmlld05hbWUpKTsKCiAgICAvKgogICAgICogSWYgd2UgZm91bmQgYSBtYXRjaGluZyB2aWV3IHN1YnRyZWUgd2l0aCBhIGxvbmdlciBPSUQgdGhhbiB0aGUgcHJvdmlkZWQKICAgICAqIE9JRCwgY2hlY2sgdG8gc2VlIGlmIGl0cyB0eXBlIGlzIGNvbnNpc3RlbnQgd2l0aCBhbnkgbWF0Y2hpbmcgdmlldwogICAgICogc3VidHJlZSB3ZSBtYXkgaGF2ZSBmb3VuZCB3aXRoIGEgc2hvcnRlciBPSUQgdGhhbiB0aGUgcHJvdmlkZWQgT0lELgogICAgICoKICAgICAqIFRoZSB2aWV3IHR5cGUgb2YgdGhlIGxvbmdlciBPSUQgaXMgaW5jb25zaXN0ZW50IHdpdGggdGhlIHNob3J0ZXIgT0lEIGluCiAgICAgKiBlaXRoZXIgb2YgdGhlc2UgdHdvIGNhc2VzOgogICAgICogIDEpIE5vIG1hdGNoaW5nIHNob3J0ZXIgT0lEIHdhcyBmb3VuZCBhbmQgdGhlIHZpZXcgdHlwZSBvZiB0aGUgbG9uZ2VyCiAgICAgKiAgICAgT0lEIGlzIElOQ0xVREUuCiAgICAgKiAgMikgQSBtYXRjaGluZyBzaG9ydGVyIElEIHdhcyBmb3VuZCBhbmQgaXRzIHZpZXcgdHlwZSBkb2Vzbid0IG1hdGNoCiAgICAgKiAgICAgdGhlIHZpZXcgdHlwZSBvZiB0aGUgbG9uZ2VyIE9JRC4KICAgICAqLwogICAgaWYgKHZwTG9uZ2VyICE9IE5VTEwpIHsKICAgICAgICBpZiAoKCF2cFNob3J0ZXIgJiYgdnBMb25nZXItPnZpZXdUeXBlICE9IFNOTVBfVklFV19FWENMVURFRCkKICAgICAgICAgICAgfHwgKHZwU2hvcnRlciAmJiB2cExvbmdlci0+dmlld1R5cGUgIT0gdnBTaG9ydGVyLT52aWV3VHlwZSkpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInZhY206Y2hlY2tTdWJ0cmVlIiwgIiwgJXNcbiIsICJ1bmtub3duIikpOwogICAgICAgICAgICByZXR1cm4gVkFDTV9TVUJUUkVFX1VOS05PV047CiAgICAgICAgfQogICAgfQoKICAgIGlmICh2cFNob3J0ZXIgJiYgdnBTaG9ydGVyLT52aWV3VHlwZSAhPSBTTk1QX1ZJRVdfRVhDTFVERUQpIHsKICAgICAgICBERUJVR01TR1RMKCgidmFjbTpjaGVja1N1YnRyZWUiLCAiLCAlc1xuIiwgImluY2x1ZGVkIikpOwogICAgICAgIHJldHVybiBWQUNNX1NVQ0NFU1M7CiAgICB9CgogICAgREVCVUdNU0dUTCgoInZhY206Y2hlY2tTdWJ0cmVlIiwgIiwgJXNcbiIsICJleGNsdWRlZCIpKTsKICAgIHJldHVybiBWQUNNX05PVElOVklFVzsKfQoKdm9pZAp2YWNtX3NjYW5WaWV3SW5pdCh2b2lkKQp7CiAgICB2aWV3U2NhblB0ciA9IHZpZXdMaXN0Owp9CgpzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKgp2YWNtX3NjYW5WaWV3TmV4dCh2b2lkKQp7CiAgICBzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKnJldHVybnZhbCA9IHZpZXdTY2FuUHRyOwogICAgaWYgKHZpZXdTY2FuUHRyKQogICAgICAgIHZpZXdTY2FuUHRyID0gdmlld1NjYW5QdHItPm5leHQ7CiAgICByZXR1cm4gcmV0dXJudmFsOwp9CgpzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKgpuZXRzbm1wX3ZpZXdfY3JlYXRlKHN0cnVjdCB2YWNtX3ZpZXdFbnRyeSAqKmhlYWQsIGNvbnN0IGNoYXIgKnZpZXdOYW1lLAogICAgICAgICAgICAgICAgICAgICBvaWQgKiB2aWV3U3VidHJlZSwgc2l6ZV90IHZpZXdTdWJ0cmVlTGVuKQp7CiAgICBzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKnZwLCAqbHAsICpvcCA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgY21wLCBjbXAyLCBnbGVuOwoKICAgIGdsZW4gPSAoaW50KSBzdHJsZW4odmlld05hbWUpOwogICAgaWYgKGdsZW4gPCAwIHx8IGdsZW4gPiBWQUNNX01BWF9TVFJJTkcpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB2cCA9IChzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3QgdmFjbV92aWV3RW50cnkpKTsKICAgIGlmICh2cCA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwogICAgdnAtPnJlc2VydmVkID0KICAgICAgICAoc3RydWN0IHZhY21fdmlld0VudHJ5ICopIGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IHZhY21fdmlld0VudHJ5KSk7CiAgICBpZiAodnAtPnJlc2VydmVkID09IE5VTEwpIHsKICAgICAgICBmcmVlKHZwKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICB2cC0+dmlld05hbWVbMF0gPSBnbGVuOwogICAgc3RyY3B5KHZwLT52aWV3TmFtZSArIDEsIHZpZXdOYW1lKTsKICAgIHZwLT52aWV3U3VidHJlZVswXSA9IHZpZXdTdWJ0cmVlTGVuOwogICAgbWVtY3B5KHZwLT52aWV3U3VidHJlZSArIDEsIHZpZXdTdWJ0cmVlLCB2aWV3U3VidHJlZUxlbiAqIHNpemVvZihvaWQpKTsKICAgIHZwLT52aWV3U3VidHJlZUxlbiA9IHZpZXdTdWJ0cmVlTGVuICsgMTsKCiAgICBscCA9ICpoZWFkOwogICAgd2hpbGUgKGxwKSB7CiAgICAgICAgY21wID0gbWVtY21wKGxwLT52aWV3TmFtZSwgdnAtPnZpZXdOYW1lLCBnbGVuICsgMSk7CiAgICAgICAgY21wMiA9IHNubXBfb2lkX2NvbXBhcmUobHAtPnZpZXdTdWJ0cmVlLCBscC0+dmlld1N1YnRyZWVMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPnZpZXdTdWJ0cmVlLCB2cC0+dmlld1N1YnRyZWVMZW4pOwogICAgICAgIGlmIChjbXAgPT0gMCAmJiBjbXAyID4gMCkKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgaWYgKGNtcCA+IDApCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIG9wID0gbHA7CiAgICAgICAgbHAgPSBscC0+bmV4dDsKICAgIH0KICAgIHZwLT5uZXh0ID0gbHA7CiAgICBpZiAob3ApCiAgICAgICAgb3AtPm5leHQgPSB2cDsKICAgIGVsc2UKICAgICAgICAqaGVhZCA9IHZwOwogICAgcmV0dXJuIHZwOwp9Cgp2b2lkCm5ldHNubXBfdmlld19kZXN0cm95KHN0cnVjdCB2YWNtX3ZpZXdFbnRyeSAqKmhlYWQsIGNvbnN0IGNoYXIgKnZpZXdOYW1lLAogICAgICAgICAgICAgICAgICAgICAgb2lkICogdmlld1N1YnRyZWUsIHNpemVfdCB2aWV3U3VidHJlZUxlbikKewogICAgc3RydWN0IHZhY21fdmlld0VudHJ5ICp2cCwgKmxhc3R2cCA9IE5VTEw7CgogICAgaWYgKCgqaGVhZCkgJiYgIXN0cmNtcCgoKmhlYWQpLT52aWV3TmFtZSArIDEsIHZpZXdOYW1lKQogICAgICAgICYmICgqaGVhZCktPnZpZXdTdWJ0cmVlTGVuID09IHZpZXdTdWJ0cmVlTGVuCiAgICAgICAgJiYgIW1lbWNtcCgoY2hhciAqKSAoKmhlYWQpLT52aWV3U3VidHJlZSwgKGNoYXIgKikgdmlld1N1YnRyZWUsCiAgICAgICAgICAgICAgICAgICB2aWV3U3VidHJlZUxlbiAqIHNpemVvZihvaWQpKSkgewogICAgICAgIHZwID0gKCpoZWFkKTsKICAgICAgICAoKmhlYWQpID0gKCpoZWFkKS0+bmV4dDsKICAgIH0gZWxzZSB7CiAgICAgICAgZm9yICh2cCA9ICgqaGVhZCk7IHZwOyB2cCA9IHZwLT5uZXh0KSB7CiAgICAgICAgICAgIGlmICghc3RyY21wKHZwLT52aWV3TmFtZSArIDEsIHZpZXdOYW1lKQogICAgICAgICAgICAgICAgJiYgdnAtPnZpZXdTdWJ0cmVlTGVuID09IHZpZXdTdWJ0cmVlTGVuCiAgICAgICAgICAgICAgICAmJiAhbWVtY21wKChjaGFyICopIHZwLT52aWV3U3VidHJlZSwgKGNoYXIgKikgdmlld1N1YnRyZWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdTdWJ0cmVlTGVuICogc2l6ZW9mKG9pZCkpKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGxhc3R2cCA9IHZwOwogICAgICAgIH0KICAgICAgICBpZiAoIXZwIHx8ICFsYXN0dnApCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBsYXN0dnAtPm5leHQgPSB2cC0+bmV4dDsKICAgIH0KICAgIGlmICh2cC0+cmVzZXJ2ZWQpCiAgICAgICAgZnJlZSh2cC0+cmVzZXJ2ZWQpOwogICAgZnJlZSh2cCk7CiAgICByZXR1cm47Cn0KCnZvaWQKbmV0c25tcF92aWV3X2NsZWFyKHN0cnVjdCB2YWNtX3ZpZXdFbnRyeSAqKmhlYWQpCnsKICAgIHN0cnVjdCB2YWNtX3ZpZXdFbnRyeSAqdnA7CiAgICB3aGlsZSAoKHZwID0gKCpoZWFkKSkpIHsKICAgICAgICAoKmhlYWQpID0gdnAtPm5leHQ7CiAgICAgICAgaWYgKHZwLT5yZXNlcnZlZCkKICAgICAgICAgICAgZnJlZSh2cC0+cmVzZXJ2ZWQpOwogICAgICAgIGZyZWUodnApOwogICAgfQp9CgpzdHJ1Y3QgdmFjbV9ncm91cEVudHJ5ICoKdmFjbV9nZXRHcm91cEVudHJ5KGludCBzZWN1cml0eU1vZGVsLCBjb25zdCBjaGFyICpzZWN1cml0eU5hbWUpCnsKICAgIHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKnZwOwogICAgY2hhciAgICAgICAgICAgIHNlY25hbWVbVkFDTVNUUklOR0xFTl07CiAgICBpbnQgICAgICAgICAgICAgZ2xlbjsKCiAgICBnbGVuID0gKGludCkgc3RybGVuKHNlY3VyaXR5TmFtZSk7CiAgICBpZiAoZ2xlbiA8IDAgfHwgZ2xlbiA+IFZBQ01fTUFYX1NUUklORykKICAgICAgICByZXR1cm4gTlVMTDsKICAgIHNlY25hbWVbMF0gPSBnbGVuOwogICAgc3RyY3B5KHNlY25hbWUgKyAxLCBzZWN1cml0eU5hbWUpOwoKICAgIGZvciAodnAgPSBncm91cExpc3Q7IHZwOyB2cCA9IHZwLT5uZXh0KSB7CiAgICAgICAgaWYgKChzZWN1cml0eU1vZGVsID09IHZwLT5zZWN1cml0eU1vZGVsCiAgICAgICAgICAgICB8fCB2cC0+c2VjdXJpdHlNb2RlbCA9PSBTTk1QX1NFQ19NT0RFTF9BTlkpCiAgICAgICAgICAgICYmICFtZW1jbXAodnAtPnNlY3VyaXR5TmFtZSwgc2VjbmFtZSwgZ2xlbiArIDEpKQogICAgICAgICAgICByZXR1cm4gdnA7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKdm9pZAp2YWNtX3NjYW5Hcm91cEluaXQodm9pZCkKewogICAgZ3JvdXBTY2FuUHRyID0gZ3JvdXBMaXN0Owp9CgpzdHJ1Y3QgdmFjbV9ncm91cEVudHJ5ICoKdmFjbV9zY2FuR3JvdXBOZXh0KHZvaWQpCnsKICAgIHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKnJldHVybnZhbCA9IGdyb3VwU2NhblB0cjsKICAgIGlmIChncm91cFNjYW5QdHIpCiAgICAgICAgZ3JvdXBTY2FuUHRyID0gZ3JvdXBTY2FuUHRyLT5uZXh0OwogICAgcmV0dXJuIHJldHVybnZhbDsKfQoKc3RydWN0IHZhY21fZ3JvdXBFbnRyeSAqCnZhY21fY3JlYXRlR3JvdXBFbnRyeShpbnQgc2VjdXJpdHlNb2RlbCwgY29uc3QgY2hhciAqc2VjdXJpdHlOYW1lKQp7CiAgICBzdHJ1Y3QgdmFjbV9ncm91cEVudHJ5ICpncCwgKmxnLCAqb2c7CiAgICBpbnQgICAgICAgICAgICAgY21wLCBnbGVuOwoKICAgIGdsZW4gPSAoaW50KSBzdHJsZW4oc2VjdXJpdHlOYW1lKTsKICAgIGlmIChnbGVuIDwgMCB8fCBnbGVuID4gVkFDTV9NQVhfU1RSSU5HKQogICAgICAgIHJldHVybiBOVUxMOwogICAgZ3AgPSAoc3RydWN0IHZhY21fZ3JvdXBFbnRyeSAqKSBjYWxsb2MoMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3QgdmFjbV9ncm91cEVudHJ5KSk7CiAgICBpZiAoZ3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGdwLT5yZXNlcnZlZCA9CiAgICAgICAgKHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzdHJ1Y3QgdmFjbV9ncm91cEVudHJ5KSk7CiAgICBpZiAoZ3AtPnJlc2VydmVkID09IE5VTEwpIHsKICAgICAgICBmcmVlKGdwKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBncC0+c2VjdXJpdHlNb2RlbCA9IHNlY3VyaXR5TW9kZWw7CiAgICBncC0+c2VjdXJpdHlOYW1lWzBdID0gZ2xlbjsKICAgIHN0cmNweShncC0+c2VjdXJpdHlOYW1lICsgMSwgc2VjdXJpdHlOYW1lKTsKCiAgICBsZyA9IGdyb3VwTGlzdDsKICAgIG9nID0gTlVMTDsKICAgIHdoaWxlIChsZykgewogICAgICAgIGlmIChsZy0+c2VjdXJpdHlNb2RlbCA+IHNlY3VyaXR5TW9kZWwpCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGlmIChsZy0+c2VjdXJpdHlNb2RlbCA9PSBzZWN1cml0eU1vZGVsICYmCiAgICAgICAgICAgIChjbXAgPQogICAgICAgICAgICAgbWVtY21wKGxnLT5zZWN1cml0eU5hbWUsIGdwLT5zZWN1cml0eU5hbWUsIGdsZW4gKyAxKSkgPiAwKQogICAgICAgICAgICBicmVhazsKICAgICAgICAvKgogICAgICAgICAqIGlmIChsZy0+c2VjdXJpdHlNb2RlbCA9PSBzZWN1cml0eU1vZGVsICYmIGNtcCA9PSAwKSBhYm9ydCgpOyAKICAgICAgICAgKi8KICAgICAgICBvZyA9IGxnOwogICAgICAgIGxnID0gbGctPm5leHQ7CiAgICB9CiAgICBncC0+bmV4dCA9IGxnOwogICAgaWYgKG9nID09IE5VTEwpCiAgICAgICAgZ3JvdXBMaXN0ID0gZ3A7CiAgICBlbHNlCiAgICAgICAgb2ctPm5leHQgPSBncDsKICAgIHJldHVybiBncDsKfQoKdm9pZAp2YWNtX2Rlc3Ryb3lHcm91cEVudHJ5KGludCBzZWN1cml0eU1vZGVsLCBjb25zdCBjaGFyICpzZWN1cml0eU5hbWUpCnsKICAgIHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKnZwLCAqbGFzdHZwID0gTlVMTDsKCiAgICBpZiAoZ3JvdXBMaXN0ICYmIGdyb3VwTGlzdC0+c2VjdXJpdHlNb2RlbCA9PSBzZWN1cml0eU1vZGVsCiAgICAgICAgJiYgIXN0cmNtcChncm91cExpc3QtPnNlY3VyaXR5TmFtZSArIDEsIHNlY3VyaXR5TmFtZSkpIHsKICAgICAgICB2cCA9IGdyb3VwTGlzdDsKICAgICAgICBncm91cExpc3QgPSBncm91cExpc3QtPm5leHQ7CiAgICB9IGVsc2UgewogICAgICAgIGZvciAodnAgPSBncm91cExpc3Q7IHZwOyB2cCA9IHZwLT5uZXh0KSB7CiAgICAgICAgICAgIGlmICh2cC0+c2VjdXJpdHlNb2RlbCA9PSBzZWN1cml0eU1vZGVsCiAgICAgICAgICAgICAgICAmJiAhc3RyY21wKHZwLT5zZWN1cml0eU5hbWUgKyAxLCBzZWN1cml0eU5hbWUpKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGxhc3R2cCA9IHZwOwogICAgICAgIH0KICAgICAgICBpZiAoIXZwIHx8ICFsYXN0dnApCiAgICAgICAgICAgIHJldHVybjsKICAgICAgICBsYXN0dnAtPm5leHQgPSB2cC0+bmV4dDsKICAgIH0KICAgIGlmICh2cC0+cmVzZXJ2ZWQpCiAgICAgICAgZnJlZSh2cC0+cmVzZXJ2ZWQpOwogICAgZnJlZSh2cCk7CiAgICByZXR1cm47Cn0KCnZvaWQKdmFjbV9kZXN0cm95QWxsR3JvdXBFbnRyaWVzKHZvaWQpCnsKICAgIHN0cnVjdCB2YWNtX2dyb3VwRW50cnkgKmdwOwogICAgd2hpbGUgKChncCA9IGdyb3VwTGlzdCkpIHsKICAgICAgICBncm91cExpc3QgPSBncC0+bmV4dDsKICAgICAgICBpZiAoZ3AtPnJlc2VydmVkKQogICAgICAgICAgICBmcmVlKGdwLT5yZXNlcnZlZCk7CiAgICAgICAgZnJlZShncCk7CiAgICB9Cn0KCnN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICoKX3ZhY21fY2hvb3NlX2Jlc3QoIHN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICpjdXJyZW50LAogICAgICAgICAgICAgICAgICAgc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKmNhbmRpZGF0ZSkKewogICAgLyoKICAgICAqIFJGQyAzNDE1OiB2YWNtQWNjZXNzVGFibGU6CiAgICAgKiAgICAyKSBpZiB0aGlzIHNldCBoYXMgW21vcmUgdGhhbl0gb25lIG1lbWJlciwgLi4uCiAgICAgKiAgICAgICBpdCBjb21lcyBkb3duIHRvIGRlY2lkaW5nIGhvdyB0byB3ZWlnaHQgdGhlCiAgICAgKiAgICAgICBwcmVmZXJlbmNlcyBiZXR3ZWVuIENvbnRleHRQcmVmaXhlcywKICAgICAqICAgICAgIFNlY3VyaXR5TW9kZWxzLCBhbmQgU2VjdXJpdHlMZXZlbHMKICAgICAqLwogICAgaWYgKCggIWN1cnJlbnQgKSB8fAogICAgICAgIC8qIGEpIGlmIHRoZSBzdWJzZXQgb2YgZW50cmllcyB3aXRoIHNlY3VyaXR5TW9kZWwKICAgICAgICAgKiAgICBtYXRjaGluZyB0aGUgc2VjdXJpdHlNb2RlbCBpbiB0aGUgbWVzc2FnZSBpcwogICAgICAgICAqICAgIG5vdCBlbXB0eSwgdGhlbiBkaXNjYXJkIHRoZSByZXN0CiAgICAgICAgICovCiAgICAgICAgKCAgY3VycmVudC0+c2VjdXJpdHlNb2RlbCA9PSBTTk1QX1NFQ19NT0RFTF9BTlkgJiYKICAgICAgICAgY2FuZGlkYXRlLT5zZWN1cml0eU1vZGVsICE9IFNOTVBfU0VDX01PREVMX0FOWSApIHx8CiAgICAgICAgLyogYikgaWYgdGhlIHN1YnNldCBvZiBlbnRyaWVzIHdpdGggdmFjbUFjY2Vzc0NvbnRleHRQcmVmaXgKICAgICAgICAgKiAgICBtYXRjaGluZyB0aGUgY29udGV4dE5hbWUgaW4gdGhlIG1lc3NhZ2UgaXMKICAgICAgICAgKiAgICBub3QgZW1wdHksIHRoZW4gZGlzY2FyZCB0aGUgcmVzdAogICAgICAgICAqLwogICAgICAgICggIGN1cnJlbnQtPmNvbnRleHRNYXRjaCAgPT0gQ09OVEVYVF9NQVRDSF9QUkVGSVggJiYKICAgICAgICAgY2FuZGlkYXRlLT5jb250ZXh0TWF0Y2ggID09IENPTlRFWFRfTUFUQ0hfRVhBQ1QgKSB8fAogICAgICAgIC8qIGMpIGRpc2NhcmQgYWxsIGVudHJpZXMgd2l0aCBDb250ZXh0UHJlZml4ZXMgc2hvcnRlcgogICAgICAgICAqICAgIHRoYW4gdGhlIGxvbmdlc3Qgb25lIHJlbWFpbmluZyBpbiB0aGUgc2V0CiAgICAgICAgICovCiAgICAgICAgKCAgY3VycmVudC0+Y29udGV4dE1hdGNoICA9PSBDT05URVhUX01BVENIX1BSRUZJWCAmJgogICAgICAgICAgIGN1cnJlbnQtPmNvbnRleHRQcmVmaXhbMF0gPCBjYW5kaWRhdGUtPmNvbnRleHRQcmVmaXhbMF0gKSB8fAogICAgICAgIC8qIGQpIHNlbGVjdCB0aGUgZW50cnkgd2l0aCB0aGUgaGlnaGVzdCBzZWN1cml0eUxldmVsCiAgICAgICAgICovCiAgICAgICAgKCAgY3VycmVudC0+c2VjdXJpdHlMZXZlbCA8IGNhbmRpZGF0ZS0+c2VjdXJpdHlMZXZlbCApKSB7CgogICAgICAgIHJldHVybiBjYW5kaWRhdGU7CiAgICB9CgogICAgcmV0dXJuIGN1cnJlbnQ7Cn0KCnN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICoKdmFjbV9nZXRBY2Nlc3NFbnRyeShjb25zdCBjaGFyICpncm91cE5hbWUsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY29udGV4dFByZWZpeCwKICAgICAgICAgICAgICAgICAgICBpbnQgc2VjdXJpdHlNb2RlbCwgaW50IHNlY3VyaXR5TGV2ZWwpCnsKICAgIHN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICp2cCwgKmJlc3Q9TlVMTDsKICAgIGNoYXIgICAgICAgICAgICBncm91cFtWQUNNU1RSSU5HTEVOXTsKICAgIGNoYXIgICAgICAgICAgICBjb250ZXh0W1ZBQ01TVFJJTkdMRU5dOwogICAgaW50ICAgICAgICAgICAgIGdsZW4sIGNsZW47CgogICAgZ2xlbiA9IChpbnQpIHN0cmxlbihncm91cE5hbWUpOwogICAgaWYgKGdsZW4gPCAwIHx8IGdsZW4gPiBWQUNNX01BWF9TVFJJTkcpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBjbGVuID0gKGludCkgc3RybGVuKGNvbnRleHRQcmVmaXgpOwogICAgaWYgKGNsZW4gPCAwIHx8IGNsZW4gPiBWQUNNX01BWF9TVFJJTkcpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgZ3JvdXBbMF0gPSBnbGVuOwogICAgc3RyY3B5KGdyb3VwICsgMSwgZ3JvdXBOYW1lKTsKICAgIGNvbnRleHRbMF0gPSBjbGVuOwogICAgc3RyY3B5KGNvbnRleHQgKyAxLCBjb250ZXh0UHJlZml4KTsKICAgIGZvciAodnAgPSBhY2Nlc3NMaXN0OyB2cDsgdnAgPSB2cC0+bmV4dCkgewogICAgICAgIGlmICgoc2VjdXJpdHlNb2RlbCA9PSB2cC0+c2VjdXJpdHlNb2RlbAogICAgICAgICAgICAgfHwgdnAtPnNlY3VyaXR5TW9kZWwgPT0gU05NUF9TRUNfTU9ERUxfQU5ZKQogICAgICAgICAgICAmJiBzZWN1cml0eUxldmVsID49IHZwLT5zZWN1cml0eUxldmVsCiAgICAgICAgICAgICYmICFtZW1jbXAodnAtPmdyb3VwTmFtZSwgZ3JvdXAsIGdsZW4gKyAxKQogICAgICAgICAgICAmJgogICAgICAgICAgICAoKHZwLT5jb250ZXh0TWF0Y2ggPT0gQ09OVEVYVF9NQVRDSF9FWEFDVAogICAgICAgICAgICAgICYmIGNsZW4gPT0gdnAtPmNvbnRleHRQcmVmaXhbMF0KICAgICAgICAgICAgICAmJiAobWVtY21wKHZwLT5jb250ZXh0UHJlZml4LCBjb250ZXh0LCBjbGVuICsgMSkgPT0gMCkpCiAgICAgICAgICAgICB8fCAodnAtPmNvbnRleHRNYXRjaCA9PSBDT05URVhUX01BVENIX1BSRUZJWAogICAgICAgICAgICAgICAgICYmIGNsZW4gPj0gdnAtPmNvbnRleHRQcmVmaXhbMF0KICAgICAgICAgICAgICAgICAmJiAobWVtY21wKHZwLT5jb250ZXh0UHJlZml4ICsgMSwgY29udGV4dCArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+Y29udGV4dFByZWZpeFswXSkgPT0gMCkpKSkKICAgICAgICAgICAgYmVzdCA9IF92YWNtX2Nob29zZV9iZXN0KCBiZXN0LCB2cCApOwogICAgfQogICAgcmV0dXJuIGJlc3Q7Cn0KCnZvaWQKdmFjbV9zY2FuQWNjZXNzSW5pdCh2b2lkKQp7CiAgICBhY2Nlc3NTY2FuUHRyID0gYWNjZXNzTGlzdDsKfQoKc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKgp2YWNtX3NjYW5BY2Nlc3NOZXh0KHZvaWQpCnsKICAgIHN0cnVjdCB2YWNtX2FjY2Vzc0VudHJ5ICpyZXR1cm52YWwgPSBhY2Nlc3NTY2FuUHRyOwogICAgaWYgKGFjY2Vzc1NjYW5QdHIpCiAgICAgICAgYWNjZXNzU2NhblB0ciA9IGFjY2Vzc1NjYW5QdHItPm5leHQ7CiAgICByZXR1cm4gcmV0dXJudmFsOwp9CgpzdHJ1Y3QgdmFjbV9hY2Nlc3NFbnRyeSAqCnZhY21fY3JlYXRlQWNjZXNzRW50cnkoY29uc3QgY2hhciAqZ3JvdXBOYW1lLAogICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmNvbnRleHRQcmVmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgaW50IHNlY3VyaXR5TW9kZWwsIGludCBzZWN1cml0eUxldmVsKQp7CiAgICBzdHJ1Y3QgdmFjbV9hY2Nlc3NFbnRyeSAqdnAsICpscCwgKm9wID0gTlVMTDsKICAgIGludCAgICAgICAgICAgICBjbXAsIGdsZW4sIGNsZW47CgogICAgZ2xlbiA9IChpbnQpIHN0cmxlbihncm91cE5hbWUpOwogICAgaWYgKGdsZW4gPCAwIHx8IGdsZW4gPiBWQUNNX01BWF9TVFJJTkcpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBjbGVuID0gKGludCkgc3RybGVuKGNvbnRleHRQcmVmaXgpOwogICAgaWYgKGNsZW4gPCAwIHx8IGNsZW4gPiBWQUNNX01BWF9TVFJJTkcpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB2cCA9IChzdHJ1Y3QgdmFjbV9hY2Nlc3NFbnRyeSAqKSBjYWxsb2MoMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3RydWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhY21fYWNjZXNzRW50cnkpKTsKICAgIGlmICh2cCA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwogICAgdnAtPnJlc2VydmVkID0KICAgICAgICAoc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc3RydWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFjbV9hY2Nlc3NFbnRyeSkpOwogICAgaWYgKHZwLT5yZXNlcnZlZCA9PSBOVUxMKSB7CiAgICAgICAgZnJlZSh2cCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgdnAtPnNlY3VyaXR5TW9kZWwgPSBzZWN1cml0eU1vZGVsOwogICAgdnAtPnNlY3VyaXR5TGV2ZWwgPSBzZWN1cml0eUxldmVsOwogICAgdnAtPmdyb3VwTmFtZVswXSA9IGdsZW47CiAgICBzdHJjcHkodnAtPmdyb3VwTmFtZSArIDEsIGdyb3VwTmFtZSk7CiAgICB2cC0+Y29udGV4dFByZWZpeFswXSA9IGNsZW47CiAgICBzdHJjcHkodnAtPmNvbnRleHRQcmVmaXggKyAxLCBjb250ZXh0UHJlZml4KTsKCiAgICBscCA9IGFjY2Vzc0xpc3Q7CiAgICB3aGlsZSAobHApIHsKICAgICAgICBjbXAgPSBtZW1jbXAobHAtPmdyb3VwTmFtZSwgdnAtPmdyb3VwTmFtZSwgZ2xlbiArIDEpOwogICAgICAgIGlmIChjbXAgPiAwKQogICAgICAgICAgICBicmVhazsKICAgICAgICBpZiAoY21wIDwgMCkKICAgICAgICAgICAgZ290byBuZXh0OwogICAgICAgIGNtcCA9IG1lbWNtcChscC0+Y29udGV4dFByZWZpeCwgdnAtPmNvbnRleHRQcmVmaXgsIGNsZW4gKyAxKTsKICAgICAgICBpZiAoY21wID4gMCkKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgaWYgKGNtcCA8IDApCiAgICAgICAgICAgIGdvdG8gbmV4dDsKICAgICAgICBpZiAobHAtPnNlY3VyaXR5TW9kZWwgPiBzZWN1cml0eU1vZGVsKQogICAgICAgICAgICBicmVhazsKICAgICAgICBpZiAobHAtPnNlY3VyaXR5TW9kZWwgPCBzZWN1cml0eU1vZGVsKQogICAgICAgICAgICBnb3RvIG5leHQ7CiAgICAgICAgaWYgKGxwLT5zZWN1cml0eUxldmVsID4gc2VjdXJpdHlMZXZlbCkKICAgICAgICAgICAgYnJlYWs7CiAgICAgIG5leHQ6CiAgICAgICAgb3AgPSBscDsKICAgICAgICBscCA9IGxwLT5uZXh0OwogICAgfQogICAgdnAtPm5leHQgPSBscDsKICAgIGlmIChvcCA9PSBOVUxMKQogICAgICAgIGFjY2Vzc0xpc3QgPSB2cDsKICAgIGVsc2UKICAgICAgICBvcC0+bmV4dCA9IHZwOwogICAgcmV0dXJuIHZwOwp9Cgp2b2lkCnZhY21fZGVzdHJveUFjY2Vzc0VudHJ5KGNvbnN0IGNoYXIgKmdyb3VwTmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqY29udGV4dFByZWZpeCwKICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNlY3VyaXR5TW9kZWwsIGludCBzZWN1cml0eUxldmVsKQp7CiAgICBzdHJ1Y3QgdmFjbV9hY2Nlc3NFbnRyeSAqdnAsICpsYXN0dnAgPSBOVUxMOwoKICAgIGlmIChhY2Nlc3NMaXN0ICYmIGFjY2Vzc0xpc3QtPnNlY3VyaXR5TW9kZWwgPT0gc2VjdXJpdHlNb2RlbAogICAgICAgICYmIGFjY2Vzc0xpc3QtPnNlY3VyaXR5TGV2ZWwgPT0gc2VjdXJpdHlMZXZlbAogICAgICAgICYmICFzdHJjbXAoYWNjZXNzTGlzdC0+Z3JvdXBOYW1lICsgMSwgZ3JvdXBOYW1lKQogICAgICAgICYmICFzdHJjbXAoYWNjZXNzTGlzdC0+Y29udGV4dFByZWZpeCArIDEsIGNvbnRleHRQcmVmaXgpKSB7CiAgICAgICAgdnAgPSBhY2Nlc3NMaXN0OwogICAgICAgIGFjY2Vzc0xpc3QgPSBhY2Nlc3NMaXN0LT5uZXh0OwogICAgfSBlbHNlIHsKICAgICAgICBmb3IgKHZwID0gYWNjZXNzTGlzdDsgdnA7IHZwID0gdnAtPm5leHQpIHsKICAgICAgICAgICAgaWYgKHZwLT5zZWN1cml0eU1vZGVsID09IHNlY3VyaXR5TW9kZWwKICAgICAgICAgICAgICAgICYmIHZwLT5zZWN1cml0eUxldmVsID09IHNlY3VyaXR5TGV2ZWwKICAgICAgICAgICAgICAgICYmICFzdHJjbXAodnAtPmdyb3VwTmFtZSArIDEsIGdyb3VwTmFtZSkKICAgICAgICAgICAgICAgICYmICFzdHJjbXAodnAtPmNvbnRleHRQcmVmaXggKyAxLCBjb250ZXh0UHJlZml4KSkKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBsYXN0dnAgPSB2cDsKICAgICAgICB9CiAgICAgICAgaWYgKCF2cCB8fCAhbGFzdHZwKQogICAgICAgICAgICByZXR1cm47CiAgICAgICAgbGFzdHZwLT5uZXh0ID0gdnAtPm5leHQ7CiAgICB9CiAgICBpZiAodnAtPnJlc2VydmVkKQogICAgICAgIGZyZWUodnAtPnJlc2VydmVkKTsKICAgIGZyZWUodnApOwogICAgcmV0dXJuOwp9Cgp2b2lkCnZhY21fZGVzdHJveUFsbEFjY2Vzc0VudHJpZXModm9pZCkKewogICAgc3RydWN0IHZhY21fYWNjZXNzRW50cnkgKmFwOwogICAgd2hpbGUgKChhcCA9IGFjY2Vzc0xpc3QpKSB7CiAgICAgICAgYWNjZXNzTGlzdCA9IGFwLT5uZXh0OwogICAgICAgIGlmIChhcC0+cmVzZXJ2ZWQpCiAgICAgICAgICAgIGZyZWUoYXAtPnJlc2VydmVkKTsKICAgICAgICBmcmVlKGFwKTsKICAgIH0KfQoKaW50CnN0b3JlX3ZhY20oaW50IG1ham9ySUQsIGludCBtaW5vcklELCB2b2lkICpzZXJ2ZXJhcmcsIHZvaWQgKmNsaWVudGFyZykKewogICAgLyoKICAgICAqIGZpZ3VyZSBvdXQgb3VyIGFwcGxpY2F0aW9uIG5hbWUgCiAgICAgKi8KICAgIGNoYXIgICAgICAgICAgICphcHBuYW1lID0gKGNoYXIgKikgY2xpZW50YXJnOwogICAgaWYgKGFwcG5hbWUgPT0gTlVMTCkgewogICAgICAgIGFwcG5hbWUgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQlORVRTTk1QX0RTX0xJQl9BUFBUWVBFKTsKICAgIH0KCiAgICAvKgogICAgICogc2F2ZSB0aGUgVkFDTSBNSUIgCiAgICAgKi8KICAgIHZhY21fc2F2ZSgidmFjbSIsIGFwcG5hbWUpOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoKICogcmV0dXJucyAxIGlmIHZhY20gaGFzICphbnkqIChub24tYnVpbHQtaW4pIGNvbmZpZ3VyYXRpb24gZW50cmllcywKICogcmVnYXJkbGVzcyBvZiB3aGV0aGVyIG9yIG5vdCB0aGVyZSBpcyBlbm91Z2ggdG8gbWFrZSBhIGRlY2lzaW9uLAogKiBlbHNlIHJldHVybiAwIAogKi8KaW50CnZhY21faXNfY29uZmlndXJlZCh2b2lkKQp7CiAgICBpZiAoYWNjZXNzTGlzdCA9PSBOVUxMICYmIGdyb3VwTGlzdCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKLyoKICogYmFja3dhcmRzIGNvbXBhdGFiaWxpdHkKICovCnN0cnVjdCB2YWNtX3ZpZXdFbnRyeSAqCnZhY21fZ2V0Vmlld0VudHJ5KGNvbnN0IGNoYXIgKnZpZXdOYW1lLAogICAgICAgICAgICAgICAgICBvaWQgKiB2aWV3U3VidHJlZSwgc2l6ZV90IHZpZXdTdWJ0cmVlTGVuLCBpbnQgbW9kZSkKewogICAgcmV0dXJuIG5ldHNubXBfdmlld19nZXQoIHZpZXdMaXN0LCB2aWV3TmFtZSwgdmlld1N1YnRyZWUsIHZpZXdTdWJ0cmVlTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGUpOwp9CgppbnQKdmFjbV9jaGVja1N1YnRyZWUoY29uc3QgY2hhciAqdmlld05hbWUsCiAgICAgICAgICAgICAgICAgIG9pZCAqIHZpZXdTdWJ0cmVlLCBzaXplX3Qgdmlld1N1YnRyZWVMZW4pCnsKICAgIHJldHVybiBuZXRzbm1wX3ZpZXdfc3VidHJlZV9jaGVjayggdmlld0xpc3QsIHZpZXdOYW1lLCB2aWV3U3VidHJlZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmlld1N1YnRyZWVMZW4pOwp9CgpzdHJ1Y3QgdmFjbV92aWV3RW50cnkgKgp2YWNtX2NyZWF0ZVZpZXdFbnRyeShjb25zdCBjaGFyICp2aWV3TmFtZSwKICAgICAgICAgICAgICAgICAgICAgb2lkICogdmlld1N1YnRyZWUsIHNpemVfdCB2aWV3U3VidHJlZUxlbikKewogICAgcmV0dXJuIG5ldHNubXBfdmlld19jcmVhdGUoICZ2aWV3TGlzdCwgdmlld05hbWUsIHZpZXdTdWJ0cmVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdTdWJ0cmVlTGVuKTsKfQoKdm9pZAp2YWNtX2Rlc3Ryb3lWaWV3RW50cnkoY29uc3QgY2hhciAqdmlld05hbWUsCiAgICAgICAgICAgICAgICAgICAgICBvaWQgKiB2aWV3U3VidHJlZSwgc2l6ZV90IHZpZXdTdWJ0cmVlTGVuKQp7CiAgICBuZXRzbm1wX3ZpZXdfZGVzdHJveSggJnZpZXdMaXN0LCB2aWV3TmFtZSwgdmlld1N1YnRyZWUsIHZpZXdTdWJ0cmVlTGVuKTsKfQoKdm9pZAp2YWNtX2Rlc3Ryb3lBbGxWaWV3RW50cmllcyh2b2lkKQp7CiAgICBuZXRzbm1wX3ZpZXdfY2xlYXIoICZ2aWV3TGlzdCApOwp9Cgo=