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

📄 loader_app.c

📁 这是DVD中伺服部分的核心代码
💻 C
📖 第 1 页 / 共 5 页
字号:
 * @param ulLBA -
 * @param pbRawKey - The unencrypted key data byte array.
 */
LOADER_ERR LoaderReadTitleKey(LOADER_HANDLE tLoader, BYTE bAgid, ULONG ulLBA, BYTE *pbRawKey)
{
    int bufSize = 12;
    struct cdrom_generic_command cgc;
    struct request_sense sense;
    LOADER_ERR err = LOADER_SUCCESS;

    if ( (tLoader == NULL) || (pbRawKey == NULL) )
    {
        return (LOADER_NULL_PTR);
    }

    memset(&cgc,   0, sizeof(cgc));
    memset(&sense, 0, sizeof(sense));

    cgc.sense   = &sense;
    cgc.buffer  = loaderBuf;
    cgc.buflen  = bufSize;
    cgc.data_direction = CGC_DATA_READ;
    cgc.timeout = HZ*5;

    cgc.cmd[ 0] = GPCMD_REPORT_KEY;
    cgc.cmd[ 2] = (BYTE)((ulLBA >> 24) & 0x000000ff);
    cgc.cmd[ 3] = (BYTE)((ulLBA >> 16) & 0x000000ff);
    cgc.cmd[ 4] = (BYTE)((ulLBA >>  8) & 0x000000ff);
    cgc.cmd[ 5] = (BYTE)((ulLBA      ) & 0x000000ff);
    cgc.cmd[ 9] = cgc.buflen;
    cgc.cmd[10] = (bAgid | 0x04);

    if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderReadTitleKey() --FAILED (%s)\n", strerror(errno)));
        DBGPRINT(DBG_ON(DBG_ERROR), ("                     --sense key: 0x%x, ASC/ASCQ: 0x%02x%02x\n", sense.sense_key, sense.asc, sense.ascq));
        loaderSetError(tLoader, errno);
        err = LOADER_FAILURE;
    }
    else if (pbRawKey != loaderBuf) {
        /* copy key data to user buffer */
        memcpy(pbRawKey, loaderBuf, bufSize);
    }

    return (err);
}


/**
 * Issue a read disc structure command to a logical unit.
 *
 * @param tLoader - The loader handle.
 * @param bAgid - The current authentication grant ID.

 * @param sub_cmd - Type of command definition to expand the command.
 * @param address - The current authentication grant ID.
 * @param format_code - Identify the type of information requested by the host.
 * @param pBuf - Buffer where the information will be copied into.
 * @param len - Length of the response.
 *
 * NOTE THAT pBuf MUST POINT TO MEMORY ALLOCATED FROM BMEM !!!
 */
LOADER_ERR LoaderReadDiscStruct(
    LOADER_HANDLE tLoader,
    BYTE bAgid,
    BYTE sub_cmd,
    ULONG address,
    BYTE format_code,
    BYTE *pBuf,
    USHORT len
)
{
    struct cdrom_generic_command cgc;
    struct request_sense sense;
    LOADER_ERR err = LOADER_SUCCESS;

    if ( (tLoader == NULL) || (pBuf == NULL) )
    {
        return (LOADER_NULL_PTR);
    }

    memset(&cgc,   0, sizeof(cgc));
    memset(&sense, 0, sizeof(sense));

    cgc.sense   = &sense;
    cgc.buffer  = pBuf;
    cgc.buflen  = len;
    cgc.data_direction = CGC_DATA_READ;
    cgc.timeout = HZ*5;

    cgc.cmd[ 0] = GPCMD_READ_DVD_STRUCTURE;
    cgc.cmd[ 1] = (sub_cmd & 0xf);
    cgc.cmd[ 2] = (BYTE)((address >> 24) & 0x000000ff);
    cgc.cmd[ 3] = (BYTE)((address >> 16) & 0x000000ff);
    cgc.cmd[ 4] = (BYTE)((address >>  8) & 0x000000ff);
    cgc.cmd[ 5] = (BYTE)((address      ) & 0x000000ff);
    cgc.cmd[ 6] = 0x00;              /* Layer 0 */
    cgc.cmd[ 7] = format_code;       /* Format is Media Key Block for AACS */
    cgc.cmd[ 8] = (BYTE)((cgc.buflen >> 8) & 0x00FF);   /* Allocation Length MSB */
    cgc.cmd[ 9] = (BYTE)((cgc.buflen     ) & 0x00FF); /* Allocation Length LSB */
    cgc.cmd[10] = (bAgid & 0x03) << 6;

    if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderReadDiscStruct() --FAILED TO READ FORMAT CODE 0x%x FOR MEDIA TYPE %d(%s)\n", format_code, sub_cmd, strerror(errno)));
        DBGPRINT(DBG_ON(DBG_TRACE), ("                       --sense key: 0x%x, ASC/ASCQ: 0x%02x%02x\n", sense.sense_key, sense.asc, sense.ascq));
        loaderSetError(tLoader, errno);
        err = LOADER_FAILURE;
    }

    return (err);
}



 












