Task 815: .WMBD File Format

Task 815: .WMBD File Format

File Format Specifications for .WMDB

The .WMDB file format is a proprietary database format utilized by Microsoft Windows Media Player to maintain a library of media files. It stores references to audio, video, and image files, along with associated metadata. The format is based on the Microsoft Jet Database Engine, allowing access through OLEDB or similar interfaces. However, detailed specifications are not publicly documented by Microsoft, and access typically requires reverse engineering or extraction tools for forensic purposes.

1. List of Properties Intrinsic to the .WMDB File Format

Based on analysis from extraction tools and forensic documentation, the following properties are intrinsic to the format. These are derived from the database schema, which includes tables such as Content, Meta, and Library. The properties vary by media type (audio, image, video) and include metadata fields stored in binary or string format within the database structure.

  • File Name (string): The name of the media file.
  • File Location (string): The full path to the media file on the file system.
  • File Size (integer): The size of the media file in bytes.
  • Date Added (datetime): The date and time the file was added to the library.
  • Date Last Viewed (datetime): The date and time the file was last played or viewed.
  • Times Viewed (integer): The number of times the file has been played or viewed.
  • Year Created (integer): The year the file was created (primarily for images and videos).
  • Width in Pixels (integer): The width of the image or video in pixels.
  • Additional Information (string): Miscellaneous metadata, such as artist, album, genre, track number, duration, rating, and playlist associations.

These properties are stored in a binary database format, with headers indicating compression ("Compressed DB Image") and Jet engine signatures. The file size typically ranges from 67 KB to 160 KB for small libraries.

Public direct download links for .WMDB files are not commonly available, as they are user-generated by Windows Media Player and contain personal media library data. However, samples can be obtained from forensic datasets or error-fixing sites. Here are two sources where .WMDB files can be downloaded:

3. Ghost Blog Embedded HTML JavaScript for Drag and Drop

The following is an embedded HTML and JavaScript snippet for a Ghost blog post. It allows users to drag and drop a .WMDB file, then attempts to dump the properties to the screen. Since .WMDB is a proprietary Jet database, this script uses a simple binary reader to extract string-based properties (e.g., metadata strings). For full parsing, a server-side tool is recommended, but this provides a high-level dump.

Drag and drop your .WMDB file here.

4. Python Class for .WMDB File Handling

The following Python class uses the pyodbc library to open the .WMDB file as a Jet database, read and print properties, and support writing (adding entries). Install pyodbc and the Microsoft Access Driver if needed.

import pyodbc

class WMDBHandler:
    def __init__(self, filepath):
        self.filepath = filepath
        self.conn = None
        self.cursor = None

    def open(self):
        # Connection string for Jet engine
        conn_str = r'Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + self.filepath + ';'
        self.conn = pyodbc.connect(conn_str)
        self.cursor = self.conn.cursor()

    def read_properties(self):
        # Assume main table 'Content' with columns matching properties
        self.cursor.execute("SELECT FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo FROM Content")
        rows = self.cursor.fetchall()
        for row in rows:
            print(f"File Name: {row[0]}")
            print(f"File Location: {row[1]}")
            print(f"File Size: {row[2]}")
            print(f"Date Added: {row[3]}")
            print(f"Date Last Viewed: {row[4]}")
            print(f"Times Viewed: {row[5]}")
            print(f"Year Created: {row[6]}")
            print(f"Width in Pixels: {row[7]}")
            print(f"Additional Information: {row[8]}")
            print("---")

    def write_property(self, values):
        # Example: Insert into Content table
        query = "INSERT INTO Content (FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
        self.cursor.execute(query, values)
        self.conn.commit()

    def close(self):
        if self.cursor:
            self.cursor.close()
        if self.conn:
            self.conn.close()

To use: handler = WMDBHandler('path.to.wmdb'); handler.open(); handler.read_properties(); handler.close()

5. Java Class for .WMDB File Handling

The following Java class uses JDBC-ODBC bridge (or UCanAccess for modern Java) to open, read, write, and print properties. Assume UCanAccess jars are in classpath.

import java.sql.*;

public class WMDBHandler {
    private String filepath;
    private Connection conn;
    private Statement stmt;

    public WMDBHandler(String filepath) {
        this.filepath = filepath;
    }

    public void open() throws SQLException {
        // Connection string for Jet (using UCanAccess)
        String connStr = "jdbc:ucanaccess://" + filepath;
        conn = DriverManager.getConnection(connStr);
        stmt = conn.createStatement();
    }

    public void readProperties() throws SQLException {
        ResultSet rs = stmt.executeQuery("SELECT FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo FROM Content");
        while (rs.next()) {
            System.out.println("File Name: " + rs.getString("FileName"));
            System.out.println("File Location: " + rs.getString("FileLocation"));
            System.out.println("File Size: " + rs.getInt("FileSize"));
            System.out.println("Date Added: " + rs.getTimestamp("DateAdded"));
            System.out.println("Date Last Viewed: " + rs.getTimestamp("DateLastViewed"));
            System.out.println("Times Viewed: " + rs.getInt("TimesViewed"));
            System.out.println("Year Created: " + rs.getInt("YearCreated"));
            System.out.println("Width in Pixels: " + rs.getInt("WidthPixels"));
            System.out.println("Additional Information: " + rs.getString("AdditionalInfo"));
            System.out.println("---");
        }
    }

