STI, device drivers and stuff

Mike McCormack mike at codeweavers.com
Mon Mar 14 08:58:11 CST 2005


Hi Damjan,

Damjan Jovanovic wrote:

> I've started working on implementing STI functionality
> in Wine. STI is a Windows 98/2000 "Still Image"
> capture system, and I'm doing it to get my scanner
> working in Linux.

Fantastic!

> 2. STI has kernel mode components to deal USB / SCSI /
> serial / parallel ports. Is there any attempt to bring
> kernel mode support into Wine (ReactOS/Wine merger?)
> any time soon? If not, should I implement USB support
> using libusb in user-space?

I think that STI support should be done using the Video4Linux API and/or 
the SANE library.  You shouldn't need to think about whether a device is 
a USB device, attached to a parallel port, serial port or anything like 
that.  Let the kernel deal with abstraction of the hardware if 
possible... can the Linux kernel already talk to your scanner?

> 3. Either way, changes need to be made to
> CreateFile(), CloseHandle(), DeviceIoControl(),
> ReadFile() and WriteFile() to accomodate this. What's
> the best way to do this? Do I need to change the Wine
> server, or just Wine's KERNEL32.DLL and/or NT*.DLL
> equivalents?

I don't think you should try to implement scanner support at the driver 
level.  The first step is to figure out how your device accesses the 
scanner, and write a test program that uses the same interface, and can 
read a simple image from it in Windows.  AFAIK, STI devices are accessed 
though sti.StiCreateInstanceA/W() which returns an IStillImageA/W interface.

> 4. Anyone wanna help out?

Sure.  I'm willing to help you build a frame for you to build your code 
in.  I've attached an IDL file for STI that I created a while back.  I 
don't think it compiles any more, but I should be able to fix it up and 
get it submitted.

Mike
-------------- next part --------------
/*
 * Copyright (C) 2004 Mike McCormack
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import "oaidl.idl";

/* encoding neutral interfaces */
/*struct STIDEVICE;
typedef struct STIDEVICE* PSTIDEVICE ;
struct IStillImage;
struct STI;
typedef struct STI *PSTI;

struct STI_DEVICE_INFORMATIONW;
struct STIDEVICEW;

typedef struct IStillImageW IStillImageW,*PSTIW;
typedef struct STIDEVICEW* PSTIDEVICEW;
typedef struct STI_DEVICE_INFORMATIONW *PSTI_DEVICE_INFORMATIONW;

struct STIDEVICEA;

typedef struct IStillImageA IStillImageA,*PSTIA;
typedef struct STIDEVICEA* PSTIDEVICEA;
typedef struct STI_DEVICE_INFORMATIONA *PSTI_DEVICE_INFORMATIONA;

HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD ver, PSTIA *ppSti, void **punk);
HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD ver, PSTIW *ppSti, void **punk);
*/

typedef struct _STI_DEV_CAPS {
    DWORD dwGeneric;
} STI_DEV_CAPS, *PSTI_DEV_CAPS;

typedef struct _STI_DEVICE_STATUS {
    DWORD dwSize;
    DWORD StatusMask;
    DWORD dwOnlineState;
    DWORD dwHardwareStatusCode;
    DWORD dwEventHandlingState;
    DWORD dwPollingInterval;
} STI_DEVICE_STATUS, *PSTI_DEVICE_STATUS;

typedef struct _ERROR_INFOA {
    DWORD dwSize;
    DWORD dwGenericError;
    DWORD dwVendorError;
    CHAR szExtendedErrorText[255];
} STI_ERROR_INFOA, *PSTI_ERROR_INFOA;

typedef struct _ERROR_INFOW {
    DWORD dwSize;
    DWORD dwGenericError;
    DWORD dwVendorError;
    WCHAR szExtendedErrorText[255];
} STI_ERROR_INFOW, *PSTI_ERROR_INFOW;

typedef struct _STI_DIAGA {
    DWORD dwSize;
    DWORD dwBasicDiagCode;
    DWORD dwVendorDiagCode;
    DWORD dwStatusMask;
    STI_ERROR_INFOA sErrorInfo;
} STI_DIAGA, *LPSTI_DIAGA;

typedef struct _STI_DIAGW {
    DWORD dwSize;
    DWORD dwBasicDiagCode;
    DWORD dwVendorDiagCode;
    DWORD dwStatusMask;
    STI_ERROR_INFOW sErrorInfo;
} STI_DIAGW, *LPSTI_DIAGW;

[
  object,
  uuid(6CFA5A80-2DC8-11D0-90EA-00AA0060F86C),
  pointer_default(unique)
]
interface IStiDevice : IUnknown
{
    HRESULT Initialize(HINSTANCE hinst, LPCWSTR pwszDeviceName, DWORD dwVersion, DWORD dwMode);
    HRESULT GetCapabilities(PSTI_DEV_CAPS pDevCaps);
    HRESULT GetStatus(PSTI_DEVICE_STATUS pDevStatus);
    HRESULT DeviceReset();
    HRESULT Diagnostic(LPSTI_DIAG pBuffer);
    HRESULT Escape(STI_RAW_CONTROL EscapeFunction, LPVOID lpInData, DWORD cbInDataSize, LPVOID pOutData, DWORD dwOutDataSize, LPDWORD pdwActualData);
    HRESULT GetLastError(LPDWORD pdwLastDeviceError);
    HRESULT LockDevice(DWORD dwTimeOut);
    HRESULT UnLockDevice();
    HRESULT RawReadData(LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes, LPOVERLAPPED lpOverlapped);
    HRESULT RawWriteData(LPVOID lpBuffer, DWORD nNumberOfBytes, LPOVERLAPPED lpOverlapped);
    HRESULT RawReadCommand(LPVOID lpBuffer, LPDWORD lpdwNumberOfBytes, LPOVERLAPPED lpOverlapped);
    HRESULT RawWriteCommand(LPVOID lpBuffer, DWORD nNumberOfBytes, LPOVERLAPPED lpOverlapped);
    HRESULT Subscribe(LPSTISUBSCRIBE lpSubscribe);
    HRESULT GetLastNotificationData(LPSTINOTIFY lpNotify);
    HRESULT UnSubscribe();
    HRESULT GetLastErrorInfo(STI_ERROR_INFO *pLastErrorInfo);
}

/*****************************************************************************
 * IStillImageW
 */
[
  object,
  uuid(641BD880-2DC8-11D0-90EA-00AA0060F86C),
  pointer_default(unique)
]
interface IStillImageW : IUnknown
{
    HRESULT Initialize(HINSTANCE hinst, DWORD dwVersion);
    HRESULT GetDeviceList(DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID* ppBuffer);
    HRESULT GetDeviceInfo(LPWSTR pwszDeviceName, LPVOID* ppBuffer);
    HRESULT CreateDevice(LPWSTR pwszDeviceName, DWORD dwMode, PSTIDEVICE* pDevice, LPUNKNOWN* punkOuter);
    HRESULT GetDeviceValue(LPWSTR pwszDeviceName, LPWSTR pValueName, LPDWORD pType, LPBYTE pData, LPDWORD cbData);
    HRESULT SetDeviceValue(LPWSTR pwszDeviceName, LPWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData);
    HRESULT GetSTILaunchInformation(LPWSTR pwszDeviceName, LPDWORD pdwEventCode, LPWSTR pwszEventName);
    HRESULT RegisterLaunchApplication(LPWSTR pwszAppName, LPWSTR pwszCommandLine);
    HRESULT UnregisterLaunchApplication(LPWSTR pwszAppName);
    HRESULT EnableHwNotifications(LPCWSTR pwszDeviceName, BOOL bNewState);
    HRESULT GetHwNotificationState(LPCWSTR pwszDeviceName, BOOL* pbCurrentState);
    HRESULT RefreshDeviceBus(LPCWSTR pwszDeviceName);
    HRESULT LaunchApplicationForDevice(LPWSTR pwszDeviceName, LPWSTR pwszAppName, LPSTINOTIFY pStiNotify);
    HRESULT SetupDeviceParameters(PSTI_DEVICE_INFORMATIONW);
    HRESULT WriteToErrorLog(DWORD dwMessageType, LPCWSTR pszMessage);
}


/*****************************************************************************
 * IStillImageA
 */
[
  object,
  uuid(A7B1F740-1D7F-11D1-ACA9-00A02438AD48),
  pointer_default(unique)
]
interface IStillImageA : IUnknown
{
    HRESULT Initialize(HINSTANCE hinst, DWORD dwVersion);
    HRESULT GetDeviceList(DWORD dwType, DWORD dwFlags, DWORD *pdwItemsReturned, LPVOID* ppBuffer);
    HRESULT GetDeviceInfo(LPSTR pwszDeviceName, LPVOID* ppBuffer);
    HRESULT CreateDevice(LPSTR pwszDeviceName, DWORD dwMode, PSTIDEVICE* pDevice, LPUNKNOWN* punkOuter);
    HRESULT GetDeviceValue(LPSTR pwszDeviceName, LPSTR pValueName, LPDWORD pType, LPBYTE pData, LPDWORD cbData);
    HRESULT SetDeviceValue(LPSTR pwszDeviceName, LPSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData);
    HRESULT GetSTILaunchInformation(LPSTR pwszDeviceName, LPDWORD pdwEventCode, LPSTR pwszEventName);
    HRESULT RegisterLaunchApplication(LPSTR pwszAppName, LPSTR pwszCommandLine);
    HRESULT UnregisterLaunchApplication(LPSTR pwszAppName);
    HRESULT EnableHwNotifications(LPCSTR pwszDeviceName, BOOL bNewState);
    HRESULT GetHwNotificationState(LPCSTR pwszDeviceName, BOOL* pbCurrentState);
    HRESULT RefreshDeviceBus(LPWSTR pwszDeviceName);
    HRESULT LaunchApplicationForDevice(LPSTR pwszDeviceName, LPSTR pwszAppName, LPSTINOTIFY pStiNotify);
    HRESULT SetupDeviceParameters(PSTI_DEVICE_INFORMATIONA);
    HRESULT WriteToErrorLog(DWORD dwMessageType, LPCSTR pszMessage);
}




More information about the wine-devel mailing list