@@ -2836,6 +2836,9 @@ fn GetModuleHandleW(emu: &mut emu::Emu) {
28362836 ) ;
28372837}
28382838
2839+ /*
2840+ DWORD TlsAlloc();
2841+ */
28392842fn TlsAlloc ( emu : & mut emu:: Emu ) {
28402843 log:: info!(
28412844 "{}** {} kernel32!TlsAlloc {}" ,
@@ -2845,16 +2848,16 @@ fn TlsAlloc(emu: &mut emu::Emu) {
28452848 ) ;
28462849
28472850 emu. tls64 . push ( 0 ) ;
2848- let tls_index = emu. tls64 . len ( ) as u64 ;
2849- log:: info!( "kernel32!TlsAlloc tls_index: {}" , tls_index) ;
2850- emu. regs . rax = tls_index;
2851+ emu. regs . rax = ( emu. tls64 . len ( ) - 1 ) as u64 ; // Return index of newly allocated slot
28512852}
28522853
2854+ /*
2855+ BOOL TlsFree(
2856+ [in] DWORD dwTlsIndex
2857+ );
2858+ */
28532859fn TlsFree ( emu : & mut emu:: Emu ) {
2854- let idx = emu
2855- . maps
2856- . read_dword ( emu. regs . get_esp ( ) )
2857- . expect ( "kernel32!TlsFree cannot read idx" ) ;
2860+ let idx = emu. regs . rcx as usize ; // First parameter passed in RCX in x64
28582861
28592862 log:: info!(
28602863 "{}** {} kernel32!TlsFree idx: {} {}" ,
@@ -2864,19 +2867,23 @@ fn TlsFree(emu: &mut emu::Emu) {
28642867 emu. colors. nc
28652868 ) ;
28662869
2867- emu. stack_pop64 ( false ) ;
2868- emu. regs . rax = 1 ;
2870+ if idx < emu. tls64 . len ( ) {
2871+ emu. tls64 [ idx] = 0 ; // Clear the slot
2872+ emu. regs . rax = 1 ; // Return TRUE
2873+ } else {
2874+ emu. regs . rax = 0 ; // Return FALSE if invalid index
2875+ }
28692876}
28702877
2878+ /*
2879+ BOOL TlsSetValue(
2880+ [in] DWORD dwTlsIndex,
2881+ [in, optional] LPVOID lpTlsValue
2882+ );
2883+ */
28712884fn TlsSetValue ( emu : & mut emu:: Emu ) {
2872- let idx = emu
2873- . maps
2874- . read_dword ( emu. regs . get_esp ( ) ) // dword, not qword despite x64?
2875- . expect ( "kernel32!TlsSetValue cannot read idx" ) ;
2876- let val = emu
2877- . maps
2878- . read_qword ( emu. regs . get_esp ( ) + 4 )
2879- . expect ( "kernel32!TlsSetValue cannot read val_ptr" ) ;
2885+ let idx = emu. regs . rcx as usize ; // First parameter in RCX
2886+ let val = emu. regs . rdx ; // Second parameter in RDX
28802887
28812888 log:: info!(
28822889 "{}** {} kernel32!TlsSetValue idx: {} val: 0x{:x} {}" ,
@@ -2887,41 +2894,41 @@ fn TlsSetValue(emu: &mut emu::Emu) {
28872894 emu. colors. nc
28882895 ) ;
28892896
2890- if emu. tls64 . len ( ) > idx as usize {
2891- emu. tls64 [ idx as usize ] = val;
2897+ if idx < emu. tls64 . len ( ) {
2898+ emu. tls64 [ idx] = val;
28922899 } else {
2893- for _ in 0 ..=idx {
2900+ // Expand TLS array if needed
2901+ while emu. tls64 . len ( ) <= idx {
28942902 emu. tls64 . push ( 0 ) ;
28952903 }
2896- emu. tls64 [ idx as usize ] = val;
2904+ emu. tls64 [ idx] = val;
28972905 }
28982906
2899- emu. stack_pop32 ( false ) ;
2900- emu. stack_pop64 ( false ) ;
2901-
2902- emu. regs . rax = 1 ;
2907+ emu. regs . rax = 1 ; // Return TRUE
29032908}
29042909
2910+ /*
2911+ DWORD TlsGetValue(
2912+ [in] DWORD dwTlsIndex
2913+ );
2914+ */
29052915fn TlsGetValue ( emu : & mut emu:: Emu ) {
2906- let idx = emu
2907- . maps
2908- . read_dword ( emu. regs . get_esp ( ) ) // dword, not qword despite x64?
2909- . expect ( "kernel32!TlsGetValue cannot read idx" ) ;
2910-
2911- emu. stack_pop32 ( false ) ; // dword, not qword despite x64?
2916+ let idx = emu. regs . rcx as usize ; // Parameter passed in RCX in x64
29122917
2913- if idx as usize > emu. tls64 . len ( ) {
2914- emu. regs . rax = 0 ;
2918+ let val = if idx < emu. tls64 . len ( ) {
2919+ emu. tls64 [ idx ]
29152920 } else {
2916- emu. regs . rax = emu. tls64 [ idx as usize ] ;
2917- }
2921+ 0
2922+ } ;
2923+
2924+ emu. regs . rax = val;
29182925
29192926 log:: info!(
29202927 "{}** {} kernel32!TlsGetValue idx: {} =0x{:x} {}" ,
29212928 emu. colors. light_red,
29222929 emu. pos,
29232930 idx,
2924- emu . regs . rax ,
2931+ val ,
29252932 emu. colors. nc
29262933 ) ;
2927- }
2934+ }
0 commit comments