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

📄 loader_app.c

📁 这是DVD中伺服部分的核心代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if ( (ldr->LoaderType != LOADER_TYPE_UNKNOWN) && (ldr->LoaderType != LOADER_TYPE_NODISK))
    {
#if 1 /* beginning of hack */
        if (PLAY_FROM_HD != 0)
        {
            /* don't try to mount...
             * just use the mount point as is
             * NOTE: YOU MUST MOUNT THE TARGET DRIVE TO /mnt/cdrom BEFORE STARTING PLAYER */
        }
        else
#endif /* end of hack */
        {
            /* Unmount the drive first, just in case it is already mounted. */
            DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady() --umount /mnt/cdrom\n"));
            umount(CDROM_MOUNT_DIRECTORY);

            if (ldr->LoaderType == LOADER_TYPE_CDROM)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady() --mount (CDROM iso9660)\n"));
                if (mount(CDROM_DEVICE_NAME, CDROM_MOUNT_DIRECTORY, "iso9660", MS_RDONLY, NULL) != 0)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderTestUnitReady() -- failed to mount drive (CDROM iso9660)!\n"));
                    //err = LOADER_FAILURE;
                }
                else {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady() --Mounted CDROM iso9660\n"));
                }
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady() --mount /dev/cdrom on /mnt/cdrom (BD/DVD udf)\n"));
                if (mount(CDROM_DEVICE_NAME, CDROM_MOUNT_DIRECTORY, "udf", MS_RDONLY, NULL) != 0)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderTestUnitReady() --UDF mount failed, try mount (BD/DVD iso9660)\n"));
                    if (mount(CDROM_DEVICE_NAME, CDROM_MOUNT_DIRECTORY, "iso9660", MS_RDONLY, NULL) != 0)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderTestUnitReady() -- failed to mount drive (BD/DVD udf/iso9660)!\n"));
                        //err = LOADER_FAILURE;
                    }
                    else {
                        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady() --Mounted BD/DVD iso9660\n"));
                    }
                }
                else {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady() --Mounted BD/DVD udf\n"));
                }
            }
        }
    }


    return (err);
}


/**
 * Stops the disc, and cleans up any parameters which may have become obsolete
 * by the stopping of the disc.
 *
 * @param tLoader - The loader handle.
 */
LOADER_ERR LoaderStop(LOADER_HANDLE tLoader)
{
    LOADER_ERR    err = LOADER_SUCCESS;
    LOADERHANDLE* ldr = (LOADERHANDLE*)tLoader;

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

    if ( (ldr->LoaderType != LOADER_TYPE_UNKNOWN) && (ldr->LoaderType != LOADER_TYPE_NODISK))
    {
        /* @todo... REMOVE ME. The following hack allows us to play the test content from HD
         * Needed because we do not have a BDROM drive yet. */

#if 1   /* beginning of hack */
        if (PLAY_FROM_HD != 0)
        {
            /* don't try to mount...
             * just use the mount point as is
             * NOTE: YOU MUST MOUNT THE TARGET DRIVE TO /mnt/cdrom BEFORE STARTING PLAYER */
        }
        else
#endif  /* end of hack */
        {
            /* unmount the drive */
            DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderStop() -- umount /mnt/cdrom\n"));
            if (umount(CDROM_MOUNT_DIRECTORY) != 0)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderStop() -- failed to unmount drive!\n"));
                err = LOADER_FAILURE;
            }
        }

        /* stop the drive */
        if (ioctl(ldr->lFileHandle, CDROMSTOP) < 0)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderStop() --FAILED (%s)\n", strerror(errno)));
            loaderSetError(tLoader, errno);
            err = LOADER_FAILURE;
        }
    }

    /* Reset the loader type */
    ldr->LoaderType = LOADER_TYPE_UNKNOWN;

    return (err);
}

/**
 * Reads a specific number of blocks from the storage media at the specified
 * sector.
 *
 * @param tLoader - The loader handle.
 * @param ulLBA - Sector offset to begin the read from.
 * @param pbData - Pointer to a buffer to receive the data.
 * @param ulNumBlocks - Number of sector sized blocks to be read. 0 and positive numbers only.
 */
