diff --git a/Crypto/Random/Entropy/Unix.hs b/Crypto/Random/Entropy/Unix.hs
--- a/Crypto/Random/Entropy/Unix.hs
+++ b/Crypto/Random/Entropy/Unix.hs
@@ -15,36 +15,53 @@
 import Data.Word (Word8)
 import Crypto.Random.Entropy.Source
 import Control.Exception as E
+
 import System.Posix.Types (Fd)
 import System.Posix.IO
 
 type H = Fd
+type DeviceName = String
 
 -- | Entropy device /dev/random on unix system 
-newtype DevRandom  = DevRandom H
+newtype DevRandom  = DevRandom DeviceName
 
 -- | Entropy device /dev/urandom on unix system 
-newtype DevURandom = DevURandom H
+newtype DevURandom = DevURandom DeviceName
 
 instance EntropySource DevRandom where
-    entropyOpen                 = fmap DevRandom `fmap` openDev "/dev/random"
-    entropyGather (DevRandom h) = gatherDevEntropy h
-    entropyClose (DevRandom h)  = closeDev h
+    entropyOpen = fmap DevRandom `fmap` testOpen "/dev/random"
+    entropyGather (DevRandom name) ptr n =
+        withDev name $ \h -> gatherDevEntropy h ptr n
+    entropyClose (DevRandom _)  = return ()
 
 instance EntropySource DevURandom where
-    entropyOpen                  = fmap DevURandom `fmap` openDev "/dev/urandom"
-    entropyGather (DevURandom h) = gatherDevEntropy h
-    entropyClose (DevURandom h)  = closeDev h
+    entropyOpen = fmap DevURandom `fmap` testOpen "/dev/urandom"
+    entropyGather (DevURandom name) ptr n =
+        withDev name $ \h -> gatherDevEntropy h ptr n
+    entropyClose (DevURandom _)  = return ()
 
+testOpen :: DeviceName -> IO (Maybe DeviceName)
+testOpen filepath = do
+    d <- openDev filepath
+    case d of
+        Nothing -> return Nothing
+        Just h  -> closeDev h >> return (Just filepath)
+
 openDev :: String -> IO (Maybe H)
 openDev filepath = (Just `fmap` openFd filepath ReadOnly Nothing fileFlags)
     `E.catch` \(_ :: IOException) -> return Nothing
   where fileFlags = defaultFileFlags { nonBlock = True }
 
+withDev :: String -> (H -> IO a) -> IO a
+withDev filepath f = openDev filepath >>= \h ->
+    case h of
+        Nothing -> error ("device " ++ filepath ++ " cannot be grabbed")
+        Just fd -> f fd >>= \r -> (closeDev fd >> return r)
+
 closeDev :: H -> IO ()
 closeDev h = closeFd h
 
 gatherDevEntropy :: H -> Ptr Word8 -> Int -> IO Int
-gatherDevEntropy fd ptr sz =
-     (fromIntegral `fmap` fdReadBuf fd ptr (fromIntegral sz))
+gatherDevEntropy h ptr sz =
+     (fromIntegral `fmap` fdReadBuf h ptr (fromIntegral sz))
     `E.catch` \(_ :: IOException) -> return 0
diff --git a/Crypto/Random/Entropy/Windows.hs b/Crypto/Random/Entropy/Windows.hs
--- a/Crypto/Random/Entropy/Windows.hs
+++ b/Crypto/Random/Entropy/Windows.hs
@@ -34,12 +34,21 @@
 cryptVerifyContext = 0xF0000000
 
 -- | handle to windows crypto API for random generation
-newtype WinCryptoAPI = WinCryptoAPI CryptCtx
+data WinCryptoAPI = WinCryptoAPI
 
 instance EntropySource WinCryptoAPI where
-    entropyOpen                    = fmap WinCryptoAPI `fmap` cryptAcquireCtx
-    entropyGather (WinCryptoAPI h) = cryptGenRandom h
-    entropyClose  (WinCryptoAPI h) = cryptReleaseCtx h
+    entropyOpen = do
+        mctx <- cryptAcquireCtx
+        maybe (return Nothing) (\ctx -> cryptReleaseCtx ctx >> return (Just WinCryptoAPI)) mctx
+    entropyGather WinCryptoAPI ptr n = do
+        mctx <- cryptAcquireCtx
+        case mctx of
+            Nothing  -> error "cannot re-grab win crypto api"
+            Just ctx -> do
+                r <- cryptGenRandom ctx ptr n
+                cryptReleaseCtx ctx
+                return r
+    entropyClose WinCryptoAPI = return ()
 
 type CryptCtx = Word32
 
diff --git a/crypto-random.cabal b/crypto-random.cabal
--- a/crypto-random.cabal
+++ b/crypto-random.cabal
@@ -1,5 +1,5 @@
 Name:                crypto-random
-Version:             0.0.5
+Version:             0.0.6
 Description:         Simple cryptographic random related types
 License:             BSD3
 License-file:        LICENSE
