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

📄 loader_app.c

📁 这是DVD中伺服部分的核心代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2002 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/

/**
 * @file loader_app.c
 *
 * $Revision: 1.67 $ 
 *
 * DVD disc access module.
 *
 */
#include "vdvd_types.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <linux/cdrom.h>
#include <linux/hdreg.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "osapi.h"
#include "loader_app.h"
#include "dbgprint.h"
#include "css.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

#define DEBUG_CDROM 0

#if 1
	#define CDROM_DEVICE_NAME       "/dev/cdrom"
	#define CDROM_MOUNT_DIRECTORY   "/mnt/cdrom"
#else
	#define CDROM_DEVICE_NAME       "/dev/cdroms/cdrom0"
	#define CDROM_MOUNT_DIRECTORY   "/hd0/mnt/cdrom"
#endif

/* MACROS AND DEFINITIONS */
#define DEBUG_LOADER DBG_ERROR
#define DBG_ON(x) (DEBUG_LOADER >= x)

#define LOADER_DIRECT_IO_ON  TRUE
#define LOADER_DIRECT_IO_OFF FALSE

#define LDR_BUF_SIZE 2052

/*
** Globals
*/
BYTE loaderBuf[LDR_BUF_SIZE];


/* used to spoof the player */
int PLAY_FROM_HD = 0;

/* Tracing counters */
static int ldr_read10_cnt = 0;
static int ldr_read12_strm_cnt = 0;


/*
 * Private Data Types
 *****************************************************************************/

typedef struct _tagLoaderHandle
{
    LONG        lFileHandle;        /**< File handle returned from open */
    ULONG       ulLastErr;
    LOADER_TYPE LoaderType;         /**< Type of media currently in the tray */
    ULONG       ulLastLBA;
    ULONG       ulBlockLength;
    BYTE        bRegionMask;        /**< region code mask */
    BYTE        bFlags;
    BYTE        bDiscType;
    BYTE        bNumLayers;
    LOADER_TYPE ptLayerFormatType[LOADER_SUPPORTED_NUMBER_OF_LAYERS];
} LOADERHANDLE;

static ULONG LoaderRead10Enable = 0;

/*
** Flags definitions
*/
#define LOADER_STREAMING_SUPPORT        0x01
#define LOADER_TIMEOUT_SUPPORT          0x02
#define LOADER_RW_ERR_RECOVERY_SUPPORT  0x04
#define LOADER_READ_12_ILLEGAL          0x08
#define LOADER_AACS_CAPABLE             0x10
#define LOADER_READ_NUMLAYERS_FAILS     0x20

/*
** Loader Eject support
*/
typedef enum _loejStart {
  LOADER_EJECT_DISC =   0x02,
  LOADER_LOAD_DISC  =   0x00
} LOEJSTARTBITS;


/*
 * Local Fuction Prototypes
 *****************************************************************************/
static void loaderSetError(LOADER_HANDLE tLoader, ULONG ulErr);
static void loaderGetRPC_local(LOADER_HANDLE tLoader);
static void loaderGetType_local(LOADER_HANDLE tLoader);
static int  test_unit_ready(int fd, int *s);
static LOADER_ERR loaderTestUnitReady_local(LOADER_HANDLE tLoader);
static LOADER_ERR LoaderSendKey(LOADER_HANDLE tLoader, BYTE bAgid, BYTE key_class, BYTE key_format, USHORT param_length, BYTE *pData);
static LOADER_ERR LoaderReportKey(LOADER_HANDLE tLoader, BYTE pAgid, ULONG address, BYTE blk_cnt, BYTE key_class, BYTE key_format, USHORT buf_length, BYTE *pData);
static LOADER_ERR LoaderReadDiscStruct(LOADER_HANDLE tLoader, BYTE bAgid, BYTE sub_cmd, ULONG address, BYTE format_code, BYTE *pBuf, USHORT len);
static LOADER_ERR LoaderInitGetAgid(LOADER_HANDLE tLoader, BYTE key_class);
static LOADER_ERR loaderGetConfiguration(int fd, char RT, int bufSize, char *bufPtr, struct request_sense *sense);
static LOADER_ERR loaderGetCapacity(int fd, int bufSize, char *bufPtr, struct request_sense *sense);
static LOADER_ERR loaderSetStreaming(int fd, int bufSize, char *bufPtr, struct request_sense *sense);
static LOADER_ERR loaderModeSense(LOADER_HANDLE tLoader, char page_code, int bufSize, char *bufPtr, struct request_sense *sense);
static LOADER_ERR loaderModeSelect(LOADER_HANDLE tLoader, int bufSize, char *bufPtr, struct request_sense *sense);
static LOADER_ERR loaderFileOpen(LOADER_HANDLE tLoader, const char *pcFileName, LOADER_FILE_HANDLE *hFileHandle, BOOLEAN fDirectIO);
static LOADER_TYPE loaderTranslateHybridLayerFormatType(USHORT usLayerFormatType);

