Reputation: 23
I want to write a small program that reads data from a text file and then imports it into the Windows Registry. I've found the bindings to the Windows functions in the System.Win32.Registry package, but ran into an issue with the regSetValueEx function. When I want to import a number as a DWORD (Word32) I can't figure out how to pass it to regSetValueEx to get the desired result.
Right now I'm storing the number as a TCHAR and using alloca and poke to get a pointer. Here's the code I'm using for testing:
module Main where
import Foreign.Marshal.Alloc
import Foreign.Storable
import System.Win32.Registry
import System.Win32.Types
number :: TCHAR
number = 42
getKey :: IO HKEY
getKey = regOpenKey hKEY_CURRENT_USER "test"
importFromTCHAR :: IO ()
importFromTCHAR = alloca $ \ptr -> do
poke ptr number
key <- getKey
regSetValueEx key "tchar" rEG_DWORD ptr (sizeOf (undefined::DWORD))
main :: IO ()
main = importFromTCHAR
The result: 0x0184002a
It kinda works, but since the size of a TCHAR value is only 2 bytes the other two bytes is taken up by junk. How can I prevent this? Any help would be greatly appreciated. I'm fairly new to Haskell (only recently finished LYAH), so please go easy on me. :)
Also, I'd really like to know what libraries more experienced Haskellers use to interface with the Windows Registry. Is there any libraries that makes working with it easier?
EDIT: Alright, as it turns out while looking through the packages on Hackage I somehow missed the castPtr function in the Foreign.Ptr package. I feel like an idiot, because with it the solution is really easy. As per Ilya's answer I just need to store the number as a Word32 (or DWORD), poke it into the pointer alloca gives me and then call castPtr on it before I pass it to regSetValueEx. Here's the modified code:
module Main where
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
import System.Win32.Registry
import System.Win32.Types
number :: DWORD
number = 42
getKey :: IO HKEY
getKey = regOpenKey hKEY_CURRENT_USER "test"
importFromDWORD :: IO ()
importFromDWORD = alloca $ \ptr -> do
poke ptr number
key <- getKey
regSetValueEx key "dword" rEG_DWORD (castPtr ptr) (sizeOf number)
main :: IO ()
main = importFromDWORD
Upvotes: 1
Views: 877
Reputation: 944
Just define number as Word32 from Data.Word:
number :: Word32
number = 42
Also you can use sizeOf on normal value like: sizeOf number
Upvotes: 1