mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 11:12:47 +00:00
setupapi: Use a handle table to allocate device nodes.
The size of DEVINST is DWORD, so using the pointer directly won't work on 64-bit. Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a3cedc1f3a
commit
f840bcc6f7
|
@ -33,6 +33,7 @@
|
|||
#include "winnls.h"
|
||||
#include "setupapi.h"
|
||||
#include "wine/debug.h"
|
||||
#include "wine/heap.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "cfgmgr32.h"
|
||||
|
@ -140,6 +141,52 @@ struct DeviceInfo
|
|||
struct list interfaces;
|
||||
};
|
||||
|
||||
static struct DeviceInfo **devnode_table;
|
||||
static unsigned int devnode_table_size;
|
||||
|
||||
static DEVINST alloc_devnode(struct DeviceInfo *device)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < devnode_table_size; ++i)
|
||||
{
|
||||
if (!devnode_table[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == devnode_table_size)
|
||||
{
|
||||
if (devnode_table)
|
||||
{
|
||||
devnode_table_size *= 2;
|
||||
devnode_table = heap_realloc_zero(devnode_table,
|
||||
devnode_table_size * sizeof(*devnode_table));
|
||||
}
|
||||
else
|
||||
{
|
||||
devnode_table_size = 256;
|
||||
devnode_table = heap_alloc_zero(devnode_table_size * sizeof(*devnode_table));
|
||||
}
|
||||
}
|
||||
|
||||
devnode_table[i] = device;
|
||||
return i;
|
||||
}
|
||||
|
||||
static void free_devnode(DEVINST devnode)
|
||||
{
|
||||
devnode_table[devnode] = NULL;
|
||||
}
|
||||
|
||||
static struct DeviceInfo *get_devnode_device(DEVINST devnode)
|
||||
{
|
||||
if (devnode < devnode_table_size)
|
||||
return devnode_table[devnode];
|
||||
|
||||
WARN("device node %u not found\n", devnode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
|
||||
{
|
||||
static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-',
|
||||
|
@ -460,15 +507,12 @@ static HKEY SETUPDI_CreateDrvKey(struct DeviceInfo *devInfo)
|
|||
static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(struct DeviceInfoSet *set,
|
||||
DWORD devId, LPCWSTR instanceId, BOOL phantom)
|
||||
{
|
||||
struct DeviceInfo *devInfo = NULL;
|
||||
HANDLE devInst = GlobalAlloc(GMEM_FIXED, sizeof(struct DeviceInfo));
|
||||
if (devInst)
|
||||
devInfo = GlobalLock(devInst);
|
||||
struct DeviceInfo *devInfo = heap_alloc(sizeof(*devInfo));
|
||||
|
||||
if (devInfo)
|
||||
{
|
||||
devInfo->set = set;
|
||||
devInfo->devId = (DWORD)devInst;
|
||||
devInfo->devId = alloc_devnode(devInfo);
|
||||
|
||||
devInfo->instanceId = HeapAlloc(GetProcessHeap(), 0,
|
||||
(lstrlenW(instanceId) + 1) * sizeof(WCHAR));
|
||||
|
@ -486,12 +530,10 @@ static struct DeviceInfo *SETUPDI_AllocateDeviceInfo(struct DeviceInfoSet *set,
|
|||
(LPBYTE)&phantom, sizeof(phantom));
|
||||
}
|
||||
list_init(&devInfo->interfaces);
|
||||
GlobalUnlock(devInst);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalUnlock(devInst);
|
||||
GlobalFree(devInst);
|
||||
heap_free(devInfo);
|
||||
devInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -525,7 +567,8 @@ static void SETUPDI_FreeDeviceInfo(struct DeviceInfo *devInfo)
|
|||
SETUPDI_FreeInterfaceInstances(iface);
|
||||
HeapFree(GetProcessHeap(), 0, iface);
|
||||
}
|
||||
GlobalFree((HANDLE)devInfo->devId);
|
||||
free_devnode(devInfo->devId);
|
||||
heap_free(devInfo);
|
||||
}
|
||||
|
||||
/* Adds a device with GUID guid and identifier devInst to set. Allocates a
|
||||
|
@ -3979,63 +4022,50 @@ BOOL WINAPI SetupDiDeleteDevRegKey(
|
|||
/***********************************************************************
|
||||
* CM_Get_Device_IDA (SETUPAPI.@)
|
||||
*/
|
||||
CONFIGRET WINAPI CM_Get_Device_IDA( DEVINST dnDevInst, PSTR Buffer,
|
||||
ULONG BufferLen, ULONG ulFlags)
|
||||
CONFIGRET WINAPI CM_Get_Device_IDA(DEVINST devnode, char *buffer, ULONG len, ULONG flags)
|
||||
{
|
||||
struct DeviceInfo *devInfo = GlobalLock((HANDLE)dnDevInst);
|
||||
struct DeviceInfo *device = get_devnode_device(devnode);
|
||||
|
||||
TRACE("%x->%p, %p, %u %u\n", dnDevInst, devInfo, Buffer, BufferLen, ulFlags);
|
||||
TRACE("%u, %p, %u, %#x\n", devnode, buffer, len, flags);
|
||||
|
||||
if (!devInfo)
|
||||
if (!device)
|
||||
return CR_NO_SUCH_DEVINST;
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, devInfo->instanceId, -1, Buffer, BufferLen, 0, 0);
|
||||
TRACE("Returning %s\n", debugstr_a(Buffer));
|
||||
WideCharToMultiByte(CP_ACP, 0, device->instanceId, -1, buffer, len, 0, 0);
|
||||
TRACE("Returning %s\n", debugstr_a(buffer));
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CM_Get_Device_IDW (SETUPAPI.@)
|
||||
*/
|
||||
CONFIGRET WINAPI CM_Get_Device_IDW( DEVINST dnDevInst, LPWSTR Buffer,
|
||||
ULONG BufferLen, ULONG ulFlags)
|
||||
CONFIGRET WINAPI CM_Get_Device_IDW(DEVINST devnode, WCHAR *buffer, ULONG len, ULONG flags)
|
||||
{
|
||||
struct DeviceInfo *devInfo = GlobalLock((HANDLE)dnDevInst);
|
||||
struct DeviceInfo *device = get_devnode_device(devnode);
|
||||
|
||||
TRACE("%x->%p, %p, %u %u\n", dnDevInst, devInfo, Buffer, BufferLen, ulFlags);
|
||||
TRACE("%u, %p, %u, %#x\n", devnode, buffer, len, flags);
|
||||
|
||||
if (!devInfo)
|
||||
{
|
||||
WARN("dev instance %d not found!\n", dnDevInst);
|
||||
if (!device)
|
||||
return CR_NO_SUCH_DEVINST;
|
||||
}
|
||||
|
||||
lstrcpynW(Buffer, devInfo->instanceId, BufferLen);
|
||||
TRACE("Returning %s\n", debugstr_w(Buffer));
|
||||
GlobalUnlock((HANDLE)dnDevInst);
|
||||
lstrcpynW(buffer, device->instanceId, len);
|
||||
TRACE("Returning %s\n", debugstr_w(buffer));
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CM_Get_Device_ID_Size (SETUPAPI.@)
|
||||
*/
|
||||
CONFIGRET WINAPI CM_Get_Device_ID_Size( PULONG pulLen, DEVINST dnDevInst,
|
||||
ULONG ulFlags)
|
||||
CONFIGRET WINAPI CM_Get_Device_ID_Size(ULONG *len, DEVINST devnode, ULONG flags)
|
||||
{
|
||||
struct DeviceInfo *ppdevInfo = GlobalLock((HANDLE)dnDevInst);
|
||||
struct DeviceInfo *device = get_devnode_device(devnode);
|
||||
|
||||
TRACE("%x->%p, %p, %u\n", dnDevInst, ppdevInfo, pulLen, ulFlags);
|
||||
TRACE("%p, %u, %#x\n", len, devnode, flags);
|
||||
|
||||
if (!ppdevInfo)
|
||||
{
|
||||
WARN("dev instance %d not found!\n", dnDevInst);
|
||||
if (!device)
|
||||
return CR_NO_SUCH_DEVINST;
|
||||
}
|
||||
|
||||
*pulLen = lstrlenW(ppdevInfo->instanceId);
|
||||
GlobalUnlock((HANDLE)dnDevInst);
|
||||
*len = lstrlenW(device->instanceId);
|
||||
return CR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,11 @@
|
|||
|
||||
extern HINSTANCE SETUPAPI_hInstance DECLSPEC_HIDDEN;
|
||||
|
||||
static inline void * __WINE_ALLOC_SIZE(2) heap_realloc_zero(void *mem, size_t len)
|
||||
{
|
||||
return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, len);
|
||||
}
|
||||
|
||||
static inline WCHAR *strdupW( const WCHAR *str )
|
||||
{
|
||||
WCHAR *ret = NULL;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "winreg.h"
|
||||
#include "guiddef.h"
|
||||
#include "setupapi.h"
|
||||
#include "cfgmgr32.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
|
@ -1355,6 +1356,26 @@ static void testSetupDiGetINFClassA(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void test_devnode(void)
|
||||
{
|
||||
HDEVINFO set;
|
||||
SP_DEVINFO_DATA device = { sizeof(SP_DEVINFO_DATA) };
|
||||
char buffer[50];
|
||||
DWORD ret;
|
||||
|
||||
set = SetupDiGetClassDevsA(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE);
|
||||
ok(set != INVALID_HANDLE_VALUE, "SetupDiGetClassDevs failed: %#x\n", GetLastError());
|
||||
ret = SetupDiCreateDeviceInfoA(set, "Root\\LEGACY_BOGUS\\0000", &guid, NULL,
|
||||
NULL, 0, &device);
|
||||
ok(ret, "SetupDiCreateDeviceInfo failed: %#x\n", GetLastError());
|
||||
|
||||
ret = CM_Get_Device_IDA(device.DevInst, buffer, sizeof(buffer), 0);
|
||||
ok(!ret, "got %#x\n", ret);
|
||||
ok(!strcmp(buffer, "ROOT\\LEGACY_BOGUS\\0000"), "got %s\n", buffer);
|
||||
|
||||
SetupDiDestroyDeviceInfoList(set);
|
||||
}
|
||||
|
||||
START_TEST(devinst)
|
||||
{
|
||||
HKEY hkey;
|
||||
|
@ -1392,4 +1413,5 @@ START_TEST(devinst)
|
|||
testDeviceRegistryPropertyA();
|
||||
testDeviceRegistryPropertyW();
|
||||
testSetupDiGetINFClassA();
|
||||
test_devnode();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue