// TestPlugin.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" // Define the exported DLL functions extern "C" { __declspec(dllexport) BOOL DVP_USBSafe(LPOPUSUSBSAFEDATA pUSBSafeData); __declspec(dllexport) BOOL DVP_Identify(LPVIEWERPLUGININFO lpVPInfo); __declspec(dllexport) BOOL DVP_IdentifyFile(HWND hWnd,LPSTR lpszName,LPVIEWERPLUGINFILEINFO lpVPFileInfo,HANDLE hAbortEvent); __declspec(dllexport) BOOL DVP_IdentifyFileStream(HWND hWnd,LPSTREAM lpStream,LPSTR lpszName,LPVIEWERPLUGINFILEINFO lpVPFileInfo,DWORD dwStreamFlags); __declspec(dllexport) BOOL DVP_LoadTextA(LPDVPLOADTEXTDATAA lpLoadTextData); __declspec(dllexport) BOOL DVP_LoadTextW(LPDVPLOADTEXTDATAW lpLoadTextData); }; // {19E1003B-072E-42d8-B361-0EF64B47DE9A} static const GUID GUIDPlugin_Torrent = { 0x19e1003b, 0x72e, 0x42d8, { 0xb3, 0x61, 0xe, 0xf6, 0x4b, 0x47, 0xde, 0x9a } }; BOOL DVP_USBSafe(LPOPUSUSBSAFEDATA pUSBSafeData) { return TRUE; } // Identify the viewer plugin to DOpus BOOL DVP_Identify(LPVIEWERPLUGININFO lpVPInfo) { // Plugin flags; we can handle streams, and only use filename extensions for identification for slow and non-random seeking media lpVPInfo->dwFlags = DVPFIF_ExtensionsOnly | DVPFIF_CanHandleStreams | DVPFIF_NoThumbnails | DVPFIF_NoFileInformation; // Version number (1.0.0.1) lpVPInfo->dwVersionHigh = MAKELONG(0,1); // Use MAKELONG instead of MAKELPARAM to avoid error assigning to DWORD under 64-bit. lpVPInfo->dwVersionLow = MAKELONG(1,0); // Preferred filename extension is .torrent lpVPInfo->lpszHandleExts = TEXT(".torrent"); // Plugin information lpVPInfo->lpszName = TEXT("Torrent"); lpVPInfo->lpszDescription = TEXT("Torrent Viewer Plugin"); lpVPInfo->lpszCopyright = TEXT("(c) Copyright 2009 Richard Fortier"); lpVPInfo->lpszURL = TEXT("http://www.example.com"); // In Opus 9.1.1.7 and below you need to return a URL to avoid the About button crashing. // Major type of file we handle is text lpVPInfo->uiMajorFileType = DVPMajorType_Text; lpVPInfo->dwlMinFileSize = 0; lpVPInfo->dwlMaxFileSize = 0; lpVPInfo->dwlMinPreviewFileSize = lpVPInfo->dwlMinFileSize; lpVPInfo->dwlMaxPreviewFileSize = lpVPInfo->dwlMaxFileSize; // Our GUID to uniquely identify us to DOpus lpVPInfo->idPlugin = GUIDPlugin_Torrent; return TRUE; } // Identify a local disk-based file BOOL DVP_IdentifyFile(HWND hWnd,LPSTR lpszName,LPVIEWERPLUGINFILEINFO lpVPFileInfo,HANDLE hAbortEvent) { lpVPFileInfo->dwFlags = DVPFIF_ReturnsText|DVPFIF_CanReturnViewer; // In Opus 9.1.1.7 and below you need to set DVPFIF_CanReturnViewer in order for DVPFIF_ReturnsText to work. lpVPFileInfo->wMajorType = DVPMajorType_Text; lpVPFileInfo->wMinorType = 0; lpVPFileInfo->iTypeHint = DVPFITypeHint_PlainText; lpVPFileInfo->szImageSize.cx = 0; lpVPFileInfo->szImageSize.cy = 0; lpVPFileInfo->iNumBits = 0; if (lpVPFileInfo->lpszInfo != 0 && lpVPFileInfo->cchInfoMax != 0) { lpVPFileInfo->lpszInfo[0] = TEXT('\0'); } return TRUE; } // Identify a stream-based file BOOL DVP_IdentifyFileStream(HWND hWnd,LPSTREAM lpStream,LPSTR lpszName,LPVIEWERPLUGINFILEINFO lpVPFileInfo,DWORD dwStreamFlags) { return DVP_IdentifyFile(hWnd, lpszName, lpVPFileInfo, NULL); } BOOL DVP_LoadTextA(LPDVPLOADTEXTDATAA lpLoadTextData) { // This will never actually be called since DVP_LoadTextW is given preference. // However, there's a bug in Opus 9.1.1.7 and below where neither DVP_LoadText // function will be called unless both are exported by the DLL. return FALSE; } BOOL DVP_LoadTextW(LPDVPLOADTEXTDATAW lpLoadTextData) { lpLoadTextData->iOutTextType = DVPText_Plain; lpLoadTextData->lpOutStream = 0; ULONG nb = 0; // It's our job to create the result stream. // CreateStreamOnHGlobal with NULL first argument creates a new in-memory stream. if (S_OK == CreateStreamOnHGlobal(NULL, TRUE, &lpLoadTextData->lpOutStream) && 0 != lpLoadTextData->lpOutStream) { bool bSourceTextIsUnicode = false; if (bSourceTextIsUnicode) { // If we write Unicode into the stream it must start with the UTF-16 BOM. const wchar_t wcUTF16BOM = L'\xFEFF'; if (S_OK == lpLoadTextData->lpOutStream->Write(&wcUTF16BOM, sizeof(wcUTF16BOM), &nb) && sizeof(wcUTF16BOM) == nb) { const wchar_t *szTextToWrite = L"salut (Unicode)"; ULONG ulBytesToWrite = wcslen(szTextToWrite) * sizeof(szTextToWrite[0]); // Don't write the null-terminator to the stream. if (S_OK == lpLoadTextData->lpOutStream->Write(szTextToWrite, ulBytesToWrite, &nb) && nb == ulBytesToWrite) { return TRUE; } } } else { const char *szTextToWrite = "salut (ANSI)"; ULONG ulBytesToWrite = strlen(szTextToWrite) * sizeof(szTextToWrite[0]); // Don't write the null-terminator to the stream. if (S_OK == lpLoadTextData->lpOutStream->Write(szTextToWrite, ulBytesToWrite, &nb) && nb == ulBytesToWrite) { return TRUE; } } } if (0 != lpLoadTextData->lpOutStream) { // If we failed then it's our job to release the stream we created. lpLoadTextData->lpOutStream->Release(); lpLoadTextData->lpOutStream = 0; } return FALSE; }