Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1116 lines
29 KiB

#include "testmcro.h"
#include "wiamicro.h"
#include "resource.h"
#include <STI.H>
#include <math.h>
#include <winioctl.h>
#include <usbscan.h>
#ifdef DEBUG
#include <stdio.h>
#endif
// #define BUTTON_SUPPORT // (uncomment this to allow BUTTON SUPPORT)
// button support is not functional in the test device
#define MAX_BUTTONS 1
#define MAX_BUTTON_NAME 255
HINSTANCE g_hInst; // instance of this MicroDriver (used for loading from a resource)
// note: MEMORYBMP, and BMP file will be added by wiafbdrv host driver.
// do not include them in your extended list.
//
// #define _USE_EXTENDED_FORMAT_LIST (uncomment this to allow Extented file and memory formats)
#define NUM_SUPPORTED_FILEFORMATS 1
GUID g_SupportedFileFormats[NUM_SUPPORTED_FILEFORMATS];
#define NUM_SUPPORTED_MEMORYFORMATS 2
GUID g_SupportedMemoryFormats[NUM_SUPPORTED_MEMORYFORMATS];
//
// Button GUID array used in Capability negotiation.
// Set your BUTTON guids here. These must match the GUIDS specified in
// your INF. The Scan Button GUID is public to all scanners with a
// scan button.
//
GUID g_Buttons[MAX_BUTTONS] ={{0xa6c5a715, 0x8c6e, 0x11d2,{ 0x97, 0x7a, 0x0, 0x0, 0xf8, 0x7a, 0x92, 0x6f}}};
BOOL g_bButtonNamesCreated = FALSE;
WCHAR* g_ButtonNames[MAX_BUTTONS];
INT g_PalIndex = 0; // simple palette index counter (test driver specific)
BOOL g_bDown = FALSE; // simple band direction bool (test drvier specific)
BOOL InitializeScanner(PSCANINFO pScanInfo);
VOID InitScannerDefaults(PSCANINFO pScanInfo);
BOOL SetScannerSettings(PSCANINFO pScanInfo);
VOID CheckButtonStatus(PVAL pValue);
VOID GetButtonPress(LONG *pButtonValue);
HRESULT GetInterruptEvent(PVAL pValue);
LONG GetButtonCount();
HRESULT GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal);
VOID ReadRegistryInformation(PVAL pValue);
BOOL APIENTRY DllMain( HANDLE hModule,DWORD dwreason, LPVOID lpReserved)
{
g_hInst = (HINSTANCE)hModule;
switch(dwreason) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
/**************************************************************************\
* MicroEntry (MicroDriver Entry point)
*
* Called by the WIA driver to communicate with the MicroDriver.
*
* Arguments:
*
* lCommand - MicroDriver Command, sent from the WIA driver
* pValue - VAL structure used for settings
*
*
* Return Value:
*
* Status
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
WIAMICRO_API HRESULT MicroEntry(LONG lCommand, PVAL pValue)
{
HRESULT hr = E_NOTIMPL;
DWORD dwBytesWritten = 0;
INT index = 0;
//#define _DEBUG_COMMANDS
#ifdef _DEBUG_COMMANDS
if(lCommand != CMD_STI_GETSTATUS)
Trace(TEXT("Command Value (%d)"),lCommand);
#endif
if(pValue->pScanInfo == NULL) {
return E_INVALIDARG;
}
switch(lCommand) {
case CMD_INITIALIZE:
hr = S_OK;
//
// create any DeviceIO handles needed, use index (1 - MAX_IO_HANDLES) to store these handles.
// Index '0' is reserved by the WIA flatbed driver. The CreateFile Name is stored in the szVal
// member of the VAL structure.
//
// pValue->pScanInfo->DeviceIOHandles[1] = CreateFileA( pValue->szVal,
// GENERIC_READ | GENERIC_WRITE, // Access mask
// 0, // Share mode
// NULL, // SA
// OPEN_EXISTING, // Create disposition
// FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, // Attributes
// NULL );
//
// if your device supports buttons, create the BUTTON name information here..
//
if(!g_bButtonNamesCreated) {
for(index = 0; index < MAX_BUTTONS; index++){
g_ButtonNames[index] = (WCHAR*)CoTaskMemAlloc(MAX_BUTTON_NAME);
}
hr = GetOLESTRResourceString(IDS_SCAN_BUTTON_NAME,&g_ButtonNames[0],TRUE);
if(SUCCEEDED(hr)){
g_bButtonNamesCreated = TRUE;
}
}
//
// Initialize the scanner's default settings
//
InitScannerDefaults(pValue->pScanInfo);
break;
case CMD_UNINITIALIZE:
//
// close any open handles created by the Micro driver
//
if(pValue->pScanInfo->DeviceIOHandles[1] != NULL){
CloseHandle(pValue->pScanInfo->DeviceIOHandles[1]);
}
//
// if your device supports buttons, free/destroy the BUTTON name information here..
//
if(g_bButtonNamesCreated) {
for(index = 0; index < MAX_BUTTONS; index++){
CoTaskMemFree(g_ButtonNames[index]);
}
}
//
// close/unload libraries
//
hr = S_OK;
break;
case CMD_RESETSCANNER:
//
// reset scanner
//
hr = S_OK;
break;
case CMD_STI_DIAGNOSTIC:
case CMD_STI_DEVICERESET:
//
// reset device
//
hr = S_OK;
break;
case CMD_STI_GETSTATUS:
//
// set status flag to ON-LINE
//
pValue->lVal = MCRO_STATUS_OK;
pValue->pGuid = (GUID*) &GUID_NULL;
//
// button polling support
//
#ifdef BUTTON_SUPPORT
CheckButtonStatus(pValue);
#endif
hr = S_OK;
break;
case CMD_SETXRESOLUTION:
pValue->pScanInfo->Xresolution = pValue->lVal;
hr = S_OK;
break;
case CMD_SETYRESOLUTION:
pValue->pScanInfo->Yresolution = pValue->lVal;
hr = S_OK;
break;
case CMD_SETCONTRAST:
pValue->pScanInfo->Contrast = pValue->lVal;
hr = S_OK;
break;
case CMD_SETINTENSITY:
pValue->pScanInfo->Intensity = pValue->lVal;
hr = S_OK;
break;
case CMD_SETDATATYPE:
pValue->pScanInfo->DataType = pValue->lVal;
hr = S_OK;
break;
case CMD_SETNEGATIVE:
pValue->pScanInfo->Negative = pValue->lVal;
hr = S_OK;
break;
case CMD_GETADFSTATUS:
case CMD_GETADFHASPAPER:
// pValue->lVal = MCRO_ERROR_PAPER_EMPTY;
// hr = S_OK;
break;
case CMD_GET_INTERRUPT_EVENT:
hr = GetInterruptEvent(pValue);
break;
case CMD_GETCAPABILITIES:
pValue->lVal = 0;
pValue->pGuid = NULL;
pValue->ppButtonNames = NULL;
hr = S_OK;
break;
case CMD_SETSCANMODE:
hr = S_OK;
switch(pValue->lVal){
case SCANMODE_FINALSCAN:
Trace(TEXT("Final Scan"));
break;
case SCANMODE_PREVIEWSCAN:
Trace(TEXT("Preview Scan"));
break;
default:
Trace(TEXT("Unknown Scan Mode (%d)"),pValue->lVal);
hr = E_FAIL;
break;
}
break;
case CMD_SETSTIDEVICEHKEY:
ReadRegistryInformation(pValue);
break;
#ifdef _USE_EXTENDED_FORMAT_LIST
// note: MEMORYBMP, and BMP file will be added by wiafbdrv host driver.
// do not include them in your extended list.
//
case CMD_GETSUPPORTEDFILEFORMATS:
g_SupportedFileFormats[0] = WiaImgFmt_JPEG;
pValue->lVal = NUM_SUPPORTED_FILEFORMATS;
pValue->pGuid = g_SupportedFileFormats;
hr = S_OK;
break;
case CMD_GETSUPPORTEDMEMORYFORMATS:
g_SupportedMemoryFormats[0] = WiaImgFmt_TIFF;
g_SupportedMemoryFormats[1] = WiaImgFmt_MYNEWFORMAT;
pValue->lVal = NUM_SUPPORTED_MEMORYFORMATS;
pValue->pGuid = g_SupportedMemoryFormats;
hr = S_OK;
break;
#endif
default:
Trace(TEXT("Unknown Command (%d)"),lCommand);
break;
}
return hr;
}
/**************************************************************************\
* Scan (MicroDriver Entry point)
*
* Called by the WIA driver to acquire data from the MicroDriver.
*
* Arguments:
*
* pScanInfo - SCANINFO structure used for settings
* lPhase - Current Scan phase, SCAN_FIRST, SCAN_NEXT, SCAN_FINISH...
* pBuffer - data buffer to be filled with scanned data
* lLength - Maximum length of pBuffer
* plReceived - Number of actual bytes written to pBuffer.
*
*
* Return Value:
*
* Status
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
WIAMICRO_API HRESULT Scan(PSCANINFO pScanInfo, LONG lPhase, PBYTE pBuffer, LONG lLength, LONG *plReceived)
{
if(pScanInfo == NULL) {
return E_INVALIDARG;
}
INT i = 0;
Trace(TEXT("------ Scan Requesting %d ------"),lLength);
switch (lPhase) {
case SCAN_FIRST:
if (!SetScannerSettings(pScanInfo)) {
return E_FAIL;
}
Trace(TEXT("SCAN_FIRST"));
g_PalIndex = 0;
g_bDown = FALSE;
//
// first phase
//
Trace(TEXT("Start Scan.."));
case SCAN_NEXT: // SCAN_FIRST will fall through to SCAN_NEXT (because it is expecting data)
//
// next phase
//
if(lPhase == SCAN_NEXT)
Trace(TEXT("SCAN_NEXT"));
//
// get data from the scanner and set plReceived value
//
//
// read data
//
switch(pScanInfo->DataType) {
case WIA_DATA_THRESHOLD:
//
// make buffer alternate black/White, for sample 1-bit data
//
memset(pBuffer,0,lLength);
memset(pBuffer,255,lLength/2);
break;
case WIA_DATA_GRAYSCALE:
//
// make buffer grayscale data, for sample 8-bit data
//
if(!g_bDown){
g_PalIndex+=10;
if(g_PalIndex > 255){
g_PalIndex = 255;
g_bDown = TRUE;
}
}
else {
g_PalIndex-=10;
if(g_PalIndex < 0){
g_PalIndex = 0;
g_bDown = FALSE;
}
}
memset(pBuffer,g_PalIndex,lLength);
break;
case WIA_DATA_COLOR:
//
// make buffer red, for sample color data
//
for (i = 0;i+2<lLength;i+=3) {
memset(pBuffer+i,255,1);
memset(pBuffer+(i+1),0,1);
memset(pBuffer+(i+2),0,1);
}
break;
default:
break;
}
//
// test device always returns the exact amount of scanned data
//
*plReceived = lLength;
break;
case SCAN_FINISHED:
default:
Trace(TEXT("SCAN_FINISHED"));
//
// stop scanner, do not set lRecieved, or write any data to pBuffer. Those values
// will be NULL. This lPhase is only to allow you to stop scanning, and return the
// scan head to the HOME position. SCAN_FINISHED will be called always for regular scans, and
// for cancelled scans.
//
break;
}
return S_OK;
}
/**************************************************************************\
* SetPixelWindow (MicroDriver Entry point)
*
* Called by the WIA driver to set the scan selection area to the MicroDriver.
*
* Arguments:
*
* pScanInfo - SCANINFO structure used for settings
* pValue - VAL structure used for settings
* x - X Position of scan rect (upper left x coordinate)
* y - Y Position of scan rect (upper left y coordinate)
* xExtent - Width of scan rect (in pixels)
* yExtent - Height of scan rect (in pixels)
*
*
* Return Value:
*
* Status
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
WIAMICRO_API HRESULT SetPixelWindow(PSCANINFO pScanInfo, LONG x, LONG y, LONG xExtent, LONG yExtent)
{
if(pScanInfo == NULL) {
return E_INVALIDARG;
}
pScanInfo->Window.xPos = x;
pScanInfo->Window.yPos = y;
pScanInfo->Window.xExtent = xExtent;
pScanInfo->Window.yExtent = yExtent;
return S_OK;
}
/**************************************************************************\
* ReadRegistryInformation (helper)
*
* Called by the MicroDriver to Read registry information from the device's
* installed device section. The HKEY passed in will be closed by the host
* driver after CMD_INITIALIZE is completed.
*
* Arguments:
*
* none
*
* Return Value:
*
* void
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
VOID ReadRegistryInformation(PVAL pValue)
{
HKEY hKey = NULL;
if(NULL != pValue->pHandle){
hKey = (HKEY)*pValue->pHandle;
//
// Open DeviceData section to read driver specific information
//
HKEY hOpenKey = NULL;
if (RegOpenKeyEx(hKey, // handle to open key
TEXT("DeviceData"), // address of name of subkey to open
0, // options (must be NULL)
KEY_QUERY_VALUE|KEY_READ, // just want to QUERY a value
&hOpenKey // address of handle to open key
) == ERROR_SUCCESS) {
DWORD dwWritten = sizeof(DWORD);
DWORD dwType = REG_DWORD;
LONG lSampleEntry = 0;
RegQueryValueEx(hOpenKey,
TEXT("Sample Entry"),
NULL,
&dwType,
(LPBYTE)&lSampleEntry,
&dwWritten);
Trace(TEXT("lSampleEntry Value = %d"),lSampleEntry);
} else {
Trace(TEXT("Could not open DeviceData section"));
}
}
}
/**************************************************************************\
* InitScannerDefaults (helper)
*
* Called by the MicroDriver to Initialize the SCANINFO structure
*
* Arguments:
*
* none
*
* Return Value:
*
* void
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
VOID InitScannerDefaults(PSCANINFO pScanInfo)
{
pScanInfo->ADF = 0; // set to no ADF in Test device
pScanInfo->RawDataFormat = WIA_PACKED_PIXEL;
pScanInfo->RawPixelOrder = WIA_ORDER_BGR;
pScanInfo->bNeedDataAlignment = TRUE;
pScanInfo->SupportedCompressionType = 0;
pScanInfo->SupportedDataTypes = SUPPORT_BW|SUPPORT_GRAYSCALE|SUPPORT_COLOR;
pScanInfo->BedWidth = 8500; // 1000's of an inch (WIA compatible unit)
pScanInfo->BedHeight = 11000; // 1000's of an inch (WIA compatible unit)
pScanInfo->OpticalXResolution = 300;
pScanInfo->OpticalYResolution = 300;
pScanInfo->IntensityRange.lMin = -127;
pScanInfo->IntensityRange.lMax = 127;
pScanInfo->IntensityRange.lStep = 1;
pScanInfo->ContrastRange.lMin = -127;
pScanInfo->ContrastRange.lMax = 127;
pScanInfo->ContrastRange.lStep = 1;
// Scanner settings
pScanInfo->Intensity = 0;
pScanInfo->Contrast = 0;
pScanInfo->Xresolution = 150;
pScanInfo->Yresolution = 150;
pScanInfo->Window.xPos = 0;
pScanInfo->Window.yPos = 0;
pScanInfo->Window.xExtent = (pScanInfo->Xresolution * pScanInfo->BedWidth)/1000;
pScanInfo->Window.yExtent = (pScanInfo->Yresolution * pScanInfo->BedHeight)/1000;
// Scanner options
pScanInfo->DitherPattern = 0;
pScanInfo->Negative = 0;
pScanInfo->Mirror = 0;
pScanInfo->AutoBack = 0;
pScanInfo->ColorDitherPattern = 0;
pScanInfo->ToneMap = 0;
pScanInfo->Compression = 0;
// Image Info
pScanInfo->DataType = WIA_DATA_GRAYSCALE;
pScanInfo->WidthPixels = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos);
switch(pScanInfo->DataType) {
case WIA_DATA_THRESHOLD:
pScanInfo->PixelBits = 1;
break;
case WIA_DATA_COLOR:
pScanInfo->PixelBits = 24;
break;
case WIA_DATA_GRAYSCALE:
default:
pScanInfo->PixelBits = 8;
break;
}
pScanInfo->WidthBytes = pScanInfo->Window.xExtent * (pScanInfo->PixelBits/8);
pScanInfo->Lines = pScanInfo->Window.yExtent;
}
/**************************************************************************\
* SetScannerSettings (helper)
*
* Called by the MicroDriver to set the values stored in the SCANINFO structure
* to the actual device.
*
* Arguments:
*
* none
*
*
* Return Value:
*
* TRUE - Success, FALSE - Failure
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
BOOL SetScannerSettings(PSCANINFO pScanInfo)
{
if(pScanInfo->DataType == WIA_DATA_THRESHOLD) {
pScanInfo->PixelBits = 1;
pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/7);
//
// Set data type to device
//
// if the set fails..
// return FALSE;
}
else if(pScanInfo->DataType == WIA_DATA_GRAYSCALE) {
pScanInfo->PixelBits = 8;
pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/8);
//
// Set data type to device
//
// if the set fails..
// return FALSE;
}
else {
pScanInfo->PixelBits = 24;
pScanInfo->WidthBytes = (pScanInfo->Window.xExtent)-(pScanInfo->Window.xPos) * (pScanInfo->PixelBits/8);
//
// Set data type to device
//
// if the set fails..
// return FALSE;
}
#ifdef DEBUG
Trace(TEXT("ScanInfo"));
Trace(TEXT("x res = %d"),pScanInfo->Xresolution);
Trace(TEXT("y res = %d"),pScanInfo->Yresolution);
Trace(TEXT("bpp = %d"),pScanInfo->PixelBits);
Trace(TEXT("xpos = %d"),pScanInfo->Window.xPos);
Trace(TEXT("ypos = %d"),pScanInfo->Window.yPos);
Trace(TEXT("xext = %d"),pScanInfo->Window.xExtent);
Trace(TEXT("yext = %d"),pScanInfo->Window.yExtent);
#endif
//
// send other values to device, use the values set in pScanInfo to set them to your
// device.
//
return TRUE;
}
/**************************************************************************\
* InitializeScanner (helper)
*
* Called by the MicroDriver to Iniitialize any device specific operations
*
* Arguments:
*
* none
*
* Return Value:
*
* TRUE - Success, FALSE - Failure
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
BOOL InitializeScanner(PSCANINFO pScanInfo)
{
HRESULT hr = S_OK;
//
// Do any device initialization here...
// The test device does not need any.
//
if (SUCCEEDED(hr)) {
return TRUE;
}
return FALSE;
}
/**************************************************************************\
* CheckButtonStatus (helper)
*
* Called by the MicroDriver to Set the current Button pressed value.
*
* Arguments:
*
* pValue - VAL structure used for settings
*
*
* Return Value:
*
* VOID
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
VOID CheckButtonStatus(PVAL pValue)
{
//
// Button Polling is done here...
//
//
// Check your device for button presses
//
LONG lButtonValue = 0;
GetButtonPress(&lButtonValue);
switch (lButtonValue) {
case 1:
pValue->pGuid = (GUID*) &guidScanButton;
Trace(TEXT("Scan Button Pressed!"));
break;
default:
pValue->pGuid = (GUID*) &GUID_NULL;
break;
}
}
/**************************************************************************\
* GetInterruptEvent (helper)
*
* Called by the MicroDriver to handle USB interrupt events.
*
* Arguments:
*
* pValue - VAL structure used for settings
*
*
* Return Value:
*
* Status
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
HRESULT GetInterruptEvent(PVAL pValue)
{
//
// Below is a simple example of how DeviceIOControl() can be used to
// determine interrupts with a USB device.
//
// The test device does not support events,
// So this should not be called.
//
BYTE InterruptData;
DWORD dwIndex;
DWORD dwError;
OVERLAPPED Overlapped;
ZeroMemory( &Overlapped, sizeof( Overlapped ));
Overlapped.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
HANDLE hEventArray[2] = {pValue->handle, Overlapped.hEvent};
BOOL fLooping = TRUE;
BOOL bRet = TRUE;
//
// use the Handle created in CMD_INITIALIZE.
//
HANDLE InterruptHandle = pValue->pScanInfo->DeviceIOHandles[1];
while (fLooping) {
//
// Set the wait event, for the interrupt
//
bRet = DeviceIoControl( InterruptHandle,
IOCTL_WAIT_ON_DEVICE_EVENT,
NULL,
0,
&InterruptData,
sizeof(InterruptData),
&dwError,
&Overlapped );
if ( bRet || ( !bRet && ( ::GetLastError() == ERROR_IO_PENDING ))) {
//
// Wait for the event to happen
//
dwIndex = WaitForMultipleObjects( 2,
hEventArray,
FALSE,
INFINITE );
//
// Trap the result of the event
//
switch ( dwIndex ) {
case WAIT_OBJECT_0+1:
DWORD dwBytesRet;
bRet = GetOverlappedResult( InterruptHandle, &Overlapped, &dwBytesRet, FALSE );
if ( dwBytesRet ) {
//
// assign the corresponding button GUID to the *pValue->pGuid
// member., and Set the event.
//
// Change detected - signal
if (*pValue->pHandle != INVALID_HANDLE_VALUE) {
switch ( InterruptData ) {
case 1:
*pValue->pGuid = guidScanButton;
Trace(TEXT("Scan Button Pressed!"));
break;
default:
*pValue->pGuid = GUID_NULL;
break;
}
Trace(TEXT("Setting This Event by Handle %d"),*pValue->pHandle);
//
// signal the event, after a button GUID was assigned.
//
SetEvent(*pValue->pHandle);
}
break;
}
//
// reset the overlapped event
//
ResetEvent( Overlapped.hEvent );
break;
case WAIT_OBJECT_0:
// Fall through
default:
fLooping = FALSE;
}
}
else {
dwError = ::GetLastError();
break;
}
}
return S_OK;
}
/**************************************************************************\
* GetButtonPress (helper)
*
* Called by the MicroDriver to set the actual button value pressed
*
* Arguments:
*
* pButtonValue - actual button pressed
*
*
* Return Value:
*
* Status
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
VOID GetButtonPress(LONG *pButtonValue)
{
//
// This where you can set your button value
//
pButtonValue = 0;
}
/**************************************************************************\
* GetButtonCount (helper)
*
* Called by the MicroDriver to get the number of buttons a device supports
*
* Arguments:
*
* none
*
* Return Value:
*
* LONG - number of supported buttons
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
LONG GetButtonCount()
{
LONG ButtonCount = 0;
//
// Since the test device does not have a button,
// set this value to 0. For a real device with a button,
// set (LONG ButtonCount = 1;)
//
//
// determine the button count of your device
//
return ButtonCount;
}
/**************************************************************************\
* GetOLDSTRResourceString (helper)
*
* Called by the MicroDriver to Load a resource string in OLESTR format
*
* Arguments:
*
* lResourceID - String resource ID
* ppsz - Pointer to a OLESTR to be filled with the loaded string
* value
* bLocal - Possible, other source for loading a resource string.
*
*
* Return Value:
*
* Status
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
HRESULT GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal)
{
HRESULT hr = S_OK;
TCHAR szStringValue[255];
if(bLocal) {
//
// We are looking for a resource in our own private resource file
//
INT NumTCHARs = LoadString(g_hInst,lResourceID,szStringValue,sizeof(szStringValue));
DWORD dwError = GetLastError();
if (NumTCHARs <= 0) {
#ifdef UNICODE
Trace(TEXT("NumTCHARs = %d dwError = %d Resource ID = %d (UNICODE)szString = %ws"),
NumTCHARs,
dwError,
lResourceID,
szStringValue);
#else
Trace(TEXT("NumTCHARs = %d dwError = %d Resource ID = %d (ANSI)szString = %s"),
NumTCHARs,
dwError,
lResourceID,
szStringValue);
#endif
return E_FAIL;
}
//
// NOTE: caller must free this allocated BSTR
//
#ifdef UNICODE
*ppsz = NULL;
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(szStringValue));
if(*ppsz != NULL) {
wcscpy(*ppsz,szStringValue);
} else {
return E_OUTOFMEMORY;
}
#else
WCHAR wszStringValue[255];
ZeroMemory(wszStringValue,sizeof(wszStringValue));
//
// convert szStringValue from char* to unsigned short* (ANSI only)
//
MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
szStringValue,
lstrlenA(szStringValue)+1,
wszStringValue,
(sizeof(wszStringValue)/sizeof(WCHAR)));
*ppsz = NULL;
*ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
if(*ppsz != NULL) {
wcscpy(*ppsz,wszStringValue);
} else {
return E_OUTOFMEMORY;
}
#endif
} else {
//
// looking another place for resources??
//
hr = E_NOTIMPL;
}
return hr;
}
/**************************************************************************\
* Trace
*
* Called by the MicroDriver to output strings to a debugger
*
* Arguments:
*
* format - formatted string to output
*
*
* Return Value:
*
* VOID
*
* History:
*
* 1/20/2000 Original Version
*
\**************************************************************************/
VOID Trace(LPCTSTR format,...)
{
#ifdef DEBUG
TCHAR Buffer[1024];
va_list arglist;
va_start(arglist, format);
wvsprintf(Buffer, format, arglist);
va_end(arglist);
OutputDebugString(Buffer);
OutputDebugString(TEXT("\n"));
#endif
}