|
|
#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
}
|