You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
498 lines
10 KiB
498 lines
10 KiB
/*++
|
|
|
|
Copyright (c) 1991 - 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
### ### ##### #### ### ##### ## ### ## ## #### ##### #####
|
|
## # ### ## ## ## ## # ## ## ## ### ## ## ## # ## ## ## ##
|
|
### ## ## ## ## ## ### ## ## ## ## ## #### ## ## ## ## ##
|
|
### ## ## ## ## ## ### ## ## ## ## ## #### ## ## ## ## ##
|
|
### ####### ## ## ## ### ##### ## ####### ## ## ##### #####
|
|
# ## ## ## ## ## ## # ## ## ## ## ## ## ## ## # ## ##
|
|
### ## ## ##### #### ### ## ##### ## ## ## ## #### ## ##
|
|
|
|
Abstract:
|
|
|
|
This module contains the implementation for
|
|
the ISaDisplay interface class.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 1-Oct-2001
|
|
|
|
Environment:
|
|
|
|
User mode only.
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
CSaDisplay::CSaDisplay()
|
|
{
|
|
m_hFile = OpenSaDevice( SA_DEVICE_DISPLAY );
|
|
if (m_hFile != INVALID_HANDLE_VALUE) {
|
|
ULONG Bytes;
|
|
m_DisplayCaps.SizeOfStruct = sizeof(SA_DISPLAY_CAPS);
|
|
BOOL b = DeviceIoControl(
|
|
m_hFile,
|
|
IOCTL_SA_GET_CAPABILITIES,
|
|
NULL,
|
|
0,
|
|
&m_DisplayCaps,
|
|
sizeof(SA_DISPLAY_CAPS),
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
if (!b) {
|
|
CloseHandle( m_hFile );
|
|
m_hFile = NULL;
|
|
}
|
|
|
|
|
|
b = DeviceIoControl(
|
|
m_hFile,
|
|
IOCTL_SA_GET_VERSION,
|
|
NULL,
|
|
0,
|
|
&m_InterfaceVersion,
|
|
sizeof(ULONG),
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
if (!b) {
|
|
CloseHandle( m_hFile );
|
|
m_hFile = NULL;
|
|
}
|
|
|
|
m_CachedBitmapSize = m_DisplayCaps.DisplayHeight * (m_DisplayCaps.DisplayWidth / 8);
|
|
m_CachedBitmap = (PUCHAR) malloc( m_CachedBitmapSize );
|
|
if (m_CachedBitmap == NULL) {
|
|
CloseHandle( m_hFile );
|
|
m_hFile = NULL;
|
|
}
|
|
|
|
} else {
|
|
m_hFile = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
CSaDisplay::~CSaDisplay()
|
|
{
|
|
if (m_hFile != NULL) {
|
|
CloseHandle( m_hFile );
|
|
}
|
|
if (m_CachedBitmap) {
|
|
free( m_CachedBitmap );
|
|
}
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::get_InterfaceVersion(long *pVal)
|
|
{
|
|
*pVal = m_InterfaceVersion;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::get_DisplayType(long *pVal)
|
|
{
|
|
*pVal = m_DisplayCaps.DisplayType;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::get_CharacterSet(long *pVal)
|
|
{
|
|
*pVal = m_DisplayCaps.CharacterSet;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::get_DisplayHeight(long *pVal)
|
|
{
|
|
*pVal = m_DisplayCaps.DisplayHeight;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::get_DisplayWidth(long *pVal)
|
|
{
|
|
*pVal = m_DisplayCaps.DisplayWidth;
|
|
return S_OK;
|
|
}
|
|
|
|
void
|
|
CSaDisplay::ConvertBottomLeft2TopLeft(
|
|
PUCHAR Bits,
|
|
ULONG Width,
|
|
ULONG Height
|
|
)
|
|
{
|
|
ULONG Row;
|
|
ULONG Col;
|
|
UCHAR Temp;
|
|
|
|
|
|
Width = Width >> 3;
|
|
|
|
for (Row = 0; Row < (Height / 2); Row++) {
|
|
for (Col = 0; Col < Width; Col++) {
|
|
Temp = Bits[Row * Width + Col];
|
|
Bits[Row * Width + Col] = Bits[(Height - Row - 1) * Width + Col];
|
|
Bits[(Height - Row - 1) * Width + Col] = Temp;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int
|
|
CSaDisplay::DisplayBitmap(
|
|
long MsgCode,
|
|
long Width,
|
|
long Height,
|
|
unsigned char *Bits
|
|
)
|
|
{
|
|
ULONG SizeOfBits;
|
|
ULONG Bytes;
|
|
BOOL b;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
ConvertBottomLeft2TopLeft( Bits, Width, Height );
|
|
|
|
//
|
|
// Check the cache for a hit
|
|
//
|
|
|
|
SizeOfBits = Height * (Width >> 3);
|
|
if (SizeOfBits == m_CachedBitmapSize && (memcmp( m_CachedBitmap, Bits, SizeOfBits ) == 0)) {
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Display the new bitmap
|
|
//
|
|
|
|
m_SaDisplay.SizeOfStruct = sizeof(SA_DISPLAY_SHOW_MESSAGE);
|
|
m_SaDisplay.MsgCode = MsgCode;
|
|
|
|
m_SaDisplay.Width = (USHORT)Width;
|
|
m_SaDisplay.Height = (USHORT)Height;
|
|
|
|
memcpy( m_SaDisplay.Bits, Bits, SizeOfBits );
|
|
|
|
b = WriteFile( m_hFile, &m_SaDisplay, sizeof(SA_DISPLAY_SHOW_MESSAGE), &Bytes, NULL );
|
|
if (b == FALSE || Bytes != sizeof(SA_DISPLAY_SHOW_MESSAGE)) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
//
|
|
// Cache the bitmap
|
|
//
|
|
|
|
m_CachedBitmapSize = SizeOfBits;
|
|
memcpy( m_CachedBitmap, Bits, m_CachedBitmapSize );
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CSaDisplay::ShowMessage(
|
|
long MsgCode,
|
|
long Width,
|
|
long Height,
|
|
unsigned char *Bits
|
|
)
|
|
{
|
|
|
|
if (Width > m_DisplayCaps.DisplayWidth) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
if (Height > m_DisplayCaps.DisplayHeight) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
if (DisplayBitmap( MsgCode, Width, Height, Bits) == -1) {
|
|
return E_FAIL;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::ClearDisplay()
|
|
{
|
|
ULONG Bytes;
|
|
BOOL b;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
memset( &m_SaDisplay, 0, sizeof(SA_DISPLAY_SHOW_MESSAGE) );
|
|
|
|
m_SaDisplay.SizeOfStruct = sizeof(SA_DISPLAY_SHOW_MESSAGE);
|
|
m_SaDisplay.MsgCode = SA_DISPLAY_READY;
|
|
|
|
m_SaDisplay.Width = m_DisplayCaps.DisplayWidth;
|
|
m_SaDisplay.Height = m_DisplayCaps.DisplayHeight;
|
|
|
|
b = WriteFile( m_hFile, &m_SaDisplay, sizeof(SA_DISPLAY_SHOW_MESSAGE), &Bytes, NULL );
|
|
if (b == FALSE || Bytes != sizeof(SA_DISPLAY_SHOW_MESSAGE)) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
//
|
|
// Clear the bitmap cache
|
|
//
|
|
|
|
m_CachedBitmapSize = 0;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CSaDisplay::ShowMessageFromFile(
|
|
long MsgCode,
|
|
BSTR BitmapFileName
|
|
)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
PBITMAPFILEHEADER bmf;
|
|
PBITMAPINFOHEADER bmi;
|
|
PUCHAR BitmapData = NULL;
|
|
ULONG FileSize;
|
|
ULONG Bytes;
|
|
|
|
|
|
__try {
|
|
|
|
hFile = CreateFile(
|
|
BitmapFileName,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL
|
|
);
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
__leave;
|
|
}
|
|
|
|
FileSize = GetFileSize( hFile, NULL );
|
|
|
|
BitmapData = (PUCHAR) malloc( FileSize );
|
|
if (BitmapData == NULL) {
|
|
__leave;
|
|
}
|
|
|
|
if (!ReadFile( hFile, BitmapData, FileSize, &Bytes, NULL )) {
|
|
__leave;
|
|
}
|
|
|
|
bmf = (PBITMAPFILEHEADER) BitmapData;
|
|
bmi = (PBITMAPINFOHEADER) (BitmapData + sizeof(BITMAPFILEHEADER));
|
|
|
|
if (bmf->bfType != 0x4d42) {
|
|
__leave;
|
|
}
|
|
|
|
if (bmi->biBitCount != 1 && bmi->biCompression != 0) {
|
|
__leave;
|
|
}
|
|
|
|
if (DisplayBitmap( 0, bmi->biWidth, bmi->biHeight, (PUCHAR)(BitmapData + bmf->bfOffBits) ) == -1) {
|
|
__leave;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
} __finally {
|
|
|
|
if (BitmapData) {
|
|
free( BitmapData );
|
|
}
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
CloseHandle( hFile );
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CSaDisplay::StoreBitmap(
|
|
long MessageId,
|
|
long Width,
|
|
long Height,
|
|
unsigned char *Bits
|
|
)
|
|
{
|
|
BOOL b;
|
|
ULONG Bytes;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
ConvertBottomLeft2TopLeft( Bits, Width, Height );
|
|
|
|
m_SaDisplay.SizeOfStruct = sizeof(SA_DISPLAY_SHOW_MESSAGE);
|
|
m_SaDisplay.MsgCode = MessageId;
|
|
m_SaDisplay.Width = (USHORT)Width;
|
|
m_SaDisplay.Height = (USHORT)Height;
|
|
|
|
memcpy( m_SaDisplay.Bits, Bits, Height * (Width >> 3) );
|
|
|
|
b = DeviceIoControl(
|
|
m_hFile,
|
|
IOCTL_FUNC_DISPLAY_STORE_BITMAP,
|
|
&m_SaDisplay,
|
|
sizeof(SA_DISPLAY_SHOW_MESSAGE),
|
|
NULL,
|
|
0,
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
if (!b) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::Lock()
|
|
{
|
|
BOOL b;
|
|
ULONG Bytes;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
b = DeviceIoControl(
|
|
m_hFile,
|
|
IOCTL_SADISPLAY_LOCK,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
if (!b) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CSaDisplay::UnLock()
|
|
{
|
|
BOOL b;
|
|
ULONG Bytes;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
b = DeviceIoControl(
|
|
m_hFile,
|
|
IOCTL_SADISPLAY_UNLOCK,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
if (!b) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSaDisplay::ReloadRegistryBitmaps()
|
|
{
|
|
BOOL b;
|
|
ULONG Bytes;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
b = DeviceIoControl(
|
|
m_hFile,
|
|
IOCTL_SADISPLAY_CHANGE_LANGUAGE,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
|
|
if (!b) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CSaDisplay::ShowRegistryBitmap(long MessageId)
|
|
{
|
|
BOOL b;
|
|
DWORD dwIoControlCode = 0;
|
|
ULONG Bytes;
|
|
|
|
if (m_hFile == NULL){
|
|
return HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
}
|
|
|
|
if (MessageId == SA_DISPLAY_CHECK_DISK){
|
|
dwIoControlCode = IOCTL_SADISPLAY_BUSY_MESSAGE;
|
|
}
|
|
else if (MessageId == SA_DISPLAY_SHUTTING_DOWN){
|
|
dwIoControlCode = IOCTL_SADISPLAY_SHUTDOWN_MESSAGE;
|
|
}
|
|
else{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
|
|
b = DeviceIoControl(
|
|
m_hFile,
|
|
dwIoControlCode,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0,
|
|
&Bytes,
|
|
NULL
|
|
);
|
|
if (!b) {
|
|
return HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|