LOADER_ERR LoaderSectorRead(LOADER_HANDLE tLoader, ULONG ulLBA, BYTE *pbData, ULONG ulNumBlocks)
{
    ULONG ulRet = LOADER_SUCCESS;

    /* verify input */
    if (ulNumBlocks == 0)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderSectorRead() --ZERO Sectors to Read. \n"));
        goto errout;
    }

    if (ulNumBlocks & 0xffff0000)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorRead() --LARGE SECTOR COUNT READ (0x%x sectors)\n", ulNumBlocks));
        ulRet = LOADER_INVALID_PARAMETER;
        goto errout;
    }

    if ( (tLoader == NULL) || (pbData == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorRead() --LOADER_NULL_PTR\n"));
        ulRet = LOADER_NULL_PTR;
        goto errout;
    }

    if (((LOADERHANDLE*)tLoader)->LoaderType == LOADER_TYPE_CDROM)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorRead() CALLED FOR CD TYPE - USE LoaderCDRead\n"));
        ulRet = LOADER_INVALID_PARAMETER;
        goto errout;
    }
    else
    {
        struct cdrom_generic_command cgc;
        struct request_sense sense;

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

        cgc.sense          = &sense;
        cgc.buffer         = pbData;
        cgc.buflen         = CD_FRAMESIZE*ulNumBlocks;
        cgc.data_direction = CGC_DATA_READ;
        cgc.timeout        = HZ*5;
        cgc.stat           = 0;
        cgc.quiet          = 0;

        /*
        ** Only Read_10 is used by this interface
        */
        cgc.cmd[ 0] = GPCMD_READ_10;
        cgc.cmd[ 1] = 0;
        cgc.cmd[ 2] = (BYTE)((ulLBA >> 24) & 0xff);
        cgc.cmd[ 3] = (BYTE)((ulLBA >> 16) & 0xff);
        cgc.cmd[ 4] = (BYTE)((ulLBA >>  8) & 0xff);
        cgc.cmd[ 5] = (BYTE)((ulLBA)       & 0xff);
        cgc.cmd[ 6] = 0;
        cgc.cmd[ 7] = (BYTE)((ulNumBlocks >>  8) & 0xff);
        cgc.cmd[ 8] = (BYTE)((ulNumBlocks)       & 0xff);
        cgc.cmd[ 9] = 0;
        cgc.cmd[10] = 0;
        cgc.cmd[11] = 0;

        if ((++ldr_read10_cnt % 100) == 0)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderSectorRead() -- Counters: READ_12 Streaming: %d, Read_10: %d\n", ldr_read12_strm_cnt, ldr_read10_cnt));
        }

        if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorRead() --FAILED (%s)\n", strerror(errno)));
            loaderSetError(tLoader, errno);
            return (LOADER_FAILURE);
        }
    }

errout:
    return (ulRet);
}

/**
 * Reads a specific number of blocks from the storage media at the specified
 * sector (streaming).
 *
 * @param tLoader - The loader handle.
 * @param ulLBA - Sector offset to begin the read from.
 * @param pbData - Pointer to a buffer to receive the data.
 * @param ulNumBlocks - Number of sector sized blocks to be read. 0 and positive numbers only.
 */
LOADER_ERR LoaderSectorReadAV(LOADER_HANDLE tLoader, ULONG ulLBA, BYTE *pbData, ULONG ulNumBlocks)
{
    ULONG ulRet = LOADER_SUCCESS;

    /* verify input */
    if (ulNumBlocks == 0)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderSectorReadAV() --ZERO Sectors to Read. \n"));
        goto errout;
    }

    if (ulNumBlocks & 0xffff0000)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderSectorReadAV() --LARGE SECTOR COUNT READ (0x%x sectors)\n", ulNumBlocks));
    }

    if ( (tLoader == NULL) || (pbData == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorReadAV() --LOADER_NULL_PTR\n"));
        ulRet = LOADER_NULL_PTR;
        goto errout;
    }

    if (((LOADERHANDLE*)tLoader)->LoaderType == LOADER_TYPE_CDROM)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorReadAV() CALLED FOR CD TYPE - USE LoaderCDRead\n"));
        ulRet = LOADER_INVALID_PARAMETER;
        goto errout;
    }
    else
    {
        struct cdrom_generic_command cgc;
        struct request_sense sense;

retry:
        memset(&sense, 0, sizeof(sense));

        cgc.sense          = &sense;
        cgc.buffer         = pbData;
        cgc.buflen         = CD_FRAMESIZE*ulNumBlocks;
        cgc.data_direction = CGC_DATA_READ;
        cgc.timeout        = HZ*5;
        cgc.stat           = 0;
        cgc.quiet          = 0;

        if (!(((LOADERHANDLE*)tLoader)->bFlags & LOADER_READ_12_ILLEGAL))
        {
            cgc.cmd[ 0] = GPCMD_READ_12;
            cgc.cmd[ 6] = (BYTE)((ulNumBlocks >> 24) & 0xff);
            cgc.cmd[ 7] = (BYTE)((ulNumBlocks >> 16) & 0xff);
            cgc.cmd[ 8] = (BYTE)((ulNumBlocks >>  8) & 0xff);
            cgc.cmd[ 9] = (BYTE)((ulNumBlocks)       & 0xff);
            cgc.cmd[10] = 0x80;

            if ((++ldr_read12_strm_cnt % 100) == 0)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderSectorReadAV() -- Counters: READ_12 Streaming: %d, READ_10: %d\n", ldr_read12_strm_cnt, ldr_read10_cnt));
            }
        }
        else
        {
            /*
            ** Read_12 not supported by loader
            */
            cgc.cmd[ 0] = GPCMD_READ_10;
            cgc.cmd[ 6] = 0;
            cgc.cmd[ 7] = (BYTE)((ulNumBlocks >>  8) & 0xff);
            cgc.cmd[ 8] = (BYTE)((ulNumBlocks)       & 0xff);
            cgc.cmd[ 9] = 0;
            cgc.cmd[10] = 0;

            if ((++ldr_read10_cnt % 100) == 0)
            {
                DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderSectorReadAV() -- Counters: READ_12 Streaming: %d, READ_10: %d\n", ldr_read12_strm_cnt, ldr_read10_cnt));
            }
        }

        cgc.cmd[ 1] = 0;
        cgc.cmd[ 2] = (BYTE)((ulLBA >> 24) & 0xff);
        cgc.cmd[ 3] = (BYTE)((ulLBA >> 16) & 0xff);
        cgc.cmd[ 4] = (BYTE)((ulLBA >>  8) & 0xff);
        cgc.cmd[ 5] = (BYTE)((ulLBA)       & 0xff);
        cgc.cmd[11] = 0;

        if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
        {
            /*
            ** If this was a Read_12 and it failed with -EIO, then the underlying
            ** Read_12 failed due to ILLEGAL_REQUEST. Therefore the device does not
            ** support Read_12 with the media currently loaded.
            */
            if (LoaderRead10Enable && (cgc.cmd[0] == GPCMD_READ_12))
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorReadAV() --READ_12 FAILED (%s), RETRY AS READ_10\n", strerror(errno)));
                ((LOADERHANDLE*)tLoader)->bFlags |= LOADER_READ_12_ILLEGAL;
                goto retry;
            }

            DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderSectorReadAV() --FAILED AT LBA 0x%x (%s)\n", ulLBA, strerror(errno)));
            loaderSetError(tLoader, errno);
            ulRet = LOADER_FAILURE;
        }
    }

