diff --git a/System/HIDAPI.hsc b/System/HIDAPI.hsc
--- a/System/HIDAPI.hsc
+++ b/System/HIDAPI.hsc
@@ -9,6 +9,8 @@
   , close
   , System.HIDAPI.read
   , System.HIDAPI.write
+  , System.HIDAPI.getFeatureReport
+  , System.HIDAPI.sendFeatureReport
   , getSerialNumberString
   , System.HIDAPI.error
   , HIDAPIException(HIDAPIException)
@@ -22,12 +24,12 @@
   , InterfaceNumber
   ) where
 
-import Control.Applicative
 import Control.DeepSeq
 import Control.DeepSeq.Generics
 import Control.Exception
 import Control.Monad
 import Data.ByteString
+import Data.ByteString.Internal (createAndTrim)
 import Data.Maybe
 import Data.Typeable
 import Data.Data
@@ -53,13 +55,10 @@
   , _next :: Ptr DeviceInfoInternal
   } deriving (Show)
 
-#let alignment t = "%lu", (unsigned long)offsetof(struct {char x__; t (y__); }, y__)
-
 -- | Note: This is currently a read-only instance. `poke` is not yet implemented.
-instance Storable DeviceInfoInternal where
-  alignment _ = #{alignment struct hid_device_info}
-  sizeOf _ = #{size struct hid_device_info}
-  peek p = DeviceInfoInternal <$>
+peekDeviceInfoInternal :: Ptr DeviceInfoInternal -> IO DeviceInfoInternal
+peekDeviceInfoInternal p =
+  DeviceInfoInternal <$>
     #{peek struct hid_device_info, path} p <*>
     #{peek struct hid_device_info, vendor_id} p <*>
     #{peek struct hid_device_info, product_id} p <*>
@@ -79,6 +78,9 @@
 type ReleaseNumber = Word16
 type SerialNumber = String
 type InterfaceNumber = Int
+type ReportID = Word8
+type ReportLength = Word16
+type FeatureReport = (ReportID, ByteString)
 
 data DeviceInfo = DeviceInfo
   { path :: DevicePath
@@ -180,7 +182,7 @@
 parseEnumeration dip
   | dip == nullPtr = return []
   | otherwise = do
-    idi <- peek dip
+    idi <- peekDeviceInfoInternal dip
     di <- fromInternalDeviceInfo idi
     dis <- parseEnumeration (_next idi)
     return (di : dis)
@@ -231,22 +233,47 @@
 
 foreign import ccall unsafe "hidapi/hidapi.h hid_read"
   hid_read :: Device -> Ptr CChar -> CSize -> IO CInt
-  
+
 foreign import ccall unsafe "hidapi/hidapi.h hid_write"
   hid_write :: Device -> Ptr CChar -> CSize -> IO CInt
 
+foreign import ccall unsafe "hidapi/hidapi.h hid_get_feature_report"
+  hid_get_feature_report :: Device -> Ptr Word8 -> CSize -> IO CInt
+
+foreign import ccall unsafe "hidapi/hidapi.h hid_send_feature_report"
+  hid_send_feature_report :: Device -> Ptr CChar -> CSize -> IO CInt
+
 read :: Device -> Int -> IO ByteString
 read dev n = allocaBytes n $ \b -> do
   n' <- hid_read dev b (fromIntegral n)
   checkWithHidError (n' /= -1) dev "Read failed" "hid_read returned -1"
   packCStringLen ( b, fromIntegral n' )
-  
+
 write :: Device -> ByteString -> IO Int
 write dev b = do
   n' <- useAsCStringLen b $ \(cs, csLen) -> hid_write dev cs (fromIntegral csLen)
   checkWithHidError (n' /= -1) dev "Write failed" "hid_write returned -1"
   return $ fromIntegral n'
 
+getFeatureReport :: Device -> ReportID -> ReportLength -> IO FeatureReport
+getFeatureReport dev r l = do
+  b <- createAndTrim (toSize l) $ \cs -> do
+    _ <- pokeElemOff cs 0 (fromIntegral r)
+    n <- hid_get_feature_report dev cs (toSize l)
+    let n' = fromIntegral n
+    checkWithHidError (n' /= -1) dev "Write failed" "hid_get_feature_report returned -1"
+    return n'
+  return (Data.ByteString.head b, Data.ByteString.tail b)
+  where
+    toSize x = fromIntegral x + 1
+
+sendFeatureReport :: Device -> ReportID -> ByteString -> IO Int
+sendFeatureReport dev r d = do
+  let b = cons r d
+  n' <- useAsCStringLen b $ \(cs, csLen) -> hid_send_feature_report dev cs (fromIntegral csLen)
+  checkWithHidError (n' /= -1) dev "Write failed" "hid_send_feature_report returned -1"
+  return $ fromIntegral n'
+
 foreign import ccall unsafe "hidapi/hidapi.h hid_get_serial_number_string"
   hid_get_serial_number_string :: Device -> CWString -> CSize -> IO CInt
 
@@ -256,7 +283,7 @@
 getSerialNumberString :: Device -> IO SerialNumber
 getSerialNumberString dev = do
   let bs = _SERIAL_NUMBER_MAX_LENGTH * sizeOf (undefined :: CWchar)
-  bracket (mallocBytes bs) free $ \b -> do
+  allocaBytes bs $ \b -> do
     n' <- hid_get_serial_number_string dev b (fromIntegral _SERIAL_NUMBER_MAX_LENGTH)
     checkWithHidError (n' /= -1) dev "Getting serial number failed" "hid_get_serial_number_string returned -1"
     peekCWString b
diff --git a/hidapi.cabal b/hidapi.cabal
--- a/hidapi.cabal
+++ b/hidapi.cabal
@@ -1,5 +1,5 @@
 name:              hidapi
-version:           0.1.4
+version:           0.1.5
 build-type:        Simple
 cabal-version:     >= 1.6
 category:          Hardware
@@ -39,6 +39,7 @@
   -- expect to be included in the software that uses it, so we do that
   include-dirs:  cbits/hidapi
   includes:      hidapi.h
+  ghc-options:   -Wall
 
   if os(windows)
     c-sources: cbits/hidapi/windows/hid.c
