diff --git a/dlls/setupapi/Makefile.in b/dlls/setupapi/Makefile.in index db76455ea54..d94b2599c8c 100644 --- a/dlls/setupapi/Makefile.in +++ b/dlls/setupapi/Makefile.in @@ -7,7 +7,7 @@ MODULE = setupapi.dll IMPORTLIB = libsetupapi.$(IMPLIBEXT) IMPORTS = user32 version advapi32 rpcrt4 kernel32 ntdll DELAYIMPORTS = shell32 -EXTRALIBS = $(LIBUNICODE) +EXTRALIBS = $(LIBUNICODE) -luuid C_SRCS = \ devinst.c \ diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index f402f00a794..c4e0bec4f7a 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -68,6 +68,16 @@ static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\', 'C','o','n','t','r','o','l','\\', 'D','e','v','i','c','e','C','l','a','s','s','e','s',0}; +/* is used to identify if a DeviceInfoSet pointer is +valid or not */ +#define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056 + +struct DeviceInfoSet +{ + DWORD magic; /* if is equal to SETUP_DEVICE_INFO_SET_MAGIC struct is okay */ + GUID ClassGuid; + HWND hwndParent; +}; /*********************************************************************** * SetupDiBuildClassInfoList (SETUPAPI.@) @@ -634,6 +644,20 @@ SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid, /*********************************************************************** * SetupDiCreateDeviceInfoListExW (SETUPAPI.@) + * + * Create an empty DeviceInfoSet list. + * + * PARAMS + * ClassGuid [I] if not NULL only devices with GUID ClcassGuid are associated + * with this list. + * hwndParent [I] hwnd needed for interface related actions. + * MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL + * local regestry will be used. + * Reserved [I] must be NULL + * + * RETURNS + * Success: empty list. + * Failure: INVALID_HANDLE_VALUE. */ HDEVINFO WINAPI SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, @@ -641,8 +665,39 @@ SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, PCWSTR MachineName, PVOID Reserved) { - FIXME("\n"); - return (HDEVINFO)INVALID_HANDLE_VALUE; + struct DeviceInfoSet *list = NULL; + DWORD size = sizeof(struct DeviceInfoSet); + + TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent, + debugstr_w(MachineName), Reserved); + + if (MachineName != NULL) + { + FIXME("remote support is not implemented"); + SetLastError(ERROR_INVALID_MACHINENAME); + return (HDEVINFO)INVALID_HANDLE_VALUE; + } + + if (Reserved != NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return (HDEVINFO)INVALID_HANDLE_VALUE; + } + + list = HeapAlloc(GetProcessHeap(), 0, size); + if (!list) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return (HDEVINFO)INVALID_HANDLE_VALUE; + } + + list->magic = SETUP_DEVICE_INFO_SET_MAGIC; + list->hwndParent = hwndParent; + memcpy(&list->ClassGuid, + ClassGuid ? ClassGuid : &GUID_NULL, + sizeof(list->ClassGuid)); + + return (HDEVINFO)list; } /*********************************************************************** @@ -887,91 +942,6 @@ end: return ret; } -#define SETUP_SERIAL_PORT_MAGIC 0xd00ff055 - -typedef struct _SerialPortName -{ - WCHAR name[5]; -} SerialPortName; - -typedef struct _SerialPortList -{ - DWORD magic; - UINT numPorts; - SerialPortName names[1]; -} SerialPortList; - -static HDEVINFO SETUP_CreateSerialDeviceList(void) -{ - static const size_t initialSize = 100; - size_t size; - WCHAR buf[initialSize]; - LPWSTR devices; - HDEVINFO ret; - BOOL failed = FALSE; - - devices = buf; - size = initialSize; - do { - if (QueryDosDeviceW(NULL, devices, size) == 0) - { - if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - size *= 2; - if (devices != buf) - HeapFree(GetProcessHeap(), 0, devices); - devices = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR)); - if (!devices) - failed = TRUE; - else - *devices = 0; - } - else - failed = TRUE; - } - } while (!*devices && !failed); - if (!failed) - { - static const WCHAR comW[] = { 'C','O','M',0 }; - LPWSTR ptr; - UINT numSerialPorts = 0; - SerialPortList *list; - - for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1) - { - if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1)) - numSerialPorts++; - } - list = HeapAlloc(GetProcessHeap(), 0, sizeof(SerialPortList) + - numSerialPorts ? (numSerialPorts - 1) * sizeof(SerialPortName) : 0); - if (list) - { - list->magic = SETUP_SERIAL_PORT_MAGIC; - list->numPorts = 0; - for (ptr = devices; *ptr; ptr += strlenW(ptr) + 1) - { - if (!strncmpW(comW, ptr, sizeof(comW) / sizeof(comW[0]) - 1)) - { - lstrcpynW(list->names[list->numPorts].name, ptr, - sizeof(list->names[list->numPorts].name) / - sizeof(list->names[list->numPorts].name[0])); - TRACE("Adding %s to list\n", - debugstr_w(list->names[list->numPorts].name)); - list->numPorts++; - } - } - TRACE("list->numPorts is %d\n", list->numPorts); - } - ret = (HDEVINFO)list; - } - else - ret = (HDEVINFO)INVALID_HANDLE_VALUE; - if (devices != buf) - HeapFree(GetProcessHeap(), 0, devices); - TRACE("returning %p\n", ret); - return ret; -} - /*********************************************************************** * SetupDiGetClassDevsW (SETUPAPI.@) */ @@ -993,12 +963,7 @@ HDEVINFO WINAPI SetupDiGetClassDevsW( FIXME(": unimplemented for DIGCF_ALLCLASSES\n"); else { - if (IsEqualIID(class, &GUID_DEVINTERFACE_COMPORT)) - ret = SETUP_CreateSerialDeviceList(); - else if (IsEqualIID(class, &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR)) - ret = SETUP_CreateSerialDeviceList(); - else - FIXME("(%s): stub\n", debugstr_guid(class)); + FIXME("(%s): stub\n", debugstr_guid(class)); } return ret; } @@ -1015,50 +980,24 @@ BOOL WINAPI SetupDiEnumDeviceInterfaces( { BOOL ret = FALSE; - TRACE("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData, + FIXME("%p, %p, %s, 0x%08lx, %p\n", DeviceInfoSet, DeviceInfoData, debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData); - if (!DeviceInterfaceData) - SetLastError(ERROR_INVALID_PARAMETER); - else if (DeviceInfoData) - FIXME(": unimplemented with PSP_DEVINFO_DATA set\n"); - else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE) - { - /* FIXME: this assumes the only possible enumeration is of serial - * ports. - */ - SerialPortList *list = (SerialPortList *)DeviceInfoSet; - if (list->magic == SETUP_SERIAL_PORT_MAGIC) - { - if (MemberIndex >= list->numPorts) - SetLastError(ERROR_NO_MORE_ITEMS); - else - { - DeviceInterfaceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - memcpy(&DeviceInterfaceData->InterfaceClassGuid, - &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, - sizeof(DeviceInterfaceData->InterfaceClassGuid)); - DeviceInterfaceData->Flags = 0; - /* Note: this appears to be dangerous, passing a private - * pointer a heap-allocated datum to the caller. However, the - * expected lifetime of the device data is the same as the - * HDEVINFO; once that is closed, the data are no longer valid. - */ - DeviceInterfaceData->Reserved = - (ULONG_PTR)&list->names[MemberIndex].name; - ret = TRUE; - } - } - else - SetLastError(ERROR_INVALID_HANDLE); - } - else - SetLastError(ERROR_INVALID_HANDLE); + SetLastError(ERROR_INVALID_HANDLE); return ret; } /*********************************************************************** * SetupDiDestroyDeviceInfoList (SETUPAPI.@) + * + * Destroy a DeviceInfoList and free all used memory of the list. + * + * PARAMS + * devinfo [I] DeviceInfoList pointer to list to destroy + * + * RETURNS + * Success: non zero value. + * Failure: zero value. */ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo) { @@ -1067,21 +1006,18 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo) TRACE("%p\n", devinfo); if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE) { - /* FIXME: this assumes the only possible enumeration is of serial - * ports. - */ - SerialPortList *list = (SerialPortList *)devinfo; + struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo; - if (list->magic == SETUP_SERIAL_PORT_MAGIC) + if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC) { HeapFree(GetProcessHeap(), 0, list); ret = TRUE; } - else - SetLastError(ERROR_INVALID_HANDLE); } - else + + if (ret == FALSE) SetLastError(ERROR_INVALID_HANDLE); + return ret; } @@ -1098,64 +1034,11 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( { BOOL ret = FALSE; - TRACE("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet, + FIXME("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet, DeviceInterfaceData, DeviceInterfaceDetailData, DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData); - if (!DeviceInterfaceData) - SetLastError(ERROR_INVALID_PARAMETER); - else if ((DeviceInterfaceDetailDataSize && !DeviceInterfaceDetailData) || - (DeviceInterfaceDetailData && !DeviceInterfaceDetailDataSize)) - SetLastError(ERROR_INVALID_PARAMETER); - else if (DeviceInfoSet && DeviceInfoSet != (HDEVINFO)INVALID_HANDLE_VALUE) - { - /* FIXME: this assumes the only possible enumeration is of serial - * ports. - */ - SerialPortList *list = (SerialPortList *)DeviceInfoSet; - if (list->magic == SETUP_SERIAL_PORT_MAGIC) - { - LPCWSTR devName = (LPCWSTR)DeviceInterfaceData->Reserved; - DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A) + - lstrlenW(devName); - - if (sizeRequired > DeviceInterfaceDetailDataSize) - { - SetLastError(ERROR_INSUFFICIENT_BUFFER); - if (RequiredSize) - *RequiredSize = sizeRequired; - } - else - { - LPSTR dst = DeviceInterfaceDetailData->DevicePath; - LPCWSTR src = devName; - - /* MSDN claims cbSize must be set by the caller, but it lies */ - DeviceInterfaceDetailData->cbSize = - sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); - for ( ; *src; src++, dst++) - *dst = *src; - *dst = '\0'; - TRACE("DevicePath is %s\n", - debugstr_a(DeviceInterfaceDetailData->DevicePath)); - if (DeviceInfoData) - { - DeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA); - memcpy(&DeviceInfoData->ClassGuid, - &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR, - sizeof(DeviceInfoData->ClassGuid)); - DeviceInfoData->DevInst = 0; - DeviceInfoData->Reserved = (ULONG_PTR)devName; - } - ret = TRUE; - } - } - else - SetLastError(ERROR_INVALID_HANDLE); - } - else - SetLastError(ERROR_INVALID_HANDLE); - TRACE("Returning %d\n", ret); + SetLastError(ERROR_INVALID_HANDLE); return ret; } diff --git a/dlls/setupapi/tests/.gitignore b/dlls/setupapi/tests/.gitignore index de7fd7fa6a0..1e161bdac35 100644 --- a/dlls/setupapi/tests/.gitignore +++ b/dlls/setupapi/tests/.gitignore @@ -1,4 +1,5 @@ Makefile +devinst.ok parser.ok query.ok stringtable.ok diff --git a/dlls/setupapi/tests/Makefile.in b/dlls/setupapi/tests/Makefile.in index 7730f688b28..1928194a761 100644 --- a/dlls/setupapi/tests/Makefile.in +++ b/dlls/setupapi/tests/Makefile.in @@ -6,6 +6,7 @@ TESTDLL = setupapi.dll IMPORTS = setupapi kernel32 CTESTS = \ + devinst.c \ parser.c \ query.c \ stringtable.c diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c new file mode 100644 index 00000000000..ad4aea0c1c6 --- /dev/null +++ b/dlls/setupapi/tests/devinst.c @@ -0,0 +1,69 @@ +/* + * Devinst tests + * + * Copyright 2006 Christian Gmeiner + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "setupapi.h" + +#include "wine/test.h" + + +static void test_Device_Info_List(void) +{ + HDEVINFO devlist; + BOOL ret; + DWORD error; + static const WCHAR machine[] = { 'd','u','m','m','y',0 }; + + SetLastError(0xdeadbeef); + /* create empty DeviceInfoList, but set Reserved to a value, which is not NULL */ + devlist = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, "NotNull"); + + error = GetLastError(); + ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %ld (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE); + ok(error == ERROR_INVALID_PARAMETER, "GetLastError returned wrong value : %ld, (expected %d)", error, ERROR_INVALID_PARAMETER); + + SetLastError(0xdeadbeef); + /* create empty DeviceInfoList, but set MachineName to something */ + devlist = SetupDiCreateDeviceInfoListExW(NULL, NULL, machine, NULL); + + error = GetLastError(); + ok(devlist == INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %ld (expected %p)\n", devlist, error, INVALID_HANDLE_VALUE); + ok(error == ERROR_INVALID_MACHINENAME, "GetLastError returned wrong value : %ld, (expected %d)", error, ERROR_INVALID_MACHINENAME); + + /* create empty DeviceInfoList */ + devlist = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); + ok(devlist && devlist != INVALID_HANDLE_VALUE, "SetupDiCreateDeviceInfoListExW failed : %p %ld (expected != %p)\n", devlist, error, INVALID_HANDLE_VALUE); + + /* destroy DeviceInfoList */ + ret = SetupDiDestroyDeviceInfoList(devlist); + ok(ret, "SetupDiDestroyDeviceInfoList failed : %ld", error); +} + +START_TEST(devinst) +{ + test_Device_Info_List(); +}