Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
После установки драйвера устройства WIA служба WIA пытается загрузить его в первый раз. Вызывается метод IStiUSD::Initialize мини-driver WIA, который должен выполнять следующие задачи:
Проверьте режим передачи, чтобы определить намерение вызывающего объекта для инициализации этого драйвера устройства. Для этого вызывается метод IStiDeviceControl::GetMyDeviceOpenMode .
Получите имя порта установленного устройства, чтобы этот драйвер смог вызвать CreateFile (задокументировано в Microsoft Windows SDK) на соответствующем порту для доступа к устройству. Для этого вызывается метод IStiDeviceControl::GetMyDevicePortName .
Чтение параметров реестра для конкретного устройства, записанных во время установки устройства. Это можно сделать с помощью параметра hParametersKey , передаваемого в IStiUSD::Initialize.
Служба WIA вызывает метод IStiUSD::Initialize при первой загрузке драйвера. Метод IStiUSD::Initialize также вызывается, когда клиент использует устаревшие DDIs STI и вызывает метод IStillImage::CreateDevice .
Метод IStiUSD::Initialize должен инициализировать драйвер WIA и устройство для использования. Драйверы WIA могут хранить указатель интерфейса IStiDeviceControl , если он понадобится позже. Перед сохранением этого интерфейса необходимо вызвать метод IStiDeviceControl::AddRef . Если вам не нужно хранить интерфейс, игнорируйте его. Не выпускайте интерфейс IStiDeviceControl, если вы не вызвали IStiDeviceControl::AddRef. Это может привести к непредсказуемым результатам. Com-интерфейс IStiDeviceControl необходим для получения сведений о портах устройства. Имя порта, используемое в вызове функции CreateFile , можно получить, вызвав метод IStiDeviceControl::GetMyDevicePortName . Для устройств с общими портами, таких как устройства с последовательным портом, открывать порт в IStiUSD::Initialize не рекомендуется. Порт должен открываться только в вызовах IStiUSD::LockDevice. Закрытие портов должно контролироваться внутри, чтобы обеспечить быстрый доступ. (Открытие и закрытие в IStiUSD::LockDevice и IStiUSD::UnLockDevice очень неэффективно. CreateFile может привести к задержке, что делает устройство медленным и не отвечает на запросы пользователя.)
Если драйвер WIA не поддерживает несколько вызовов CreateFile на одном порту устройства, следует вызвать метод IStiDeviceControl::GetMyDeviceOpenMode .
Драйвер WIA должен проверка возвращенное значение режима для флага STI_DEVICE_CREATE_DATA и открыть порт соответствующим образом.
Если необходимо открыть порт устройства, следует использовать вызов CreateFile . При открытии порта следует использовать флаг FILE_FLAG_OVERLAPPED. Это позволяет использовать структуру OVERLAPPED (описанную в документации windows SDK) при доступе к устройству. Использование перекрывающихся операций ввода-вывода поможет контролировать быстрый доступ к оборудованию. При обнаружении проблемы драйвер WIA может вызвать CancelIo (описано в документации windows SDK), чтобы остановить доступ ко всему текущему оборудованию.
В следующем примере показана реализация метода IStiUSD::Initialize .
STDMETHODIMP CWIADevice::Initialize(
PSTIDEVICECONTROL pIStiDeviceControl,
DWORD dwStiVersion,
HKEY hParametersKey)
{
if (!pIStiDeviceControl) {
return STIERR_INVALID_PARAM;
}
HRESULT hr = S_OK;
//
// Get the mode of the device to check why we were created. status, data, or both...
//
DWORD dwMode = 0;
hr = pIStiDeviceControl->GetMyDeviceOpenMode(&dwMode);
if(FAILED(hr)){
return hr;
}
if(dwMode & STI_DEVICE_CREATE_DATA)
{
//
// device is being opened for data
//
}
if(dwMode & STI_DEVICE_CREATE_STATUS)
{
//
// device is being opened for status
//
}
if(dwMode & STI_DEVICE_CREATE_BOTH)
{
//
// device is being opened for both data and status
//
}
//
// Get the name of the device port to be used in a call to CreateFile().
//
WCHAR szDevicePortNameW[MAX_PATH];
memset(szDevicePortNameW,0,sizeof(szDevicePortNameW));
hr = pIStiDeviceControl->GetMyDevicePortName(szDevicePortNameW,
sizeof(szDevicePortNameW)/sizeof(WCHAR));
if(FAILED(hr)) {
return hr;
}
//
// Open kernel-mode device driver. Use the FILE_FLAG_OVERLAPPED flag
// for proper cancellation
// of kernel-mode operations and asynchronous file IO.
// The CancelIo() call will function properly if this flag is used.
// It is recommended to use this flag.
//
m_hDeviceDataHandle = CreateFileW(szDevicePortNameW,
GENERIC_READ | GENERIC_WRITE, // Access mask
0, // Share mode
NULL, // SA
OPEN_EXISTING, // Create disposition
FILE_ATTRIBUTE_SYSTEM|FILE_FLAG_OVERLAPPED,
NULL );
m_dwLastOperationError = ::GetLastError();
hr = (m_hDeviceDataHandle != INVALID_HANDLE_VALUE) ?
S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,m_dwLastOperationError);
if (FAILED(hr)) {
return hr;
}
//
// Open DeviceData section to read driver specific information
//
HKEY hKey = hParametersKey;
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) {
//
// This is where you read registry entries for your device.
// The DeviceData section is the proper place to put this
// information. Information about your device should
// have been written using the WIA device's .INF installation
// file.
// You can access this information from this location in the
// Registry. The WIA service owns the hParameters HKEY.
// DO NOT CLOSE THIS KEY. Always close any HKEYS opened by
// this WIA driver after you are finished.
//
//
// close registry key when finished, reading DeviceData information.
//
RegCloseKey(hOpenKey);
} else {
return E_FAIL;
}
return hr;
}
Служба WIA вызывает IStiUSD::GetCapabilities после успешного вызова метода IStiUSD::Initialize . Затем IStiUSD::GetCapabilities предоставляет структуру STI_USD_CAPS с информацией о версии STI, флагами поддержки WIA (битовые флаги, указывающие возможности драйвера) и любыми требованиями к событиям.
В следующем примере показана реализация IStiUSD::GetCapabilities.
/********************************************************************\
* CWIADevice::GetCapabilities
* Remarks:
* This WIA driver sets the following capability flags:
* 1. STI_GENCAP_WIA - This driver supports WIA
* 2. STI_USD_GENCAP_NATIVE_PUSHSUPPORT - This driver supports push
* buttons
* 3. STI_GENCAP_NOTIFICATIONS - This driver requires the use of
* interrupt events.
*
\********************************************************************/
STDMETHODIMP CWIADevice::GetCapabilities(PSTI_USD_CAPS pUsdCaps)
{
//
// If the caller did not pass in the correct parameters,
// then fail the call with E_INVALIDARG.
//
if (!pUsdCaps) {
return E_INVALIDARG;
}
memset(pUsdCaps, 0, sizeof(STI_USD_CAPS));
pUsdCaps->dwVersion = STI_VERSION; // STI version
pUsdCaps->dwGenericCaps = STI_GENCAP_WIA| // WIA support
STI_USD_GENCAP_NATIVE_PUSHSUPPORT| // button support
STI_GENCAP_NOTIFICATIONS; // interrupt event support
return S_OK;
}