News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Problems with creating a Struct in MASM32.

Started by Shooter, February 15, 2011, 09:08:59 PM

Previous topic - Next topic

Shooter

I thought I had it figured out on how to read the subfolders in the System Registry, but apparently I don't.

Does anyone have any sample code in MASM32 I could examine that shows how to read them? In particular I'm trying to read the folder names in "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\"

Many thanks,
Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

dedndave

http://www.masm32.com/board/index.php?topic=11963.msg90835#msg90835
version 2.03 has a decent routine

you would make a string like:
SubKeyName db "SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces",0

another null terminated string for the value name, 
and use HKEY_LOCAL_MACHINE as the key, which is an equate in windows.inc

don't forget to:
INCLUDE \masm32\include\advapi32.inc
INCLUDELIB \masm32\lib\advapi32.lib

Shooter

Dave,
Thanks. I ran into that while searching the forum and I've VERY interested in how that all works for converting the ProductIDs, but for now I have to concentrate on this program. I've written some code that reads values of subkeys with success, but in this particular case I need to find a subfolder first before I can read the values in it's subkeys. Windows is kinda strange as to where it stores some of it's info.

In your proggy, does it actually read sub-folders, or just the values listed in "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" ?

-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

dedndave

well - there are Keys, SubKeys, and Values
Values may have a number of different Types

in your case, "HKEY_LOCAL_MACHINE" is the Key name
"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces" is a SubKey name

under that SubKey, are more SubKeys
you may need to use RegEnumKey or RegEnumKeyEx to enumerate the SubKeys

under those SubKeys, you will find Values like "Domain", which has the Type REG_SZ (zero-terminated string)
another example is "EnableDHCP", which has the Type REG_DWORD

the Keys (HKEY_LOCAL_MACHINE) and Types (REG_DWORD) are all defined as EQUates in windows.inc (they really belong in advapi32.inc)

here is a link to the registry functions...
http://msdn.microsoft.com/en-us/library/ms724875%28v=VS.85%29.aspx

in my code, i already knew the subkey names in advance, which simplifies the code a bit   :P

Gunner

Shooter, it is actually very easy... you basically open a handle to the "root" key ("parent folder") you want to enumerate then you pass that handle to RegEnumKeyEx in a loop until RegEnumKeyEx returns ERROR_NO_MORE_ITEMS  you can use RegEnumValue
to get all the values in the currently enumerated key...  You must open the "root" key with KEY_ENUMERATE_SUB_KEYS rights...

~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

Shooter

Quote from: Gunner on February 15, 2011, 11:24:36 PM
Shooter, it is actually very easy... you basically open a handle to the "root" key ("parent folder") you want to enumerate then you pass that handle to RegEnumKeyEx in a loop until RegEnumKeyEx returns ERROR_NO_MORE_ITEMS  you can use RegEnumValue
to get all the values in the currently enumerated key...  You must open the "root" key with KEY_ENUMERATE_SUB_KEYS rights...

