📄 loader_win32.cpp
字号:
/******************************************************************************
*******************************************************************************
** **
** Copyright (c) 2006 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_win32.cpp
*
* win32 loader implementation
*
*/
#include "loader_win32.h"
#include "arch.h"
#include "dbgprint.h"
#include <windows.h>
#include "devioctl.h"
#include "ntddstor.h"
#pragma warning( disable : 4200 )
#include "ntddcdvd.h"
#pragma warning( default : 4200 )
#include "ntddcdrm.h"
#include <io.h>
/********************************************************************************
CONSTANTS
********************************************************************************/
// default drive to use if no optical drive is found automatically
#define DEFAULT_OPTICAL_DRIVE_LETTER 'D'
// automatically search for optical drives, set to 0 to force using default drive
#define WIN32_LOADER_SEARCH_FOR_OPTICAL_DRIVE 1
#define CD_SECTOR_SIZE 2352
/********************************************************************************
DATA TYPES
********************************************************************************/
struct WIN32LoaderData
{
HANDLE deviceHandle;
DVD_SESSION_ID sessionId;
char driveName[8];
};
/**
*******************************************************************************
* WIN32Loader::WIN32Loader initializes member variables to known state
* This routine will querry the system for drives to find an optical drive.
* It will use the last optical drive found.
*******************************************************************************/
WIN32Loader::WIN32Loader ( void )
{
char opticalDriveLetter;
data = new WIN32LoaderData;
DbgAssert( data != NULL );
memset(data,0,sizeof(WIN32LoaderData));
data->deviceHandle = INVALID_HANDLE_VALUE;
data->sessionId = 0;
opticalDriveLetter = DEFAULT_OPTICAL_DRIVE_LETTER;
#if WIN32_LOADER_SEARCH_FOR_OPTICAL_DRIVE
const char* driveTypeString = NULL;
char driveStringsBuffer[256];
UINT driveType = 0;
DWORD index = 0;
DWORD driveStringsLength = 0;
// Find optical drive
DbgPrint(("WIN32Loader: searching for drives:\n"));
driveStringsLength = GetLogicalDriveStrings(sizeof(driveStringsBuffer),driveStringsBuffer);
for ( index = 0; index < driveStringsLength; )
{
driveType = GetDriveType(&driveStringsBuffer[index]);
switch ( driveType )
{
case DRIVE_UNKNOWN: driveTypeString = "unknown"; break;
case DRIVE_NO_ROOT_DIR: driveTypeString = "unknown"; break;
case DRIVE_REMOVABLE: driveTypeString = "removable"; break;
case DRIVE_FIXED: driveTypeString = "fixed"; break;
case DRIVE_REMOTE: driveTypeString = "network"; break;
case DRIVE_RAMDISK: driveTypeString = "ram disk"; break;
case DRIVE_CDROM:
opticalDriveLetter = driveStringsBuffer[index];
driveTypeString = "cd-rom";
break;
default: driveTypeString = "ram disk"; break;
}
DbgPrint((" %s %s drive\n", &driveStringsBuffer[index], driveTypeString));
index += strlen(&driveStringsBuffer[index])+1;
}
#endif
snprintf(data->driveName,sizeof(data->driveName), "\\\\.\\%c:",opticalDriveLetter);
DbgPrint(("WIN32Loader: using optical drive: %s\n",data->driveName));
}
/**
*******************************************************************************
* WIN32Loader::~WIN32Loader free resources allocated.
*******************************************************************************/
WIN32Loader::~WIN32Loader ( void )
{
delete (data);
}
/**
*******************************************************************************
* WIN32Loader::Initialize free resources allocated.
*******************************************************************************/
void WIN32Loader::Initialize ( void )
{
DbgAssert( data != NULL );
if ( data->deviceHandle != INVALID_HANDLE_VALUE )
{
CloseHandle ( data->deviceHandle );
data->deviceHandle = INVALID_HANDLE_VALUE;
}
data->sessionId = 0;
data->deviceHandle = CreateFile(data->driveName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING,
NULL);
if (data->deviceHandle == INVALID_HANDLE_VALUE)
{
DbgPrint(("WIN32Loader::Initialize CreateFile failed, error %d\n", GetLastError()));
}
}
/**
*******************************************************************************
* WIN32Loader::Destroy close drive
*******************************************************************************/
void WIN32Loader::Destroy ( void )
{
DbgAssert(( data != NULL ));
if ( data->deviceHandle != INVALID_HANDLE_VALUE )
{
CloseHandle ( data->deviceHandle );
}
data->deviceHandle = INVALID_HANDLE_VALUE;
}
/**
*******************************************************************************
* WIN32Loader::OpenTray Opens the optical loader's tray
*
* @return WIN32LOADER_SUCCESS if successful, otherwise WIN32LOADER_FAILURE
*******************************************************************************/
int WIN32Loader::OpenTray ( void )
{
BOOL win32Result;
DWORD outputByteCount;
DbgAssert ( data != NULL );
if ( data->deviceHandle == INVALID_HANDLE_VALUE )
{
return ( WIN32LOADER_FAILURE );
}
win32Result = DeviceIoControl( data->deviceHandle, // device handle
IOCTL_STORAGE_EJECT_MEDIA, // operation
NULL, // must be NULL
0, // must be 0
NULL, // must be NULL
0, // must be 0
&outputByteCount, // output byte count
NULL); // overlapped structure for async operations
if (win32Result == 0x00)
{
DbgPrint(("WIN32Loader::LoaderOpenTray: ERROR %d\n", GetLastError() ));
return (WIN32LOADER_FAILURE);
}
CloseHandle ( data->deviceHandle );
data->deviceHandle = INVALID_HANDLE_VALUE;
return ( WIN32LOADER_SUCCESS );
}
/**
*******************************************************************************
* WIN32Loader::CloseTray Closes the optical loader's tray
*
* @return WIN32LOADER_SUCCESS if successful, otherwise WIN32LOADER_FAILURE
*******************************************************************************/
int WIN32Loader::CloseTray ( void )
{
BOOL win32Result;
DWORD outputByteCount;
DiscType discType;
DbgAssert ( data != NULL );
Initialize();
if ( data->deviceHandle == INVALID_HANDLE_VALUE )
{
DbgPrint(("\nWIN32Loader::CloseTray failed - unable to close your drive, please close it\n"));
return ( WIN32LOADER_SUCCESS );
}
win32Result = DeviceIoControl( data->deviceHandle, // device handle
IOCTL_STORAGE_LOAD_MEDIA, // operation
NULL, // must be NULL
0, // must be 0
NULL, // must be NULL
0, // must be 0
&outputByteCount, // output byte count
NULL); // overlapped structure for async operations
if (win32Result == 0x00)
{
if ( GetLastError() == ERROR_INVALID_FUNCTION )
{
// Drive does not support close command, see if media is already available
if ( GetDiscType( &discType ) == WIN32LOADER_SUCCESS )
{
return ( WIN32LOADER_SUCCESS );
}
DbgPrint(("WIN32Loader::CloseTray failed %d\n", GetLastError() ));
if ( data->deviceHandle != INVALID_HANDLE_VALUE )
{
CloseHandle ( data->deviceHandle );
data->deviceHandle = INVALID_HANDLE_VALUE;
}
DbgPrint(("\nWIN32Loader::CloseTray failed - unable to close your drive, please close it\n"));
return ( WIN32LOADER_SUCCESS );
}
}
return ( WIN32LOADER_SUCCESS );
}
/**
*******************************************************************************
* WIN32Loader::CloseTray Closes the optical loader's tray
*
* @param regionCode pointer to variable to receive region code mask
*
* @return WIN32LOADER_SUCCESS if successful, otherwise WIN32LOADER_FAILURE
*******************************************************************************/
int WIN32Loader::GetRegionCode ( unsigned char* regionCode )
{
BOOL win32Result;
DWORD outputByteCount;
BYTE keyBuffer[DVD_RPC_KEY_LENGTH];
PDVD_COPY_PROTECT_KEY pKey;
pKey = NULL;
DbgAssert ( data != NULL );
*regionCode = 0;
if ( data->deviceHandle == INVALID_HANDLE_VALUE )
{
return ( WIN32LOADER_FAILURE );
}
memset(keyBuffer, 0, sizeof(keyBuffer) );
pKey = (PDVD_COPY_PROTECT_KEY) &keyBuffer;
pKey->KeyLength = DVD_RPC_KEY_LENGTH;
pKey->SessionId = data->sessionId;
pKey->KeyType = DvdGetRpcKey;
win32Result = DeviceIoControl( data->deviceHandle, // device handle
IOCTL_DVD_READ_KEY, // operation
&keyBuffer,
DVD_RPC_KEY_LENGTH,
&keyBuffer,
DVD_RPC_KEY_LENGTH,
&outputByteCount, // output byte count
NULL); // overlapped structure for async operations
if (win32Result == 0x00)
{
DbgPrint(("WIN32Loader::GetRegionCode: ERROR %d\n", GetLastError() ));
return ( WIN32LOADER_FAILURE );
}
*regionCode = pKey->KeyData[1];
return ( WIN32LOADER_SUCCESS );
}
/**
*******************************************************************************
* WIN32Loader::GetDiscType Determine if media is DVD or CDDA
*
* @param discType pointer to variable to receive disc type
*
* @return WIN32LOADER_SUCCESS if successful, otherwise WIN32LOADER_FAILURE
*******************************************************************************/
int WIN32Loader::GetDiscType( DiscType* discType )
{
bool encrypted;
if ( GetDVDDiscInfo(discType, &encrypted) == WIN32LOADER_SUCCESS )
{
return ( WIN32LOADER_SUCCESS );
}
if ( GetCDDiscInfo(discType) == WIN32LOADER_SUCCESS )
{
return ( WIN32LOADER_SUCCESS );
}
return ( WIN32LOADER_FAILURE );
}
/**
*******************************************************************************
* WIN32Loader::GetDVDDiscInfo Determine type of DVD media
*
* @param discType pointer to variable to receive disc type
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -