[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);
Public Declare Function FindMimeFromData Lib "urlmon.dll" ( _
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 ppwzMimeOut As IntPtr, _
ByVal dwReserved As Integer) As Integer
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) {
//todo: this leaks memory outPtr must be freed
return Marshal.PtrToStringUni(outPtr);
}
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
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)