/**
 * Creates a handle to a loader device, initializes any global variables,
 * allocates any required memory, and returns a pointer to the device handle.
 *
 * @param eBusType    - NOT USED FOR THIS IMPLEMENTATION
 * @param ulDeviceNum - NOT USED FOR THIS IMPLEMENTATION
 */
LOADER_HANDLE LoaderCreate(LOADER_BUS_TYPE eBusType, ULONG ulDeviceNum)
{
    LOADERHANDLE *tLoader = NULL;
    LONG lFileHandle;

    (void)eBusType;
    (void)ulDeviceNum;

    lFileHandle = open(CDROM_DEVICE_NAME, O_RDONLY | O_NONBLOCK);
    if (lFileHandle < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderCreate() --FAILED (%s)\n", strerror(errno)));
    }
    else
    {
        tLoader   = (LOADERHANDLE*)OS_MemAlloc(sizeof(LOADERHANDLE));
        if ( tLoader == NULL )
        {
            /* Out of memory, close device */
            close(lFileHandle);
        }
        else
        {
            /* set initial state */
            memset( tLoader, 0, sizeof(LOADERHANDLE) );
            tLoader->lFileHandle = lFileHandle;
            tLoader->LoaderType  = LOADER_TYPE_UNKNOWN;
        }
    }

    DBGPRINT(DBG_ON(DBG_ERROR),("LoaderCreate() -- r10_ok fallback enabled\n"));
    LoaderRead10Enable = 1;

    return ((LOADER_HANDLE)tLoader);
}

/**
 * Stops the storage media if necessary, closes the current session and frees
 * any memory allocated during the LoaderCreate() call.
 *
 * @param tLoader - The loader handle.
 */
LOADER_ERR LoaderDestroy(LOADER_HANDLE tLoader)
{
    if (tLoader == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderDestroy() --LOADER_NULL_PTR\n"));
        return (LOADER_NULL_PTR);
    }

    if (((LOADERHANDLE*)tLoader)->lFileHandle != 0)
    {
        /* close the drive */
        close(((LOADERHANDLE*)tLoader)->lFileHandle);
    }

    /* free the memory */
    OS_MemFree(tLoader);

    return (LOADER_SUCCESS);
}

/**
 * Loads/Eject a disc into the device with Immediate bit set
 * This function is critical for emergency exit.
 *
 * @param tLoader - The loader handle.
 */
static LOADER_ERR LoaderStartStopUnit(LOADER_HANDLE tLoader, LOEJSTARTBITS loejStartBits)
{
    int    cdrom;
    struct cdrom_generic_command cgc;
    struct request_sense sense;
    LOADER_ERR ldrSts = LOADER_SUCCESS;

    cdrom = ((LOADERHANDLE*)tLoader)->lFileHandle;

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

    /* fill in required info for GPCMD_REPORT_KEY RPC State request */
    cgc.sense =  &sense;
    cgc.data_direction = CGC_DATA_NONE;
    cgc.timeout = 20000;

    cgc.cmd[ 0] = GPCMD_START_STOP_UNIT;
    cgc.cmd[ 1] = 0x01;
    cgc.cmd[ 4] = loejStartBits;

    /* send command to driver */
    if (ioctl(cdrom, CDROM_SEND_PACKET, &cgc) < 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderStartStopUnit() --FAILED (%s), loejStartBits 0x%x\n", strerror(errno), loejStartBits));
        ldrSts = LOADER_FAILURE;
    }

    return ldrSts;
}


/**
 * Stops the disc if necessary, closes the session, and opens the tray holding
 * the disc.
 *
 * @param tLoader - The loader handle.
 */
