diff --git a/const.py b/const.py
new file mode 100644
index 0000000000000000000000000000000000000000..bac3f747c819f4c6a3ae8244c86fc9a8f6b6695b
--- /dev/null
+++ b/const.py
@@ -0,0 +1,47 @@
+from enum import Enum
+
+
+class MSFTDiskBusType(Enum):
+    UNKNOWN = 0
+    SCSI = 1
+    ATAPI = 2
+    ATA = 3
+    IEEE_1394 = 4
+    SSA = 5
+    FIBER_CHANNEL = 6
+    USB = 7
+    RAID = 8
+    iSCSI = 9
+    SAS = 10
+    SATA = 11
+    SD = 12
+    MMC = 13
+    _SYSTEM_RESERVED_14 = 14
+    FILE_BACKUP_VIRTUAL = 15
+    STORAGE_SPACE = 16
+    NVMe = 17
+    _SYSTEM_RESERVED_18 = 18
+
+    @classmethod
+    def whitelist(cls):
+        return set([
+            MSFTDiskBusType.SCSI,
+            MSFTDiskBusType.ATA,
+            MSFTDiskBusType.iSCSI,
+            MSFTDiskBusType.SAS,
+            MSFTDiskBusType.SATA,
+            MSFTDiskBusType.NVMe,
+            ])
+
+class MSFTDiskMediaType(Enum):
+    UNSPECIFIED = 0
+    HDD = 3
+    SSD = 4
+    SCM = 5
+
+    @classmethod
+    def whitelist(cls):
+        return set([
+            MSFTDiskMediaType.HDD,
+            MSFTDiskMediaType.SSD,
+            ])
diff --git a/parse.py b/parse.py
index 08d64bfcc673cd7ff9f4e49485fc85b7c708c63e..d1e355f6022be8595544b8018e98adcbf4150653 100644
--- a/parse.py
+++ b/parse.py
@@ -1,7 +1,18 @@
 import os
 import re
+import sys
 import xml.etree.ElementTree as ET
 
+import const
+
+
+HACK_NOTE = dict()
+_hacknote_filename = os.getenv("HWINFO_HACKNOTE_FILE", "hacknote.json")
+if os.path.exists(_hacknote_filename):
+    import json
+    HACK_NOTE = json.load(open(_hacknote_filename, encoding="utf-8"))
+    print("Loaded {:,} keys from hack note".format(len(HACK_NOTE)))
+
 
 def parse_single(body):
     stripped = body
@@ -16,7 +27,11 @@ def parse_single(body):
     
     for search in doc.findall("search"):
         query = search.find("query")
-        part_type = query.text.lower().split(' win32_')[-1]
+
+        if "MSFT" in query.text:
+            part_type = query.text.lower().split("_")[-1]
+        else:
+            part_type = query.text.lower().split(' win32_')[-1]
 
         if part_type not in parsed:
             parsed[part_type] = []
@@ -137,6 +152,39 @@ def parser_disk(_tree):
     }
 
 
+def parser_disk_meta(_tree):
+    name = extract_tag(_tree, ("Model", "FriendlyName",))
+    capacity = failsafe(int, extract_tag(_tree, ("Size",)))
+    _media_type = failsafe(int, extract_tag(_tree, ("MediaType",)))
+    _bus_type = failsafe(int, extract_tag(_tree, ("BusType",)))
+    serial = extract_tag(_tree, ("SerialNumber",))
+
+    if isinstance(capacity, int):
+        capacity = readable(capacity, base=1000)
+
+    media_type = None
+    try:
+        media_type = const.MSFTDiskMediaType(_media_type)
+    except:
+        print("Unknown disk media type", _media_type, file=sys.stderr)
+        pass
+
+    bus_type = None
+    try:
+        bus_type = const.MSFTDiskBusType(_bus_type)
+    except:
+        print("Unknown disk bus type", _bus_type, file=sys.stderr)
+        pass
+
+    return {
+        "name": name,
+        "capacity": capacity,
+        "media_type": media_type,
+        "bus_type": bus_type,
+        "serial": serial,
+    }
+
+
 def parser_gpu(_tree):
     name = extract_tag(_tree, ("Name", "VideoProcessor", "Caption",))
     manufacturer = extract_tag(_tree, ("AdapterCompatibility",))
@@ -177,22 +225,71 @@ def handle_xml_body(data):
     tree = parse_single(data)
     
     cpu_name = filter_virtual([parse_cpu(_doc) for _doc in tree['processor']])
-    disks_name = filter_virtual([parser_disk(_doc) for _doc in tree['diskdrive']])
     board_name = filter_virtual([parser_mb(tree['baseboard'][0])])
     memory_name = filter_virtual([parser_mem(_doc) for _doc in tree['physicalmemory']])
     gpu_name = filter_virtual([parser_gpu(_doc) for _doc in tree['videocontroller']])
 
+    disk_name = filter_virtual([parser_disk(_doc) for _doc in tree['diskdrive']])
+    _disk_meta = filter_virtual([parser_disk_meta(_doc) for _doc in tree['physicaldisk']]) \
+        if 'physicaldisk' in tree else []
+
+    _disk_meta_dict = dict((x.get('name') or None, x,) for x in _disk_meta)
+
+    for _part in disk_name:
+        _part["type"] = None
+        _part["interface"] = None
+
+        _part_name = _part.get('name')
+        if not _part_name:
+            continue
+
+        if _part_name in HACK_NOTE:
+            _note = HACK_NOTE[_part_name]
+            _media_type = const.MSFTDiskMediaType(_note['media_type'])
+            _bus_type = const.MSFTDiskBusType(_note["bus_type"])
+        
+        else:
+            _part_meta = _disk_meta_dict.get(_part_name)
+            if not _part_meta:
+                continue
+
+            _media_type = _part_meta['media_type']
+            _bus_type = _part_meta["bus_type"]
+
+        if _media_type not in const.MSFTDiskMediaType.whitelist():
+            print("Ignorin ", _part_name, "due to not whitelisted device media type", _media_type, file=sys.stderr)
+            continue
+
+        _part["type"] = _media_type.name
+
+        if _bus_type not in const.MSFTDiskBusType.whitelist():
+            print("Ignorin ", _part_name, "due to not whitelisted device bus type", _bus_type, file=sys.stderr)
+            continue
+
+        _part["interface"] = _bus_type.name
+
+
     return {
         "CPU": cpu_name,
         "MB": board_name,
         "RAM": memory_name,
-        "DISK": disks_name,
+        "DISK": disk_name,
         "GPU": gpu_name,
     }
 
 
 if __name__ == "__main__":
     files = list(filter(lambda x: x.startswith("meanspec-log"), os.listdir()))
+    _meta_required = set()
+
     for fname in files:
-        print(fname, handle_xml(fname))
+        print(fname)
+        parsed = handle_file(fname)
+        print(parsed["DISK"])
+        print()
+
+        for _disk in parsed["DISK"]:
+            if not _disk["interface"] or not _disk["type"]:
+                _meta_required.add(_disk["name"])
 
+    [print(x) for x in _meta_required]