Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNdWx0aS1QYWdlIGZ1bmN0aW9ucwovLwovLyBEZXNpZ24gYW5kIGltcGxlbWVudGF0aW9uIGJ5Ci8vIC0gRmxvcmlzIHZhbiBkZW4gQmVyZyAoZmx2ZGJlcmdAd3hzLm5sKQovLyAtIExhdXJlbnQgUm9jaGVyIChyb2NoZXJsQGNsdWItaW50ZXJuZXQuZnIpCi8vIC0gU3RldmUgSm9obnNvbiAoc3RldmVAcGFyaXNncm91cC5uZXQpCi8vIC0gUGV0ciBQeXRlbGthIChweXRhQGxpZ2h0Y29tcC5jb20pCi8vIC0gSGVydukgRHJvbG9uIChkcm9sb25AaW5mb25pZS5mcikKLy8gLSBWYWRpbSBBbGV4YW5kcm92ICh2YWRpbWFsZXhhbmRyb3ZAdXNlcnMuc291cmNlZm9yZ2UubmV0Ci8vIC0gTWFydGluIER5cmluZy1BbmRlcnNlbiAobWRhQHNwYW1maWdodGVyLmNvbSkKLy8gLSBWb2xvZHlteXIgR29uY2hhcm92ICh2b2xvZHlteXIuZ29uY2hhcm92QGdtYWlsLmNvbSkKLy8KLy8gVGhpcyBmaWxlIGlzIHBhcnQgb2YgRnJlZUltYWdlIDMKLy8KLy8gQ09WRVJFRCBDT0RFIElTIFBST1ZJREVEIFVOREVSIFRISVMgTElDRU5TRSBPTiBBTiAiQVMgSVMiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRZCi8vIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTU0VEIE9SIElNUExJRUQsIElOQ0xVRElORywgV0lUSE9VVCBMSU1JVEFUSU9OLCBXQVJSQU5USUVTCi8vIFRIQVQgVEhFIENPVkVSRUQgQ09ERSBJUyBGUkVFIE9GIERFRkVDVFMsIE1FUkNIQU5UQUJMRSwgRklUIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQovLyBPUiBOT04tSU5GUklOR0lORy4gVEhFIEVOVElSRSBSSVNLIEFTIFRPIFRIRSBRVUFMSVRZIEFORCBQRVJGT1JNQU5DRSBPRiBUSEUgQ09WRVJFRAovLyBDT0RFIElTIFdJVEggWU9VLiBTSE9VTEQgQU5ZIENPVkVSRUQgQ09ERSBQUk9WRSBERUZFQ1RJVkUgSU4gQU5ZIFJFU1BFQ1QsIFlPVSAoTk9UCi8vIFRIRSBJTklUSUFMIERFVkVMT1BFUiBPUiBBTlkgT1RIRVIgQ09OVFJJQlVUT1IpIEFTU1VNRSBUSEUgQ09TVCBPRiBBTlkgTkVDRVNTQVJZCi8vIFNFUlZJQ0lORywgUkVQQUlSIE9SIENPUlJFQ1RJT04uIFRISVMgRElTQ0xBSU1FUiBPRiBXQVJSQU5UWSBDT05TVElUVVRFUyBBTiBFU1NFTlRJQUwKLy8gUEFSVCBPRiBUSElTIExJQ0VOU0UuIE5PIFVTRSBPRiBBTlkgQ09WRVJFRCBDT0RFIElTIEFVVEhPUklaRUQgSEVSRVVOREVSIEVYQ0VQVCBVTkRFUgovLyBUSElTIERJU0NMQUlNRVIuCi8vCi8vIFVzZSBhdCB5b3VyIG93biByaXNrIQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaWZkZWYgX01TQ19WRVIgCiNwcmFnbWEgd2FybmluZyAoZGlzYWJsZSA6IDQ3ODYpIC8vIGlkZW50aWZpZXIgd2FzIHRydW5jYXRlZCB0byAnbnVtYmVyJyBjaGFyYWN0ZXJzCiNlbmRpZgoKI2luY2x1ZGUgIkNhY2hlRmlsZS5oIgojaW5jbHVkZSAiRnJlZUltYWdlSU8uaCIKI2luY2x1ZGUgIlBsdWdpbi5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCmVudW0gQmxvY2tUeXBlIHsgQkxPQ0tfQ09OVElOVUVVUywgQkxPQ0tfUkVGRVJFTkNFIH07CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdHJ1Y3QgQmxvY2tUeXBlUyB7CglCbG9ja1R5cGUgbV90eXBlOwoKCUJsb2NrVHlwZVMoQmxvY2tUeXBlIHR5cGUpIDogbV90eXBlKHR5cGUpIHsKCX0KCXZpcnR1YWwgfkJsb2NrVHlwZVMoKSB7fQp9OwoKc3RydWN0IEJsb2NrQ29udGludWV1cyA6IHB1YmxpYyBCbG9ja1R5cGVTIHsKCWludCAgICAgICBtX3N0YXJ0OwoJaW50ICAgICAgIG1fZW5kOwoKCUJsb2NrQ29udGludWV1cyhpbnQgcywgaW50IGUpIDogQmxvY2tUeXBlUyhCTE9DS19DT05USU5VRVVTKSwKCW1fc3RhcnQocyksCgltX2VuZChlKSB7Cgl9CQp9OwoKc3RydWN0IEJsb2NrUmVmZXJlbmNlIDogcHVibGljIEJsb2NrVHlwZVMgewoJaW50ICAgICAgIG1fcmVmZXJlbmNlOwoJaW50ICAgICAgIG1fc2l6ZTsKCglCbG9ja1JlZmVyZW5jZShpbnQgciwgaW50IHNpemUpIDogQmxvY2tUeXBlUyhCTE9DS19SRUZFUkVOQ0UpLAoJbV9yZWZlcmVuY2UociksCgltX3NpemUoc2l6ZSkgewoJfQp9OwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdHlwZWRlZiBzdGQ6Omxpc3Q8QmxvY2tUeXBlUyAqPiBCbG9ja0xpc3Q7CnR5cGVkZWYgc3RkOjpsaXN0PEJsb2NrVHlwZVMgKj46Oml0ZXJhdG9yIEJsb2NrTGlzdEl0ZXJhdG9yOwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKRklfU1RSVUNUIChNVUxUSUJJVE1BUEhFQURFUikgewoJUGx1Z2luTm9kZSAqbm9kZTsKCUZSRUVfSU1BR0VfRk9STUFUIGZpZjsKCUZyZWVJbWFnZUlPICppbzsKCWZpX2hhbmRsZSBoYW5kbGU7CglDYWNoZUZpbGUgKm1fY2FjaGVmaWxlOwoJc3RkOjptYXA8RklCSVRNQVAgKiwgaW50PiBsb2NrZWRfcGFnZXM7CglCT09MIGNoYW5nZWQ7CglpbnQgcGFnZV9jb3VudDsKCUJsb2NrTGlzdCBtX2Jsb2NrczsKCWNoYXIgKm1fZmlsZW5hbWU7CglCT09MIHJlYWRfb25seTsKCUZSRUVfSU1BR0VfRk9STUFUIGNhY2hlX2ZpZjsKCWludCBsb2FkX2ZsYWdzOwp9OwoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEhlbHBlciBmdW5jdGlvbnMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgppbmxpbmUgdm9pZApSZXBsYWNlRXh0ZW5zaW9uKHN0ZDo6c3RyaW5nJiBkc3RfZmlsZW5hbWUsIGNvbnN0IHN0ZDo6c3RyaW5nJiBzcmNfZmlsZW5hbWUsIGNvbnN0IHN0ZDo6c3RyaW5nJiBkc3RfZXh0ZW5zaW9uKSB7CglzaXplX3QgbGFzdERvdCA9IHNyY19maWxlbmFtZS5maW5kX2xhc3Rfb2YoJy4nKTsKCWlmIChsYXN0RG90ID09IHN0ZDo6c3RyaW5nOjpucG9zKSB7CgkJZHN0X2ZpbGVuYW1lID0gc3JjX2ZpbGVuYW1lOwoJCWRzdF9maWxlbmFtZSArPSAiLiI7CgkJZHN0X2ZpbGVuYW1lICs9IGRzdF9leHRlbnNpb247Cgl9CgllbHNlIHsKCQlkc3RfZmlsZW5hbWUgPSBzcmNfZmlsZW5hbWUuc3Vic3RyKDAsIGxhc3REb3QgKyAxKTsKCQlkc3RfZmlsZW5hbWUgKz0gZHN0X2V4dGVuc2lvbjsKCX0KfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIEludGVybmFsIE11bHRpcGFnZSBmdW5jdGlvbnMKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgppbmxpbmUgTVVMVElCSVRNQVBIRUFERVIgKgpGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoRklNVUxUSUJJVE1BUCAqYml0bWFwKSB7CglyZXR1cm4gKE1VTFRJQklUTUFQSEVBREVSICopYml0bWFwLT5kYXRhOwp9CgpzdGF0aWMgQmxvY2tMaXN0SXRlcmF0b3IgRExMX0NBTExDT05WCkZyZWVJbWFnZV9GaW5kQmxvY2soRklNVUxUSUJJVE1BUCAqYml0bWFwLCBpbnQgcG9zaXRpb24pIHsKCWFzc2VydChOVUxMICE9IGJpdG1hcCk7CgoJTVVMVElCSVRNQVBIRUFERVIgKmhlYWRlciA9IEZyZWVJbWFnZV9HZXRNdWx0aUJpdG1hcEhlYWRlcihiaXRtYXApOwoKCS8vIHN0ZXAgMTogZmluZCB0aGUgYmxvY2sgdGhhdCBtYXRjaGVzIHRoZSBnaXZlbiBwb3NpdGlvbgoKCWludCBwcmV2X2NvdW50ID0gMDsKCWludCBjb3VudCA9IDA7CglCbG9ja0xpc3RJdGVyYXRvciBpOwoJQmxvY2tUeXBlUyAqY3VycmVudF9ibG9jayA9IE5VTEw7CgoJZm9yIChpID0gaGVhZGVyLT5tX2Jsb2Nrcy5iZWdpbigpOyBpICE9IGhlYWRlci0+bV9ibG9ja3MuZW5kKCk7ICsraSkgewoJCXByZXZfY291bnQgPSBjb3VudDsKCgkJc3dpdGNoKCgqaSktPm1fdHlwZSkgewoJCQljYXNlIEJMT0NLX0NPTlRJTlVFVVMgOgoJCQkJY291bnQgKz0gKChCbG9ja0NvbnRpbnVldXMgKikoKmkpKS0+bV9lbmQgLSAoKEJsb2NrQ29udGludWV1cyAqKSgqaSkpLT5tX3N0YXJ0ICsgMTsKCQkJCWJyZWFrOwoKCQkJY2FzZSBCTE9DS19SRUZFUkVOQ0UgOgoJCQkJY291bnQrKzsKCQkJCWJyZWFrOwoJCX0KCgkJY3VycmVudF9ibG9jayA9ICppOwoKCQlpZiAoY291bnQgPiBwb3NpdGlvbikKCQkJYnJlYWs7Cgl9CgoJLy8gc3RlcCAyOiBtYWtlIHN1cmUgd2UgZm91bmQgdGhlIG5vZGUuIGZyb20gaGVyZSBpdCBnZXRzIGEgbGl0dGxlIGNvbXBsaWNhdGVkOgoJLy8gKiBpZiB0aGUgYmxvY2sgaXMgdGhlcmUsIGp1c3QgcmV0dXJuIGl0CgkvLyAqIGlmIHRoZSBibG9jayBpcyBhIHNlcmllcyBvZiBibG9ja3MsIHNwbGl0IGl0IGluIG1heCAzIG5ldyBibG9ja3MKCS8vICAgYW5kIHJldHVybiB0aGUgc3BsaXR0ZWQgYmxvY2sKCglpZiAoKGN1cnJlbnRfYmxvY2spICYmIChjb3VudCA+IHBvc2l0aW9uKSkgewoJCXN3aXRjaChjdXJyZW50X2Jsb2NrLT5tX3R5cGUpIHsKCQkJY2FzZSBCTE9DS19SRUZFUkVOQ0UgOgoJCQkJcmV0dXJuIGk7CgoJCQljYXNlIEJMT0NLX0NPTlRJTlVFVVMgOgoJCQl7CgkJCQlCbG9ja0NvbnRpbnVldXMgKmJsb2NrID0gKEJsb2NrQ29udGludWV1cyAqKWN1cnJlbnRfYmxvY2s7CgoJCQkJaWYgKGJsb2NrLT5tX3N0YXJ0ICE9IGJsb2NrLT5tX2VuZCkgewoJCQkJCWludCBpdGVtID0gYmxvY2stPm1fc3RhcnQgKyAocG9zaXRpb24gLSBwcmV2X2NvdW50KTsKCgkJCQkJLy8gbGVmdCBwYXJ0CgoJCQkJCWlmIChpdGVtICE9IGJsb2NrLT5tX3N0YXJ0KSB7CgkJCQkJCUJsb2NrQ29udGludWV1cyAqYmxvY2tfYSA9IG5ldyBCbG9ja0NvbnRpbnVldXMoYmxvY2stPm1fc3RhcnQsIGl0ZW0gLSAxKTsKCQkJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5pbnNlcnQoaSwgKEJsb2NrVHlwZVMgKilibG9ja19hKTsKCQkJCQl9CgoJCQkJCS8vIG1pZGRsZSBwYXJ0CgoJCQkJCUJsb2NrQ29udGludWV1cyAqYmxvY2tfYiA9IG5ldyBCbG9ja0NvbnRpbnVldXMoaXRlbSwgaXRlbSk7CgkJCQkJQmxvY2tMaXN0SXRlcmF0b3IgYmxvY2tfdGFyZ2V0ID0gaGVhZGVyLT5tX2Jsb2Nrcy5pbnNlcnQoaSwgKEJsb2NrVHlwZVMgKilibG9ja19iKTsKCgkJCQkJLy8gcmlnaHQgcGFydAoKCQkJCQlpZiAoaXRlbSAhPSBibG9jay0+bV9lbmQpIHsKCQkJCQkJQmxvY2tDb250aW51ZXVzICpibG9ja19jID0gbmV3IEJsb2NrQ29udGludWV1cyhpdGVtICsgMSwgYmxvY2stPm1fZW5kKTsKCQkJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5pbnNlcnQoaSwgKEJsb2NrVHlwZVMgKilibG9ja19jKTsKCQkJCQl9CgoJCQkJCS8vIHJlbW92ZSB0aGUgb2xkIGJsb2NrIHRoYXQgd2FzIGp1c3Qgc3BsaXR0ZWQKCgkJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5yZW1vdmUoKEJsb2NrVHlwZVMgKilibG9jayk7CgkJCQkJZGVsZXRlIGJsb2NrOwoKCQkJCQkvLyByZXR1cm4gdGhlIHNwbGl0dGVkIGJsb2NrCgkJCQkJCgkJCQkJcmV0dXJuIGJsb2NrX3RhcmdldDsKCQkJCX0KCgkJCQlyZXR1cm4gaTsKCQkJfQoJCX0KCX0KCS8vIHdlIHNob3VsZCBuZXZlciBnbyBoZXJlIC4uLgoJYXNzZXJ0KGZhbHNlKTsKCXJldHVybiBoZWFkZXItPm1fYmxvY2tzLmVuZCgpOwp9CgppbnQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9JbnRlcm5hbEdldFBhZ2VDb3VudChGSU1VTFRJQklUTUFQICpiaXRtYXApIHsJCglpZiAoYml0bWFwKSB7CgkJaWYgKCgoTVVMVElCSVRNQVBIRUFERVIgKiliaXRtYXAtPmRhdGEpLT5oYW5kbGUpIHsKCQkJTVVMVElCSVRNQVBIRUFERVIgKmhlYWRlciA9IEZyZWVJbWFnZV9HZXRNdWx0aUJpdG1hcEhlYWRlcihiaXRtYXApOwoKCQkJaGVhZGVyLT5pby0+c2Vla19wcm9jKGhlYWRlci0+aGFuZGxlLCAwLCBTRUVLX1NFVCk7CgogICAJCQl2b2lkICpkYXRhID0gRnJlZUltYWdlX09wZW4oaGVhZGVyLT5ub2RlLCBoZWFkZXItPmlvLCBoZWFkZXItPmhhbmRsZSwgVFJVRSk7CgoJCQlpbnQgcGFnZV9jb3VudCA9IChoZWFkZXItPm5vZGUtPm1fcGx1Z2luLT5wYWdlY291bnRfcHJvYyAhPSBOVUxMKSA/IGhlYWRlci0+bm9kZS0+bV9wbHVnaW4tPnBhZ2Vjb3VudF9wcm9jKGhlYWRlci0+aW8sIGhlYWRlci0+aGFuZGxlLCBkYXRhKSA6IDE7CgoJCQlGcmVlSW1hZ2VfQ2xvc2UoaGVhZGVyLT5ub2RlLCBoZWFkZXItPmlvLCBoZWFkZXItPmhhbmRsZSwgZGF0YSk7CgoJCQlyZXR1cm4gcGFnZV9jb3VudDsKCQl9Cgl9CgoJcmV0dXJuIDA7Cn0KCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBNdWx0aXBhZ2UgZnVuY3Rpb25zCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKRklNVUxUSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfT3Blbk11bHRpQml0bWFwKEZSRUVfSU1BR0VfRk9STUFUIGZpZiwgY29uc3QgY2hhciAqZmlsZW5hbWUsIEJPT0wgY3JlYXRlX25ldywgQk9PTCByZWFkX29ubHksIEJPT0wga2VlcF9jYWNoZV9pbl9tZW1vcnksIGludCBmbGFncykgewoKCUZJTEUgKmhhbmRsZSA9IE5VTEw7Cgl0cnkgewoJCS8vIHNhbml0eSBjaGVjayBvbiB0aGUgcGFyYW1ldGVycwoKCQlpZiAoY3JlYXRlX25ldykgewoJCQlyZWFkX29ubHkgPSBGQUxTRTsKCQl9CgoJCS8vIHJldHJpZXZlIHRoZSBwbHVnaW4gbGlzdCB0byBmaW5kIHRoZSBub2RlIGJlbG9uZ2luZyB0byB0aGlzIHBsdWdpbgoKCQlQbHVnaW5MaXN0ICpsaXN0ID0gRnJlZUltYWdlX0dldFBsdWdpbkxpc3QoKTsKCgkJaWYgKGxpc3QpIHsKCQkJUGx1Z2luTm9kZSAqbm9kZSA9IGxpc3QtPkZpbmROb2RlRnJvbUZJRihmaWYpOwoKCQkJaWYgKG5vZGUpIHsKCQkJCXN0ZDo6dW5pcXVlX3B0cjxGcmVlSW1hZ2VJTz4gaW8gKG5ldyBGcmVlSW1hZ2VJTyk7CgoJCQkJU2V0RGVmYXVsdElPKGlvLmdldCgpKTsKCgkJCQlpZiAoIWNyZWF0ZV9uZXcpIHsKCQkJCQloYW5kbGUgPSBmb3BlbihmaWxlbmFtZSwgInJiIik7CgkJCQkJaWYgKGhhbmRsZSA9PSBOVUxMKSB7CgkJCQkJCXJldHVybiBOVUxMOwoJCQkJCX0KCQkJCX0KCgkJCQlzdGQ6OnVuaXF1ZV9wdHI8RklNVUxUSUJJVE1BUD4gYml0bWFwIChuZXcgRklNVUxUSUJJVE1BUCk7CgkJCQlzdGQ6OnVuaXF1ZV9wdHI8TVVMVElCSVRNQVBIRUFERVI+IGhlYWRlciAobmV3IE1VTFRJQklUTUFQSEVBREVSKTsKCQkJCWhlYWRlci0+bV9maWxlbmFtZSA9IG5ldyBjaGFyW3N0cmxlbihmaWxlbmFtZSkgKyAxXTsKCQkJCXN0cmNweShoZWFkZXItPm1fZmlsZW5hbWUsIGZpbGVuYW1lKTsKCQkJCWhlYWRlci0+bm9kZSA9IG5vZGU7CgkJCQloZWFkZXItPmZpZiA9IGZpZjsKCQkJCWhlYWRlci0+aW8gPSBpby5nZXQgKCk7CgkJCQloZWFkZXItPmhhbmRsZSA9IGhhbmRsZTsJCQkJCQkKCQkJCWhlYWRlci0+Y2hhbmdlZCA9IEZBTFNFOwkJCQkJCQoJCQkJaGVhZGVyLT5yZWFkX29ubHkgPSByZWFkX29ubHk7CgkJCQloZWFkZXItPm1fY2FjaGVmaWxlID0gTlVMTDsKCQkJCWhlYWRlci0+Y2FjaGVfZmlmID0gZmlmOwoJCQkJaGVhZGVyLT5sb2FkX2ZsYWdzID0gZmxhZ3M7CgoJCQkJLy8gc3RvcmUgdGhlIE1VTFRJQklUTUFQSEVBREVSIGluIHRoZSBzdXJyb3VuZGluZyBGSU1VTFRJQklUTUFQIHN0cnVjdHVyZQoKCQkJCWJpdG1hcC0+ZGF0YSA9IGhlYWRlci5nZXQoKTsKCgkJCQkvLyBjYWNoZSB0aGUgcGFnZSBjb3VudAoKCQkJCWhlYWRlci0+cGFnZV9jb3VudCA9IEZyZWVJbWFnZV9JbnRlcm5hbEdldFBhZ2VDb3VudChiaXRtYXAuZ2V0KCkpOwoKCQkJCS8vIGFsbG9jYXRlIGEgY29udGludWV1cyBibG9jayB0byBkZXNjcmliZSB0aGUgYml0bWFwCgoJCQkJaWYgKCFjcmVhdGVfbmV3KSB7CgkJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5wdXNoX2JhY2soKEJsb2NrVHlwZVMgKiluZXcgQmxvY2tDb250aW51ZXVzKDAsIGhlYWRlci0+cGFnZV9jb3VudCAtIDEpKTsKCQkJCX0KCgkJCQkvLyBzZXQgdXAgdGhlIGNhY2hlCgoJCQkJaWYgKCFyZWFkX29ubHkpIHsKCQkJCQlzdGQ6OnN0cmluZyBjYWNoZV9uYW1lOwoJCQkJCVJlcGxhY2VFeHRlbnNpb24oY2FjaGVfbmFtZSwgZmlsZW5hbWUsICJmaWNhY2hlIik7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RkOjp1bmlxdWVfcHRyPENhY2hlRmlsZT4gY2FjaGVfZmlsZSgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgQ2FjaGVGaWxlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWNoZV9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZWVwX2NhY2hlX2luX21lbW9yeSkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjYWNoZV9maWxlLT5vcGVuKCkpIHsKCQkJCQkJLy8gd2UgY2FuIHVzZSByZWxlYXNlKCkgYXMgc3RkOjpiYWRfYWxsb2Mgd29uJ3QgYmUgdGhyb3duIGZyb20gaGVyZSBvbgoJCQkJCQloZWFkZXItPm1fY2FjaGVmaWxlID0gY2FjaGVfZmlsZS5yZWxlYXNlKCk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJLy8gYW4gZXJyb3Igb2NjdXJlZCAuLi4KCQkJCQkJZmNsb3NlKGhhbmRsZSk7CgkJCQkJCXJldHVybiBOVUxMOwoJCQkJCX0KCQkJCX0KCQkJCS8vIHJldHVybiB0aGUgbXVsdGliaXRtYXAKCQkJCS8vIHN0ZDo6YmFkX2FsbG9jIHdvbid0IGJlIHRocm93biBmcm9tIGhlcmUgb24KCQkJCWhlYWRlci5yZWxlYXNlKCk7IC8vIG5vdyBvd25lZCBieSBiaXRtYXAKCQkJCWlvLnJlbGVhc2UoKTsJICAvLyBub3cgb3duZWQgYnkgYml0bWFwCgkJCQlyZXR1cm4gYml0bWFwLnJlbGVhc2UoKTsgLy8gbm93IG93bmVkIGJ5IGNhbGxlcgoJCQl9CgkJfQoJfSBjYXRjaCAoc3RkOjpiYWRfYWxsb2MgJikgewoJCS8qKiBAdG9kbyByZXBvcnQgZXJyb3IgKi8KCX0KCWlmIChoYW5kbGUpCgkJZmNsb3NlKGhhbmRsZSk7CglyZXR1cm4gTlVMTDsKfQoKRklNVUxUSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfT3Blbk11bHRpQml0bWFwRnJvbUhhbmRsZShGUkVFX0lNQUdFX0ZPUk1BVCBmaWYsIEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgaW50IGZsYWdzKSB7Cgl0cnkgewoJCUJPT0wgcmVhZF9vbmx5ID0gRkFMU0U7CS8vIG1vZGlmaWNhdGlvbnMgKGlmIGFueSkgd2lsbCBiZSBzdG9yZWQgaW50byB0aGUgbWVtb3J5IGNhY2hlCgoJCWlmIChpbyAmJiBoYW5kbGUpIHsKCQkKCQkJLy8gcmV0cmlldmUgdGhlIHBsdWdpbiBsaXN0IHRvIGZpbmQgdGhlIG5vZGUgYmVsb25naW5nIHRvIHRoaXMgcGx1Z2luCgkJCVBsdWdpbkxpc3QgKmxpc3QgPSBGcmVlSW1hZ2VfR2V0UGx1Z2luTGlzdCgpOwoJCQoJCQlpZiAobGlzdCkgewoJCQkJUGx1Z2luTm9kZSAqbm9kZSA9IGxpc3QtPkZpbmROb2RlRnJvbUZJRihmaWYpOwoJCQkKCQkJCWlmIChub2RlKSB7CgkJCQkJc3RkOjp1bmlxdWVfcHRyPEZJTVVMVElCSVRNQVA+IGJpdG1hcCAobmV3IEZJTVVMVElCSVRNQVApOwoJCQkJCXN0ZDo6dW5pcXVlX3B0cjxNVUxUSUJJVE1BUEhFQURFUj4gaGVhZGVyIChuZXcgTVVMVElCSVRNQVBIRUFERVIpOwoJCQkJCXN0ZDo6dW5pcXVlX3B0cjxGcmVlSW1hZ2VJTz4gdG1wX2lvIChuZXcgRnJlZUltYWdlSU8gKCppbykpOwoJCQkJCWhlYWRlci0+aW8gPSB0bXBfaW8uZ2V0KCk7CgkJCQkJaGVhZGVyLT5tX2ZpbGVuYW1lID0gTlVMTDsKCQkJCQloZWFkZXItPm5vZGUgPSBub2RlOwoJCQkJCWhlYWRlci0+ZmlmID0gZmlmOwoJCQkJCWhlYWRlci0+aGFuZGxlID0gaGFuZGxlOwkJCQkJCQoJCQkJCWhlYWRlci0+Y2hhbmdlZCA9IEZBTFNFOwkJCQkJCQoJCQkJCWhlYWRlci0+cmVhZF9vbmx5ID0gcmVhZF9vbmx5OwkKCQkJCQloZWFkZXItPm1fY2FjaGVmaWxlID0gTlVMTDsKCQkJCQloZWFkZXItPmNhY2hlX2ZpZiA9IGZpZjsKCQkJCQloZWFkZXItPmxvYWRfZmxhZ3MgPSBmbGFnczsKCQkJCQkJCQoJCQkJCS8vIHN0b3JlIHRoZSBNVUxUSUJJVE1BUEhFQURFUiBpbiB0aGUgc3Vycm91bmRpbmcgRklNVUxUSUJJVE1BUCBzdHJ1Y3R1cmUKCgkJCQkJYml0bWFwLT5kYXRhID0gaGVhZGVyLmdldCgpOwoKCQkJCQkvLyBjYWNoZSB0aGUgcGFnZSBjb3VudAoKCQkJCQloZWFkZXItPnBhZ2VfY291bnQgPSBGcmVlSW1hZ2VfSW50ZXJuYWxHZXRQYWdlQ291bnQoYml0bWFwLmdldCgpKTsKCgkJCQkJLy8gYWxsb2NhdGUgYSBjb250aW51ZXVzIGJsb2NrIHRvIGRlc2NyaWJlIHRoZSBiaXRtYXAKCgkJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5wdXNoX2JhY2soKEJsb2NrVHlwZVMgKiluZXcgQmxvY2tDb250aW51ZXVzKDAsIGhlYWRlci0+cGFnZV9jb3VudCAtIDEpKTsKCgkJCQkJaWYgKCFyZWFkX29ubHkpIHsKCQkJCQkJLy8gc2V0IHVwIHRoZSBjYWNoZQoJCQkJCQlzdGQ6OnVuaXF1ZV9wdHI8Q2FjaGVGaWxlPiBjYWNoZV9maWxlIChuZXcgQ2FjaGVGaWxlKCIiLCBUUlVFKSk7CgkJCQkJCQoJCQkJCQlpZiAoY2FjaGVfZmlsZS0+b3BlbigpKSB7CgkJCQkJCQloZWFkZXItPm1fY2FjaGVmaWxlID0gY2FjaGVfZmlsZS5yZWxlYXNlKCk7CgkJCQkJCX0KCQkJCQl9CgkJCQkJdG1wX2lvLnJlbGVhc2UoKTsKCQkJCQloZWFkZXIucmVsZWFzZSgpOwoJCQkJCXJldHVybiBiaXRtYXAucmVsZWFzZSgpOwoJCQkJfQoJCQl9CgkJfQoJfSBjYXRjaCAoc3RkOjpiYWRfYWxsb2MgJikgewoJCS8qKiBAdG9kbyByZXBvcnQgZXJyb3IgKi8KCX0KCXJldHVybiBOVUxMOwp9CgpCT09MIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfU2F2ZU11bHRpQml0bWFwVG9IYW5kbGUoRlJFRV9JTUFHRV9GT1JNQVQgZmlmLCBGSU1VTFRJQklUTUFQICpiaXRtYXAsIEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgaW50IGZsYWdzKSB7CglpZighYml0bWFwIHx8ICFiaXRtYXAtPmRhdGEgfHwgIWlvIHx8ICFoYW5kbGUpIHsKCQlyZXR1cm4gRkFMU0U7Cgl9CgoJQk9PTCBzdWNjZXNzID0gVFJVRTsKCgkvLyByZXRyaWV2ZSB0aGUgcGx1Z2luIGxpc3QgdG8gZmluZCB0aGUgbm9kZSBiZWxvbmdpbmcgdG8gdGhpcyBwbHVnaW4KCVBsdWdpbkxpc3QgKmxpc3QgPSBGcmVlSW1hZ2VfR2V0UGx1Z2luTGlzdCgpOwoJCglpZiAobGlzdCkgewoJCVBsdWdpbk5vZGUgKm5vZGUgPSBsaXN0LT5GaW5kTm9kZUZyb21GSUYoZmlmKTsKCgkJaWYobm9kZSkgewoJCQlNVUxUSUJJVE1BUEhFQURFUiAqaGVhZGVyID0gRnJlZUltYWdlX0dldE11bHRpQml0bWFwSGVhZGVyKGJpdG1hcCk7CgkJCQoJCQkvLyBkc3QgZGF0YQoJCQl2b2lkICpkYXRhID0gRnJlZUltYWdlX09wZW4obm9kZSwgaW8sIGhhbmRsZSwgRkFMU0UpOwoJCQkvLyBzcmMgZGF0YQoJCQl2b2lkICpkYXRhX3JlYWQgPSBOVUxMOwoJCQkKCQkJaWYoaGVhZGVyLT5oYW5kbGUpIHsKCQkJCS8vIG9wZW4gc3JjCgkJCQloZWFkZXItPmlvLT5zZWVrX3Byb2MoaGVhZGVyLT5oYW5kbGUsIDAsIFNFRUtfU0VUKTsKCQkJCWRhdGFfcmVhZCA9IEZyZWVJbWFnZV9PcGVuKGhlYWRlci0+bm9kZSwgaGVhZGVyLT5pbywgaGVhZGVyLT5oYW5kbGUsIFRSVUUpOwoJCQl9CgkJCQoJCQkvLyB3cml0ZSBhbGwgdGhlIHBhZ2VzIHRvIHRoZSBmaWxlIHVzaW5nIGhhbmRsZSBhbmQgaW8KCQkJCgkJCWludCBjb3VudCA9IDA7CgkJCQoJCQlmb3IgKEJsb2NrTGlzdEl0ZXJhdG9yIGkgPSBoZWFkZXItPm1fYmxvY2tzLmJlZ2luKCk7IGkgIT0gaGVhZGVyLT5tX2Jsb2Nrcy5lbmQoKTsgaSsrKSB7CgkJCQlpZiAoc3VjY2VzcykgewoJCQkJCXN3aXRjaCgoKmkpLT5tX3R5cGUpIHsKCQkJCQkJY2FzZSBCTE9DS19DT05USU5VRVVTOgoJCQkJCQl7CgkJCQkJCQlCbG9ja0NvbnRpbnVldXMgKmJsb2NrID0gKEJsb2NrQ29udGludWV1cyAqKSgqaSk7CgkJCQkJCQkKCQkJCQkJCWZvciAoaW50IGogPSBibG9jay0+bV9zdGFydDsgaiA8PSBibG9jay0+bV9lbmQ7IGorKykgewoKCQkJCQkJCQkvLyBsb2FkIHRoZSBvcmlnaW5hbCBzb3VyY2UgZGF0YQoJCQkJCQkJCUZJQklUTUFQICpkaWIgPSBoZWFkZXItPm5vZGUtPm1fcGx1Z2luLT5sb2FkX3Byb2MoaGVhZGVyLT5pbywgaGVhZGVyLT5oYW5kbGUsIGosIGhlYWRlci0+bG9hZF9mbGFncywgZGF0YV9yZWFkKTsKCQkJCQkJCQkKCQkJCQkJCQkvLyBzYXZlIHRoZSBkYXRhCgkJCQkJCQkJc3VjY2VzcyA9IG5vZGUtPm1fcGx1Z2luLT5zYXZlX3Byb2MoaW8sIGRpYiwgaGFuZGxlLCBjb3VudCwgZmxhZ3MsIGRhdGEpOwoJCQkJCQkJCWNvdW50Kys7CgkJCQkJCQkJCgkJCQkJCQkJRnJlZUltYWdlX1VubG9hZChkaWIpOwoJCQkJCQkJfQoJCQkJCQkJCgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCQkKCQkJCQkJY2FzZSBCTE9DS19SRUZFUkVOQ0U6CgkJCQkJCXsKCQkJCQkJCUJsb2NrUmVmZXJlbmNlICpyZWYgPSAoQmxvY2tSZWZlcmVuY2UgKikoKmkpOwoJCQkJCQkJCgkJCQkJCQkvLyByZWFkIHRoZSBjb21wcmVzc2VkIGRhdGEKCQkJCQkJCQoJCQkJCQkJQllURSAqY29tcHJlc3NlZF9kYXRhID0gKEJZVEUqKW1hbGxvYyhyZWYtPm1fc2l6ZSAqIHNpemVvZihCWVRFKSk7CgkJCQkJCQkKCQkJCQkJCWhlYWRlci0+bV9jYWNoZWZpbGUtPnJlYWRGaWxlKChCWVRFICopY29tcHJlc3NlZF9kYXRhLCByZWYtPm1fcmVmZXJlbmNlLCByZWYtPm1fc2l6ZSk7CgkJCQkJCQkKCQkJCQkJCS8vIHVuY29tcHJlc3MgdGhlIGRhdGEKCQkJCQkJCQoJCQkJCQkJRklNRU1PUlkgKmhtZW0gPSBGcmVlSW1hZ2VfT3Blbk1lbW9yeShjb21wcmVzc2VkX2RhdGEsIHJlZi0+bV9zaXplKTsKCQkJCQkJCUZJQklUTUFQICpkaWIgPSBGcmVlSW1hZ2VfTG9hZEZyb21NZW1vcnkoaGVhZGVyLT5jYWNoZV9maWYsIGhtZW0sIDApOwoJCQkJCQkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhtZW0pOwoJCQkJCQkJCgkJCQkJCQkvLyBnZXQgcmlkIG9mIHRoZSBidWZmZXIKCQkJCQkJCWZyZWUoY29tcHJlc3NlZF9kYXRhKTsKCQkJCQkJCQoJCQkJCQkJLy8gc2F2ZSB0aGUgZGF0YQoJCQkJCQkJCgkJCQkJCQlzdWNjZXNzID0gbm9kZS0+bV9wbHVnaW4tPnNhdmVfcHJvYyhpbywgZGliLCBoYW5kbGUsIGNvdW50LCBmbGFncywgZGF0YSk7CgkJCQkJCQljb3VudCsrOwoJCQkJCQkJCgkJCQkJCQkvLyB1bmxvYWQgdGhlIGRpYgoKCQkJCQkJCUZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCX0gZWxzZSB7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQkJCgkJCS8vIGNsb3NlIHRoZSBmaWxlcwoJCQkKCQkJRnJlZUltYWdlX0Nsb3NlKGhlYWRlci0+bm9kZSwgaGVhZGVyLT5pbywgaGVhZGVyLT5oYW5kbGUsIGRhdGFfcmVhZCk7CgoJCQlGcmVlSW1hZ2VfQ2xvc2Uobm9kZSwgaW8sIGhhbmRsZSwgZGF0YSk7IAoJCQkKCQkJcmV0dXJuIHN1Y2Nlc3M7CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKCkJPT0wgRExMX0NBTExDT05WCkZyZWVJbWFnZV9DbG9zZU11bHRpQml0bWFwKEZJTVVMVElCSVRNQVAgKmJpdG1hcCwgaW50IGZsYWdzKSB7CglpZiAoYml0bWFwKSB7CgkJQk9PTCBzdWNjZXNzID0gVFJVRTsKCQkKCQlpZiAoYml0bWFwLT5kYXRhKSB7CgkJCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsJCQkKCQkJCgkJCS8vIHNhdmVzIGNoYW5nZXMgb25seSBvZiBpbWFnZXMgbG9hZGVkIGRpcmVjdGx5IGZyb20gYSBmaWxlCgkJCWlmIChoZWFkZXItPmNoYW5nZWQgJiYgaGVhZGVyLT5tX2ZpbGVuYW1lKSB7CgkJCQl0cnkgewoJCQkJCS8vIG9wZW4gYSB0ZW1wIGZpbGUKCgkJCQkJc3RkOjpzdHJpbmcgc3Bvb2xfbmFtZTsKCgkJCQkJUmVwbGFjZUV4dGVuc2lvbihzcG9vbF9uYW1lLCBoZWFkZXItPm1fZmlsZW5hbWUsICJmaXNwb29sIik7CgoJCQkJCS8vIG9wZW4gdGhlIHNwb29sIGZpbGUgYW5kIHRoZSBzb3VyY2UgZmlsZQogICAgICAgIAoJCQkJCUZJTEUgKmYgPSBmb3BlbihzcG9vbF9uYW1lLmNfc3RyKCksICJ3K2IiKTsKCQkJCQoJCQkJCS8vIHNhdmVzIGNoYW5nZXMKCQkJCQlpZiAoZiA9PSBOVUxMKSB7CgkJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhoZWFkZXItPmZpZiwgIkZhaWxlZCB0byBvcGVuICVzLCAlcyIsIHNwb29sX25hbWUuY19zdHIoKSwgc3RyZXJyb3IoZXJybm8pKTsKCQkJCQkJc3VjY2VzcyA9IEZBTFNFOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXN1Y2Nlc3MgPSBGcmVlSW1hZ2VfU2F2ZU11bHRpQml0bWFwVG9IYW5kbGUoaGVhZGVyLT5maWYsIGJpdG1hcCwgaGVhZGVyLT5pbywgKGZpX2hhbmRsZSlmLCBmbGFncyk7CgoJCQkJCQkvLyBjbG9zZSB0aGUgZmlsZXMKCgkJCQkJCWlmIChmY2xvc2UoZikgIT0gMCkgewoJCQkJCQkJc3VjY2VzcyA9IEZBTFNFOwoJCQkJCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGhlYWRlci0+ZmlmLCAiRmFpbGVkIHRvIGNsb3NlICVzLCAlcyIsIHNwb29sX25hbWUuY19zdHIoKSwgc3RyZXJyb3IoZXJybm8pKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQlpZiAoaGVhZGVyLT5oYW5kbGUpIHsKCQkJCQkJZmNsb3NlKChGSUxFICopaGVhZGVyLT5oYW5kbGUpOwoJCQkJCX0KCQkJCQoJCQkJCS8vIGFwcGxpZXMgY2hhbmdlcyB0byB0aGUgZGVzdGluYXRpb24gZmlsZQoKCQkJCQlpZiAoc3VjY2VzcykgewoJCQkJCQlyZW1vdmUoaGVhZGVyLT5tX2ZpbGVuYW1lKTsKCQkJCQkJc3VjY2VzcyA9IChyZW5hbWUoc3Bvb2xfbmFtZS5jX3N0cigpLCBoZWFkZXItPm1fZmlsZW5hbWUpID09IDApID8gVFJVRTpGQUxTRTsKCQkJCQkJaWYoIXN1Y2Nlc3MpIHsKCQkJCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhoZWFkZXItPmZpZiwgIkZhaWxlZCB0byByZW5hbWUgJXMgdG8gJXMiLCBzcG9vbF9uYW1lLmNfc3RyKCksIGhlYWRlci0+bV9maWxlbmFtZSk7CgkJCQkJCX0KCQkJCQl9IGVsc2UgewoJCQkJCQlyZW1vdmUoc3Bvb2xfbmFtZS5jX3N0cigpKTsKCQkJCQl9CgkJCQl9IGNhdGNoIChzdGQ6OmJhZF9hbGxvYyAmKSB7CgkJCQkJc3VjY2VzcyA9IEZBTFNFOwoJCQkJfQoKCQkJfSBlbHNlIHsKCQkJCWlmIChoZWFkZXItPmhhbmRsZSAmJiBoZWFkZXItPm1fZmlsZW5hbWUpIHsKCQkJCQlmY2xvc2UoKEZJTEUgKiloZWFkZXItPmhhbmRsZSk7CgkJCQl9CgkJCX0KCgkJCS8vIGNsZWFyIHRoZSBibG9ja3MgbGlzdAoKCQkJZm9yIChCbG9ja0xpc3RJdGVyYXRvciBpID0gaGVhZGVyLT5tX2Jsb2Nrcy5iZWdpbigpOyBpICE9IGhlYWRlci0+bV9ibG9ja3MuZW5kKCk7ICsraSkgewoJCQkJZGVsZXRlICppOwoJCQl9CgoJCQkvLyBmbHVzaCBhbmQgZGlzcG9zZSB0aGUgY2FjaGUKCgkJCWlmIChoZWFkZXItPm1fY2FjaGVmaWxlKSB7CgkJCQloZWFkZXItPm1fY2FjaGVmaWxlLT5jbG9zZSgpOwoJCQkJZGVsZXRlIGhlYWRlci0+bV9jYWNoZWZpbGU7CgkJCX0KCgkJCS8vIGRlbGV0ZSB0aGUgbGFzdCBvcGVuIGJpdG1hcHMKCgkJCXdoaWxlICghaGVhZGVyLT5sb2NrZWRfcGFnZXMuZW1wdHkoKSkgewoJCQkJRnJlZUltYWdlX1VubG9hZChoZWFkZXItPmxvY2tlZF9wYWdlcy5iZWdpbigpLT5maXJzdCk7CgoJCQkJaGVhZGVyLT5sb2NrZWRfcGFnZXMuZXJhc2UoaGVhZGVyLT5sb2NrZWRfcGFnZXMuYmVnaW4oKS0+Zmlyc3QpOwoJCQl9CgoJCQkvLyBnZXQgcmlkIG9mIHRoZSBJTyBzdHJ1Y3R1cmUKCgkJCWRlbGV0ZSBoZWFkZXItPmlvOwoKCQkJLy8gZGVsZXRlIHRoZSBmaWxlbmFtZQoKCQkJaWYoaGVhZGVyLT5tX2ZpbGVuYW1lKSB7CgkJCQlkZWxldGVbXSBoZWFkZXItPm1fZmlsZW5hbWU7CgkJCX0KCgkJCS8vIGRlbGV0ZSB0aGUgRklNVUxUSUJJVE1BUEhFQURFUgoKCQkJZGVsZXRlIGhlYWRlcjsKCQl9CgoJCWRlbGV0ZSBiaXRtYXA7CgoJCXJldHVybiBzdWNjZXNzOwoJfQoKCXJldHVybiBGQUxTRTsKfQoKaW50IERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfR2V0UGFnZUNvdW50KEZJTVVMVElCSVRNQVAgKmJpdG1hcCkgewoJaWYgKGJpdG1hcCkgewoJCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsKCgkJaWYgKGhlYWRlci0+cGFnZV9jb3VudCA9PSAtMSkgewoJCQloZWFkZXItPnBhZ2VfY291bnQgPSAwOwoKCQkJZm9yIChCbG9ja0xpc3RJdGVyYXRvciBpID0gaGVhZGVyLT5tX2Jsb2Nrcy5iZWdpbigpOyBpICE9IGhlYWRlci0+bV9ibG9ja3MuZW5kKCk7ICsraSkgewoJCQkJc3dpdGNoKCgqaSktPm1fdHlwZSkgewoJCQkJCWNhc2UgQkxPQ0tfQ09OVElOVUVVUyA6CgkJCQkJCWhlYWRlci0+cGFnZV9jb3VudCArPSAoKEJsb2NrQ29udGludWV1cyAqKSgqaSkpLT5tX2VuZCAtICgoQmxvY2tDb250aW51ZXVzICopKCppKSktPm1fc3RhcnQgKyAxOwoJCQkJCQlicmVhazsKCgkJCQkJY2FzZSBCTE9DS19SRUZFUkVOQ0UgOgoJCQkJCQloZWFkZXItPnBhZ2VfY291bnQrKzsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBoZWFkZXItPnBhZ2VfY291bnQ7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBCbG9ja1JlZmVyZW5jZSogCkZyZWVJbWFnZV9TYXZlUGFnZVRvQmxvY2soTVVMVElCSVRNQVBIRUFERVIgKmhlYWRlciwgRklCSVRNQVAgKmRhdGEpIHsKCWlmIChoZWFkZXItPnJlYWRfb25seSB8fCAhaGVhZGVyLT5sb2NrZWRfcGFnZXMuZW1wdHkoKSkKCQlyZXR1cm4gTlVMTDsKCglEV09SRCBjb21wcmVzc2VkX3NpemUgPSAwOwoJQllURSAqY29tcHJlc3NlZF9kYXRhID0gTlVMTDsKCgkvLyBjb21wcmVzcyB0aGUgYml0bWFwIGRhdGEKCgkvLyBvcGVuIGEgbWVtb3J5IGhhbmRsZQoJRklNRU1PUlkgKmhtZW0gPSBGcmVlSW1hZ2VfT3Blbk1lbW9yeSgpOwoJaWYoaG1lbT09TlVMTCkgcmV0dXJuIE5VTEw7CgkvLyBzYXZlIHRoZSBmaWxlIHRvIG1lbW9yeQoJaWYoIUZyZWVJbWFnZV9TYXZlVG9NZW1vcnkoaGVhZGVyLT5jYWNoZV9maWYsIGRhdGEsIGhtZW0sIDApKSB7CgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhtZW0pOwoJCXJldHVybiBOVUxMOwoJfQoJLy8gZ2V0IHRoZSBidWZmZXIgZnJvbSB0aGUgbWVtb3J5IHN0cmVhbQoJaWYoIUZyZWVJbWFnZV9BY3F1aXJlTWVtb3J5KGhtZW0sICZjb21wcmVzc2VkX2RhdGEsICZjb21wcmVzc2VkX3NpemUpKSB7CgkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhtZW0pOwoJCXJldHVybiBOVUxMOwoJfQoKCS8vIHdyaXRlIHRoZSBjb21wcmVzc2VkIGRhdGEgdG8gdGhlIGNhY2hlCglpbnQgcmVmID0gaGVhZGVyLT5tX2NhY2hlZmlsZS0+d3JpdGVGaWxlKGNvbXByZXNzZWRfZGF0YSwgY29tcHJlc3NlZF9zaXplKTsKCS8vIGdldCByaWQgb2YgdGhlIGNvbXByZXNzZWQgZGF0YQoJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhtZW0pOwoKCXJldHVybiBuZXcoc3RkOjpub3Rocm93KSBCbG9ja1JlZmVyZW5jZShyZWYsIGNvbXByZXNzZWRfc2l6ZSk7Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9BcHBlbmRQYWdlKEZJTVVMVElCSVRNQVAgKmJpdG1hcCwgRklCSVRNQVAgKmRhdGEpIHsKCWlmICghYml0bWFwIHx8ICFkYXRhKSAKCQlyZXR1cm47CgoJTVVMVElCSVRNQVBIRUFERVIgKmhlYWRlciA9IEZyZWVJbWFnZV9HZXRNdWx0aUJpdG1hcEhlYWRlcihiaXRtYXApOwoKCUJsb2NrUmVmZXJlbmNlICpibG9jayA9IEZyZWVJbWFnZV9TYXZlUGFnZVRvQmxvY2soaGVhZGVyLCBkYXRhKTsKCWlmKGJsb2NrPT1OVUxMKSByZXR1cm47CgoJLy8gYWRkIHRoZSBibG9jawoJaGVhZGVyLT5tX2Jsb2Nrcy5wdXNoX2JhY2soKEJsb2NrVHlwZVMgKilibG9jayk7CgloZWFkZXItPmNoYW5nZWQgPSBUUlVFOwoJaGVhZGVyLT5wYWdlX2NvdW50ID0gLTE7Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9JbnNlcnRQYWdlKEZJTVVMVElCSVRNQVAgKmJpdG1hcCwgaW50IHBhZ2UsIEZJQklUTUFQICpkYXRhKSB7CglpZiAoIWJpdG1hcCB8fCAhZGF0YSkgCgkJcmV0dXJuOwoKCWlmIChwYWdlID49IEZyZWVJbWFnZV9HZXRQYWdlQ291bnQoYml0bWFwKSkgCgkJcmV0dXJuOwoJCQkKCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsKCglCbG9ja1JlZmVyZW5jZSAqYmxvY2sgPSBGcmVlSW1hZ2VfU2F2ZVBhZ2VUb0Jsb2NrKGhlYWRlciwgZGF0YSk7CglpZihibG9jaz09TlVMTCkgcmV0dXJuOwoKCS8vIGFkZCBhIGJsb2NrCglpZiAocGFnZSA+IDApIHsKCQlCbG9ja0xpc3RJdGVyYXRvciBibG9ja19zb3VyY2UgPSBGcmVlSW1hZ2VfRmluZEJsb2NrKGJpdG1hcCwgcGFnZSk7CQkKCgkJaGVhZGVyLT5tX2Jsb2Nrcy5pbnNlcnQoYmxvY2tfc291cmNlLCAoQmxvY2tUeXBlUyAqKWJsb2NrKTsKCX0gZWxzZSB7CgkJaGVhZGVyLT5tX2Jsb2Nrcy5wdXNoX2Zyb250KChCbG9ja1R5cGVTICopYmxvY2spOwoJfQoKCWhlYWRlci0+Y2hhbmdlZCA9IFRSVUU7CgloZWFkZXItPnBhZ2VfY291bnQgPSAtMTsKfQoKdm9pZCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0RlbGV0ZVBhZ2UoRklNVUxUSUJJVE1BUCAqYml0bWFwLCBpbnQgcGFnZSkgewoJaWYgKGJpdG1hcCkgewoJCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsKCgkJaWYgKCghaGVhZGVyLT5yZWFkX29ubHkpICYmIChoZWFkZXItPmxvY2tlZF9wYWdlcy5lbXB0eSgpKSkgewoJCQlpZiAoRnJlZUltYWdlX0dldFBhZ2VDb3VudChiaXRtYXApID4gMSkgewoJCQkJQmxvY2tMaXN0SXRlcmF0b3IgaSA9IEZyZWVJbWFnZV9GaW5kQmxvY2soYml0bWFwLCBwYWdlKTsKCgkJCQlpZiAoaSAhPSBoZWFkZXItPm1fYmxvY2tzLmVuZCgpKSB7CgkJCQkJc3dpdGNoKCgqaSktPm1fdHlwZSkgewoJCQkJCQljYXNlIEJMT0NLX0NPTlRJTlVFVVMgOgoJCQkJCQkJZGVsZXRlICppOwoJCQkJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5lcmFzZShpKTsKCQkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSBCTE9DS19SRUZFUkVOQ0UgOgoJCQkJCQkJaGVhZGVyLT5tX2NhY2hlZmlsZS0+ZGVsZXRlRmlsZSgoKEJsb2NrUmVmZXJlbmNlICopKCppKSktPm1fcmVmZXJlbmNlKTsKCQkJCQkJCWRlbGV0ZSAqaTsKCQkJCQkJCWhlYWRlci0+bV9ibG9ja3MuZXJhc2UoaSk7CgkJCQkJCQlicmVhazsKCQkJCQl9CgoJCQkJCWhlYWRlci0+Y2hhbmdlZCA9IFRSVUU7CgkJCQkJaGVhZGVyLT5wYWdlX2NvdW50ID0gLTE7CgkJCQl9CgkJCX0KCQl9Cgl9Cn0KCgpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfTG9ja1BhZ2UoRklNVUxUSUJJVE1BUCAqYml0bWFwLCBpbnQgcGFnZSkgewoJaWYgKGJpdG1hcCkgewoJCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsKCgkJLy8gb25seSBsb2NrIGlmIHRoZSBwYWdlIHdhc24ndCBsb2NrZWQgYmVmb3JlLi4uCgoJCWZvciAoc3RkOjptYXA8RklCSVRNQVAgKiwgaW50Pjo6aXRlcmF0b3IgaSA9IGhlYWRlci0+bG9ja2VkX3BhZ2VzLmJlZ2luKCk7IGkgIT0gaGVhZGVyLT5sb2NrZWRfcGFnZXMuZW5kKCk7ICsraSkgewoJCQlpZiAoaS0+c2Vjb25kID09IHBhZ2UpIHsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgkJfQoKCQkvLyBvcGVuIHRoZSBiaXRtYXAKCgkJaGVhZGVyLT5pby0+c2Vla19wcm9jKGhlYWRlci0+aGFuZGxlLCAwLCBTRUVLX1NFVCk7CgogICAJCXZvaWQgKmRhdGEgPSBGcmVlSW1hZ2VfT3BlbihoZWFkZXItPm5vZGUsIGhlYWRlci0+aW8sIGhlYWRlci0+aGFuZGxlLCBUUlVFKTsKCgkJLy8gbG9hZCB0aGUgYml0bWFwIGRhdGEKCgkJaWYgKGRhdGEgIT0gTlVMTCkgewoJCQlGSUJJVE1BUCAqZGliID0gKGhlYWRlci0+bm9kZS0+bV9wbHVnaW4tPmxvYWRfcHJvYyAhPSBOVUxMKSA/IGhlYWRlci0+bm9kZS0+bV9wbHVnaW4tPmxvYWRfcHJvYyhoZWFkZXItPmlvLCBoZWFkZXItPmhhbmRsZSwgcGFnZSwgaGVhZGVyLT5sb2FkX2ZsYWdzLCBkYXRhKSA6IE5VTEw7CgoJCQkvLyBjbG9zZSB0aGUgZmlsZQoKCQkJRnJlZUltYWdlX0Nsb3NlKGhlYWRlci0+bm9kZSwgaGVhZGVyLT5pbywgaGVhZGVyLT5oYW5kbGUsIGRhdGEpOwoKCQkJLy8gaWYgdGhlcmUgd2FzIHN0aWxsIGFub3RoZXIgYml0bWFwIG9wZW4sIGdldCByaWQgb2YgaXQKCgkJCWlmIChkaWIpIHsKCQkJCWhlYWRlci0+bG9ja2VkX3BhZ2VzW2RpYl0gPSBwYWdlOwoKCQkJCXJldHVybiBkaWI7CgkJCX0JCgoJCQlyZXR1cm4gTlVMTDsKCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgRExMX0NBTExDT05WCkZyZWVJbWFnZV9VbmxvY2tQYWdlKEZJTVVMVElCSVRNQVAgKmJpdG1hcCwgRklCSVRNQVAgKnBhZ2UsIEJPT0wgY2hhbmdlZCkgewoJaWYgKChiaXRtYXApICYmIChwYWdlKSkgewoJCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsKCgkJLy8gZmluZCBvdXQgaWYgdGhlIHBhZ2Ugd2UgdHJ5IHRvIHVubG9jayBpcyBhY3R1YWxseSBsb2NrZWQuLi4KCgkJaWYgKGhlYWRlci0+bG9ja2VkX3BhZ2VzLmZpbmQocGFnZSkgIT0gaGVhZGVyLT5sb2NrZWRfcGFnZXMuZW5kKCkpIHsKCQkJLy8gc3RvcmUgdGhlIGJpdG1hcCBjb21wcmVzc2VkIGluIHRoZSBjYWNoZSBmb3IgbGF0ZXIgd3JpdGluZwoKCQkJaWYgKGNoYW5nZWQgJiYgIWhlYWRlci0+cmVhZF9vbmx5KSB7CgkJCQloZWFkZXItPmNoYW5nZWQgPSBUUlVFOwoKCQkJCS8vIGN1dCBsb29zZSB0aGUgYmxvY2sgZnJvbSB0aGUgcmVzdAoKCQkJCUJsb2NrTGlzdEl0ZXJhdG9yIGkgPSBGcmVlSW1hZ2VfRmluZEJsb2NrKGJpdG1hcCwgaGVhZGVyLT5sb2NrZWRfcGFnZXNbcGFnZV0pOwoKCQkJCS8vIGNvbXByZXNzIHRoZSBkYXRhCgoJCQkJRFdPUkQgY29tcHJlc3NlZF9zaXplID0gMDsKCQkJCUJZVEUgKmNvbXByZXNzZWRfZGF0YSA9IE5VTEw7CgoJCQkJLy8gb3BlbiBhIG1lbW9yeSBoYW5kbGUKCQkJCUZJTUVNT1JZICpobWVtID0gRnJlZUltYWdlX09wZW5NZW1vcnkoKTsKCQkJCS8vIHNhdmUgdGhlIHBhZ2UgdG8gbWVtb3J5CgkJCQlGcmVlSW1hZ2VfU2F2ZVRvTWVtb3J5KGhlYWRlci0+Y2FjaGVfZmlmLCBwYWdlLCBobWVtLCAwKTsKCQkJCS8vIGdldCB0aGUgYnVmZmVyIGZyb20gdGhlIG1lbW9yeSBzdHJlYW0KCQkJCUZyZWVJbWFnZV9BY3F1aXJlTWVtb3J5KGhtZW0sICZjb21wcmVzc2VkX2RhdGEsICZjb21wcmVzc2VkX3NpemUpOwoKCQkJCS8vIHdyaXRlIHRoZSBkYXRhIHRvIHRoZSBjYWNoZQoKCQkJCXN3aXRjaCAoKCppKS0+bV90eXBlKSB7CgkJCQkJY2FzZSBCTE9DS19DT05USU5VRVVTIDoKCQkJCQl7CgkJCQkJCWludCBpUGFnZSA9IGhlYWRlci0+bV9jYWNoZWZpbGUtPndyaXRlRmlsZShjb21wcmVzc2VkX2RhdGEsIGNvbXByZXNzZWRfc2l6ZSk7CgoJCQkJCQlkZWxldGUgKCppKTsKCgkJCQkJCSppID0gKEJsb2NrVHlwZVMgKiluZXcgQmxvY2tSZWZlcmVuY2UoaVBhZ2UsIGNvbXByZXNzZWRfc2l6ZSk7CgoJCQkJCQlicmVhazsKCQkJCQl9CgoJCQkJCWNhc2UgQkxPQ0tfUkVGRVJFTkNFIDoKCQkJCQl7CgkJCQkJCUJsb2NrUmVmZXJlbmNlICpyZWZlcmVuY2UgPSAoQmxvY2tSZWZlcmVuY2UgKikoKmkpOwoKCQkJCQkJaGVhZGVyLT5tX2NhY2hlZmlsZS0+ZGVsZXRlRmlsZShyZWZlcmVuY2UtPm1fcmVmZXJlbmNlKTsKCgkJCQkJCWRlbGV0ZSAoKmkpOwoKCQkJCQkJaW50IGlQYWdlID0gaGVhZGVyLT5tX2NhY2hlZmlsZS0+d3JpdGVGaWxlKGNvbXByZXNzZWRfZGF0YSwgY29tcHJlc3NlZF9zaXplKTsKCgkJCQkJCSppID0gKEJsb2NrVHlwZVMgKiluZXcgQmxvY2tSZWZlcmVuY2UoaVBhZ2UsIGNvbXByZXNzZWRfc2l6ZSk7CgoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gZ2V0IHJpZCBvZiB0aGUgY29tcHJlc3NlZCBkYXRhCgoJCQkJRnJlZUltYWdlX0Nsb3NlTWVtb3J5KGhtZW0pOwoJCQl9CgoJCQkvLyByZXNldCB0aGUgbG9ja2VkIHBhZ2Ugc28gdGhhdCBhbm90aGVyIHBhZ2UgY2FuIGJlIGxvY2tlZAoKCQkJRnJlZUltYWdlX1VubG9hZChwYWdlKTsKCgkJCWhlYWRlci0+bG9ja2VkX3BhZ2VzLmVyYXNlKHBhZ2UpOwoJCX0KCX0KfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX01vdmVQYWdlKEZJTVVMVElCSVRNQVAgKmJpdG1hcCwgaW50IHRhcmdldCwgaW50IHNvdXJjZSkgewoJaWYgKGJpdG1hcCkgewoJCU1VTFRJQklUTUFQSEVBREVSICpoZWFkZXIgPSBGcmVlSW1hZ2VfR2V0TXVsdGlCaXRtYXBIZWFkZXIoYml0bWFwKTsKCgkJaWYgKCghaGVhZGVyLT5yZWFkX29ubHkpICYmIChoZWFkZXItPmxvY2tlZF9wYWdlcy5lbXB0eSgpKSkgewoJCQlpZiAoKHRhcmdldCAhPSBzb3VyY2UpICYmICgodGFyZ2V0ID49IDApICYmICh0YXJnZXQgPCBGcmVlSW1hZ2VfR2V0UGFnZUNvdW50KGJpdG1hcCkpKSAmJiAoKHNvdXJjZSA+PSAwKSAmJiAoc291cmNlIDwgRnJlZUltYWdlX0dldFBhZ2VDb3VudChiaXRtYXApKSkpIHsKCQkJCUJsb2NrTGlzdEl0ZXJhdG9yIGJsb2NrX3NvdXJjZSA9IEZyZWVJbWFnZV9GaW5kQmxvY2soYml0bWFwLCB0YXJnZXQpOwoJCQkJQmxvY2tMaXN0SXRlcmF0b3IgYmxvY2tfdGFyZ2V0ID0gRnJlZUltYWdlX0ZpbmRCbG9jayhiaXRtYXAsIHNvdXJjZSk7CgoJCQkJaGVhZGVyLT5tX2Jsb2Nrcy5pbnNlcnQoYmxvY2tfdGFyZ2V0LCAqYmxvY2tfc291cmNlKTsJCQkKCQkJCWhlYWRlci0+bV9ibG9ja3MuZXJhc2UoYmxvY2tfc291cmNlKTsKCgkJCQloZWFkZXItPmNoYW5nZWQgPSBUUlVFOwoKCQkJCXJldHVybiBUUlVFOwoJCQl9CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX0dldExvY2tlZFBhZ2VOdW1iZXJzKEZJTVVMVElCSVRNQVAgKmJpdG1hcCwgaW50ICpwYWdlcywgaW50ICpjb3VudCkgewoJaWYgKChiaXRtYXApICYmIChjb3VudCkpIHsKCQlNVUxUSUJJVE1BUEhFQURFUiAqaGVhZGVyID0gRnJlZUltYWdlX0dldE11bHRpQml0bWFwSGVhZGVyKGJpdG1hcCk7CgoJCWlmICgocGFnZXMgPT0gTlVMTCkgfHwgKCpjb3VudCA9PSAwKSkgewoJCQkqY291bnQgPSAoaW50KWhlYWRlci0+bG9ja2VkX3BhZ2VzLnNpemUoKTsKCQl9IGVsc2UgewoJCQlpbnQgYyA9IDA7CgoJCQlmb3IgKHN0ZDo6bWFwPEZJQklUTUFQICosIGludD46Oml0ZXJhdG9yIGkgPSBoZWFkZXItPmxvY2tlZF9wYWdlcy5iZWdpbigpOyBpICE9IGhlYWRlci0+bG9ja2VkX3BhZ2VzLmVuZCgpOyArK2kpIHsKCQkJCXBhZ2VzW2NdID0gaS0+c2Vjb25kOwoKCQkJCWMrKzsKCgkJCQlpZiAoYyA9PSAqY291bnQpCgkJCQkJYnJlYWs7CgkJCX0KCQl9CgoJCXJldHVybiBUUlVFOwoJfQoKCXJldHVybiBGQUxTRTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIE1lbW9yeSBJTyBNdWx0aXBhZ2UgZnVuY3Rpb25zCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKRklNVUxUSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfTG9hZE11bHRpQml0bWFwRnJvbU1lbW9yeShGUkVFX0lNQUdFX0ZPUk1BVCBmaWYsIEZJTUVNT1JZICpzdHJlYW0sIGludCBmbGFncykgewoJQk9PTCByZWFkX29ubHkgPSBGQUxTRTsJLy8gbW9kaWZpY2F0aW9ucyAoaWYgYW55KSB3aWxsIGJlIHN0b3JlZCBpbnRvIHRoZSBtZW1vcnkgY2FjaGUKCgkvLyByZXRyaWV2ZSB0aGUgcGx1Z2luIGxpc3QgdG8gZmluZCB0aGUgbm9kZSBiZWxvbmdpbmcgdG8gdGhpcyBwbHVnaW4KCglQbHVnaW5MaXN0ICpsaXN0ID0gRnJlZUltYWdlX0dldFBsdWdpbkxpc3QoKTsKCglpZiAobGlzdCkgewoJCVBsdWdpbk5vZGUgKm5vZGUgPSBsaXN0LT5GaW5kTm9kZUZyb21GSUYoZmlmKTsKCgkJaWYgKG5vZGUpIHsKCQkJRnJlZUltYWdlSU8gKmlvID0gbmV3KHN0ZDo6bm90aHJvdykgRnJlZUltYWdlSU87CgoJCQlpZiAoaW8pIHsKCQkJCVNldE1lbW9yeUlPKGlvKTsKCgkJCQlGSU1VTFRJQklUTUFQICpiaXRtYXAgPSBuZXcoc3RkOjpub3Rocm93KSBGSU1VTFRJQklUTUFQOwoKCQkJCWlmIChiaXRtYXApIHsKCQkJCQlNVUxUSUJJVE1BUEhFQURFUiAqaGVhZGVyID0gbmV3KHN0ZDo6bm90aHJvdykgTVVMVElCSVRNQVBIRUFERVI7CgoJCQkJCWlmIChoZWFkZXIpIHsKCQkJCQkJaGVhZGVyLT5tX2ZpbGVuYW1lID0gTlVMTDsKCQkJCQkJaGVhZGVyLT5ub2RlID0gbm9kZTsKCQkJCQkJaGVhZGVyLT5maWYgPSBmaWY7CgkJCQkJCWhlYWRlci0+aW8gPSBpbzsKCQkJCQkJaGVhZGVyLT5oYW5kbGUgPSAoZmlfaGFuZGxlKXN0cmVhbTsJCQkJCQkKCQkJCQkJaGVhZGVyLT5jaGFuZ2VkID0gRkFMU0U7CQkJCQkJCgkJCQkJCWhlYWRlci0+cmVhZF9vbmx5ID0gcmVhZF9vbmx5OwoJCQkJCQloZWFkZXItPm1fY2FjaGVmaWxlID0gTlVMTDsKCQkJCQkJaGVhZGVyLT5jYWNoZV9maWYgPSBmaWY7CgkJCQkJCWhlYWRlci0+bG9hZF9mbGFncyA9IGZsYWdzOwoKCQkJCQkJLy8gc3RvcmUgdGhlIE1VTFRJQklUTUFQSEVBREVSIGluIHRoZSBzdXJyb3VuZGluZyBGSU1VTFRJQklUTUFQIHN0cnVjdHVyZQoKCQkJCQkJYml0bWFwLT5kYXRhID0gaGVhZGVyOwoKCQkJCQkJLy8gY2FjaGUgdGhlIHBhZ2UgY291bnQKCgkJCQkJCWhlYWRlci0+cGFnZV9jb3VudCA9IEZyZWVJbWFnZV9JbnRlcm5hbEdldFBhZ2VDb3VudChiaXRtYXApOwoKCQkJCQkJLy8gYWxsb2NhdGUgYSBjb250aW51ZXVzIGJsb2NrIHRvIGRlc2NyaWJlIHRoZSBiaXRtYXAKCgkJCQkJCWhlYWRlci0+bV9ibG9ja3MucHVzaF9iYWNrKChCbG9ja1R5cGVTICopbmV3IEJsb2NrQ29udGludWV1cygwLCBoZWFkZXItPnBhZ2VfY291bnQgLSAxKSk7CgkJCQkJCQoJCQkJCQlpZiAoIXJlYWRfb25seSkgewoJCQkJCQkJLy8gc2V0IHVwIHRoZSBjYWNoZQoJCQkJCQkJQ2FjaGVGaWxlICpjYWNoZV9maWxlID0gbmV3KHN0ZDo6bm90aHJvdykgQ2FjaGVGaWxlKCIiLCBUUlVFKTsKCQkJCQkJCQoJCQkJCQkJaWYgKGNhY2hlX2ZpbGUgJiYgY2FjaGVfZmlsZS0+b3BlbigpKSB7CgkJCQkJCQkJaGVhZGVyLT5tX2NhY2hlZmlsZSA9IGNhY2hlX2ZpbGU7CgkJCQkJCQl9CgkJCQkJCX0KCgkJCQkJCXJldHVybiBiaXRtYXA7CgkJCQkJfQoJCQkJCQoJCQkJCWRlbGV0ZSBiaXRtYXA7CgkJCQl9CgkJCQkKCQkJCWRlbGV0ZSBpbzsKCQkJfQoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKQk9PTCBETExfQ0FMTENPTlYKRnJlZUltYWdlX1NhdmVNdWx0aUJpdG1hcFRvTWVtb3J5KEZSRUVfSU1BR0VfRk9STUFUIGZpZiwgRklNVUxUSUJJVE1BUCAqYml0bWFwLCBGSU1FTU9SWSAqc3RyZWFtLCBpbnQgZmxhZ3MpIHsKCWlmIChzdHJlYW0gJiYgc3RyZWFtLT5kYXRhKSB7CgkJRnJlZUltYWdlSU8gaW87CgkJU2V0TWVtb3J5SU8oJmlvKTsKCgkJcmV0dXJuIEZyZWVJbWFnZV9TYXZlTXVsdGlCaXRtYXBUb0hhbmRsZShmaWYsIGJpdG1hcCwgJmlvLCAoZmlfaGFuZGxlKXN0cmVhbSwgZmxhZ3MpOwoJfQoKCXJldHVybiBGQUxTRTsKfQo=