/**
 * Returns the type of data storage media loaded into the system.
 *
 * @param tLoader     - The loader handle.
 * @param pLoaderType - Pointer to receive the data storage media type.
 */
LOADER_ERR LoaderGetType(LOADER_HANDLE tLoader, LOADER_TYPE *pLoaderType)
{
    LOADERHANDLE* ldr = (LOADERHANDLE*)tLoader;

    if (NULL == pLoaderType)
    {
        return (LOADER_FAILURE);
    }
    if (NULL == tLoader)
    {
        *pLoaderType = LOADER_TYPE_UNKNOWN;
        return (LOADER_FAILURE);
    }

    /* Set loader type */
    *pLoaderType = ldr->LoaderType;

    return (LOADER_SUCCESS);
}


/**
 * Returns the data storage media details.
 *
 * @param tLoader     - The loader handle.
 * @param pMediaData  - Pointer to LoaderMediaData structure
 *
 * Current LOADER_MEDIA_DATA definition:
 * 	typedef struct _LoaderMediaData {
 * 		int  *media_type;
 * 		int  *num_layers;
 * 	} LOADER_MEDIA_DATA;
 */
LOADER_ERR LoaderGetMediaData(LOADER_HANDLE tLoader, LOADER_MEDIA_DATA *pMediaData)
{
    LOADERHANDLE* ldr        = (LOADERHANDLE*)tLoader;

    if (NULL == tLoader || NULL == pMediaData)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetMediaData() --CALLED WITH NULL POINTER(S)!\n"));
        return (LOADER_FAILURE);
    }

    loaderGetType_local(tLoader);

    if (ldr->LoaderType == LOADER_TYPE_NODISK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetMediaData() --LOADER_TYPE_NODISK!\n"));
        *pMediaData->media_type = 0;
        *pMediaData->num_layers = 0;
        return (LOADER_FAILURE);
    }

    if (pMediaData->media_type)
    {
        *pMediaData->media_type = ldr->bDiscType;
    }

    if (pMediaData->num_layers)
    {
        *pMediaData->num_layers = ldr->bNumLayers;
    }

    return (LOADER_SUCCESS);
}


/**
 * Retrieves the Table of Contents from a Compact Disc (VCD)
 *
 * @param tLoader  - The loader handle.
 * @param format   - Format field for READ_TOC_PMA_ATIP command.
 * @param point    - point parameter see Mt.Fuji spec: table 369
 * @param readType - toc read type
 * @param pData    - toc buffer
 * @param size     - size of pData buffer
 */

LOADER_ERR LoaderGetTOC (LOADER_HANDLE tLoader, LOADER_TOC_CMD format, BYTE point, LOADER_TOC_ADDR_MODE readType, BYTE *pData, ULONG size)
{
    struct cdrom_generic_command cgc;
    struct request_sense         sense;
    LOADER_ERR                   err = LOADER_SUCCESS;

    if ( (tLoader == NULL) || (pData == NULL) )
    {
        return (LOADER_NULL_PTR);
    }

    DbgAssert(size < LDR_BUF_SIZE);

    memset(&cgc,   0, sizeof(cgc));
    memset(&sense, 0, sizeof(sense));

    cgc.sense           = &sense;
    cgc.buffer          = loaderBuf;
    cgc.buflen          = size;
    cgc.data_direction  = CGC_DATA_READ;
    cgc.timeout         = HZ * 5;

    cgc.cmd[0]  = GPCMD_READ_TOC_PMA_ATIP;
    cgc.cmd[1]  = readType;                 // MSF (0x2) or LBA (0x0)
    cgc.cmd[2]  = format & 0xF;             // upper 4 bits reserved
    cgc.cmd[6]  = point;                    // see Mt.Fuji spec: table 369
    cgc.cmd[7]  = (BYTE)(( size & 0x0000FF00 ) >> 8);        // MSB
    cgc.cmd[8]  = (BYTE)(size & 0x000000FF);        // LSB

    DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderGetTOC() -- Length %02x %02x\n", cgc.cmd[7], cgc.cmd[8]));

    if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetTOC() --FAILED (%s)\n", strerror(errno)));
        DBGPRINT(DBG_ON(DBG_ERROR), ("               --sense key: 0x%x, ASC/ASCQ: 0x%02x%02x\n", sense.sense_key, sense.asc, sense.ascq));
        loaderSetError(tLoader, errno);
        err = LOADER_FAILURE;
    }
    else if (pData != loaderBuf) 
    {
        /* copy key data to user buffer */
        memcpy(pData, loaderBuf, size);
    }

    return (err);
}


/**
 * Retrieves the SubChannel information as detailed in Mt.Fuji section 17.26
 *
 * @param tLoader  - The loader handle.
 * @param fMSF     - Requests format to be in MSF. 
 * @param fSubQ    - Requests the Q-channel data
 * @param bFormat  - Format (0x01 retrieves current position)
 * @param bTrack   - Track number (use 0 if format is not track specific)
 * @param pData    - buffer for return
 * @param ulSize   - size of pData buffer
 */

