⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fakecam.cpp

📁 winddk src目录下的WDM源码压缩!
💻 CPP
📖 第 1 页 / 共 4 页
字号:

//
// This function reads a JPEG file looking for the frame header, which contains
// the width and height of the image.
//
HRESULT ReadDimFromJpeg(PTSTR ptszFullName, WORD *pWidth, WORD *pHeight)
{
    DBG_FN("ReadDimFromJpeg");
    
    HRESULT hr = S_OK;
    BOOL ret;

    //
    // Locals
    //
    HANDLE hFile = NULL;
    BYTE *pBuffer = NULL;
    DWORD BytesRead = 0;
    BYTE *pCur = NULL;
    int SegmentLength = 0;
    const int Overlap = 8;  // if pCur gets within Overlap bytes of the end, read another chunk
    const DWORD BytesToRead = 32 * 1024;

    REQUIRE_ARGS(!ptszFullName || !pWidth || !pHeight, hr, "ReadDimFromJpeg");

    *pWidth = 0;
    *pHeight = 0;

    hFile = CreateFile(ptszFullName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    REQUIRE_FILEHANDLE(hFile, hr, "ReadDimFromJpeg", "CreateFile failed");
    
    pBuffer = new BYTE[BytesToRead];
    REQUIRE_ALLOC(pBuffer, hr, "ReadDimFromJpeg");

    ret = ReadFile(hFile, pBuffer, BytesToRead, &BytesRead, NULL);
    REQUIRE_FILEIO(ret, hr, "ReadDimFromJpeg", "ReadFile failed");

    wiauDbgTrace("ReadDimFromJpeg", "Read %d bytes", BytesRead);

    pCur = pBuffer;

    //
    // Pretend that we read Overlap fewer bytes than were actually read
    //
    BytesRead -= Overlap;

    while (SUCCEEDED(hr) &&
           BytesRead != 0 &&
           pCur[1] != 0xc0)
    {
        if (pCur[0] != 0xff)
        {
            wiauDbgError("ReadDimFromJpeg", "Not a JFIF format image");
            hr = E_FAIL;
            goto Cleanup;
        }

        //
        // if the marker is >= 0xd0 and <= 0xd9 or is equal to 0x01
        // there is no length field
        //
        if (((pCur[1] & 0xf0) == 0xd0 &&
             (pCur[1] & 0x0f) < 0xa) ||
            pCur[1] == 0x01)
        {
            SegmentLength = 0;
        }
        else
        {
            SegmentLength = ByteSwapWord(*((UNALIGNED WORD *) (pCur + 2)));
        }

        pCur += SegmentLength + 2;

        if (pCur >= pBuffer + BytesRead)
        {
            memcpy(pBuffer, pBuffer + BytesRead, Overlap);

            pCur -= BytesRead;

            ret = ReadFile(hFile, pBuffer + Overlap, BytesToRead - Overlap, &BytesRead, NULL);
            REQUIRE_FILEIO(ret, hr, "ReadDimFromJpeg", "ReadFile failed");

            wiauDbgTrace("ReadDimFromJpeg", "Read %d more bytes", BytesRead);
        }
    }

    if (pCur[0] != 0xff)
    {
        wiauDbgError("ReadDimFromJpeg", "Not a JFIF format image");
        return E_FAIL;
    }

    *pHeight = ByteSwapWord(*((UNALIGNED WORD *) (pCur + 5)));
    *pWidth =  ByteSwapWord(*((UNALIGNED WORD *) (pCur + 7)));

Cleanup:
    if (pBuffer) {
        delete []pBuffer;
    }
    if (hFile && hFile != INVALID_HANDLE_VALUE) {
        CloseHandle(hFile);
    }

    return hr;
}

//
// The next section contains functions useful for reading information from
// Exif files.
//
HRESULT ReadJpegHdr(PTSTR ptszFullName, BYTE **ppBuf)
{
    DBG_FN("ReadJpegHdr");
    
    HRESULT hr = S_OK;
    BOOL ret;

    //
    // Locals
    //
    HANDLE hFile = NULL;
    
    //
    // Note: 
    // 
    // The actual first 4 BYTEs from a JPEG IF file could be either:
    //
    // 0xFF 0xD8 0xFF 0xE0 for a JFIF 1.x file;
    // 0xFF 0xD8 0xFF 0xE1 for a EEXIF 2.0 file.
    // 
    // The code here is supporting only the EEXIF version:
    //
    BYTE JpegHdr[] = {0xff, 0xd8, 0xff, 0xe1};

    const int JpegHdrSize = sizeof(JpegHdr) + 2;
    BYTE tempBuf[JpegHdrSize];
    DWORD BytesRead = 0;
    WORD TagSize = 0;

    hFile = CreateFile(ptszFullName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
    REQUIRE_FILEHANDLE(hFile, hr, "ReadJpegHdr", "CreateFile failed");

    ret = ReadFile(hFile, tempBuf, JpegHdrSize, &BytesRead, NULL);
    REQUIRE_FILEIO(ret, hr, "ReadJpegHdr", "ReadFile failed");
    
    if (BytesRead != JpegHdrSize) {
        wiauDbgError("ReadJpegHdr", "Wrong amount read %d", BytesRead);
        hr = E_FAIL;
        goto Cleanup;
    }
    
    if(memcmp(tempBuf, JpegHdr, sizeof(JpegHdr)) != 0)
    {
        wiauDbgError("ReadJpegHdr", "JPEG header not found");
        hr = E_FAIL;
        goto Cleanup;
    }

    TagSize = GetWord(tempBuf + sizeof(JpegHdr), TRUE);
    *ppBuf = new BYTE[TagSize];
    REQUIRE_ALLOC(ppBuf, hr, "ReadJpegHdr");

    ret = ReadFile(hFile, *ppBuf, TagSize, &BytesRead, NULL);
    REQUIRE_FILEIO(ret, hr, "ReadJpegHdr", "ReadFile failed");
     
    if (BytesRead != TagSize)
    {
        wiauDbgError("ReadJpegHdr", "Wrong amount read %d", BytesRead);
        hr = E_FAIL;
        goto Cleanup;
    }

Cleanup:
    if (hFile && hFile != INVALID_HANDLE_VALUE) {
        CloseHandle(hFile);
    }

    return hr;
}


HRESULT ReadExifJpeg(BYTE *pBuf, IFD *pImageIfd, IFD *pThumbIfd, BOOL *pbSwap)
{
    DBG_FN("ReadExifJpeg");
    
    HRESULT hr = S_OK;

    //
    // Note: this tag works only for EEXIF JPEG files 
    // (older JFIF files need 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01):
    //
    BYTE ExifTag[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};

    if (memcmp(pBuf, ExifTag, sizeof(ExifTag)) != 0)
    {
        wiauDbgError("ReadExifJpeg", "EXIF/JFIF tag not found");
        hr = E_FAIL;
        goto Cleanup;
    }

    hr = ReadTiff(pBuf + APP1_OFFSET, pImageIfd, pThumbIfd, pbSwap);
    REQUIRE_SUCCESS(hr, "ReadExifJpeg", "ReadTiff failed");

Cleanup:
    return hr;
}

HRESULT ReadTiff(BYTE *pBuf, IFD *pImageIfd, IFD *pThumbIfd, BOOL *pbSwap)
{
    DBG_FN("ReadTiff");
    
    HRESULT hr = S_OK;

    //
    // Locals
    //
    WORD MagicNumber = 0;

    *pbSwap = FALSE;

    if (pBuf[0] == 0x4d) {
        *pbSwap = TRUE;
        if (pBuf[1] != 0x4d)
        {
            wiauDbgError("ReadTiff", "Second TIFF byte swap indicator not present");
            hr = E_FAIL;
            goto Cleanup;
        }
    }
    else if (pBuf[0] != 0x49 ||
             pBuf[1] != 0x49)
    {
        wiauDbgError("ReadTiff", "TIFF byte swap indicator not present");
        hr = E_FAIL;
        goto Cleanup;
    }

    MagicNumber = GetWord(pBuf+2, *pbSwap);
    if (MagicNumber != 42)
    {
        wiauDbgError("ReadTiff", "TIFF magic number not present");
        hr = E_FAIL;
        goto Cleanup;
    }

    wiauDbgTrace("ReadTiff", "Reading image IFD");

    pImageIfd->Offset = GetDword(pBuf + 4, *pbSwap);
    hr = ReadIfd(pBuf, pImageIfd, *pbSwap);
    REQUIRE_SUCCESS(hr, "ReadTiff", "ReadIfd failed");

    wiauDbgTrace("ReadTiff", "Reading thumb IFD");

    pThumbIfd->Offset = pImageIfd->NextIfdOffset;
    hr = ReadIfd(pBuf, pThumbIfd, *pbSwap);
    REQUIRE_SUCCESS(hr, "ReadTiff", "ReadIfd failed");

Cleanup:
    return hr;
}

HRESULT ReadIfd(BYTE *pBuf, IFD *pIfd, BOOL bSwap)
{
    DBG_FN("ReadIfd");
    
    HRESULT hr = S_OK;

    const int DIR_ENTRY_SIZE = 12;
    
    pBuf += pIfd->Offset;

    pIfd->Count = GetWord(pBuf, bSwap);

    pIfd->pEntries = new DIR_ENTRY[pIfd->Count];
    if (!pIfd->pEntries)
        return E_OUTOFMEMORY;

    pBuf += 2;
    for (int count = 0; count < pIfd->Count; count++)
    {
        pIfd->pEntries[count].Tag = GetWord(pBuf, bSwap);
        pIfd->pEntries[count].Type = GetWord(pBuf + 2, bSwap);
        pIfd->pEntries[count].Count = GetDword(pBuf + 4, bSwap);
        pIfd->pEntries[count].Offset = GetDword(pBuf + 8, bSwap);
        pBuf += DIR_ENTRY_SIZE;

        wiauDbgDump("ReadIfd", "Tag 0x%04x, type %2d offset/value 0x%08x",
                    pIfd->pEntries[count].Tag, pIfd->pEntries[count].Type, pIfd->pEntries[count].Offset);
    }

    pIfd->NextIfdOffset = GetDword(pBuf, bSwap);

    return hr;
}

VOID FreeIfd(IFD *pIfd)
{
    if (pIfd->pEntries)
        delete []pIfd->pEntries;
    pIfd->pEntries = NULL;
}

WORD ByteSwapWord(WORD w)
{
    return (w >> 8) | (w << 8);
}

DWORD ByteSwapDword(DWORD dw)
{
    return ByteSwapWord((WORD) (dw >> 16)) | (ByteSwapWord((WORD) (dw & 0xffff)) << 16);
}

WORD GetWord(BYTE *pBuf, BOOL bSwap)
{
    WORD w = *((UNALIGNED WORD *) pBuf);

    if (bSwap)
        w = ByteSwapWord(w);
    
    return w;
}

DWORD GetDword(BYTE *pBuf, BOOL bSwap)
{
    DWORD dw = *((UNALIGNED DWORD *) pBuf);

    if (bSwap)
        dw = ByteSwapDword(dw);

    return dw;
}

/*
//
// Set the default and valid values for a property
//
VOID
FakeCamera::SetValidValues(
    INT index,
    CWiaPropertyList *pPropertyList
    )
{
    HRESULT hr = S_OK;

    ULONG ExposureModeList[] = {
        EXPOSUREMODE_MANUAL,
        EXPOSUREMODE_AUTO,
        EXPOSUREMODE_APERTURE_PRIORITY,
        EXPOSUREMODE_SHUTTER_PRIORITY,
        EXPOSUREMODE_PROGRAM_CREATIVE,
        EXPOSUREMODE_PROGRAM_ACTION,
        EXPOSUREMODE_PORTRAIT
    };

    PROPID PropId = pPropertyList->GetPropId(index);
    WIA_PROPERTY_INFO *pPropInfo = pPropertyList->GetWiaPropInfo(index);

    //
    // Based on the property ID, populate the valid values range or list information
    //
    switch (PropId)
    {
    case WIA_DPC_EXPOSURE_MODE:
        pPropInfo->ValidVal.List.Nom      = EXPOSUREMODE_MANUAL;
        pPropInfo->ValidVal.List.cNumList = sizeof(ExposureModeList) / sizeof(ExposureModeList[0]);
        pPropInfo->ValidVal.List.pList    = (BYTE*) ExposureModeList;
        break;

    case WIA_DPC_EXPOSURE_COMP:
        pPropInfo->ValidVal.Range.Nom = 0;
        pPropInfo->ValidVal.Range.Min = -200;
        pPropInfo->ValidVal.Range.Max = 200;
        pPropInfo->ValidVal.Range.Inc = 50;
        break;

    default:
        WIAS_LERROR(g_pIWiaLog,WIALOG_NO_RESOURCE_ID,("FakeCamera::SetValidValues, property 0x%08x not defined", PropId));
        return;
    }

    return;
}
*/

/**************************************************************************\
* DllMain
*
*   Main library entry point. Receives DLL event notification from OS.
*
*       We are not interested in thread attaches and detaches,
*       so we disable thread notifications for performance reasons.
*
* Arguments:
*
*    hinst      -
*    dwReason   -
*    lpReserved -
*
* Return Value:
*
*    Returns TRUE to allow the DLL to load.
*
\**************************************************************************/


extern "C" 
BOOL 
APIENTRY 
DllMain(
    HINSTANCE   hinst,
    DWORD       dwReason,
    LPVOID      lpReserved
    )
{
    switch (dwReason) {
        case DLL_PROCESS_ATTACH:
            g_hInst = hinst;
            DisableThreadLibraryCalls(hinst);
            
            break;

        case DLL_PROCESS_DETACH:
            
            break;
    }
    return TRUE;
}

/**************************************************************************\
* DllCanUnloadNow
*
*   Determines whether the DLL has any outstanding interfaces.
*
* Arguments:
*
*    None
*
* Return Value:
*
*   Returns S_OK if the DLL can unload, S_FALSE if it is not safe to unload.
*
\**************************************************************************/

extern "C" STDMETHODIMP DllCanUnloadNow(void)
{
    return S_OK;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -