Jump to content
Larry Ullman's Book Forums

Checking MIME Type

Recommended Posts

Hi, If anyone has some C++ code to check a file's MIME type, I'd really appreciate a copy or a URL to find it.  I am specifically trying to verify that if a file that I am reading (from a Windows file system) has a jpg file suffix, or variants thereof, that the file is indeed of MIME type image/jpeg. The development environment in this instance is Visual Studio 2017.  I have scoured Google and Stack Overflow but haven't come up with anything.

Many thanks in anticipation,

Cheers, Necuima

Link to comment
Share on other sites

I am going around and around in circles trying to create an LPWSTR (wchar_t*) variable in Visual Studio C++ 2017.  MS and Stack Overflow provide lots of examples but I can't get any of them to work!

I THINK that I have all the other variables/parameters set OK for the native C 'FindMimeFromData' function.

I'll keep experimenting! And if I find a solution I will post it.

Link to comment
Share on other sites

I finally found how to create the variable required which was LPWSTR* and now it compiles OK but won't link.  It is more trouble than it is worth but I found one already developed in C# which I might play around with in due course.  The solution in C# is from https://www.codeproject.com/Articles/849083/Determining-File-Type-A-Demonstration-of-Different

For anyone interested, here's the code to get the variables all in the correct format (Visual Studio 2017 C++17 Windows Form):

if (openFileDialog1->ShowDialog() != System::Windows::Forms::DialogResult::Yes)
		{	// weird!!  The negative case is the one that works??
			//save the file name in the text box
			this->txtFileName->Text = openFileDialog1->FileName;
			// see: https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/ms775107(v=vs.85)
			// convert the file name to the form that the FindMimeFromData expects
			// fopen expects a C string
			char* InputFileName = (char*)Marshal::StringToHGlobalAnsi(txtFileName->Text).ToPointer();
			// now 'looking for'
			String^ managed_looking_for = L"image/jpeg";
			marshal::marshal_context context;	// sets the context - needed - see: https://msdn.microsoft.com/en-us/library/bb384865.aspx
			wchar_t const* c_looking_for = context.marshal_as<wchar_t const*>(managed_looking_for);

			// now 'out'
			String^ managed_out = gcnew String("                                  ");
			LPWSTR* c_out = (LPWSTR*)Marshal::StringToHGlobalUni(managed_out).ToPointer();
			char buff[256];
			FILE *in = fopen(InputFileName, "rb");
			fread(buff, 1, 256, in);

			FindMimeFromData(NULL, NULL, buff, 256, c_looking_for, FMFD_DEFAULT, c_out, 0);
			printf("%ls\n", c_out);
		MessageBox::Show("An error occurred during the file select process - please try again.");
}	// end file select button clicked

Just FYI the linker errors are:

unresolved token (0A000B0F) "extern "C" long __stdcall FindMimeFromData(struct IBindCtx *,wchar_t const *,void *,unsigned long,wchar_t const *,unsigned long,wchar_t * *,unsigned long)" (?FindMimeFromData@@$$J232YGJPAUIBindCtx@@PB_WPAXK1KPAPA_WK@Z) referenced in function "private: void __clrcall TestFileType::MyForm::btnSelectFile_Click(class System::Object ^,class System::EventArgs ^)" (?btnSelectFile_Click@MyForm@TestFileType@@$$FA$AAMXP$AAVObject@System@@P$AAVEventArgs@4@@Z)

I do not intend to spend any more time on this at the moment!

Cheers from Oz.



Link to comment
Share on other sites

  • 1 month later...

