📄 loader_app.c
字号:
* @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 + -