Jump to content
Larry Ullman's Book Forums

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

Share this post


Link to post
Share on other sites

Hi Larry,

I have found a function 'FindMimeFromData' and will see if I can figure out how to use it.

Will let you know how I get on.

Cheers, Necuima

Share this post


Link to post
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.

Share this post


Link to post
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);
			
		}
	else
		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.

 

 

Share this post


Link to post
Share on other sites

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()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void btnSelectFile_Click(object sender, EventArgs e)
        {
            var filePath = string.Empty;
            txtMIMETypeBox.Clear();
            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;
                    btnSelectFile.Focus();
                    // 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)
        {
            this.Close();
        }

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

It may be of interest to someone!

Season's Greetings from Oz.

Share this post


Link to post
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.

Cheers

Share this post


Link to post
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

×