LOADER_ERR LoaderOpenTray(LOADER_HANDLE tLoader)
{
    LOADER_ERR    err = LOADER_SUCCESS;
    LOADERHANDLE* ldr = (LOADERHANDLE*)tLoader;

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

    err = LoaderStartStopUnit(tLoader, LOADER_EJECT_DISC);

    if (err == LOADER_SUCCESS)
    {
        /* Reset the loader type */
        ldr->LoaderType = LOADER_TYPE_UNKNOWN;
    }

    /*
    ** Clear flags that change with media.
    */
    ldr->bFlags = 0;

    return (err);
}

/**
 * Loads a disc into the device, and prepares everything needed to start the
 * disc.
 *
 * @param tLoader - The loader handle.
 */
LOADER_ERR LoaderCloseTray(LOADER_HANDLE tLoader)
{
    LOADER_ERR    err = LOADER_SUCCESS;
    LOADERHANDLE* ldr = (LOADERHANDLE*)tLoader;

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

    err = LoaderStartStopUnit(tLoader, LOADER_LOAD_DISC);

    if (err == LOADER_SUCCESS)
    {
        /* Reset the loader type */
        ldr->LoaderType = LOADER_TYPE_UNKNOWN;
    }

    /*
    ** Clear flags that change with media.
    */
    ldr->bFlags = 0;

    return (err);
}


/**
 * Starts the spinning of the disc, as well as detection of the disc type,
 * sector size, and encryption. This also begins the disc authentication
 * process.
 *
 * @param tLoader - The loader handle.
 */
LOADER_ERR LoaderStart(LOADER_HANDLE tLoader)
{
    if (tLoader == NULL)
    {
        return (LOADER_NULL_PTR);
    }

    /*DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderStart() --Entry LoaderType %d\n", ldr->LoaderType));*/

    /* check the "spoof" environment setting */
    if ( getenv( "PLAY_FROM_HD" ) )
    {
        PLAY_FROM_HD = 1;
        printf("\nENABLE PLAY FROM HD\n");
    }
    else
    {
        PLAY_FROM_HD = 0;
    }

    /* start the drive */
    if (LoaderStartStopUnit(tLoader, LOADER_LOAD_DISC) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderStart: LOADER FAILED TO START UNIT!!!\n"));
        return (LOADER_FAILURE);
    }

    return (LOADER_SUCCESS);
}

/**
 * Checks if the unit is ready. If the unit is not ready, fReady is set to 
 * false and the function returns.  If the unit is ready, fReady is set to
 * true and the loader startup is completed.
 *
 * @param tLoader - The loader handle.
 * @param fReady - gets set to true if unit is ready, false otherwise
 */
LOADER_ERR LoaderTestUnitReady(LOADER_HANDLE tLoader, BOOLEAN *fReady)
{
    LOADERHANDLE*   ldr = (LOADERHANDLE*)tLoader;
    LOADER_ERR      err = LOADER_SUCCESS;

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

    if (fReady == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("LoaderTestUnitReady: NULL pointer!\n"));
        return (LOADER_NULL_PTR);
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady()\n"));
           
    /* test for unit ready */
    if (loaderTestUnitReady_local(tLoader) != LOADER_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady: LOADER FAILED TO BECOME READY!!!\n"));
        *fReady = FALSE;
        
        /* unit not ready, so just return */
        return (LOADER_SUCCESS);
    }

    /* unit is ready */
    *fReady = TRUE;

    DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady: READY!\n"));

    if (ldr->LoaderType == LOADER_TYPE_NODISK)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady: No disc!\n"));

        /* no disc, so just return */
        return (LOADER_SUCCESS);
    }

    /* medium loaded so get type */
    loaderGetType_local(tLoader);

    if (ldr->LoaderType == LOADER_TYPE_UNKNOWN)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("LoaderTestUnitReady: Unknown disc type!\n"));

        /* unknown disc type, so just return */
        return (LOADER_SUCCESS);
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("Loader: LOADER_TYPE %d, Media Type 0x%x, Num Layers %d\n", ldr->LoaderType, ldr->bDiscType, ldr->bNumLayers));

    /* get the region of the drive */
    loaderGetRPC_local(tLoader);


    /*
    ** Perform a read to LBA 0x10 to absorb drive head recalibration.
    ** Read status is unimportant.
    ** Note that this operation placed here helps to avoid errors during mount.
    */
    LoaderSectorRead(tLoader, 0x10, loaderBuf, 1);

    /*
     * If loader type is known and there is a disc in the tray, then
     * mount the drive.  Otherwise, just lock the drive.
     */

⌨️ 快捷键说明

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