Index: comtypes/automation.py
===================================================================
--- comtypes/automation.py	(revision 56864)
+++ comtypes/automation.py	(working copy)
@@ -115,6 +115,11 @@
     # The C Header file defn of VARIANT is much more complicated, but
     # this is the ctypes version - functional as well.
     class U_VARIANT(Union):
+        class tagBRECORD(Structure):
+            _fields_ = [
+                ("pvRecord", c_void_p),
+                ("pRecInfo", POINTER(IUnknown))
+                ]
         _fields_ = [
             ("VT_BOOL", VARIANT_BOOL),
             ("VT_I1", c_byte),
@@ -132,20 +137,16 @@
             ("c_void_p", c_void_p),
 
             ("bstrVal", BSTR),
-            # placeholder only, for the correct size:
-            #struct  __tagBRECORD
-            #    {
-            #        PVOID pvRecord;
-            #        IRecordInfo __RPC_FAR *pRecInfo;
-            #    }__VARIANT_NAME_4;
-            ("__tagBRECORD", c_void_p * 2),
+            ("_tagBRECORD", tagBRECORD),
             ]
+        _anonymous_ = ["_tagBRECORD"]
     _fields_ = [("vt", VARTYPE),
                 ("wReserved1", c_ushort),
                 ("wReserved2", c_ushort),
                 ("wReserved3", c_ushort),
                 ("_", U_VARIANT)
     ]
+    _anonymous_ = ["_"]
 
     def __init__(self, *args):
         if args:
@@ -227,6 +228,19 @@
             typecode, psa = SafeArray_FromArray(value)
             self._.c_void_p = cast(psa, c_void_p)
             self.vt = VT_ARRAY | typecode
+        elif isinstance(value, Structure):
+            try:
+                guids = value._recordinfo_
+            except AttributeError:
+                raise TypeError("need _recordinfo_") # XXX better exception
+
+            from comtypes.typeinfo import GetRecordInfoFromGuids
+            ri = GetRecordInfoFromGuids(*guids)
+            ri.AddRef()
+            self.pRecInfo = ri
+            self.pvRecord = ri.RecordCreateCopy(byref(value))
+
+            self.vt = VT_RECORD
         else:
             raise "VARIANT _set_value, NYI", value
         # buffer ->  SAFEARRAY of VT_UI1 ?
@@ -301,6 +315,22 @@
         elif self.vt & VT_ARRAY:
             from comtypes.safearray import UnpackSafeArray
             return UnpackSafeArray(self._.c_void_p)
+        elif self.vt == VT_RECORD:
+            p = self.pRecInfo
+            p.AddRef()
+            from comtypes.typeinfo import IRecordInfo
+            ri = p.QueryInterface(IRecordInfo)
+
+            tlib, _ = ri.GetTypeInfo().GetContainingTypeLib()
+
+            from comtypes.client import GetModule
+            mod = GetModule(tlib)
+            struct_type = getattr(mod, ri.GetName())
+
+            obj = struct_type()
+
+            ri.RecordCopy(self.pvRecord, byref(obj))
+            return obj
         else:
             raise NotImplementedError("typecode %d = 0x%x)" % (vt, vt))
 
Index: comtypes/safearray.py
===================================================================
--- comtypes/safearray.py	(revision 56864)
+++ comtypes/safearray.py	(working copy)
@@ -1,6 +1,7 @@
 # very thin safearray support
 from ctypes import *
-from comtypes.typeinfo import SAFEARRAYBOUND
+from comtypes.typeinfo import SAFEARRAYBOUND, IRecordInfo
+from comtypes.client import GetModule
 from comtypes.automation import VARIANT, VARTYPE, BSTR
 from comtypes.automation import VT_VARIANT, VT_R4, VT_R8, VT_I1, VT_I2, VT_I4, VT_INT, VT_UI1, VT_UI2, VT_UI4, VT_UINT, VT_BSTR
 
@@ -83,6 +84,11 @@
 SafeArrayGetDim = oledll.oleaut32.SafeArrayGetDim
 SafeArrayGetDim.restype = c_uint
 
+def SafeArrayGetRecordInfo(psa):
+    ri = POINTER(IRecordInfo)()
+    oledll.oleaut32.SafeArrayGetRecordInfo(psa, byref(ri))
+    return ri
+
 ################################################################
 
 def SafeArray_FromSequence(seq):
@@ -129,7 +135,10 @@
         for i in range(indices[dim], upperbounds[dim]+1):
             indices[dim] = i
             SafeArrayGetElement(psa, indices, byref(ctype))
-            result.append(ctype.value)
+            if hasattr(ctype, "value"):
+                result.append(ctype.value)
+            else:
+                result.append(ctype)
     else:
         for i in range(indices[dim], upperbounds[dim]+1):
             indices[dim] = i
@@ -156,8 +165,17 @@
     # Return the ctypes data type corresponding to the SAFEARRAY's typecode.
     vt = VARTYPE()
     SafeArrayGetVartype(psa, byref(vt))
-    return _VT2CTYPE[vt.value]
+    try:
+        return _VT2CTYPE[vt.value]
+    except KeyError:
+        ri = SafeArrayGetRecordInfo(psa)
 
+        tlib, _ = ri.GetTypeInfo().GetContainingTypeLib()
+
+        mod = GetModule(tlib)
+        return getattr(mod, ri.GetName())
+        
+
 def _get_ubound(psa, dim):
     # Return the upper bound of a dimension in a safearray
     ubound = c_long()
