Cititi cu atentie ce spunea genialul @raz12345, Atotputernicul, in data de 30 septembrie 2012 intr-o postare.
Totul a pornit de la executabilul 9.6.5.245577 titanic(exe-fixed)
► Show Spoiler
Soluția nu-mi aparține nici mie, nici lui titanic(Titanic52) cum greșit se vehiculează prin diverse cercuri, ci lui madRat, care, mai exact a identificat problema și care a făcut publică o soluție la începutul acestui an pentru comunitatea de "pasionați GPS". Ulterior și eu și alții doar am implementat soluția în versiunile ulterior apărute pentru a funcționa pe device-urile care rulează Windows Mobile 5.x, respectiv 6.x.
Problema:
Windows CE 5.x / 6.x are implementat la nivelul nucleului(kernel - coredll.dll) funcțiile GetSystemMemoryDivision respectiv SetSystemMemoryDivision, funcții care în Windows Mobile 5.x / 6.x (care este DIFERIT atât la nivelul nucleului cât și la nivelele superioare față de Windows CE) nu funcționează, generând runtime error:
Fatal error occurred in main thread.
Address: 0x03fafa78
Exception: 0xc0000005
Funcția SetSystemMemoryDivision permite divizarea memoriei RAM în Storage Memory respectiv Program Memory în timpul execuției(runtime) prin specificarea numărului de pagini alocate pentru Storage Memory detalii aici (După cum și Microsoft precizează: "This function is deprecated" și "For Windows Mobile, this function will always fail").
In Windows CE în Control Panel > System > Memory se poate configura această divizare.
NNG folosește această funcție pentru a (re)aloca mai multa memorie de tip "Storage Memory", pentru a încăpea conținutul arhivei data.zip.
În versiunile Igo 8.x.x, Primo 1.0, 1.1, 1.2 (8.5.9, 8.5.11, 9.2.0, 9.2.1) subrutina in cadrul căreia se face apelul funcției SetSystemMemoryDivision verifica înainte de apel, dacă funcția este suportată sau nu și de aceea funcționează (nu dă eroare) pe Windows Mobile.
Mai jos subrutina în cauză din Primo 9.2.0.192885:
Cod: Selectaţi tot
var_60 = -0x60
var_5C = -0x5C
var_58 = -0x58
TotalNumberOfFreeBytes= -0x54
TotalNumberOfBytes= -0x4C
FreeBytesAvailableToCaller= -0x44
Buffer = -0x3C
STMFD SP!, {R4-R9,LR}
SUB SP, SP, #0x44
LDR R0, =aCoredll_dll_0 ; "coredll.dll"
BL LoadLibraryW
LDR R1, =aGetsystemmemor ; "GetSystemMemoryDivision"
MOV R7, R0
BL GetProcAddressW
LDR R1, =aSetsystemmemor ; "SetSystemMemoryDivision"
MOV R4, R0
MOV R0, R7 ; hModule
BL GetProcAddressW
MOVS R8, R0
BEQ loc_7499F8
CMP R4, #0
BEQ loc_7499F8
ADD R2, SP, #0x60+var_58
ADD R1, SP, #0x60+var_5C
ADD R0, SP, #0x60+var_60
MOV LR, PC
MOV PC, R4
CMP R0, #0
BEQ loc_7499F8
ADD R0, SP, #0x60+Buffer ; lpBuffer
BL GlobalMemoryStatus
ADD R3, SP, #0x60+TotalNumberOfFreeBytes ; lpTotalNumberOfFreeBytes
ADD R2, SP, #0x60+TotalNumberOfBytes ; lpTotalNumberOfBytes
ADD R1, SP, #0x60+FreeBytesAvailableToCaller ; lpFreeBytesAvailableToCaller
MOV R0, #0 ; lpDirectoryName
BL GetDiskFreeSpaceExW
LDR R2, [SP,#0x60+TotalNumberOfFreeBytes]
LDR R3, [SP,#0x60+TotalNumberOfBytes]
LDR R6, [SP,#0x60+Buffer.dwAvailVirtual]
LDR R1, [SP,#0x60+Buffer.dwTotalVirtual]
SUB R3, R3, R2
LDR R2, =byte_828FE7
ADD R3, R3, #0xF00
MOV R9, #0x8100000
LDRB R5, [R2]
LDR R4, [SP,#0x60+var_5C]
ADD R0, R3, #0xFF
SUB R1, R1, R6
ORR R3, R9, #0x100
ADD R3, R1, R3
CMP R5, #0
RSB R1, R4, R3,LSR#12
LDRNE R3, =dword_83165C
LDR LR, [SP,#0x60+FreeBytesAvailableToCaller]
MOV R2, R0,LSR#12
LDRNE R3, [R3]
ADD R0, R2, #0x40
MOV LR, LR,LSR#12
CMPNE R3, #0xB
MOVNE R2, #0x200
MOVEQ R2, #0x40
CMP R1, #0
BLE loc_7499F8
ADD R3, R2, R1
CMP R3, LR
LDR R3, [SP,#0x60+var_60]
BCS loc_7499E8
SUB R0, R3, R1
MOV LR, PC
MOV PC, R8
B loc_7499F8
; ---------------------------------------------------------------------------
loc_7499E8 ; CODE XREF: sub_7498E8+ECj
ADD R0, R2, R0
CMP R0, R3
MOVCC LR, PC
MOVCC PC, R8
loc_7499F8 ; CODE XREF: sub_7498E8+30j
; sub_7498E8+38j ...
MOV R0, R7 ; hLibModule
BL FreeLibrary
ADD SP, SP, #0x44
LDMFD SP!, {R4-R9,PC}
; End of function sub_7498E8
Mai jos subrutina din Primo 9.6.5.245577:
Cod: Selectaţi tot
var_64 = -0x64
var_60 = -0x60
var_5C = -0x5C
TotalNumberOfFreeBytes= -0x58
TotalNumberOfBytes= -0x50
FreeBytesAvailableToCaller= -0x48
Buffer = -0x40
STMFD SP!, {R4-R10,LR}
SUB SP, SP, #0x44
MOV R4, R0
LDR R1, =aGetsystemmemor ; "GetSystemMemoryDivision"
BL GetProcAddressW
LDR R1, =aSetsystemmemor ; "SetSystemMemoryDivision"
MOV R5, R0
MOV R0, R4 ; hModule
BL GetProcAddressW
MOVS R8, R0
BEQ loc_859830
CMP R5, #0
BEQ loc_859830
ADD R2, SP, #0x64+var_60
ADD R1, SP, #0x64+var_5C
ADD R0, SP, #0x64+var_64
MOV LR, PC
MOV PC, R5
CMP R0, #0
BEQ loc_859830
ADD R3, SP, #0x64+TotalNumberOfFreeBytes ; lpTotalNumberOfFreeBytes
ADD R2, SP, #0x64+TotalNumberOfBytes ; lpTotalNumberOfBytes
ADD R1, SP, #0x64+FreeBytesAvailableToCaller ; lpFreeBytesAvailableToCaller
MOV R0, #0 ; lpDirectoryName
BL GetDiskFreeSpaceExW
CMP R0, #0
BEQ loc_859830
ADD R0, SP, #0x64+Buffer ; lpBuffer
BL GlobalMemoryStatus
LDR R2, [SP,#0x64+TotalNumberOfFreeBytes]
LDR R3, [SP,#0x64+TotalNumberOfBytes]
LDR R5, [SP,#0x64+var_60]
LDR R1, =__imp__rt_udiv
SUB R3, R3, R2
ADD R3, R3, R5
LDR R2, [R1]
SUB R1, R3, #1
MOV R0, R5
MOV LR, PC
MOV PC, R2
LDR R3, =__imp__rt_udiv
LDR R1, [SP,#0x64+FreeBytesAvailableToCaller]
MOV R10, R0
MOV R0, R5
MOV LR, PC
LDR PC, [R3]
LDR R3, =byte_94693A
LDR R7, =dword_951310
LDR R1, [SP,#0x64+Buffer.dwAvailPhys]
LDRB R3, [R3]
MOV R2, #0x8100000
MOV R9, R0
CMP R3, #0
LDRNE R3, [R7,#(dword_951428 - 0x951310)]
MOV R0, R5
CMPNE R3, #0xB
LDR R3, =_rt_sdiv
MOVNE R6, #0x200
MOVEQ R6, #0x40
LDR R4, [R3]
ORR R3, R2, #0x100
ADD R2, R6, R10
ADD R5, R2, #0x40
RSB R1, R1, R3
MOV LR, PC
MOV PC, R4
CMP R0, #0
BLE loc_859830
ADD R3, R0, R6
CMP R3, R9
LDR R3, [SP,#0x64+var_64]
SUBCC R5, R3, R0
BCC loc_8597CC
CMP R5, R3
BCS loc_859830
loc_8597CC ; CODE XREF: sub_8596A0+120j
CMP R5, #0
BEQ loc_859830
MOV R0, R5
MOV LR, PC
MOV PC, R8
CMP R0, #0
BEQ loc_859830
CMP R0, #1
BEQ loc_85981C
CMP R0, #3
BEQ loc_859810
LDR R1, =aUnknownErrorDO ; "Unknown error (%d)\noccured setting the "...
loc_8597FC ; CODE XREF: sub_8596A0+178j
MOV R2, R0
MOV R0, #0 ; lpBuffer
BL wsprintfW
MOV R1, #0
B loc_859820
; ---------------------------------------------------------------------------
loc_859810 ; CODE XREF: sub_8596A0+154j
BL GetLastError
LDR R1, =aTheNumberOfSto ; "The number of storage pages\ncould not b"...
B loc_8597FC
; ---------------------------------------------------------------------------
loc_85981C ; CODE XREF: sub_8596A0+14Cj
LDR R1, =aTheNumberOfS_0 ; "The number of storage pages\ncould not b"...
loc_859820 ; CODE XREF: sub_8596A0+16Cj
LDR R2, =aError_1 ; "ERROR"
LDR R0, [R7]
MOV R3, #0
BL sub_1F968
loc_859830 ; CODE XREF: sub_8596A0+28j
; sub_8596A0+30j ...
ADD SP, SP, #0x44
LDMFD SP!, {R4-R10,PC}
; End of function sub_8596A0
Cod: Selectaţi tot
offset 91575c: 53 -> 55
offset 91575e: 65 -> 6e
offset 915760: 74 -> 6b
Confuzia cum că unele versiuni de Primo 2.0.x funcționează şi pe Windows CE şi pe Windows Mobile fără a aplica soluţia de mai sus provine din faptul că cei care au modificat executabilul (tratat / vaccinat), au modificat şi numele funcției SetSystemMemoryDivision astfel că atunci când au ”lansat” noua versiune au lansat-o cu soluția de mai sus gata integrată.
Deci fără aceasta modificare, nici o versiune oficială de primo 2.0.x NU funcționează pe Windows Mobile.
Aceasta este soluţia "PDA memory fixed" şi nicidecum "optimizări" sau "modificări" pentru device-uri cu memorie mai redusă, cum eronat se vehiculează prin diverse posturi / forumuri.