[DllImport("urlmon.dll", 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 IntPtr ppwzMimeOut,
int dwReserved);
VB.NET dwMimeFlags: (http://msdn.microsoft.com/en-us/library/ie/ms775107(v=vs.85).aspx)
<Flags()> Public Enum MIMEFlags As UInteger
''' <summary>No flags specified. Use default behavior for the function.</summary>
[Default] = &H0
''' <summary>Treat the specified pwzUrl as a file name. </summary>
URLAsFileName = &H1
''' <summary>Internet Explorer 6 for Windows XP SP2 and later. Use MIME-type detection even if FEATURE_MIME_SNIFFING is detected. Usually, this feature control key would disable MIME-type detection.</summary>
EnableMIMESniffing = &H2
''' <summary>Internet Explorer 6 for Windows XP SP2 and later. Perform MIME-type detection if "text/plain" is proposed, even if data sniffing is otherwise disabled. Plain text may be converted to text/html if HTML tags are detected. </summary>
IgnoreMIMETextPlain = &H4
''' <summary>Internet Explorer 8. Use the authoritative MIME type specified in pwzMimeProposed. Unless <see cref="MIMEFlags.IgnoreMIMETextPlain "/> is specified, no data sniffing is performed.</summary>
ServerMIME = &H8
''' <summary>Internet Explorer 9. Do not perform detection if "text/plain" is specified in pwzMimeProposed.</summary>
RespectTextPlain = &H10
''' <summary>Internet Explorer 9. Returns image/png and image/jpeg instead of image/x-png and image/pjpeg. </summary>
ReturnUpdatedImgMIMEs = &H20
End Enum
<DllImport("urlmon.dll", CharSet:=CharSet.Auto)> _
Private Shared Function FindMimeFromData( _
ByVal pBC As IntPtr, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByVal pwzUrl As String, _
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.I1, SizeParamIndex:=3)> ByVal _
pBuffer As Byte(), _
ByVal cbSize As Integer, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByVal pwzMimeProposed As String, _
ByVal dwMimeFlags As Integer, _
<MarshalAs(UnmanagedType.LPWStr)> _
ByRef ppwzMimeOut As String, _
ByVal dwReserved As Integer) As Integer
End Function
Public Declare Function FindMimeFromData Lib "urlmon.dll" ( _
ByVal pbc As Long, _
ByVal pwzUrl As String, _
pBuffer As Any, _
cbSize As Long, _
ByVal pwzMimeProposed As String, _
dwMimeFlags As Long, _
ppwzMimeOut As Long, _
dwReserved As Long) As Long
None.
VB6 Users also use these declares
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)
Public Declare Function lstrlenW Lib "kernel32.dll" (ByVal lpString As Long) As Long
and this additional code
'Convert a LPWSTR pointer to a VB string
Private Function PtrToString(lpwString As Long) As String
Dim Buffer() As Byte
Dim nLen As Long
If lpwString Then
nLen = lstrlenW(lpwString) * 2
If nLen Then
ReDim Buffer(0 To (nLen - 1)) As Byte
CopyMemory Buffer(0), ByVal lpwString, nLen
PtrToString = Buffer
End If
End If
End Function
public string MimeTypeFrom(byte[] dataBytes, string mimeProposed) {
if (dataBytes == null)
throw new ArgumentNullException("dataBytes");
string mimeRet = String.Empty;
IntPtr suggestPtr = IntPtr.Zero, filePtr = IntPtr.Zero, outPtr = IntPtr.Zero;
if (mimeProposed != null && mimeProposed.Length > 0) {
//suggestPtr = Marshal.StringToCoTaskMemUni(mimeProposed); // for your experiments ;-)
mimeRet = mimeProposed;
}
int ret = FindMimeFromData(IntPtr.Zero, null, dataBytes, dataBytes.Length, mimeProposed, 0, out outPtr, 0);
if (ret == 0 && outPtr != IntPtr.Zero) {
mimeRet = Marshal.PtrToStringUni(outPtr);
Marshal.FreeCoTaskMem(outPtr); //msdn docs wrongly states that operator 'delete' must be used. Do not remove FreeCoTaskMem
return mimeRet;
}
return mimeRet;
}
// call it this way:
Trace.Write("MimeType is " + MimeTypeFrom(Encoding.ASCII.GetBytes("%PDF-"), "text/plain"));
Do you know one? Please contribute it!
/// <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)
{
IntPtr mimeout;
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);
fs.Close();
int result = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, null, 0, out mimeout, 0);
if (result != 0)
throw Marshal.GetExceptionForHR(result);
string mime = Marshal.PtrToStringUni(mimeout);
Marshal.FreeCoTaskMem(mimeout);
return mime;
}
//rename crystal.jpg to .gif to test functionality!
string getImg = Environment.GetEnvironmentVariable("windir") + "\\Web\\WallPaper\\Crystal.gif";
string mime = getMimeFromFile(getImg);
Public Shared Function getMimeFromFile(ByVal file As String) As String
Dim mimeout As IntPtr
If Not System.IO.File.Exists(file) Then
Throw New FileNotFoundException(file + " not found")
End If
Dim MaxContent As Integer = CInt(New FileInfo(file).Length)
If MaxContent > 4096 Then
MaxContent = 4096
End If
Dim fs As New FileStream(file, FileMode.Open)
Dim buf(MaxContent) As Byte
fs.Read(buf, 0, MaxContent)
fs.Close()
Dim result As Integer = FindMimeFromData(IntPtr.Zero, file, buf, MaxContent, Nothing, 0, mimeout, 0)
If result <> 0 Then
'Throw Marshal.GetHRForExceptionresult)
End If
Dim mime As String = Marshal.PtrToStringUni(mimeout)
Marshal.FreeCoTaskMem(mimeout)
Return mime
End Function 'getMimeFromFile
''' <summary>
''' The second to last parameter errors out if its data type is set to string.
''' </summary>
''' <param name="pBC"></param>
''' <param name="pwzUrl"></param>
''' <param name="pBuffer"></param>
''' <param name="cbSize"></param>
''' <param name="pwzMimeProposed"></param>
''' <param name="dwMimeFlags"></param>
''' <param name="mimeOut"></param>
''' <param name="dwReserved"></param>
''' <returns></returns>
<DllImport("urlmon.dll", CharSet:=CharSet.Auto)>
Private Function FindMimeFromData(
ByVal pBC As IntPtr,
<MarshalAs(UnmanagedType.LPWStr)> ByVal pwzUrl As String,
<MarshalAs(UnmanagedType.LPArray, ArraySubType:=UnmanagedType.I1, SizeParamIndex:=3)> ByVal pBuffer As Byte(),
ByVal cbSize As Integer,
<MarshalAs(UnmanagedType.LPWStr)> ByVal pwzMimeProposed As String,
ByVal dwMimeFlags As Integer,
ByRef mimeOut As IntPtr,
ByVal dwReserved As Integer) As Integer
End Function
''' <summary>
''' Written for use as an extension method for the byte array class.
''' </summary>
''' <param name="bytes"></param>
''' <param name="mimeContentType"></param>
''' <returns></returns>
<Extension()>
Public Function TryDetermineMimeType(
bytes As Byte(),
<Out()> ByRef mimeContentType As String) As Boolean
Dim mimeSampleSize As Integer = 256
Dim defaultMimeType As String = "application/octet-stream"
Dim mimeOut As IntPtr = IntPtr.Zero
Dim successful As Boolean = False
mimeContentType = defaultMimeType
Try
FindMimeFromData(
IntPtr.Zero,
Nothing,
bytes,
Convert.ToUInt32(mimeSampleSize),
Nothing,
0,
mimeOut,
0)
mimeContentType = Marshal.PtrToStringUni(mimeOut)
Marshal.FreeCoTaskMem(mimeOut)
successful = True
Catch x As Exception
Console.WriteLine(x.ToString())
End Try
Return successful
End Function
Dim result As Long
Dim bufferOut As String
bufferOut = Space$(256)
Dim buffAddr As Long
buffAddr = StrPtr(bufferOut)
result = FindMimeFromData(0, "file://c:/test/form1.frm", vbNullString, 0, vbNullString, 0, buffAddr, 0)
Debug.Print PtrToString(buffAddr)