Windows Registry: Jump to item (#2)

Just starting out? Need help? Post your questions and find answers here.
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Windows Registry: Jump to item (#2)

Post by ZX80 »

Hello all.

I'm stuck again. In one of the previous topics(recently, 2-3 days ago), I already wrote about jumping to the desired registry subkey(editing the "Lastkey" parameter). That method is fine, but only when regedit hasn't been opened yet. So, I need a second method that won't restart regedit every time I change the key. Otherwise it will be very flickering and annoying. And again the problem is related to win8.1 x64. I don't have this system on my home PC, so debugging is very slow. And every time I get another surprise.

I found some old code that does what I'm talking about. But not for win8.1 x64. I was very surprised because it works great on my win7 x86. I don't understand what else I need to do to make this work? After all, there is nothing supernatural here.

Can someone test this code on their x64 OS? And if that doesn't work, then fix it, please. Let me know. I just can't finish one of my small programs. I don't want it to be so raw.

By the way, Mark Russinovich uses the same approach, if I'm not mistaken. And he is a Windows expert(works for MS).

Here is the code:

Code: Select all

hReg = FindWindow_("Regedit_Regedit", 0)
Debug hReg
If hReg
  ShowWindow_(hReg, #SW_SHOWNORMAL)
  SetForegroundWindow_(hReg)
  hTree = FindWindowEx_(hReg, 0, "SysTreeView32", 0)
  Debug hTree
  If hTree
    idx = SendMessage_(hTree, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
    Sleep_(50)
    Debug idx
    If idx
      SendMessage_(hTree, #TVM_SELECTITEM, #TVGN_CARET, idx)
      Sleep_(50)
      sKey.s = "HKEY_CLASSES_ROOT\exefile\Excelxmlss"
      Debug sKey
      lKeyLen = Len(sKey)
      sChar.s = ""
      For idx = 1 To lKeyLen
        sChar = Mid(sKey, idx, 1)
        If sChar = "\"
          SendMessage_(hTree, #WM_KEYDOWN, #VK_RIGHT, $014D0001)
          SendMessage_(hTree, #WM_KEYUP, #VK_RIGHT, $C14D0001)
        Else
          SendMessage_(hTree, #WM_CHAR, Asc(sChar), $00230001)
        EndIf
        Sleep_(5)
      Next
    EndIf
  EndIf
EndIf
It all ends at line 12, because line 9 will always return 0. For my win7 x86 this is not the case.


Thank you in advance.
AZJIO
Addict
Addict
Posts: 1364
Joined: Sun May 14, 2017 1:48 am

Re: jmp to reg #2

Post by AZJIO »

I did the functionality in another language. But there are ready-made internal functions that jump to the TreeView element. (Try JumpReg)
It is necessary to make analogue using WinAPI.
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: jmp to reg #2

Post by ZX80 »

Hi, AZJIO.

I want to say thank you for your response and for all your hard work on the AutoIt documentation and especially for translation of the PureBasic help. And also for other things with source codes. But in this case I'm looking for a PureBasic solution. If possible, I would be very grateful. Today I read a similar thread (actually a theme duplicate) on the OSZone forum when I was looking for a solution.

Manhunter also did the same, but he has everything in asm, which is a dark forest for me. Now I see he also opened a process with the PROCESS_QUERY_INFORMATION constant. Then he uses something like:

Code: Select all

SendMessage_(hReg, #WM_COMMAND, 10288h, 0)
But where did this hex number come from?
AZJIO
Addict
Addict
Posts: 1364
Joined: Sun May 14, 2017 1:48 am

Re: jmp to reg #2

Post by AZJIO »

ZX80 wrote: Sat Sep 04, 2021 6:23 pmand especially for translation of the PureBasic help
1. I did not translate the PureBasic help, but only processed it with scripts to make a dark theme and highlight the code in the examples.
2. I make a hint that the TreeView has the ability to iterate through the items (TVGN_NEXT, TVM_EXPAND). I need to experiment, I'm not getting it yet.
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: jmp to reg #2

Post by ZX80 »

Can anyone translate this code from asm into PB?
Original code by Manhunter. Only comments have been translated.

Code: Select all

        ; Find Registry Editor Window
        invoke  FindWindow,szClass,NULL
        Or      eax,eax
        jz      loc_exit
        mov     [hRWnd],eax
 
        ; Find the list in the Registry Editor window
        invoke  FindWindowEx,[hRWnd],NULL,szList,NULL
        Or      eax,eax
        jz      loc_exit
        mov     [hWnd],eax
 
        ; Get the handle of the owner process
        invoke  GetWindowThreadProcessId,[hRWnd],ProcessId
        invoke  OpenProcess,PROCESS_QUERY_INFORMATION,0,[ProcessId]
        Or      eax,eax
        jz      loc_exit
        mov     [hProcess],eax
 
        ; Activate the Registry Editor window
        invoke  ShowWindow,[hRWnd],SW_RESTORE
        invoke  SetForegroundWindow,[hRWnd]
        ; Set focus to list
        invoke  SetFocus,[hWnd]
        invoke  WaitForInputIdle,[hProcess],-1
 
        ; It is not clear here :(
        invoke  SendMessage,[hRWnd],WM_COMMAND,10288h,0
        invoke  WaitForInputIdle,[hProcess],-1
 
        ; Move to the top level of the list
        ; It is assumed that it is impossible to go deeper than the 30th level of the list.
        mov     ebx,30
@@:
        invoke  SendMessage,[hWnd],WM_KEYDOWN,VK_LEFT,0
        invoke  WaitForInputIdle,[hProcess],-1
        sub     ebx,1
        jnz     @b
 
        ; Pointer to a string in the name of the registry branch
        mov     esi,szReg
loc_loop:
        lodsb
        Or      al,al
        jz      loc_exit_clean
 
        cmp     al,'\'
        jne     @f
        ; Open list branch
        invoke  SendMessage,[hWnd],WM_KEYDOWN,VK_RIGHT,0
        invoke  WaitForInputIdle,[hProcess],-1
        jmp     loc_loop
@@:
        movzx   eax,al
        ; Search for a string in a list
        invoke  SendMessage,[hWnd],WM_CHAR,eax,0
        invoke  WaitForInputIdle,[hProcess],-1
        jmp     loc_loop
loc_exit_clean:
        invoke  CloseHandle,[hProcess]
 
loc_exit:
AZJIO
Addict
Addict
Posts: 1364
Joined: Sun May 14, 2017 1:48 am

Re: jmp to reg #2

Post by AZJIO »

I remembered that kvitaliy gave this code... Turn on the startup mode from the administrator.

Code: Select all

Procedure JumpToKey(key.s)
  hWin = FindWindow_("RegEdit_RegEdit", #NUL);
  ShowWindow_(hWin, #SW_SHOWNORMAL) ;
  hWin= FindWindowEx_(hWin, 0, "SysTreeView32", 0);
  SetForegroundWindow_(hWin) ;
If hWin 
   For i = 1 To 30
    SendMessage_(hWin, #WM_KEYDOWN, #VK_LEFT, 0) ;
   Next
  Sleep_(100) ;
  SendMessage_(hWin, #WM_KEYDOWN, #VK_RIGHT, 0) ;
  Sleep_(100)                                   ;
  n= Len(Key) ;
  For i = 1 To n
    char.s = Mid(Key,i,1)
    If char = "\" 
      SendMessage_(hWin, #WM_KEYDOWN, #VK_RIGHT, 0);
      Sleep_(100)
    Else
      SendMessage_(hWin, #WM_CHAR, Asc(char), 0) ;
    EndIf
    
  Next
  ProcedureReturn 1
Else
  ProcedureReturn 0
EndIf
 
EndProcedure
 
;- Test programm
 
key.s="HKEY_CURRENT_USER\Software\Microsoft\Notepad"
 
If JumpToKey(key) > 0
  
Else
  If RunProgram ("regedit.exe")
     Sleep_(1000)
     JumpToKey(key)
  Else  
    MessageRequester("Message","RegEdit is not running")  
  EndIf
  
EndIf 
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: jmp to reg #2

Post by ZX80 »

AZJIO, thank you.

I understood the meaning. I can check it only tomorrow. I think it will work.
However! ... This code does not collapse previously opened subkeys above and below the current/last position.
So it's still not perfect. For example, I run a fresh copy of regedit with all subkeys collapsed. Now I will open the following paths one by one:

HKEY_CLASSES_ROOT\.3gp\ShellEx
HKEY_LOCAL_MACHINE\SOFTWARE\7-Zip
HKEY_CURRENT_CONFIG\System\CurrentControlSet\Control
HKEY_CURRENT_USER\Control Panel\Desktop\Colors

And now I will choose: HKEY_CURRENT_USER\Network - (current/last position)

If you run your code now, all previously opened subkeys will be also open.
Due to this, further manual navigation through the tree can be difficult.

I would like to know why this line does not work:

Code: Select all

idx = SendMessage_(hTree, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
How to fix it and make it work. As I said, idx is always zero. Why?
AZJIO
Addict
Addict
Posts: 1364
Joined: Sun May 14, 2017 1:48 am

Re: jmp to reg #2

Post by AZJIO »

ZX80 wrote: Sun Sep 05, 2021 9:43 amHow to fix it and make it work. As I said, idx is always zero. Why?
If you run from the administrator, then the idx is not equal to 0. This selects the first root element, but it does not collapse the tree.
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: jmp to reg #2

Post by ZX80 »

AZJIO,

I have admin rights, but get 0 on win 8.1 x64. Okay. I'll try again tomorrow and report back.
Yes, the word "root" speaks for itself. I understand it. More precisely, it gets the id of the root element. The transition is carried out by the next sending of a message to treegadget.
it does not collapse the tree.
Yes, I already noticed that the code in my post also sins with this. Then the question is still not closed. How to pre-collapse(before navigating to the required subkey) all previously opened nodes? To make it great.
Is this topic still interesting for someone?

P.S. In my previous post, I wanted to show or simulate any user actions. We don't know in advance which nodes were open before running our code. But after doing it, everything should be beautiful.
AZJIO
Addict
Addict
Posts: 1364
Joined: Sun May 14, 2017 1:48 am

Re: jmp to reg #2

Post by AZJIO »

TVE_COLLAPSE, TVGN_NEXT

Code: Select all

Sleep_(2000)
idx = SendMessage_(hWin, #TVM_GETNEXTITEM, #TVGN_ROOT, 0)
Debug idx
SendMessage_(hWin, #TVM_EXPAND, #TVE_COLLAPSE, idx)

Code: Select all

Sleep_(2000)
idx = SendMessage_(hWin, #TVM_GETNEXTITEM, #TVGN_ROOT, 0) ; select root
idx = SendMessage_(hWin, #TVM_GETNEXTITEM, #TVGN_CHILD, idx) ; go to the first child
idx = SendMessage_(hWin, #TVM_GETNEXTITEM, #TVGN_NEXT, idx) ; select the next one at the same level, provided that we have opened HKEY_CURRENT_USER
Debug idx
SendMessage_(hWin, #TVM_EXPAND, #TVE_COLLAPSE, idx)
ZX80
Enthusiast
Enthusiast
Posts: 331
Joined: Mon Dec 12, 2016 1:37 pm

Re: Windows Registry: Jump to item (#2)

Post by ZX80 »

AZJIO, both codes work (yours and mine). My bad. I assumed that when you run the program under program environment(F5), it will automatically inherit the debugger attributes (no need to mark it in the compiler settings). I thought it only needs to be done for the final compiled program. Similar to streams. After all, PB IDE allows you to create threads (run by F5) without this setting. The fact that it is unsafe is another matter. At least this works and does not return 0.
Post Reply