diff --git a/analysis/ghidra/exports/Lmx.dll.set-attribute-result-decompile.md b/analysis/ghidra/exports/Lmx.dll.set-attribute-result-decompile.md new file mode 100644 index 0000000..83ead5f --- /dev/null +++ b/analysis/ghidra/exports/Lmx.dll.set-attribute-result-decompile.md @@ -0,0 +1,501 @@ +# Lmx.dll selected decompile + +## FUN_10114a90 at 10114a90 + +Signature: `undefined FUN_10114a90(void)` + +```c + +void __thiscall +FUN_10114a90(undefined4 *param_1,int param_2,int *param_3,ushort param_4,undefined4 param_5, + void *param_6,short *param_7) + +{ + char cVar1; + uint uVar2; + undefined4 uVar3; + basic_ostream_> *pbVar4; + int iVar5; + undefined4 *puVar6; + wchar_t *pwVar7; + wchar_t *pwVar8; + size_t _MaxCount; + DWORD DVar9; + int iVar10; + int *piVar11; + undefined2 uVar12; + wchar_t _Ch; + _func_basic_ostream_>_ptr_basic_ostream_>_ptr + *p_Var13; + undefined4 uVar14; + undefined1 local_ba4 [20]; + undefined1 local_b90 [20]; + undefined4 local_b7c; + undefined4 local_b74; + void *local_b70; + short *local_b6c; + undefined4 *local_b68; + int *local_b64; + char local_b5e; + char local_b5d; + undefined4 *local_b5c [391]; + wchar_t local_540 [520]; + undefined1 local_130 [20]; + undefined1 local_11c [20]; + undefined1 local_108 [60]; + undefined1 local_cc [20]; + undefined4 local_b8 [36]; + undefined4 local_28; + undefined4 local_24; + undefined4 local_20; + uint local_14; + void *local_10; + undefined1 *puStack_c; + undefined4 local_8; + + local_8 = 0xffffffff; + puStack_c = &LAB_101729a5; + local_10 = ExceptionList; + uVar2 = DAT_101d60b8 ^ (uint)&stack0xfffffffc; + ExceptionList = &local_10; + local_b5c[0] = (undefined4 *)(uint)param_4; + local_b74 = param_5; + local_b70 = param_6; + local_b6c = param_7; + local_14 = uVar2; + cVar1 = FUN_100408d0(uVar2); + if (cVar1 != '\0') { + local_20 = *(undefined4 *)(local_b6c + 2); + swprintf_s(local_540,0x104,L"", + (int)(short)*(undefined4 *)local_b6c,local_20,*(undefined4 *)(local_b6c + 4), + (int)local_b6c[6]); + local_b64 = (int *)FUN_10004010(local_b74,local_b70); + local_b5c[0] = (undefined4 *)FUN_100040a0(local_b5c[0]); + uVar3 = FUN_100300d0(param_3); + iVar5 = param_2; + p_Var13 = endl_exref; + pbVar4 = (basic_ostream_> *) + FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x20), + L"PreboundReference::OnSetAttributeResult - ENTER correlationId ",param_2, + L" pValue ",uVar3,L" quality ",local_b5c[0],L" timestamp ",local_b64, + L" mxStatus ",local_540); + pbVar4 = std::basic_ostream_>::operator<< + (pbVar4,iVar5); + uVar3 = FUN_1001a0e0(pbVar4); + uVar3 = FUN_1001a0e0(uVar3); + uVar3 = FUN_1001a0e0(uVar3); + uVar3 = FUN_1001a0e0(uVar3); + uVar3 = FUN_1001a0e0(uVar3); + uVar3 = FUN_1001a0e0(uVar3); + uVar3 = FUN_1001a0e0(uVar3); + pbVar4 = (basic_ostream_> *) + FUN_1001a0e0(uVar3); + std::basic_ostream_>::operator<< + (pbVar4,p_Var13); + } + if (param_2 == 0) { + if (*local_b6c == -1) { + iVar5 = (**(code **)(*param_3 + 0x60))(param_3,&local_b68); + iVar5 = FUN_10048e60(iVar5 == 0,iVar5,300,"preboundreference.cpp"); + if (iVar5 == 0) goto LAB_1011543c; + if (local_b68 != (undefined4 *)0x0) { + local_b64 = (int *)0x0; + local_8 = 1; + uVar12 = 0x1011; + iVar5 = (**(code **)(*param_3 + 0x80))(param_3,&local_b64); + if (iVar5 == 0) { + FUN_1008e710(local_b64); + local_8._0_1_ = 2; + FUN_10112f20(local_b90); + local_8._0_1_ = 1; + FUN_10021cc0(); + FUN_1005f730(&local_28); + uVar3 = CONCAT22(uVar12,(undefined2)local_20); + cVar1 = FUN_100057b0(local_28,local_24,uVar3,0x138,"preboundreference.cpp"); + uVar12 = (undefined2)((uint)uVar3 >> 0x10); + if (cVar1 != '\0') { + FUN_1004c220(); + local_8._0_1_ = 3; + FUN_1004c320(param_1[0x14]); + local_b5c[0] = local_b8; + uVar12 = 0x1011; + FUN_10073b80(local_b5c,0); + iVar5 = FUN_1005f730(local_130); + FUN_10040470(*(undefined2 *)(iVar5 + 2)); + local_8._0_1_ = 1; + FUN_1002e080(); + } + cVar1 = FUN_100057b0(local_28,local_24,CONCAT22(uVar12,(undefined2)local_20),0x144, + "preboundreference.cpp"); + if (cVar1 == '\0') { + param_1[0x2a] = 4; + } + else { + iVar5 = FUN_1005f730(local_11c); + if (*(short *)(iVar5 + 10) == 0) { + FUN_101131d0(); + } + else { + param_1[0x2a] = 3; + param_1[0x29] = 0; + FUN_10114620(); + } + } + } + local_8 = 0xffffffff; + if (local_b64 != (int *)0x0) { + (**(code **)(*local_b64 + 8))(local_b64); + } + goto LAB_1011543c; + } + } + else if (((DAT_101d8c40 == 2) && (param_1[0x29] == 0)) && + (*(ushort *)(param_1[0x19] + 0x2ac) - 0x7c17 < 0x3e9)) { + cVar1 = FUN_100408d0(uVar2); + if (cVar1 != '\0') { + uVar3 = FUN_10003fc0(*(undefined4 *)local_b6c,*(undefined4 *)(local_b6c + 2), + *(undefined4 *)(local_b6c + 4),*(undefined4 *)(local_b6c + 6)); + p_Var13 = endl_exref; + uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x1c), + L"PreboundReference - attempting local platform <",param_1 + 6, + L"> - status ",uVar3); + uVar3 = FUN_1001dec0(uVar3); + uVar3 = FUN_1001a0e0(uVar3); + pbVar4 = (basic_ostream_> *) + FUN_1001a0e0(uVar3); + std::basic_ostream_>::operator<< + (pbVar4,p_Var13); + } + param_1[5] = param_1[5] + 1; + param_1[0x2a] = 1; + param_1[0x29] = 1; + FUN_10112cd0(); + goto LAB_1011543c; + } +LAB_10115432: + param_1[0x2a] = 4; + goto LAB_1011543c; + } + if (param_2 != 1) goto LAB_1011543c; + param_1[0x2a] = 6; + if (*local_b6c != -1) { + if (*(char *)(param_1 + 0x1b) != '\0') { + if ((uint)param_1[0x21] < 8) { + puVar6 = param_1 + 0x1c; + } + else { + puVar6 = (undefined4 *)param_1[0x1c]; + } + iVar5 = (**(code **)(*(int *)param_1[0x14] + 0x44))((int *)param_1[0x14],puVar6); + if (iVar5 < 0) { + /* WARNING: Subroutine does not return */ + FUN_1005bf30(iVar5,0,"E:\\BldSrc\\6\\s\\ExtInterfaces\\Lmx\\IMxReferencePtr.h",0x75); + } + *(undefined1 *)(param_1 + 0x1b) = 0; + } + if (*(int *)(local_b6c + 2) == 3) { +LAB_1011502e: + param_1[0x2a] = 6; + goto LAB_1011543c; + } + if ((*(int *)(local_b6c + 2) == 4) && (local_b6c[6] == 0x1f42)) { + local_b70 = operator_new(8); + local_8 = 0xb; + if (local_b70 == (void *)0x0) { + local_b5c[0] = (undefined4 *)0x0; + } + else { + local_b5c[0] = (undefined4 *)FUN_10112b50(param_1); + } + local_8 = 0xffffffff; + cVar1 = FUN_10048d60(local_b5c[0] != (undefined4 *)0x0,0x23b,"preboundreference.cpp"); + if (cVar1 != '\0') { + uVar3 = FUN_10016fd0(); + FUN_1005f7e0(uVar3); + FUN_1004c220(); + local_8 = 0xc; + FUN_1004c320(param_1[0x14]); + local_b68 = local_b8; + FUN_10073b80(&local_b68,0); + param_1[5] = param_1[5] + 1; + param_1[0x2a] = 1; + DVar9 = GetTickCount(); + FUN_1008f150(local_b5c[0],0,0,0,0,*(undefined4 *)local_b6c,*(undefined4 *)(local_b6c + 2), + *(undefined4 *)(local_b6c + 4),*(undefined4 *)(local_b6c + 6),0,DVar9); + local_8 = 0xffffffff; + FUN_1002e080(); + } + goto LAB_1011543c; + } + goto LAB_10115432; + } + iVar5 = (**(code **)(*param_3 + 0x60))(param_3,&local_b68); + iVar5 = FUN_10048e60(iVar5 == 0,iVar5,0x19d,"preboundreference.cpp"); + if (iVar5 == 0) goto LAB_1011543c; + if (local_b68 == (undefined4 *)0x0) goto LAB_1011502e; + local_b64 = (int *)0x0; + local_8 = 6; + uVar12 = 0x1011; + iVar5 = (**(code **)(*param_3 + 0x80))(param_3,&local_b64); + if (iVar5 == 0) { + FUN_1008e710(local_b64); + local_8._0_1_ = 7; + FUN_10112f20(local_ba4); + local_8 = CONCAT31(local_8._1_3_,6); + FUN_10021cc0(); + if (*(char *)(param_1 + 0x1b) != '\0') { + piVar11 = param_1 + 0x1c; + if (7 < (uint)param_1[0x21]) { + piVar11 = (int *)*piVar11; + } + FUN_1005f700(piVar11); + *(undefined1 *)(param_1 + 0x1b) = 0; + } + iVar5 = FUN_1005f730(local_108); + if (*(short *)(iVar5 + 10) == 0) { + local_b5d = '\0'; + local_b5e = '\0'; + puVar6 = (undefined4 *)FUN_1005f730(local_cc); + cVar1 = FUN_100057b0(*puVar6,puVar6[1],CONCAT22(uVar12,*(undefined2 *)(puVar6 + 2)),0x1c1, + "preboundreference.cpp"); + if (cVar1 == '\0') { + if (*(char *)(param_1 + 4) != '\0') { + FUN_1004c220(); + local_8._0_1_ = 8; + FUN_1004c320(param_1[0x14]); + local_b5c[0] = local_b8; + FUN_10073b80(local_b5c,0); + local_8 = CONCAT31(local_8._1_3_,6); + FUN_1002e080(); + } + local_b5e = '\x01'; + } + else { + pwVar7 = (wchar_t *)FUN_1005f590(); + cVar1 = FUN_10134a10(pwVar7); + if (cVar1 == '\0') { + pwVar8 = wcschr(pwVar7,L'.'); + if ((pwVar8 != (wchar_t *)0x0) && + (_MaxCount = (int)pwVar8 - (int)pwVar7 >> 1, _MaxCount != 0)) { + pwVar8 = (wchar_t *)FUN_1005f610(); + iVar5 = _wcsnicmp(pwVar7,pwVar8,_MaxCount); + if (iVar5 == 0) { + _Ch = L'.'; + pwVar7 = (wchar_t *)FUN_1005f660(); + pwVar7 = wcschr(pwVar7,_Ch); + if (pwVar7 == (wchar_t *)0x0) goto LAB_10114e2f; + } + local_b5d = '\x01'; + } + } + } +LAB_10114e2f: + if ((*(char *)(param_1 + 4) == '\0') || ((local_b5d == '\0' && (local_b5e == '\0')))) { + param_1[0x2a] = 4; + } + else { + local_b70 = operator_new(8); + local_8._0_1_ = 9; + if (local_b70 == (void *)0x0) { + local_b5c[0] = (undefined4 *)0x0; + } + else { + local_b5c[0] = (undefined4 *)FUN_10112b50(param_1); + } + local_8 = CONCAT31(local_8._1_3_,6); + cVar1 = FUN_10048d60(local_b5c[0] != (undefined4 *)0x0,0x1ee,"preboundreference.cpp"); + if (cVar1 == '\0') { + param_1[0x2a] = 4; + iVar5 = FUN_10022ff0(); + if (*(int *)(iVar5 + 0xac) == 0) { + iVar10 = FUN_1002f080(); + if (iVar10 != 0) goto LAB_10114f66; + uVar3 = 0; + } + else { +LAB_10114f66: + uVar3 = *(undefined4 *)(iVar5 + 0xac); + } + uVar14 = 0; + FUN_10022ff0(uVar3,0); + cVar1 = FUN_10022ba0(uVar3,uVar14); + if (cVar1 != '\0') { + uVar3 = FUN_1005f590(); + uVar3 = FUN_10022ff0(L"PreboundReference::OnSetAttributeResult unable to crreate CPreboundReferenceAdapter for ref %s" + ,uVar3); + FUN_10022cb0(uVar3); + } + } + else { + *(undefined1 *)(param_1 + 4) = 0; + uVar3 = FUN_10016fd0(); + FUN_1005f7e0(uVar3); + FUN_1008fc40(&DAT_1017a514); + FUN_1008fc70(&DAT_1017a514); + param_1[5] = param_1[5] + 1; + param_1[0x2a] = 1; + DVar9 = GetTickCount(); + local_b70 = (void *)CONCAT22(local_b70._2_2_,0x1f42); + local_b7c = (uint)local_b7c._2_2_ << 0x10; + FUN_1008f150(local_b5c[0],0,0,0,0,local_b7c,4,0,local_b70,0,DVar9); + } + } + } + else { + param_1[0x2a] = 3; + param_1[0x29] = 0; + FUN_10114620(); + } + } + local_8 = 0xffffffff; + if (local_b64 != (int *)0x0) { + (**(code **)(*local_b64 + 8))(local_b64); + } +LAB_1011543c: + if (*(char *)(param_1 + 0x1b) != '\0') { + if ((uint)param_1[0x21] < 8) { + puVar6 = param_1 + 0x1c; + } + else { + puVar6 = (undefined4 *)param_1[0x1c]; + } + iVar5 = (**(code **)(*(int *)param_1[0x14] + 0x44))((int *)param_1[0x14],puVar6); + if (iVar5 < 0) { + /* WARNING: Subroutine does not return */ + FUN_1005bf30(iVar5,0,"E:\\BldSrc\\6\\s\\ExtInterfaces\\Lmx\\IMxReferencePtr.h",0x75); + } + *(undefined1 *)(param_1 + 0x1b) = 0; + } + if ((param_1[0x2a] != 1) && (param_1[0x2a] != 2)) { + FUN_10050df0(local_b6c,param_1); + } + piVar11 = param_1 + 5; + *piVar11 = *piVar11 + -1; + if (*piVar11 == 0) { + (**(code **)*param_1)(1); + } + local_b5c[0] = (undefined4 *)param_1[0x2a]; + if (param_1[5] == 1) { + local_b68 = param_1; + piVar11 = (int *)FUN_100484c0(&local_b70,&local_b68); + iVar5 = *piVar11; + cVar1 = FUN_10048d60(iVar5 != *(int *)(param_1[0x19] + 0x180),0x273,"preboundreference.cpp"); + if (cVar1 != '\0') { + FUN_100382e0(&local_b70,iVar5); + piVar11 = param_1 + 5; + *piVar11 = *piVar11 + -1; + if (*piVar11 == 0) { + (**(code **)*param_1)(1); + } + } + } + cVar1 = FUN_100408d0(); + if (cVar1 != '\0') { + uVar3 = FUN_10001e20(local_b5c); + p_Var13 = endl_exref; + uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x20), + L"PreboundReference::OnSetAttributeResult - EXIT status ",uVar3); + pbVar4 = (basic_ostream_> *) + FUN_1001a0e0(uVar3); + std::basic_ostream_>::operator<< + (pbVar4,p_Var13); + } + ExceptionList = local_10; + __security_check_cookie(local_14 ^ (uint)&stack0xfffffffc); + return; +} + + +``` + +## FUN_100dc750 at 100dc750 + +Signature: `undefined FUN_100dc750(void)` + +```c + +void __thiscall FUN_100dc750(int *param_1,uint param_2,int param_3,int param_4,BSTR param_5) + +{ + char cVar1; + uint uVar2; + undefined4 uVar3; + basic_ostream_> *pbVar4; + undefined4 *puVar5; + _func_basic_ostream_>_ptr_basic_ostream_>_ptr + *p_Var6; + uint local_23c; + int *local_234; + BSTR local_230; + uint local_22c; + int local_228; + int local_224; + BSTR local_220; + wchar_t local_21c [260]; + uint local_14; + void *local_10; + undefined1 *puStack_c; + undefined4 local_8; + + local_8 = 0xffffffff; + puStack_c = &LAB_1016d12b; + local_10 = ExceptionList; + uVar2 = DAT_101d60b8 ^ (uint)&stack0xfffffffc; + ExceptionList = &local_10; + local_14 = uVar2; + cVar1 = FUN_100408d0(uVar2); + if (cVar1 != '\0') { + local_23c._0_2_ = (short)param_2; + swprintf_s(local_21c,0x104,L"", + (int)(short)local_23c,param_3,param_4,(int)(short)param_5); + p_Var6 = endl_exref; + uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x14), + L"DemandReadCallback::CancelWithStatus - status ",local_21c); + pbVar4 = (basic_ostream_> *) + FUN_1001a0e0(uVar3); + std::basic_ostream_>::operator<< + (pbVar4,p_Var6); + } + if (((param_3 == 5) && (param_4 == 0)) && ((short)param_5 == 1)) { + local_23c = param_2 & 0xffff0000; + local_230 = (BSTR)CONCAT22(local_230._2_2_,5); + local_228 = 3; + local_22c = local_23c; + local_224 = 2; + local_220 = local_230; + } + else { + local_22c = param_2; + local_228 = param_3; + local_224 = param_4; + local_220 = param_5; + } + cVar1 = FUN_100408d0(uVar2); + if (cVar1 != '\0') { + swprintf_s(local_21c,0x104,L"", + (int)(short)local_22c,local_228,local_224,(int)(short)local_220); + p_Var6 = endl_exref; + uVar3 = FUN_1001a0e0(*(undefined4 *)(DAT_101d6474 + 0x14), + L"DemandReadCallback::CancelWithStatus - Calling OnGetAttributeResult with status " + ,local_21c); + pbVar4 = (basic_ostream_> *) + FUN_1001a0e0(uVar3); + std::basic_ostream_>::operator<< + (pbVar4,p_Var6); + } + puVar5 = (undefined4 *)FUN_10005170(); + local_8 = 0; + (**(code **)(*param_1 + 4))(*puVar5,0,DAT_101d6504,DAT_101d6508,&local_22c); + local_8 = 0xffffffff; + if (local_234 != (int *)0x0) { + (**(code **)(*local_234 + 8))(local_234); + } + SysFreeString(local_230); + ExceptionList = local_10; + __security_check_cookie(local_14 ^ (uint)&stack0xfffffffc); + return; +} + + +``` + diff --git a/analysis/ghidra/exports/LmxProxy.dll.fire-event-xrefs.md b/analysis/ghidra/exports/LmxProxy.dll.fire-event-xrefs.md new file mode 100644 index 0000000..03ccfa6 --- /dev/null +++ b/analysis/ghidra/exports/LmxProxy.dll.fire-event-xrefs.md @@ -0,0 +1,34 @@ +# LmxProxy.dll xrefs + +## 0x15f72 at 10015f72 + +Target function: `FUN_10015f72` + +| From | Ref type | Caller function | +| --- | --- | --- | +| `1001695a` | `UNCONDITIONAL_CALL` | `FUN_1001657f` | + +## 0x1611f at 1001611f + +Target function: `FUN_1001611f` + +| From | Ref type | Caller function | +| --- | --- | --- | +| `10016cc8` | `UNCONDITIONAL_CALL` | `FUN_10016b50` | + +## 0x16271 at 10016271 + +Target function: `FUN_10016271` + +| From | Ref type | Caller function | +| --- | --- | --- | +| `10016eb3` | `UNCONDITIONAL_CALL` | `FUN_10016d4b` | + +## 0x163c0 at 100163c0 + +Target function: `FUN_100163c0` + +| From | Ref type | Caller function | +| --- | --- | --- | +| `10016ad8` | `UNCONDITIONAL_CALL` | `FUN_1001657f` | + diff --git a/analysis/ghidra/exports/LmxProxy.dll.mxstatus-safearray-decompile.md b/analysis/ghidra/exports/LmxProxy.dll.mxstatus-safearray-decompile.md new file mode 100644 index 0000000..dc9ee8d --- /dev/null +++ b/analysis/ghidra/exports/LmxProxy.dll.mxstatus-safearray-decompile.md @@ -0,0 +1,125 @@ +# LmxProxy.dll selected decompile + +## FUN_10003f60 at 10003f60 + +Signature: `HRESULT __cdecl FUN_10003f60(undefined4 * param_1, undefined2 * param_2, ULONG param_3)` + +```c + +HRESULT __cdecl FUN_10003f60(undefined4 *param_1,undefined2 *param_2,ULONG param_3) + +{ + basic_ostream_> bVar1; + HRESULT HVar2; + basic_ostream_> *pbVar3; + SAFEARRAY *pSVar4; + HRESULT HVar5; + _func_basic_ostream_>_ptr_basic_ostream_>_ptr + *p_Var6; + SAFEARRAYBOUND local_18; + LONG local_10; + IRecordInfo *local_c; + undefined2 *local_8; + + local_c = (IRecordInfo *)0x0; + HVar2 = GetRecordInfoFromGuids((GUID *)&DAT_1001c2d0,1,0,0,(GUID *)&DAT_1001b530,&local_c); + if (HVar2 < 0) { + if ((HVar2 != -0x7ffd7fe3) && + (bVar1 = FUN_10003f01(*(basic_ostream_> **) + (DAT_100294e0 + 4)), + bVar1 != (basic_ostream_>)0x0)) { + HVar5 = HVar2; + p_Var6 = endl_exref; + pbVar3 = (basic_ostream_> *) + FUN_10002dbf(*(int **)(DAT_100294e0 + 4),L"GetRecordInfoFromGuids failed - hr = "); + pbVar3 = std::basic_ostream_>::operator<< + (pbVar3,HVar5); + std::basic_ostream_>::operator<<(pbVar3,p_Var6); + } + } + else { + local_18.lLbound = 0; + local_18.cElements = param_3; + pSVar4 = SafeArrayCreateEx(0x24,1,&local_18,local_c); + *param_1 = pSVar4; + (*local_c->lpVtbl->Release)(local_c); + if ((SAFEARRAY *)*param_1 == (SAFEARRAY *)0x0) { + HVar2 = -0x7fffbffb; + } + else { + HVar2 = SafeArrayGetLBound((SAFEARRAY *)*param_1,1,&local_10); + if ((-1 < HVar2) && (HVar2 = SafeArrayAccessData((SAFEARRAY *)*param_1,&local_8), -1 < HVar2)) + { + *local_8 = *param_2; + *(undefined4 *)(local_8 + 2) = *(undefined4 *)(param_2 + 2); + *(undefined4 *)(local_8 + 4) = *(undefined4 *)(param_2 + 4); + local_8[6] = param_2[6]; + SafeArrayUnaccessData((SAFEARRAY *)*param_1); + HVar2 = 0; + } + } + } + return HVar2; +} + + +``` + +## FUN_10015db2 at 10015db2 + +Signature: `void * __thiscall FUN_10015db2(void * this, int * param_1, undefined4 param_2, undefined4 param_3, undefined4 param_4, undefined4 param_5, undefined4 param_6)` + +```c + +/* WARNING: Function: __EH_prolog3 replaced with injection: EH_prolog3 */ +/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */ + +void * __thiscall +FUN_10015db2(void *this,int *param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4, + undefined4 param_5,undefined4 param_6) + +{ + *(undefined4 *)this = 1; + FUN_10015d38((void *)((int)this + 4),param_1); + *(undefined4 *)((int)this + 8) = 0; + *(undefined4 *)((int)this + 0x10) = param_2; + *(undefined4 *)((int)this + 0x14) = param_3; + *(undefined4 *)((int)this + 0x18) = param_4; + *(undefined4 *)((int)this + 0xc) = param_6; + *(undefined4 *)((int)this + 0x1c) = param_5; + *(undefined4 *)((int)this + 0x20) = 0; + return this; +} + + +``` + +## FUN_10015e4e at 10015e4e + +Signature: `void * __thiscall FUN_10015e4e(void * this, int * param_1, undefined4 param_2, undefined4 param_3, undefined4 param_4, undefined4 param_5, undefined4 param_6)` + +```c + +/* WARNING: Function: __EH_prolog3 replaced with injection: EH_prolog3 */ +/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */ + +void * __thiscall +FUN_10015e4e(void *this,int *param_1,undefined4 param_2,undefined4 param_3,undefined4 param_4, + undefined4 param_5,undefined4 param_6) + +{ + *(undefined4 *)this = 2; + *(undefined4 *)((int)this + 4) = 0; + FUN_10015d38((void *)((int)this + 8),param_1); + *(undefined4 *)((int)this + 0x20) = 0; + *(undefined4 *)((int)this + 0x10) = param_2; + *(undefined4 *)((int)this + 0x14) = param_3; + *(undefined4 *)((int)this + 0x18) = param_4; + *(undefined4 *)((int)this + 0xc) = param_6; + *(undefined4 *)((int)this + 0x1c) = param_5; + return this; +} + + +``` + diff --git a/analysis/ghidra/exports/LmxProxy.dll.status-synthesis-decompile.md b/analysis/ghidra/exports/LmxProxy.dll.status-synthesis-decompile.md new file mode 100644 index 0000000..7cc38f8 --- /dev/null +++ b/analysis/ghidra/exports/LmxProxy.dll.status-synthesis-decompile.md @@ -0,0 +1,475 @@ +# LmxProxy.dll selected decompile + +## FUN_1001657f at 1001657f + +Signature: `undefined __stdcall FUN_1001657f(uint param_1, undefined4 param_2)` + +```c + +/* WARNING: Function: __EH_prolog3_catch_GS replaced with injection: EH_prolog3 */ + +void FUN_1001657f(uint param_1,undefined4 param_2) + +{ + DWORD DVar1; + basic_ostream_> bVar2; + undefined *puVar3; + int iVar4; + int *piVar5; + DWORD DVar6; + undefined4 *puVar7; + HRESULT HVar8; + basic_ostream_> *pbVar9; + uint uVar10; + undefined4 uVar11; + wchar_t *pwVar12; + _func_basic_ostream_>_ptr_basic_ostream_>_ptr + *p_Var13; + void **in_stack_ffffff1c; + undefined1 local_d4 [36]; + VARIANTARG local_b0; + _union_2683 local_a0; + VARIANTARG local_90; + VARIANTARG local_80; + int *local_70 [2]; + DWORD local_68; + undefined *local_64; + IUnknown *local_60 [2]; + BSTR local_58; + uint local_54; + int *local_50 [2]; + SAFEARRAY *local_48; + undefined1 local_44 [4]; + FILETIME local_40; + undefined2 local_38 [8]; + undefined1 local_28 [32]; + uint local_8; + undefined4 uStack_4; + + uStack_4 = 0xc4; + local_54 = param_1; + local_68 = 0; + local_64 = (undefined *)0x0; + local_58 = (BSTR)0x0; + local_8 = 0; + FUN_1000107a((int *)local_50); + local_8 = CONCAT31(local_8._1_3_,1); + uVar11 = 0; + uVar10 = 3; + puVar3 = FUN_10003248(); + iVar4 = FUN_10003897(puVar3,uVar10); + puVar3 = FUN_10003248(); + uVar10 = FUN_1000305b(puVar3,iVar4,uVar11); + if ((char)uVar10 != '\0') { + pwVar12 = L"OnDataChange callback received"; + piVar5 = (int *)FUN_10003248(); + FUN_100031b7(piVar5,pwVar12); + } + if (DAT_10029594 == 0) { + local_8 = local_8 & 0xffffff00; + FUN_1000111b((int *)local_50); + local_8 = 0xffffffff; + SysFreeString(local_58); + } + else { + DVar6 = GetCurrentThreadId(); + if (DVar6 == DAT_10029594) { + iVar4 = *(int *)(param_1 + 8); + FUN_1000f663((void *)(iVar4 + 0x2c),&local_40.dwHighDateTime,(int *)(param_1 + 0xc)); + DVar6 = local_40.dwHighDateTime; + if ((((undefined *)local_40.dwHighDateTime != *(undefined **)(iVar4 + 0x30)) && + (FUN_1000f5ef((undefined *)(local_40.dwHighDateTime + 0x3c),&local_40.dwHighDateTime, + (int *)(param_1 + 0x10)), DVar1 = local_40.dwHighDateTime, + (undefined *)local_40.dwHighDateTime != *(undefined **)(DVar6 + 0x40))) && + (*(char *)(local_40.dwHighDateTime + 0x1c) != '\0')) { + if (*(char *)(local_40.dwHighDateTime + 0x1f) == '\0') { + if (*(char *)(local_40.dwHighDateTime + 0x1e) == '\0') { + local_40.dwHighDateTime = 0; + local_28._0_4_ = (uint)(ushort)local_28._2_2_ << 0x10; + local_28._4_4_ = 0; + local_28._8_4_ = 0; + local_28._12_4_ = (undefined *)0x0; + (**(code **)(**(int **)(DVar6 + 0x24) + 0x60)) + (*(int **)(DVar6 + 0x24),*(undefined4 *)(DVar1 + 0x18), + &local_40.dwHighDateTime,local_28); + if ((local_28._0_2_ == 0xffff) && (local_28._4_4_ == 0)) { + *(undefined1 *)(DVar1 + 0x1e) = 1; + *(byte *)(DVar1 + 0x1d) = (byte)(local_40.dwHighDateTime >> 1) & 1; + } + } + piVar5 = *(int **)(DVar6 + 0x24); + if (local_50[0] != (int *)0x0) { + (**(code **)(*local_50[0] + 8))(local_50[0]); + local_50[0] = (int *)0x0; + } + iVar4 = (**(code **)(*piVar5 + 0x50)) + (piVar5,*(undefined4 *)(DVar1 + 0x18),local_44,&local_68,local_38, + &local_58,local_50); + } + else { + if (*(char *)(local_40.dwHighDateTime + 0x1e) == '\0') { + local_40.dwHighDateTime = 0; + local_28._0_4_ = (uint)(ushort)local_28._2_2_ << 0x10; + local_28._4_4_ = 0; + local_28._8_4_ = 0; + local_28._12_4_ = (undefined *)0x0; + (**(code **)(**(int **)(DVar6 + 0x30) + 0x28)) + (*(int **)(DVar6 + 0x30),*(undefined4 *)(DVar1 + 0x18), + &local_40.dwHighDateTime,local_28); + if ((local_28._0_2_ == 0xffff) && (local_28._4_4_ == 0)) { + *(undefined1 *)(DVar1 + 0x1e) = 1; + *(byte *)(DVar1 + 0x1d) = (byte)(local_40.dwHighDateTime >> 1) & 1; + } + } + piVar5 = *(int **)(DVar6 + 0x30); + if (local_50[0] != (int *)0x0) { + (**(code **)(*local_50[0] + 8))(local_50[0]); + local_50[0] = (int *)0x0; + } + iVar4 = (**(code **)(*piVar5 + 0x20)) + (piVar5,*(undefined4 *)(DVar1 + 0x18),local_44,&local_68,local_38, + local_50); + } + iVar4 = FUN_1000f8d9((undefined4 *)(uint)(iVar4 == 0),iVar4,0x6d,"MxCallback.cpp"); + if (iVar4 != 0) { + if (*(char *)(DVar1 + 0x28) == '\0') { + FUN_1000107a((int *)local_60); + local_8 = CONCAT31(local_8._1_3_,4); + if (*(char *)(DVar1 + 0x1d) == '\0') { + local_40.dwLowDateTime = 0; + local_40.dwHighDateTime = 0; + CoFileTimeNow(&local_40); + local_28._8_4_ = local_40.dwLowDateTime; + local_28._12_4_ = local_40.dwHighDateTime; + } + else { + local_28._8_4_ = local_68; + local_28._12_4_ = local_64; + } + HVar8 = (*local_60[0]->lpVtbl[5].QueryInterface) + (local_60[0],(IID *)(local_28 + 8),in_stack_ffffff1c); + if (HVar8 < 0) { + _com_issue_errorex(HVar8,local_60[0],(_GUID *)&DAT_1001b590); + } + puVar3 = FUN_100012e6(local_60); + FUN_10001269(local_70,puVar3); + local_8._0_1_ = 5; + FUN_100060a2((CComVariant *)&local_b0,local_70[0],0x40); + local_8._0_1_ = 6; + FUN_100060a2((CComVariant *)&local_a0.n2,local_50[0],0); + local_8._0_1_ = 7; + HVar8 = FUN_10003f60(&local_48,local_38,1); + if (HVar8 < 0) { + bVar2 = FUN_10003f01(*(basic_ostream_> **) + (DAT_100294e0 + 8)); + if (bVar2 != (basic_ostream_>)0x0) { + p_Var13 = endl_exref; + pbVar9 = (basic_ostream_> *) + FUN_10002dbf(*(int **)(DAT_100294e0 + 8), + L"CUserConnectionCallback::OnDataChange - Create MxStatus SafeArray failed. hr = " + ); + pbVar9 = std::basic_ostream_>::operator<< + (pbVar9,HVar8); + std::basic_ostream_>::operator<< + (pbVar9,p_Var13); + } + } + else { + local_8 = CONCAT31(local_8._1_3_,8); + FUN_10015f72((void *)(*(int *)(local_54 + 8) + 0xc),*(long *)(local_54 + 0xc), + *(long *)(local_54 + 0x10),local_a0._0_4_); + local_8._0_1_ = 7; + local_8._1_3_ = 0; + HVar8 = SafeArrayDestroy(local_48); + if (HVar8 != 0) { + pwVar12 = + L"CUserConnectionCallback::OnDataChange - SafeArrayDestroy failed - hr %08X"; + piVar5 = (int *)FUN_10003248(); + FUN_1000308b(piVar5,pwVar12); + } + } + local_8._0_1_ = 6; + VariantClear((VARIANTARG *)&local_a0.n2); + local_8._0_1_ = 5; + VariantClear(&local_b0); + local_8._0_1_ = 4; + FUN_1000111b((int *)local_70); + local_8 = CONCAT31(local_8._1_3_,1); + FUN_1000111b((int *)local_60); + } + else { + VariantInit(&local_80); + local_8._0_1_ = 10; + VariantInit(&local_90); + local_8._0_1_ = 0xb; + VariantInit((VARIANTARG *)local_28); + local_8._0_1_ = 0xc; + local_40.dwHighDateTime = 0; + FUN_100069ad(local_50[0],(ushort *)&local_80,(undefined2 *)&local_90, + (undefined2 *)local_28,(BSTR)&local_40.dwHighDateTime); + HVar8 = FUN_10003f60(&local_48,local_38,1); + if (HVar8 < 0) { + bVar2 = FUN_10003f01(*(basic_ostream_> **) + (DAT_100294e0 + 8)); + if (bVar2 != (basic_ostream_>)0x0) { + p_Var13 = endl_exref; + pbVar9 = (basic_ostream_> *) + FUN_10002dbf(*(int **)(DAT_100294e0 + 8), + L"CUserConnectionCallback::OnDataChange - Create MxStatus SafeArray failed on Buffered Data callback. hr = " + ); + pbVar9 = std::basic_ostream_>::operator<< + (pbVar9,HVar8); + std::basic_ostream_>::operator<< + (pbVar9,p_Var13); + } + } + else { + local_8 = CONCAT31(local_8._1_3_,0xd); + FUN_100163c0((void *)(*(int *)(local_54 + 8) + 0x18),*(long *)(local_54 + 0xc), + *(long *)(local_54 + 0x10),local_40.dwHighDateTime); + local_8._0_1_ = 0xc; + local_8._1_3_ = 0; + HVar8 = SafeArrayDestroy(local_48); + if (HVar8 != 0) { + pwVar12 = + L"CUserConnectionCallback::OnDataChange - SafeArrayDestroy failed - hr %08X"; + piVar5 = (int *)FUN_10003248(); + FUN_1000308b(piVar5,pwVar12); + } + } + local_8._0_1_ = 0xb; + VariantClear((VARIANTARG *)local_28); + local_8._0_1_ = 10; + VariantClear(&local_90); + local_8 = CONCAT31(local_8._1_3_,1); + VariantClear(&local_80); + } + } + } + } + else { + local_40.dwHighDateTime = (DWORD)&DAT_100295bc; + EnterCriticalSection((LPCRITICAL_SECTION)&DAT_100295bc); + local_8._0_1_ = 2; + puVar7 = FUN_10015e06(local_d4,(int *)(-(uint)(param_1 != 4) & param_1),param_2); + local_8._0_1_ = 3; + FUN_1001654d(&DAT_100295b0,DAT_100295b0,puVar7); + local_8._0_1_ = 2; + FUN_1000d639((int)local_d4); + local_8 = CONCAT31(local_8._1_3_,1); + LeaveCriticalSection((LPCRITICAL_SECTION)&DAT_100295bc); + } + local_8 = local_8 & 0xffffff00; + FUN_1000111b((int *)local_50); + local_8 = 0xffffffff; + SysFreeString(local_58); + } + FUN_10017482(); + return; +} + + +``` + +## FUN_10016b50 at 10016b50 + +Signature: `HRESULT __stdcall FUN_10016b50(uint param_1, undefined4 param_2, undefined4 * param_3)` + +```c + +/* WARNING: Function: __EH_prolog3_catch replaced with injection: EH_prolog3 */ +/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */ + +HRESULT FUN_10016b50(uint param_1,undefined4 param_2,undefined4 *param_3) + +{ + uint uVar1; + basic_ostream_> bVar2; + undefined *puVar3; + int iVar4; + int *piVar5; + DWORD DVar6; + undefined4 *puVar7; + HRESULT HVar8; + basic_ostream_> *pbVar9; + uint uVar10; + HRESULT HVar11; + undefined4 uVar12; + wchar_t *pwVar13; + _func_basic_ostream_>_ptr_basic_ostream_>_ptr + *p_Var14; + undefined1 local_40 [36]; + undefined *local_1c; + undefined4 local_18 [4]; + int local_8; + undefined4 uStack_4; + + uStack_4 = 0x30; + local_8 = 0x10016b5c; + local_18[0] = 0; + uVar12 = 0; + uVar10 = 3; + puVar3 = FUN_10003248(); + iVar4 = FUN_10003897(puVar3,uVar10); + puVar3 = FUN_10003248(); + uVar10 = FUN_1000305b(puVar3,iVar4,uVar12); + if ((char)uVar10 != '\0') { + pwVar13 = L"OnSetAttributeResult callback received"; + piVar5 = (int *)FUN_10003248(); + FUN_100031b7(piVar5,pwVar13); + } + if (DAT_10029594 != 0) { + DVar6 = GetCurrentThreadId(); + uVar10 = param_1; + if (DVar6 == DAT_10029594) { + piVar5 = (int *)(param_1 + 0xc); + iVar4 = *(int *)(param_1 + 8); + FUN_1000f663((void *)(iVar4 + 0x2c),¶m_1,piVar5); + uVar1 = param_1; + if ((param_1 == *(uint *)(iVar4 + 0x30)) || + (FUN_1000f5ef((void *)(param_1 + 0x3c),¶m_1,(int *)(uVar10 + 0x10)), + param_1 == *(uint *)(uVar1 + 0x40))) { + return -0x7fffbffb; + } + HVar8 = FUN_10003f60(local_18,(undefined2 *)param_3,1); + if (-1 < HVar8) { + local_8 = 2; + FUN_1001611f((void *)(*(int *)(uVar10 + 8) + 0xc),*piVar5,*(long *)(uVar10 + 0x10),local_18) + ; + local_8 = 0xffffffff; + HVar8 = FUN_10016d1a(); + return HVar8; + } + bVar2 = FUN_10003f01(*(basic_ostream_> **) + (DAT_100294e0 + 8)); + if (bVar2 == (basic_ostream_>)0x0) { + return HVar8; + } + HVar11 = HVar8; + p_Var14 = endl_exref; + pbVar9 = (basic_ostream_> *) + FUN_10002dbf(*(int **)(DAT_100294e0 + 8), + L"CUserConnectionCallback::OnSetAttributeResult - Create MxStatus SafeArray failed. hr = " + ); + pbVar9 = std::basic_ostream_>::operator<< + (pbVar9,HVar11); + std::basic_ostream_>::operator<<(pbVar9,p_Var14); + return HVar8; + } + local_1c = &DAT_100295bc; + EnterCriticalSection((LPCRITICAL_SECTION)&DAT_100295bc); + local_8 = 0; + puVar7 = FUN_10015db2(local_40,(int *)(-(uint)(param_1 != 4) & param_1),*param_3,param_3[1], + param_3[2],param_3[3],param_2); + local_8._0_1_ = 1; + FUN_1001654d(&DAT_100295b0,DAT_100295b0,puVar7); + local_8 = (uint)local_8._1_3_ << 8; + FUN_1000d639((int)local_40); + local_8 = 0xffffffff; + LeaveCriticalSection((LPCRITICAL_SECTION)&DAT_100295bc); + } + return 0; +} + + +``` + +## FUN_10016d4b at 10016d4b + +Signature: `HRESULT __stdcall FUN_10016d4b(int * param_1, undefined4 param_2, undefined4 * param_3)` + +```c + +/* WARNING: Function: __EH_prolog3_catch replaced with injection: EH_prolog3 */ +/* WARNING: Function: __EH_epilog3 replaced with injection: EH_epilog3 */ + +HRESULT FUN_10016d4b(int *param_1,undefined4 param_2,undefined4 *param_3) + +{ + int *piVar1; + int *piVar2; + basic_ostream_> bVar3; + undefined *puVar4; + int iVar5; + int *piVar6; + DWORD DVar7; + undefined4 *puVar8; + HRESULT HVar9; + basic_ostream_> *pbVar10; + uint uVar11; + undefined4 uVar12; + wchar_t *pwVar13; + _func_basic_ostream_>_ptr_basic_ostream_>_ptr + *p_Var14; + undefined1 local_40 [36]; + undefined *local_1c; + undefined4 local_18 [4]; + int local_8; + undefined4 uStack_4; + + uStack_4 = 0x30; + local_8 = 0x10016d57; + uVar12 = 0; + uVar11 = 3; + puVar4 = FUN_10003248(); + iVar5 = FUN_10003897(puVar4,uVar11); + puVar4 = FUN_10003248(); + uVar11 = FUN_1000305b(puVar4,iVar5,uVar12); + if ((char)uVar11 != '\0') { + pwVar13 = L"OperationComplete callback received"; + piVar6 = (int *)FUN_10003248(); + FUN_100031b7(piVar6,pwVar13); + } + if (DAT_10029594 != 0) { + DVar7 = GetCurrentThreadId(); + piVar6 = param_1; + if (DVar7 == DAT_10029594) { + piVar1 = param_1 + 4; + iVar5 = param_1[3]; + FUN_1000f663((void *)(iVar5 + 0x2c),¶m_1,piVar1); + piVar2 = param_1; + if ((param_1 == *(int **)(iVar5 + 0x30)) || + (FUN_1000f5ef(param_1 + 0xf,¶m_1,piVar6 + 5), param_1 == (int *)piVar2[0x10])) { + return -0x7fffbffb; + } + HVar9 = FUN_10003f60(local_18,(undefined2 *)param_3,1); + if (-1 < HVar9) { + local_8 = 2; + FUN_10016271((void *)(piVar6[3] + 0xc),*piVar1,piVar6[5],local_18); + local_8 = 0xffffffff; + HVar9 = FUN_10016f05(); + return HVar9; + } + bVar3 = FUN_10003f01(*(basic_ostream_> **) + (DAT_100294e0 + 8)); + if (bVar3 == (basic_ostream_>)0x0) { + return HVar9; + } + p_Var14 = endl_exref; + pbVar10 = (basic_ostream_> *) + FUN_10002dbf(*(int **)(DAT_100294e0 + 8), + L"CUserConnectionCallback::CUserConnectionCallback::OperationComplete - Create MxStatus SafeArray failed. hr = " + ); + pbVar10 = std::basic_ostream_>::operator<< + (pbVar10,HVar9); + std::basic_ostream_>::operator<<(pbVar10,p_Var14); + HVar9 = FUN_10016f05(); + return HVar9; + } + local_1c = &DAT_100295bc; + EnterCriticalSection((LPCRITICAL_SECTION)&DAT_100295bc); + local_8 = 0; + puVar8 = FUN_10015e4e(local_40,param_1,*param_3,param_3[1],param_3[2],param_3[3],param_2); + local_8._0_1_ = 1; + FUN_1001654d(&DAT_100295b0,DAT_100295b0,puVar8); + local_8 = (uint)local_8._1_3_ << 8; + FUN_1000d639((int)local_40); + local_8 = 0xffffffff; + LeaveCriticalSection((LPCRITICAL_SECTION)&DAT_100295bc); + } + return 0; +} + + +``` + diff --git a/design/70-risks-and-open-questions.md b/design/70-risks-and-open-questions.md index e39a857..9b15953 100644 --- a/design/70-risks-and-open-questions.md +++ b/design/70-risks-and-open-questions.md @@ -44,17 +44,32 @@ The `OnBufferedDataChange` **public event shape** the wwtools api-notes describe **Severity: P1** (was a blocker; now settled per option: verbatim preserve is the canonical native behaviour) -**Status (2026-05-06): SETTLED.** Ghidra headless decompile + string-ref walk across `Lmx.dll`, `LmxProxy.dll`, `NmxAdptr.dll`, `NmxSvc.exe`, and `NmxSvcps.dll` (logs at `analysis/ghidra/exports/Lmx.dll.aadct-decompile.md` + `analysis/ghidra/exports/LmxProxy.dll.completion-status-decompile.md`) confirms there is **no static byte→status lookup table** to extract. Specifically: +**Status (2026-05-06): SETTLED.** Five-stage Ghidra headless decompile traced the byte-to-`MXSTATUS_PROXY` synthesis path end-to-end across `Lmx.dll` and `LmxProxy.dll`. Logs: +- `analysis/ghidra/exports/Lmx.dll.aadct-decompile.md` — `aaDCT` symbol +- `analysis/ghidra/exports/LmxProxy.dll.completion-status-decompile.md` — Fire_* event handlers +- `analysis/ghidra/exports/LmxProxy.dll.fire-event-xrefs.md` — xrefs to Fire_* +- `analysis/ghidra/exports/LmxProxy.dll.status-synthesis-decompile.md` — Fire_* callers (`FUN_1001657f` / `FUN_10016b50` / `FUN_10016d4b`) +- `analysis/ghidra/exports/LmxProxy.dll.mxstatus-safearray-decompile.md` — `FUN_10003f60` (the SafeArray creator) +- `analysis/ghidra/exports/Lmx.dll.set-attribute-result-decompile.md` — `PreboundReference::OnSetAttributeResult` (`FUN_10114a90`) -- The `Lmx.aaDCT` symbol referenced at `0x10178fc0` is a `SysAllocString(L"Lmx.aaDCT")` call into a global BSTR — a logging category name, not a status-mapping table. Decompiled function body is a textbook static initializer, no array / lookup logic. -- `MXSTATUS_PROXY` (`analysis/decompiled-interop/Interop.Lmx/Interop/Lmx/MXSTATUS_PROXY.cs`) is a 4-field struct (`success: i16`, `category: MxStatusCategory`, `detectedBy: MxStatusSource`, `detail: i16`), used as the marshalled COM event payload — not a static array of pre-mapped statuses. -- The `Fire_OnDataChange` / `Fire_OnWriteComplete` / `Fire_OperationComplete` / `Fire_OnBufferedDataChange` event-firing functions in `LmxProxy.dll` (RVAs `0x15f72`, `0x1611f`, `0x16271`, `0x163c0`) receive **already-populated** `MXSTATUS_PROXY[]` arrays — the byte-to-struct synthesis happens upstream in the proxy's NMX-callback ingestion code, not via a table lookup. The synthesis is per-call computation from operation state (engine ids, item handles, retry counters), not a static byte→status promotion. +Findings, layer by layer (the wire bytes flow inward; the synthesis flows outward): -This means the .NET reference's verbatim-preservation strategy IS the canonical native behaviour: there is no table to mirror because the native code computes the `MXSTATUS_PROXY` from operation context per-event, not from a lookup. The 1-byte completion frames `0x00`, `0x41`, `0xEF` etc. are intermediate NMX-internal signaling that the proxy synthesizes contextual status from; the only frame with a proven typed promotion is the 5-byte status-word `00 00 50 80 00` → `MxStatus.WriteCompleteOk`. +1. **`Lmx.aaDCT`** at `0x10178fc0` is a `SysAllocString(L"Lmx.aaDCT")` into a global BSTR — a tracing category name, not a status-mapping table. No array / lookup logic. +2. **`MXSTATUS_PROXY`** (16 bytes, Pack=4) is a 4-field marshalled struct: `success: i16` at offset 0, `category: i16` at offset 4, `detectedBy: i16` at offset 8, `detail: i16` at offset 12. It is the *output* of synthesis, not a lookup-table entry. +3. **`LmxProxy.dll` Fire_* event handlers** (`FUN_10015f72`, `FUN_1001611f`, `FUN_10016271`, `FUN_100163c0`) take an *already-populated* `MXSTATUS_PROXY[]` and forward it through ATL connection-point dispatch. No synthesis here. +4. **`LmxProxy.dll` Fire_* callers** (`FUN_1001657f` for OnDataChange / OnBufferedDataChange, `FUN_10016b50` for OnWriteComplete, `FUN_10016d4b` for OperationComplete) call **`FUN_10003f60(out_safearray, in_status_ptr, count=1)`** which creates the SafeArray. `FUN_10003f60` is **a verbatim memcpy** of an existing 14-byte buffer into the SAFEARRAY data — no transformation. Source confirms: bytes flow `*local_8 = *param_2; *(local_8+2) = *(param_2+2); *(local_8+4) = *(param_2+4); local_8[6] = param_2[6]`. +5. **`Lmx.dll` `PreboundReference::OnSetAttributeResult`** (`FUN_10114a90`) — the CALLER of step 4's path — receives an already-populated `short *param_7` status buffer. Its log line confirms the layout: `swprintf_s(L"", (i16)*p, *(p+2), *(p+4), p[6])`. Its dispatch logic checks typed values (`*local_b6c == -1`, `*(int *)(local_b6c + 2) == 3`) — synthesis is upstream of THIS function too. -**Current best answer:** unchanged — `Session::operation_status_events()` exposes `Stream` carrying frame bytes. Promote to a typed `WriteCompleted` only on the proven `00 00 50 80 00` 5-byte pattern. Other bytes stay raw as `MxStatus { Success: 0, Category: Unknown, DetectedBy: Unknown, Detail: byte }`. The Rust codec mirrors `src/MxNativeCodec/NmxOperationStatusMessage.cs:TryParseInner`. +**The synthesizer is the NMX-frame decoder in `Lmx.dll`** that calls `OnSetAttributeResult` / `OnGetAttributeResult` / equivalent OperationComplete handler. That decoder takes raw NMX bytes (e.g. 1-byte `0x00`/`0x41`/`0xEF` completion frames or 5-byte `00 00 50 80 00`-style status words) plus operation context (which item, which engine, retry state, last-write-correlation-id) and computes the populated `MXSTATUS_PROXY`. **There is no static lookup table** — the synthesis is per-message contextual. -**Reopen when:** a live capture surfaces a 1-byte completion frame whose surrounding context (e.g. observed `MXSTATUS_PROXY` struct fired through the .NET probe alongside the byte) lets us back-derive a context-aware promotion. Since the native code synthesises the struct from operation state rather than a table, the promotion logic would itself need to be context-aware — i.e. the codec would need access to the originating operation's context, which is upstream of the bytes themselves. Until then, verbatim preservation is correct by construction. +**Why this means R3/R4 stay at "verbatim preserve" canonically.** Two viable paths exist if a future consumer demands typed promotion (neither is a small Rust patch): + +- **Path A — port the synthesizer.** Find every NMX-decoder callsite of `OnSetAttributeResult`/`OnGetAttributeResult`/`OperationComplete` in `Lmx.dll` (next xref ring beyond `FUN_10114a90`); decompile each; reverse-engineer the per-decoder synthesis logic; port to Rust. The synthesis depends on operation-tracking state (item handles, retry counters, correlation ids) the Rust codec does not currently track — so the port is more than a codec change; it's a session-state-machine extension. Estimate: ~1-2 weeks of focused work. +- **Path B — empirical capture pairs.** Run the .NET probe in scenarios that produce each completion byte; capture the (input NMX bytes, observed `MXSTATUS_PROXY`) pair via Frida hooks on `LmxProxy.dll!FUN_10003f60`; build an empirical (byte + context → status) mapping. ~30 min × 6-10 scenarios. Output: a mapping table that approximates the synthesizer without re-implementing it. Risk: the mapping is only valid for the captured operation contexts; new contexts may produce statuses outside the table. + +**Current best answer:** unchanged — `Session::operation_status_events()` exposes `Stream` carrying frame bytes. Promote to a typed `WriteCompleted` only on the proven `00 00 50 80 00` 5-byte pattern. Other bytes stay raw as `MxStatus { Success: 0, Category: Unknown, DetectedBy: Unknown, Detail: byte }`. The Rust codec mirrors `src/MxNativeCodec/NmxOperationStatusMessage.cs:TryParseInner`. The .NET reference does the same, for the same reason: the synthesizer is too context-dependent to mirror without porting the entire operation-tracking state machine, and that exceeds V1 scope. + +**Reopen when:** either (a) a consumer files a concrete use case for typed promotion of a specific byte+context combination — at which point Path B's empirical capture for that one combination is the cheapest answer; or (b) a major-version bump justifies the operation-tracking state-machine port (Path A). Until then, verbatim preservation is correct by construction. ### R4 — Completion-only byte mapping **(settled 2026-05-06 — collapses into R3's resolution)**