LOADER_ERR LoaderReadSubChannel (LOADER_HANDLE tLoader, BOOLEAN fMSF, BOOLEAN fSubQ, BYTE bFormat, BYTE bTrack, BYTE *pData, ULONG size)
{
    struct cdrom_generic_command cgc;
    struct request_sense         sense;
    LOADER_ERR                   err = LOADER_SUCCESS;

    if ( (tLoader == NULL) || (pData == NULL) )
    {
        return (LOADER_NULL_PTR);
    }

    DbgAssert(size < LDR_BUF_SIZE);

    memset(&cgc,   0, sizeof(cgc));
    memset(&sense, 0, sizeof(sense));

    cgc.sense           = &sense;
    cgc.buffer          = loaderBuf;
    cgc.buflen          = size;
    cgc.data_direction  = CGC_DATA_READ;
    cgc.timeout         = HZ * 5;

    cgc.cmd[0]  = GPCMD_READ_SUBCHANNEL;
    if (TRUE == fMSF)
    {
        cgc.cmd[1] = 0x02;
    }
    if (TRUE == fSubQ)
    {
        cgc.cmd[2] = 0x40;
    }
    cgc.cmd[3] = bFormat;
    cgc.cmd[6] = bTrack;
    cgc.cmd[7] = (BYTE)((size & 0x0000FF00) >> 8);        // MSB
    cgc.cmd[8] = (BYTE)(size & 0x000000FF);        // LSB

    DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderReadSubChannel() -- Length %02x %02x\n", cgc.cmd[7], cgc.cmd[8]));

    if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderReadSubChannel() --FAILED (%s)\n", strerror(errno)));
        DBGPRINT(DBG_ON(DBG_ERROR), ("                       --sense key: 0x%x, ASC/ASCQ: 0x%02x%02x\n", sense.sense_key, sense.asc, sense.ascq));
        loaderSetError(tLoader, errno);
        err = LOADER_FAILURE;
    }
    else if (pData != loaderBuf)
    {
        /* copy q-data to user buffer */
        memcpy(pData, loaderBuf, size);
    }

    return (err);
}


/**
 * Retrieves the last error encountered by the disc access module.
 *
 * @param tLoader - The loader handle.
 * @param pulErr - Pointer to be filled with last error.
 */
LOADER_ERR LoaderGetLastError(LOADER_HANDLE tLoader, ULONG *pulErr)
{
    if ( (tLoader == NULL) || (pulErr == NULL) )
    {
        return (LOADER_NULL_PTR);
    }

    *pulErr = ((LOADERHANDLE*)tLoader)->ulLastErr;

    return (LOADER_SUCCESS);
}

/**
 * Retrieves sectors from various CD formats (CDDA, CD-ROM, ...).
 *
 * @param tLoader - The loader handle.
 * @param ulLBA
 * @param ulNumBlocks
 * @param ulSectorSize
 * @param mode
 * @param pbData
 *
 * NOTE THAT pbData MUST POINT TO MEMORY ALLOCATED FROM BMEM !!!
 */
LOADER_ERR LoaderCDRead(LOADER_HANDLE tLoader, ULONG ulLBA, ULONG ulNumBlocks,
                              LOADER_CD_SECTOR_TYPE sectorType, LOADER_CD_DATA_SELECT dataSelect,
                              BYTE *pbData, ULONG ulBufSize)
{
    struct cdrom_generic_command cgc;
    struct request_sense sense;
    ULONG  ulRet, ulSectorSize;

    if ((tLoader == NULL) || (pbData == NULL))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCDRead() --LOADER_NULL_PTR\n"));
        return (LOADER_NULL_PTR);
    }

    if (((LOADERHANDLE*)tLoader)->LoaderType != LOADER_TYPE_CDROM)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCDRead() --INVALID LOADER TYPE\n"));
        return (LOADER_FAILURE);
    }


    switch (sectorType)
    {
        case LOADER_CD_SECTOR_CDDA:
            if(dataSelect == LOADER_CDDS_USER)
            {
                ulSectorSize = CDDA_SECTOR_SIZE;
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCDRead() -- Unimplemented case\n"));
                return (LOADER_NOT_IMPLEMENTED);
            }
            break;
        case LOADER_CD_SECTOR_MODE1:
            if(dataSelect == LOADER_CDDS_USER)
            {
                ulSectorSize = CD_MODE1_USER_DATA;
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCDRead() -- Unimplemented case\n"));
                return (LOADER_NOT_IMPLEMENTED);
            }
            break;
        case LOADER_CD_SECTOR_MODE2:
            if(dataSelect == LOADER_CDDS_USER)
            {
                ulSectorSize = CD_MODE2_USER_DATA;
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCDRead() -- Unimplemented case\n"));
                return (LOADER_NOT_IMPLEMENTED);
            }
            break;
        case LOADER_CD_SECTOR_MODE2_FORM1:
            if(dataSelect == LOADER_CDDS_USER)
            {
                ulSectorSize = CD_MODE2_FORM1_USER_DATA;
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCDRead() -- Unimplemented case\n"));
                return (LOADER_NOT_IMPLEMENTED);
            }

⌨️ 快捷键说明

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