Rob, Question about that... I took a look at a discussion on the forum you and Dave (and others) were having the other day using RegEnumKeyEx and wrote a quick code causing it to loop (pretty close to exactly what you wrote as an example)... I noticed that it didn't stop at the end of the current 'folder' set, but continued on to the next one. I take it does that all the way until the end of the registry? I don't want to read the entire registry, just the one 'folder' set... anyway of knowing when I reach that end? (I'm still trying to understand all of the API calls, but it's a slow process, especially when I can't sit down and concentrate on it like I want to.)

In particular, I've used GetHostByName to find the active IP address, but when the computer is using a manual connection, I want to identify the other addresses (Subnet Mask, Default Gateway, Preferred DNS, etc). So far the only means that I know of to determine if DHCP is being used (from the registry) is to look at [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DHCP] to see if the "Start" value is not equal to 4. If it's 4 (DHCP not used), then I need to extract those other addresses.

I suppose I could compare the value of "DhcpIPAddress" within the TCPIP set of 'folders' to the one I retrieve from GetHostByName to see if I've found the correct NIC, and then get the other addresses from that folder (such a pain in the @$$).

I tried to see if GetHostByName could be used to extract the non-DHCP addresses, but I haven't really been able to find an example to study off of yet, and my current machine USES DHCP, so it's not like I can use my computer as an example.

-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

dedndave

it will enumerate all subkeys under the one you start with
if you want to enumerate only one, create a string with that subkey and open a handle to it, then enumerate
as Rob said, it will return ERROR_NO_MORE_ITEMS when done

Gunner

Quote from: Shooter on February 16, 2011, 12:04:26 PM
Rob, Question about that... I took a look at a discussion on the forum you and Dave (and others) were having the other day using RegEnumKeyEx and wrote a quick code causing it to loop (pretty close to exactly what you wrote as an example)... I noticed that it didn't stop at the end of the current 'folder' set, but continued on to the next one. I take it does that all the way until the end of the registry? I don't want to read the entire registry, just the one 'folder' set... anyway of knowing when I reach that end? (I'm still trying to understand all of the API calls, but it's a slow process, especially when I can't sit down and concentrate on it like I want to.)

In particular, I've used GetHostByName to find the active IP address, but when the computer is using a manual connection, I want to identify the other addresses (Subnet Mask, Default Gateway, Preferred DNS, etc). So far the only means that I know of to determine if DHCP is being used (from the registry) is to look at [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DHCP] to see if the "Start" value is not equal to 4. If it's 4 (DHCP not used), then I need to extract those other addresses.

I suppose I could compare the value of "DhcpIPAddress" within the TCPIP set of 'folders' to the one I retrieve from GetHostByName to see if I've found the correct NIC, and then get the other addresses from that folder (such a pain in the @$$).

I tried to see if GetHostByName could be used to extract the non-DHCP addresses, but I haven't really been able to find an example to study off of yet, and my current machine USES DHCP, so it's not like I can use my computer as an example.

-Shooter

Yes it will enumerate all "Top level" folders until there is no more.  So if you pass HCU as the root folder to RegEnumKeyEx, it will enumerate ALL the "Top Level" folders of HKEY_CURRENT_USER.  RegEnum does not however enumerate child folders of the TL Folders or children of the children.

But if all you want is to see if some value is set a certain way, then (In your example above)  Off the top of my head so if I get an api name wrong, don't shoot me!  You would do a RegOpenKeyEx with:
HKEY_LOCAL_MACHINE == hKey
"SYSTEM\CurrentControlSet\Services\DHCP" == SubKey
KEY_QUERY_VALUE == access rights

The handle is returned in the pointer you passed as phkResult...

Next RegQueryValueEx:
phkResult == hKey
Start == ValueName
REG_DWORD == lpType (I don't think you need to set this since you are expecting a dword anyway so you know the type of data you are expecting)
lpData is a pointer to a dword var to hold the setting

Once you got the info, pass phkResult to RegCloseKey

Now, if you still want to Enumerate all keys of a "Folder" I will help with that too...
~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

Shooter

Welp, I'm thinking the best way I can do what I want above is to read in the GUIDs (#4) from the subkey (#5), compare the value in DhcpIPAddress (#1) to the IP address I got from GetHostByName. If I get a match, then read in the other two values I'm looking for (#2 & #3), if not, move on.

It's the loading of the names of the GUIDs that I'm having a problem with. Recursive input seems to be the only viable means to achieve this as each machine I work on has a different set of numbers depending on the model of the NIC.

Got a good way to do that, OR possibly a completely different approach to this?

Thanks a million,
-Shooter

Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

Gunner

Sure you could enumerate the subkeys under interfaces, but there should be API functions to get the info you need..  Check out:
GetIpAddrTable

The GetIpAddrTable function retrieves the interface–to–IP address mapping table.



And the structure IP_ADAPTER_INFO might be of use to you:
IP_ADAPTER_INFO

The IP_ADAPTER_INFO structure contains information about a particular network adapter on the local computer


Hell, the more I look in the PSDK the more I find...  Look up Internet Protocal Helper on MSDN or your PSDK and you will find what you need...


~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

Shooter

#10
GetIpAddrTable

The GetIpAddrTable function retrieves the interface–to–IP address mapping table.



I take it I have to build my own Structs for this to work with Masm32? I've included "Iphlpapi.lib", but something is still wrong.

I get the following error:
QuoteReadRegKey.asm(289) : error A2114: INVOKE argument type mismatch : argument : 1
ReadRegKey.asm(126) : warning A4014: instructions and initialized data not supported in BSS segments

My declaration is:
.data
_MIB_IPADDRTABLE struct
dwAddr DW 0
dwIndex DW 0
dwMask DW 0
dwBCastAddr DW 0
dwReasmSize DW 0
unused1 DB 0
wType DW 0
_MIB_IPADDRTABLE ends


Line 126:
pIpAddrTable _MIB_IPADDRTABLE <?>
.
.
.
bOrder DW ?
pdwSize DW ?


And I'm calling it with (line 289):
INVOKE GetIpAddrTable,pIpAddrTable,pdwSize,bOrder

I'm not undertstanding what I'm doing wrong. Any ideas?

-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

Shooter

Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

dedndave

do you have:
        INCLUDE    \masm32\include\iphlpapi.inc
        INCLUDELIB \masm32\lib\iphlpapi.lib

Shooter

Quote from: dedndave on February 19, 2011, 03:34:08 PM
do you have:
        INCLUDE    \masm32\include\iphlpapi.inc
        INCLUDELIB \masm32\lib\iphlpapi.lib


Dave,
Yup... just not sure how to implement this one. All the examples I'm finding across the web (very few, by the way) are in a different language, and I don't know how to translate them.

-Shooter
Never use direct references to anything ever. Bury everything in
macros. Bury the macros in include files. Reference those include
files indirectly from other include files. Use macros to reference
those include files.

dedndave

well - this tells you something is wrong
ReadRegKey.asm(289) : error A2114: INVOKE argument type mismatch : argument : 1
that can be caused by the lack of a PROTOtype
or else, the first parm probably should be a dword type and you have it defined otherwise

perhaps it needs a pointer...
        INVOKE GetIpAddrTable,ADDR pIpAddrTable,pdwSize,bOrder
;or
        INVOKE GetIpAddrTable,OFFSET pIpAddrTable,pdwSize,bOrder

but that mistake usually assembles ok - then generates c0000005   :P