Files
EF3-Interface/PcDmis/ThirdParty/UsbSupport/libusb-win32-src-1.2.4.0/src/driver/driver_registry.c
T
2013-05-09 20:29:54 +08:00

276 lines
7.9 KiB
C

/* libusb-win32, Generic Windows USB Library
* Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "libusb_driver.h"
/* missing in mingw's ddk headers */
#ifndef PLUGPLAY_REGKEY_DEVICE
#define PLUGPLAY_REGKEY_DEVICE 1
#endif
#define LIBUSB_REG_SURPRISE_REMOVAL_OK L"SurpriseRemovalOK"
#define LIBUSB_REG_INITIAL_CONFIG_VALUE L"InitialConfigValue"
static bool_t reg_get_property(DEVICE_OBJECT *physical_device_object,
int property, char *data, int size);
static bool_t reg_get_property(DEVICE_OBJECT *physical_device_object,
int property, char *data, int size)
{
WCHAR tmp[512];
ULONG ret;
ULONG i;
if (!physical_device_object || !data || !size)
{
return FALSE;
}
memset(data, 0, size);
memset(tmp, 0, sizeof(tmp));
if (NT_SUCCESS(IoGetDeviceProperty(physical_device_object,
property,
sizeof(tmp) - 2,
tmp,
&ret)) && ret)
{
/* convert unicode string to normal character string */
for (i = 0; (i < ret/2) && (i < ((ULONG)size - 1)); i++)
{
data[i] = (char)tmp[i];
}
_strlwr(data);
return TRUE;
}
return FALSE;
}
bool_t reg_get_properties(libusb_device_t *dev)
{
HANDLE key = NULL;
PVOID keyObject = NULL;
NTSTATUS status;
UNICODE_STRING surprise_removal_ok_name;
UNICODE_STRING initial_config_value_name;
KEY_VALUE_FULL_INFORMATION *info;
ULONG pool_length;
ULONG length;
ULONG val;
if (!dev->physical_device_object)
{
return FALSE;
}
/* default settings */
dev->surprise_removal_ok = FALSE;
dev->is_filter = TRUE;
dev->initial_config_value = SET_CONFIG_ACTIVE_CONFIG;
status = IoOpenDeviceRegistryKey(dev->physical_device_object,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_ALL,
&key);
if (NT_SUCCESS(status))
{
RtlInitUnicodeString(&surprise_removal_ok_name,
LIBUSB_REG_SURPRISE_REMOVAL_OK);
RtlInitUnicodeString(&initial_config_value_name,
LIBUSB_REG_INITIAL_CONFIG_VALUE);
pool_length = sizeof(KEY_VALUE_FULL_INFORMATION) + 512;
info = ExAllocatePool(NonPagedPool, pool_length);
if (!info)
{
ZwClose(key);
USBERR("ExAllocatePool failed allocating %d bytes\n", pool_length);
return FALSE;
}
// get surprise_removal_ok
// get is_filter
length = pool_length;
memset(info, 0, length);
status = ZwQueryValueKey(key, &surprise_removal_ok_name,
KeyValueFullInformation, info, length, &length);
if (NT_SUCCESS(status) && (info->Type == REG_DWORD))
{
val = *((ULONG *)(((char *)info) + info->DataOffset));
dev->surprise_removal_ok = val ? TRUE : FALSE;
dev->is_filter = FALSE;
}
// get initial_config_value
length = pool_length;
memset(info, 0, length);
status = ZwQueryValueKey(key, &initial_config_value_name,
KeyValueFullInformation, info, length, &length);
if (NT_SUCCESS(status) && (info->Type == REG_DWORD))
{
val = *((ULONG *)(((char *)info) + info->DataOffset));
dev->initial_config_value = (int)val;
}
status = ObReferenceObjectByHandle(key, KEY_READ, NULL, KernelMode, &keyObject, NULL);
if (NT_SUCCESS(status))
{
length = pool_length;
memset(info, 0, length);
status = ObQueryNameString(keyObject, (POBJECT_NAME_INFORMATION)info, length, &length);
if (NT_SUCCESS(status))
{
PWSTR nameW =((POBJECT_NAME_INFORMATION)info)->Name.Buffer;
PSTR nameA = dev->objname_plugplay_registry_key;
val=0;
while (nameW[val] && val < (length/2))
{
*nameA=(char)nameW[val];
nameA++;
val++;
}
*nameA='\0';
USBDBG("reg-key-name=%s\n",dev->objname_plugplay_registry_key);
}
else
{
USBERR("ObQueryNameString failed. status=%Xh\n",status);
}
ObDereferenceObject(keyObject);
}
else
{
USBERR("ObReferenceObjectByHandle failed. status=%Xh\n",status);
}
ExFreePool(info);
ZwClose(key);
}
return TRUE;
}
bool_t reg_get_hardware_id(DEVICE_OBJECT *physical_device_object,
char *data, int size)
{
if (!physical_device_object || !data || !size)
{
return FALSE;
}
return reg_get_property(physical_device_object, DevicePropertyHardwareID,
data, size);
}
bool_t reg_get_compatible_id(DEVICE_OBJECT *physical_device_object,
char *data, int size)
{
if (!physical_device_object || !data || !size)
{
return FALSE;
}
return reg_get_property(physical_device_object, DevicePropertyCompatibleIDs,
data, size);
}
/*
Gets a device property for the device_object.
Returns: NTSTATUS code from IoGetDeviceProperty
STATUS_INVALID_PARAMETER
*/
NTSTATUS reg_get_device_property(PDEVICE_OBJECT device_object,
int property,
char* data_buffer,
int data_length,
int* actual_length)
{
NTSTATUS status = STATUS_INVALID_PARAMETER;
if (!device_object || !data_buffer || !data_length || !actual_length)
return status;
// clear data
memset(data_buffer, 0, data_length);
*actual_length=0;
// get device property
status = IoGetDeviceProperty(
device_object, property, data_length, data_buffer, (PULONG)actual_length);
return status;
}
/*
Gets a property from the device registry key of the device_object.
Returns: NTSTATUS from ZwQueryValueKey
NTSTATUS from IoOpenDeviceRegistryKey if the device registry
key could not be opened.
*/
NTSTATUS reg_get_custom_property(PDEVICE_OBJECT device_object,
char *data_buffer,
unsigned int data_length,
unsigned int name_offset,
int* actual_length)
{
HANDLE key = NULL;
NTSTATUS status;
UNICODE_STRING name;
KEY_VALUE_FULL_INFORMATION *info;
ULONG length;
status = IoOpenDeviceRegistryKey(device_object, PLUGPLAY_REGKEY_DEVICE, KEY_READ, &key);
if (NT_SUCCESS(status))
{
RtlInitUnicodeString(&name, (WCHAR*)(&data_buffer[name_offset]));
length = sizeof(KEY_VALUE_FULL_INFORMATION) + name.MaximumLength + data_length;
info = ExAllocatePool(NonPagedPool, length);
if (info)
{
memset(info, 0, length);
status = ZwQueryValueKey(key, &name, KeyValueFullInformation, info, length, &length);
if (NT_SUCCESS(status))
{
data_length = (info->DataLength > data_length) ? data_length : info->DataLength;
memcpy(data_buffer, (((char *)info) + info->DataOffset),data_length);
*actual_length=data_length;
}
ExFreePool(info);
}
ZwClose(key);
}
return status;
}