Windows is a powerful platform, at least, if you know which APIs are at your service :)

For instance, function FindMimeFromData (exported from UrlMon.dll) was very helpfull in telling me that the user is opening the right type of file based on the content-type. I did not test if this is full proof for all conten types, but I just needed it for determing the type of image (jpeg/png/gif/wmf/emf/tif/ etc) and that works! You can't fool this function, by modifying the extension of the file, from .jpg to .gif for instance!

I got this TIP from a hardcore ATL programmer Alex Fedotov. The Russians are the best programmers :). And in fact, you could easily use this function in C# as well.

Spasiba! (it seems that .Text developers did not utilize nvarchar (unicode-16) for text its database storage so I can't use russian characters)

ps: If you wonder if I copied this from, no, it's the other way around :)


[DllImport("urlmon.dll", EntryPoint="FindMimeFromData", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false)]

static extern int FindMimeFromData(IntPtr pBC,

      [MarshalAs(UnmanagedType.LPWStr)] string pwzUrl,

    [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1, SizeParamIndex = 3)] byte[] pBuffer,

      int cbSize,

     [MarshalAs(UnmanagedType.LPWStr)]  string pwzMimeProposed,

      int dwMimeFlags,


      out string ppwzMimeOut,

      int dwReserved);


/// <summary>

/// Ensures that file exists and retrieves the content type

/// </summary>

/// <param name="file"></param>

/// <returns>Returns for instance "images/jpeg" </returns>

public static string getMimeFromFile(string file)



    if (!System.IO.File.Exists(file))

        throw new FileNotFoundException(file + " not found");


    int MaxContent = (int)new FileInfo(file).Length;

    if (MaxContent > 4096) MaxContent = 4096;


    FileStream fs = File.OpenRead(file);


    byte[] buf = new byte[MaxContent];

    fs.Read(buf, 0, MaxContent);



    string mime;

    //note: the CLR frees the data automatically returned in ppwzMimeOut     

    int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out mime, 0);


    if (result != 0)           

       throw Marshal.GetExceptionForHR(result);


   return mime;


Note that the MSDN does not tell us, how to free the returned data pointed by ppwzMimeOut. I simply assume it to be a CoTaskAlloc-ed string and if it were not true, we have no problem unless you try to run this on a winblows 9.x environment. If someone knows facts about this please let me know.

Here it comes in C++.

/// accepts an existing path to a file and reads some bytes (max 4096) to determine the content type
<returns>"images/jpeg" for instance</returns>

STDMETHODIMP GetContentType(PCWSTR file, BSTR* contentType) throw()


      AtlTrace(L"GetContentType %s\n", file);


      CAtlFile fl;

      ULONGLONG maxContent ;



      if (hr != S_OK) return hr;


      hr = fl.GetSize(maxContent);

      DWORD maxData = maxContent > 4096 ? 4096 : (DWORD)maxContent;


      CTempBuffer<BYTE, 4096, CComAllocator> data(maxData);

      PWSTR mime;


      if (data != NULL)


            hr = fl.Read(data, maxData, maxData);


            // have urlmon do the task   

            hr = FindMimeFromData(NULL, file, data, maxData, NULL, 0, &mime, 0);           



            return E_OUTOFMEMORY;


      if (SUCCEEDED(hr)) 

*contentType = CComBSTR(mime).Detach();




      return hr;