errout:
    return (ulRet);
}

/**
 * Retrieves the current status of the media storage device.
 *
 * @param tLoader - The loader handle.
 * @param pStatus - Status will be returned through this pointer.
 */
LOADER_ERR LoaderGetStatus(LOADER_HANDLE tLoader, LOADER_STATUS *pStatus)
{
    int bufSize = 8;
    struct cdrom_generic_command cgc;
    struct request_sense sense;
    unsigned int changerState;
    unsigned int doorOpenState;
    LOADER_ERR err = LOADER_SUCCESS;

    if ( (tLoader == NULL) || (pStatus == 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_MECHANISM_STATUS;
    cgc.cmd[ 8] = (cgc.buflen >> 8) & 0xff;
    cgc.cmd[ 9] = (cgc.buflen & 0xff);

    if (ioctl(((LOADERHANDLE*)tLoader)->lFileHandle, CDROM_SEND_PACKET, &cgc) < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderGetStatus() --FAILED (%s)\n", strerror(errno)));
        loaderSetError(tLoader, errno);
        err = LOADER_FAILURE;

		// unable to read tray status on this drive, assume it's closed
		pStatus->ulTrayStatus = LOADER_TRAY_CLOSED;
        err = LOADER_SUCCESS;
    }
    else
    {
        /*
         * Check the Mechanism status header for DoorOpen and Changer State bits
         * byte 0 bit 5-6 and byte 1 bit 4
         */
        doorOpenState = (loaderBuf[1] & 0x10) >> 4;
        changerState  = (loaderBuf[0] & 0x60) >> 5;

        if (!changerState && doorOpenState)
        {
            pStatus->ulTrayStatus = LOADER_TRAY_OPEN;
        }
        else if (changerState == 0)
        {
            pStatus->ulTrayStatus = LOADER_TRAY_CLOSED;
        }
        else if (changerState == 1)
        {
            pStatus->ulTrayStatus = LOADER_TRAY_CLOSING;
        }
        else if (changerState == 2)
        {
            pStatus->ulTrayStatus = LOADER_TRAY_OPENING;
        }
        else
        {
            /* Actually this is not needed for multidisc tray, but here for completeness */
            pStatus->ulTrayStatus = LOADER_TRAY_INITIALIZING;
        }
    }

    pStatus->ulLoaderBusy = 0;

    return (err);
}

/**
 *  Gets the authentication grant ID (AGID) from the loader.
 *
 *  @param tLoader - The loader handle.
 *  @param pulAgid - Pointer to memory where AGID is stored.
 */
static LOADER_ERR LoaderInitGetAgid(LOADER_HANDLE tLoader, BYTE key_class)
{
        int bufSize = 8;
        struct cdrom_generic_command cgc;
        struct request_sense sense;
        LOADER_ERR err = LOADER_SUCCESS;

        if (tLoader == 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;

⌨️ 快捷键说明

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