But I did spend some more time on it!  I leveraged the class library kindly provided by Ed Gadziemski (https://www.codeproject.com/Articles/849083/Determining-File-Type-A-Demonstration-of-Different) and developed a small C# UI front-end in Visual Studio 2017.  I used C# as that is what Ed's class library is written in.

Here's part of the UI/front-end code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using FileTypesLib;

namespace ReadFile
    public partial class ReadFileCS : Form
        FileTypes fileTypes = new FileTypes();

        public ReadFileCS()

        private void Form1_Load(object sender, EventArgs e)


        private void btnSelectFile_Click(object sender, EventArgs e)
            var filePath = string.Empty;
            using (OpenFileDialog openFileDialog = new OpenFileDialog())
                openFileDialog.InitialDirectory = "e:\\pictures";
                openFileDialog.Filter = "image files (*.jpg)|*.jpg|All files (*.*)|*.*";
                openFileDialog.FilterIndex = 2;
                openFileDialog.RestoreDirectory = true;

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                    //Get the path of specified file
                    filePath = openFileDialog.FileName;
                    txtSelected_File.Text = filePath;
                    // get the file's MIME type
                    txtMIMETypeBox.Text = fileTypes.GetMimeType(filePath);
                }   // end dialog box opened OK
            }   // end using (OpenFileDialog openFileDialog = new OpenFileDialog())

        }   // end private void btnSelectFile_Click(object sender, EventArgs e)

        private void btnExit_Click(object sender, EventArgs e)

    }   // end public partial class ReadFileCS : Form
}   // end namespace ReadFile

It may be of interest to someone!

Season's Greetings from Oz.

Link to comment
Share on other sites

Hi Larry,

Now have it working with a Visual Studio 2017 C++ front-end using the same C sharp DLL.  It is very similar.

The changes are:

using namespace FileTypesLib; 

FileTypes^ fileTypes = gcnew FileTypes();

if (openFileDialog1->ShowDialog() != System::Windows::Forms::DialogResult::Yes)

{ // weird!! The negative case is the one that works??

String^ theFileName = openFileDialog1->FileName;

// save the file name in the text box

this->txtSelectedFile->Text = theFileName;

// get the MIME type and save it in the form text box

txtMIMEType->Text = fileTypes->GetMimeType(theFileName);


Again, it may be of interest to someone.


Link to comment
Share on other sites

  • 3 weeks later...

Here's some C++ to check if a file is of MIME type 'image/jpeg'.

private: String^ GetMimeType(String^ FileName)
			// MessageBox::Show("GetMimeType called with " + FileName);
			const unsigned short JPG_SIGNATURE_LENGTH = 3;
			char jpg_signature[JPG_SIGNATURE_LENGTH] = { 255, 216, 255 };	// an array of chars with the 'signature' for jpg files
			char buff[12];	// create a buffer for the first 12 bytes of the file
			// convert managed string FileName to a standard string
			// ifstream expects a pointer to a C string (array) of chars
			char* InputFileName = (char*)Marshal::StringToHGlobalAnsi(FileName).ToPointer();
			std::ifstream fileInput(InputFileName, std::ios::binary);	// opens the file as a binary file
			if (fileInput.is_open())
					// MessageBox::Show("fileInput is open for " + FileName);
					fileInput.read(reinterpret_cast<char *>(&buff), sizeof(buff));	// read the first 12 bytes of the binary input file
					// now compare the first three bytes
					for (int i = 0; i < JPG_SIGNATURE_LENGTH; i++)
							if (jpg_signature[i] != buff[i])
									return "Not jpeg";	// this will break the for loop and exit the method
						}	// end for loop
					// the first 3 bytes matched the 'signature' for a jpeg file
					return "image/jpeg";
					MessageBox::Show("fileInput open failed for " + FileName);
		}	// end GetMimeType

This is a combination of Visual Studio managed C++ and standard C++. The path of the file is passed to the method.  It may be of interest to someone.

Cheers from Oz.

Link to comment
Share on other sites

  • 2 weeks later...

To avoid compiler warnings change the following:

Change 'char jpg_signature' to 'unsigned char jpg_signature' and 'char buff[12]' to 'unsigned char buff[12]'.

Tested and still works correctly.

The method should probably be named 'checkMimeType'.


Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Create New...