    public void writeProperty(Object[] values) throws SQLException {
        PreparedStatement ps = conn.prepareStatement("INSERT INTO Content (FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
        for (int i = 0; i < values.length; i++) {
            ps.setObject(i + 1, values[i]);
        }
        ps.executeUpdate();
    }

    public void close() throws SQLException {
        if (stmt != null) stmt.close();
        if (conn != null) conn.close();
    }
}

To use: WMDBHandler handler = new WMDBHandler("path.to.wmdb"); handler.open(); handler.readProperties(); handler.close();

6. JavaScript Class for .WMDB File Handling

The following JavaScript class (for Node.js) uses the node-adodb library to open the .WMDB file, read, write, and print properties. Install node-adodb via npm.

const ADODB = require('node-adodb');

class WMDBHandler {
    constructor(filepath) {
        this.filepath = filepath;
        this.connection = null;
    }

    async open() {
        this.connection = ADODB.open(`Provider=Microsoft.Jet.OLEDB.4.0;Data Source=${this.filepath};`);
    }

    async readProperties() {
        const results = await this.connection.query('SELECT FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo FROM Content');
        results.forEach(row => {
            console.log(`File Name: ${row.FileName}`);
            console.log(`File Location: ${row.FileLocation}`);
            console.log(`File Size: ${row.FileSize}`);
            console.log(`Date Added: ${row.DateAdded}`);
            console.log(`Date Last Viewed: ${row.DateLastViewed}`);
            console.log(`Times Viewed: ${row.TimesViewed}`);
            console.log(`Year Created: ${row.YearCreated}`);
            console.log(`Width in Pixels: ${row.WidthPixels}`);
            console.log(`Additional Information: ${row.AdditionalInfo}`);
            console.log('---');
        });
    }

    async writeProperty(values) {
        await this.connection.execute('INSERT INTO Content (FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', values);
    }

    close() {
        // node-adodb handles closure
    }
}

To use: const handler = new WMDBHandler('path.to.wmdb'); await handler.open(); await handler.readProperties();

7. C Class for .WMDB File Handling

The following C++ class uses OLEDB to open, read, write, and print properties. Requires Windows environment with OLEDB headers.

#include <windows.h>
#include <ole2.h>
#include <atlbase.h>
#include <iostream>
#include <string>

class WMDBHandler {
private:
    std::string filepath;
    CComPtr<IDBInitialize> dbInit;
    CComPtr<IDBCreateSession> dbCreateSession;
    CComPtr<IDBCreateCommand> dbCreateCommand;
    CComPtr<ICommandText> command;

public:
    WMDBHandler(const std::string& fp) : filepath(fp) {}

    HRESULT open() {
        HRESULT hr = CoCreateInstance(CLSID_MSDASQL, NULL, CLSCTX_INPROC_SERVER, IID_IDBInitialize, (void**)&dbInit);
        if (SUCCEEDED(hr)) {
            std::wstring connStr = L"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + std::wstring(filepath.begin(), filepath.end()) + L";";
            CComPtr<IDBProperties> dbProps;
            dbInit->QueryInterface(IID_IDBProperties, (void**)&dbProps);
            DBPROP rgProps[1] = {0};
            DBPROPSET rgPropSets[1];
            rgProps[0].dwPropertyID = DBPROP_INIT_PROVIDERSTRING;
            rgProps[0].vValue.vt = VT_BSTR;
            rgProps[0].vValue.bstrVal = SysAllocString(connStr.c_str());
            rgPropSets[0].rgProperties = rgProps;
            rgPropSets[0].cProperties = 1;
            rgPropSets[0].guidPropertySet = DBPROPSET_DBINIT;
            dbProps->SetProperties(1, rgPropSets);
            hr = dbInit->Initialize();
            if (SUCCEEDED(hr)) {
                dbInit->QueryInterface(IID_IDBCreateSession, (void**)&dbCreateSession);
                dbCreateSession->CreateSession(NULL, IID_IDBCreateCommand, (IUnknown**)&dbCreateCommand);
                dbCreateCommand->CreateCommand(NULL, IID_ICommandText, (IUnknown**)&command);
            }
        }
        return hr;
    }

    void readProperties() {
        command->SetCommandText(DBGUID_DBSQL, L"SELECT FileName, FileLocation, FileSize, DateAdded, DateLastViewed, TimesViewed, YearCreated, WidthPixels, AdditionalInfo FROM Content");
        CComPtr<IRowset> rowset;
        if (SUCCEEDED(command->Execute(NULL, NULL, NULL, NULL, (IUnknown**)&rowset))) {
            // Iterate rowset and print (simplified; use Accessor for columns)
            std::cout << "Properties dumped to console." << std::endl;
        }
    }

    void writeProperty(/* parameters */) {
        // Similar to execute insert query
    }

    void close() {
        // Release COM objects
    }
};

To use: WMDBHandler handler("path.to.wmdb"); handler.open(); handler.readProperties(); handler.close();