proc VerQueryValue; ptrExe/Dll ;;;;;, WhichModeStr (always ANSI!!!!!), bufferout(size $100!)  ; ret len
  cmp byte [IsUnicode], 0
  je GetBuildNumber_RealAW

  push dword [esp + 8]
  call dword [klstrlenA]
  or eax, eax
  jz VerQueryValue_PreFail1

  mov ecx, eax
  shl ecx, 1
  sub ecx, 3
  push ebx
  mov ebx, esp
  xor edx, edx
  push edx ;word zero!
  push edx ;word zero!
  sub esp, ecx
  and esp, $fffffffC

  mov ecx, esp

  push eax
  push ecx
  push eax
  push dword [ebx + $c]
  push edx
  push edx
  call dword [kMultiByteToWideChar]
  or eax, eax
  jz NoCall

  mov ecx, esp
  push dword [ebx + $10]
;  mov ecx, esp
;  push dword ecx
;  push dword [esp + 4]
  push ecx
  push dword [ebx + $8]
  call dword GetBuildNumber_RealAW

NoCall:
  mov esp, ebx
  pop ebx
VerQueryValue_PreFail1:
  ret $c


GetBuildNumber_RealAW:
  push ebx
  push ebp

  push eax ; set zero
  mov eax, esp
  push eax ; set zero
  push dword [esp + $14]
  mov eax, [vGetFileVersionInfoSizeA]
  cmp byte [IsUnicode], 0
  je GetBuildNumber_GFVUISA
  mov eax, [vGetFileVersionInfoSizeW]
GetBuildNumber_GFVUISA:
  call eax
  pop ebp ; ecx ; set zero
  or eax, eax
  jz GetBuildNumber_Fail1

  mov ebx, eax
  push eax
  push dword $0
  call dword [kLocalAlloc]
  or eax, eax
  jz GetBuildNumber_Fail1

  push eax
  push ebx
  push ebp ; (set to zero value / ignored but pasing correctly anyway)
  mov ebx, eax
  push dword [esp + $18]
  mov eax, [vGetFileVersionInfoA]
  cmp byte [IsUnicode], 0
  je GetBuildNumber_GFVIA
  mov eax, [vGetFileVersionInfoW]
GetBuildNumber_GFVIA:
  call eax
  or eax, eax
  jz GetBuildNumber_Fail2













; ebx = *hMem / localalloc
; fixed *ptrTo
; ret   Len/Success

  sub esp, 8
  mov eax, esp

  add eax, 4
  push eax
  sub eax, 4
  push eax
  push dword [esp + $20]
  push ebx
  mov eax, [vVerQueryValueA]
  cmp byte [IsUnicode], 0
  je VerQueryValue_VQVA
  mov eax, [vVerQueryValueW]
VerQueryValue_VQVA:
  call eax ;-> Success?
  ;pop ecx  ;-> Len?
  ;pop edx  ;-> SubMem?
  or eax, eax
  jz VerQueryValue_Fail1
  mov eax, [esp + 4]
  or eax, eax
  jz VerQueryValue_Fail1
  cmp eax, $7f
  jae VerQueryValue_Fail1

  cmp byte [IsUnicode], 0
  je GetBuildNumber_RMMA
  shl eax, 1
  mov [esp + 4], eax
  GetBuildNumber_RMMA:
  push dword [esp + $1c]
  mov ebp, eax
  call dword [kRtlMoveMemory]
  push ebx
  call dword [kLocalFree]
  mov eax, ebp
  add ebp, [esp + $14]
  mov [ebp], byte 0
;  add esp, 8
  pop ebp
  pop ebx
  ret $c

VerQueryValue_Fail1:
  add esp, 8
GetBuildNumber_Fail2:
;  mov ebp, 0
  push ebx
  call dword [kLocalFree]
;NoGetBuildNumber1:
GetBuildNumber_Fail1:
  xor eax, eax
GetBuildNumber_Success:
  pop ebp
  pop ebx
  ret $c
endp

