| /* |
| * SetupAPI device installer |
| * |
| * Copyright 2000 Andreas Mohr for CodeWeavers |
| * |
| * 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 "config.h" |
| #include "wine/port.h" |
| |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winnt.h" |
| #include "winreg.h" |
| #include "winternl.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winnls.h" |
| #include "setupapi.h" |
| #include "wine/debug.h" |
| #include "wine/unicode.h" |
| #include "cfgmgr32.h" |
| #include "initguid.h" |
| #include "winioctl.h" |
| #include "rpc.h" |
| #include "rpcdce.h" |
| |
| #include "setupapi_private.h" |
| |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(setupapi); |
| |
| /* Unicode constants */ |
| static const WCHAR ClassGUID[] = {'C','l','a','s','s','G','U','I','D',0}; |
| static const WCHAR Class[] = {'C','l','a','s','s',0}; |
| static const WCHAR ClassInstall32[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0}; |
| static const WCHAR NoDisplayClass[] = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0}; |
| static const WCHAR NoInstallClass[] = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0}; |
| static const WCHAR NoUseClass[] = {'N','o','U','s','e','C','l','a','s','s',0}; |
| static const WCHAR NtExtension[] = {'.','N','T',0}; |
| static const WCHAR NtPlatformExtension[] = {'.','N','T','x','8','6',0}; |
| static const WCHAR Version[] = {'V','e','r','s','i','o','n',0}; |
| static const WCHAR WinExtension[] = {'.','W','i','n',0}; |
| |
| /* Registry key and value names */ |
| static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\', |
| 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', |
| 'C','o','n','t','r','o','l','\\', |
| 'C','l','a','s','s',0}; |
| |
| static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\', |
| 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\', |
| '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.@) |
| * |
| * Returns a list of setup class GUIDs that identify the classes |
| * that are installed on a local machine. |
| * |
| * PARAMS |
| * Flags [I] control exclusion of classes from the list. |
| * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs. |
| * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList). |
| * RequiredSize [O] pointer, which receives the number of GUIDs that are returned. |
| * |
| * RETURNS |
| * Success: TRUE. |
| * Failure: FALSE. |
| */ |
| BOOL WINAPI SetupDiBuildClassInfoList( |
| DWORD Flags, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize) |
| { |
| TRACE("\n"); |
| return SetupDiBuildClassInfoListExW(Flags, ClassGuidList, |
| ClassGuidListSize, RequiredSize, |
| NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiBuildClassInfoListExA (SETUPAPI.@) |
| * |
| * Returns a list of setup class GUIDs that identify the classes |
| * that are installed on a local or remote macine. |
| * |
| * PARAMS |
| * Flags [I] control exclusion of classes from the list. |
| * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs. |
| * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList). |
| * RequiredSize [O] pointer, which receives the number of GUIDs that are returned. |
| * MachineName [I] name of a remote machine. |
| * Reserved [I] must be NULL. |
| * |
| * RETURNS |
| * Success: TRUE. |
| * Failure: FALSE. |
| */ |
| BOOL WINAPI SetupDiBuildClassInfoListExA( |
| DWORD Flags, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize, |
| LPCSTR MachineName, |
| PVOID Reserved) |
| { |
| LPWSTR MachineNameW = NULL; |
| BOOL bResult; |
| |
| TRACE("\n"); |
| |
| if (MachineName) |
| { |
| MachineNameW = MultiByteToUnicode(MachineName, CP_ACP); |
| if (MachineNameW == NULL) return FALSE; |
| } |
| |
| bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList, |
| ClassGuidListSize, RequiredSize, |
| MachineNameW, Reserved); |
| |
| MyFree(MachineNameW); |
| |
| return bResult; |
| } |
| |
| /*********************************************************************** |
| * SetupDiBuildClassInfoListExW (SETUPAPI.@) |
| * |
| * Returns a list of setup class GUIDs that identify the classes |
| * that are installed on a local or remote macine. |
| * |
| * PARAMS |
| * Flags [I] control exclusion of classes from the list. |
| * ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs. |
| * ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList). |
| * RequiredSize [O] pointer, which receives the number of GUIDs that are returned. |
| * MachineName [I] name of a remote machine. |
| * Reserved [I] must be NULL. |
| * |
| * RETURNS |
| * Success: TRUE. |
| * Failure: FALSE. |
| */ |
| BOOL WINAPI SetupDiBuildClassInfoListExW( |
| DWORD Flags, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize, |
| LPCWSTR MachineName, |
| PVOID Reserved) |
| { |
| WCHAR szKeyName[40]; |
| HKEY hClassesKey; |
| HKEY hClassKey; |
| DWORD dwLength; |
| DWORD dwIndex; |
| LONG lError; |
| DWORD dwGuidListIndex = 0; |
| |
| TRACE("\n"); |
| |
| if (RequiredSize != NULL) |
| *RequiredSize = 0; |
| |
| hClassesKey = SetupDiOpenClassRegKeyExW(NULL, |
| KEY_ALL_ACCESS, |
| DIOCR_INSTALLER, |
| MachineName, |
| Reserved); |
| if (hClassesKey == INVALID_HANDLE_VALUE) |
| { |
| return FALSE; |
| } |
| |
| for (dwIndex = 0; ; dwIndex++) |
| { |
| dwLength = 40; |
| lError = RegEnumKeyExW(hClassesKey, |
| dwIndex, |
| szKeyName, |
| &dwLength, |
| NULL, |
| NULL, |
| NULL, |
| NULL); |
| TRACE("RegEnumKeyExW() returns %d\n", lError); |
| if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA) |
| { |
| TRACE("Key name: %p\n", szKeyName); |
| |
| if (RegOpenKeyExW(hClassesKey, |
| szKeyName, |
| 0, |
| KEY_ALL_ACCESS, |
| &hClassKey)) |
| { |
| RegCloseKey(hClassesKey); |
| return FALSE; |
| } |
| |
| if (!RegQueryValueExW(hClassKey, |
| NoUseClass, |
| NULL, |
| NULL, |
| NULL, |
| NULL)) |
| { |
| TRACE("'NoUseClass' value found!\n"); |
| RegCloseKey(hClassKey); |
| continue; |
| } |
| |
| if ((Flags & DIBCI_NOINSTALLCLASS) && |
| (!RegQueryValueExW(hClassKey, |
| NoInstallClass, |
| NULL, |
| NULL, |
| NULL, |
| NULL))) |
| { |
| TRACE("'NoInstallClass' value found!\n"); |
| RegCloseKey(hClassKey); |
| continue; |
| } |
| |
| if ((Flags & DIBCI_NODISPLAYCLASS) && |
| (!RegQueryValueExW(hClassKey, |
| NoDisplayClass, |
| NULL, |
| NULL, |
| NULL, |
| NULL))) |
| { |
| TRACE("'NoDisplayClass' value found!\n"); |
| RegCloseKey(hClassKey); |
| continue; |
| } |
| |
| RegCloseKey(hClassKey); |
| |
| TRACE("Guid: %p\n", szKeyName); |
| if (dwGuidListIndex < ClassGuidListSize) |
| { |
| if (szKeyName[0] == '{' && szKeyName[37] == '}') |
| { |
| szKeyName[37] = 0; |
| } |
| TRACE("Guid: %p\n", &szKeyName[1]); |
| |
| UuidFromStringW(&szKeyName[1], |
| &ClassGuidList[dwGuidListIndex]); |
| } |
| |
| dwGuidListIndex++; |
| } |
| |
| if (lError != ERROR_SUCCESS) |
| break; |
| } |
| |
| RegCloseKey(hClassesKey); |
| |
| if (RequiredSize != NULL) |
| *RequiredSize = dwGuidListIndex; |
| |
| if (ClassGuidListSize < dwGuidListIndex) |
| { |
| SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassGuidsFromNameA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassGuidsFromNameA( |
| LPCSTR ClassName, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize) |
| { |
| return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList, |
| ClassGuidListSize, RequiredSize, |
| NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassGuidsFromNameW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassGuidsFromNameW( |
| LPCWSTR ClassName, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize) |
| { |
| return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList, |
| ClassGuidListSize, RequiredSize, |
| NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassGuidsFromNameExA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassGuidsFromNameExA( |
| LPCSTR ClassName, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize, |
| LPCSTR MachineName, |
| PVOID Reserved) |
| { |
| LPWSTR ClassNameW = NULL; |
| LPWSTR MachineNameW = NULL; |
| BOOL bResult; |
| |
| FIXME("\n"); |
| |
| ClassNameW = MultiByteToUnicode(ClassName, CP_ACP); |
| if (ClassNameW == NULL) |
| return FALSE; |
| |
| if (MachineName) |
| { |
| MachineNameW = MultiByteToUnicode(MachineName, CP_ACP); |
| if (MachineNameW == NULL) |
| { |
| MyFree(ClassNameW); |
| return FALSE; |
| } |
| } |
| |
| bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList, |
| ClassGuidListSize, RequiredSize, |
| MachineNameW, Reserved); |
| |
| MyFree(MachineNameW); |
| MyFree(ClassNameW); |
| |
| return bResult; |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassGuidsFromNameExW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassGuidsFromNameExW( |
| LPCWSTR ClassName, |
| LPGUID ClassGuidList, |
| DWORD ClassGuidListSize, |
| PDWORD RequiredSize, |
| LPCWSTR MachineName, |
| PVOID Reserved) |
| { |
| WCHAR szKeyName[40]; |
| WCHAR szClassName[256]; |
| HKEY hClassesKey; |
| HKEY hClassKey; |
| DWORD dwLength; |
| DWORD dwIndex; |
| LONG lError; |
| DWORD dwGuidListIndex = 0; |
| |
| if (RequiredSize != NULL) |
| *RequiredSize = 0; |
| |
| hClassesKey = SetupDiOpenClassRegKeyExW(NULL, |
| KEY_ALL_ACCESS, |
| DIOCR_INSTALLER, |
| MachineName, |
| Reserved); |
| if (hClassesKey == INVALID_HANDLE_VALUE) |
| { |
| return FALSE; |
| } |
| |
| for (dwIndex = 0; ; dwIndex++) |
| { |
| dwLength = 40; |
| lError = RegEnumKeyExW(hClassesKey, |
| dwIndex, |
| szKeyName, |
| &dwLength, |
| NULL, |
| NULL, |
| NULL, |
| NULL); |
| TRACE("RegEnumKeyExW() returns %d\n", lError); |
| if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA) |
| { |
| TRACE("Key name: %p\n", szKeyName); |
| |
| if (RegOpenKeyExW(hClassesKey, |
| szKeyName, |
| 0, |
| KEY_ALL_ACCESS, |
| &hClassKey)) |
| { |
| RegCloseKey(hClassesKey); |
| return FALSE; |
| } |
| |
| dwLength = 256 * sizeof(WCHAR); |
| if (!RegQueryValueExW(hClassKey, |
| Class, |
| NULL, |
| NULL, |
| (LPBYTE)szClassName, |
| &dwLength)) |
| { |
| TRACE("Class name: %p\n", szClassName); |
| |
| if (strcmpiW(szClassName, ClassName) == 0) |
| { |
| TRACE("Found matching class name\n"); |
| |
| TRACE("Guid: %p\n", szKeyName); |
| if (dwGuidListIndex < ClassGuidListSize) |
| { |
| if (szKeyName[0] == '{' && szKeyName[37] == '}') |
| { |
| szKeyName[37] = 0; |
| } |
| TRACE("Guid: %p\n", &szKeyName[1]); |
| |
| UuidFromStringW(&szKeyName[1], |
| &ClassGuidList[dwGuidListIndex]); |
| } |
| |
| dwGuidListIndex++; |
| } |
| } |
| |
| RegCloseKey(hClassKey); |
| } |
| |
| if (lError != ERROR_SUCCESS) |
| break; |
| } |
| |
| RegCloseKey(hClassesKey); |
| |
| if (RequiredSize != NULL) |
| *RequiredSize = dwGuidListIndex; |
| |
| if (ClassGuidListSize < dwGuidListIndex) |
| { |
| SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassNameFromGuidA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassNameFromGuidA( |
| const GUID* ClassGuid, |
| PSTR ClassName, |
| DWORD ClassNameSize, |
| PDWORD RequiredSize) |
| { |
| return SetupDiClassNameFromGuidExA(ClassGuid, ClassName, |
| ClassNameSize, RequiredSize, |
| NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassNameFromGuidW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassNameFromGuidW( |
| const GUID* ClassGuid, |
| PWSTR ClassName, |
| DWORD ClassNameSize, |
| PDWORD RequiredSize) |
| { |
| return SetupDiClassNameFromGuidExW(ClassGuid, ClassName, |
| ClassNameSize, RequiredSize, |
| NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassNameFromGuidExA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassNameFromGuidExA( |
| const GUID* ClassGuid, |
| PSTR ClassName, |
| DWORD ClassNameSize, |
| PDWORD RequiredSize, |
| PCSTR MachineName, |
| PVOID Reserved) |
| { |
| WCHAR ClassNameW[MAX_CLASS_NAME_LEN]; |
| LPWSTR MachineNameW = NULL; |
| BOOL ret; |
| |
| if (MachineName) |
| MachineNameW = MultiByteToUnicode(MachineName, CP_ACP); |
| ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN, |
| NULL, MachineNameW, Reserved); |
| if (ret) |
| { |
| int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName, |
| ClassNameSize, NULL, NULL); |
| |
| if (!ClassNameSize && RequiredSize) |
| *RequiredSize = len; |
| } |
| MyFree(MachineNameW); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * SetupDiClassNameFromGuidExW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiClassNameFromGuidExW( |
| const GUID* ClassGuid, |
| PWSTR ClassName, |
| DWORD ClassNameSize, |
| PDWORD RequiredSize, |
| PCWSTR MachineName, |
| PVOID Reserved) |
| { |
| HKEY hKey; |
| DWORD dwLength; |
| |
| hKey = SetupDiOpenClassRegKeyExW(ClassGuid, |
| KEY_ALL_ACCESS, |
| DIOCR_INSTALLER, |
| MachineName, |
| Reserved); |
| if (hKey == INVALID_HANDLE_VALUE) |
| { |
| return FALSE; |
| } |
| |
| if (RequiredSize != NULL) |
| { |
| dwLength = 0; |
| if (RegQueryValueExW(hKey, |
| Class, |
| NULL, |
| NULL, |
| NULL, |
| &dwLength)) |
| { |
| RegCloseKey(hKey); |
| return FALSE; |
| } |
| |
| *RequiredSize = dwLength / sizeof(WCHAR); |
| } |
| |
| dwLength = ClassNameSize * sizeof(WCHAR); |
| if (RegQueryValueExW(hKey, |
| Class, |
| NULL, |
| NULL, |
| (LPBYTE)ClassName, |
| &dwLength)) |
| { |
| RegCloseKey(hKey); |
| return FALSE; |
| } |
| |
| RegCloseKey(hKey); |
| |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiCreateDeviceInfoList (SETUPAPI.@) |
| */ |
| HDEVINFO WINAPI |
| SetupDiCreateDeviceInfoList(const GUID *ClassGuid, |
| HWND hwndParent) |
| { |
| return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiCreateDeviceInfoListExA (SETUPAPI.@) |
| */ |
| HDEVINFO WINAPI |
| SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid, |
| HWND hwndParent, |
| PCSTR MachineName, |
| PVOID Reserved) |
| { |
| LPWSTR MachineNameW = NULL; |
| HDEVINFO hDevInfo; |
| |
| TRACE("\n"); |
| |
| if (MachineName) |
| { |
| MachineNameW = MultiByteToUnicode(MachineName, CP_ACP); |
| if (MachineNameW == NULL) |
| return (HDEVINFO)INVALID_HANDLE_VALUE; |
| } |
| |
| hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, |
| MachineNameW, Reserved); |
| |
| MyFree(MachineNameW); |
| |
| return hDevInfo; |
| } |
| |
| /*********************************************************************** |
| * 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 registry will be used. |
| * Reserved [I] must be NULL |
| * |
| * RETURNS |
| * Success: empty list. |
| * Failure: INVALID_HANDLE_VALUE. |
| */ |
| HDEVINFO WINAPI |
| SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, |
| HWND hwndParent, |
| PCWSTR MachineName, |
| PVOID Reserved) |
| { |
| 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\n"); |
| 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; |
| } |
| |
| /*********************************************************************** |
| * SetupDiCreateDeviceInfoA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiCreateDeviceInfoA( |
| HDEVINFO DeviceInfoSet, |
| PCSTR DeviceName, |
| CONST GUID *ClassGuid, |
| PCSTR DeviceDescription, |
| HWND hwndParent, |
| DWORD CreationFlags, |
| PSP_DEVINFO_DATA DeviceInfoData) |
| { |
| BOOL ret = FALSE; |
| LPWSTR DeviceNameW = NULL; |
| LPWSTR DeviceDescriptionW = NULL; |
| |
| if (DeviceName) |
| { |
| DeviceNameW = MultiByteToUnicode(DeviceName, CP_ACP); |
| if (DeviceNameW == NULL) return FALSE; |
| } |
| if (DeviceDescription) |
| { |
| DeviceDescriptionW = MultiByteToUnicode(DeviceDescription, CP_ACP); |
| if (DeviceDescriptionW == NULL) |
| { |
| MyFree(DeviceNameW); |
| return FALSE; |
| } |
| } |
| |
| ret = SetupDiCreateDeviceInfoW(DeviceInfoSet, DeviceNameW, ClassGuid, DeviceDescriptionW, |
| hwndParent, CreationFlags, DeviceInfoData); |
| |
| MyFree(DeviceNameW); |
| MyFree(DeviceDescriptionW); |
| |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * SetupDiCreateDeviceInfoW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiCreateDeviceInfoW( |
| HDEVINFO DeviceInfoSet, |
| PCWSTR DeviceName, |
| CONST GUID *ClassGuid, |
| PCWSTR DeviceDescription, |
| HWND hwndParent, |
| DWORD CreationFlags, |
| PSP_DEVINFO_DATA DeviceInfoData) |
| { |
| TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName), |
| debugstr_guid(ClassGuid), debugstr_w(DeviceDescription), |
| hwndParent, CreationFlags, DeviceInfoData); |
| |
| FIXME("stub\n"); |
| |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiEnumDeviceInfo (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiEnumDeviceInfo( |
| HDEVINFO devinfo, |
| DWORD index, |
| PSP_DEVINFO_DATA info) |
| { |
| FIXME("%p %d %p\n", devinfo, index, info); |
| |
| if(info==NULL) |
| return FALSE; |
| if(info->cbSize < sizeof(*info)) |
| return FALSE; |
| |
| SetLastError(ERROR_NO_MORE_ITEMS); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetActualSectionToInstallA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetActualSectionToInstallA( |
| HINF InfHandle, |
| PCSTR InfSectionName, |
| PSTR InfSectionWithExt, |
| DWORD InfSectionWithExtSize, |
| PDWORD RequiredSize, |
| PSTR *Extension) |
| { |
| FIXME("\n"); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetActualSectionToInstallW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetActualSectionToInstallW( |
| HINF InfHandle, |
| PCWSTR InfSectionName, |
| PWSTR InfSectionWithExt, |
| DWORD InfSectionWithExtSize, |
| PDWORD RequiredSize, |
| PWSTR *Extension) |
| { |
| WCHAR szBuffer[MAX_PATH]; |
| DWORD dwLength; |
| DWORD dwFullLength; |
| LONG lLineCount = -1; |
| |
| lstrcpyW(szBuffer, InfSectionName); |
| dwLength = lstrlenW(szBuffer); |
| |
| if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) |
| { |
| /* Test section name with '.NTx86' extension */ |
| lstrcpyW(&szBuffer[dwLength], NtPlatformExtension); |
| lLineCount = SetupGetLineCountW(InfHandle, szBuffer); |
| |
| if (lLineCount == -1) |
| { |
| /* Test section name with '.NT' extension */ |
| lstrcpyW(&szBuffer[dwLength], NtExtension); |
| lLineCount = SetupGetLineCountW(InfHandle, szBuffer); |
| } |
| } |
| else |
| { |
| /* Test section name with '.Win' extension */ |
| lstrcpyW(&szBuffer[dwLength], WinExtension); |
| lLineCount = SetupGetLineCountW(InfHandle, szBuffer); |
| } |
| |
| if (lLineCount == -1) |
| { |
| /* Test section name without extension */ |
| szBuffer[dwLength] = 0; |
| lLineCount = SetupGetLineCountW(InfHandle, szBuffer); |
| } |
| |
| if (lLineCount == -1) |
| { |
| SetLastError(ERROR_INVALID_PARAMETER); |
| return FALSE; |
| } |
| |
| dwFullLength = lstrlenW(szBuffer); |
| |
| if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0) |
| { |
| if (InfSectionWithExtSize < (dwFullLength + 1)) |
| { |
| SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| return FALSE; |
| } |
| |
| lstrcpyW(InfSectionWithExt, szBuffer); |
| if (Extension != NULL) |
| { |
| *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength]; |
| } |
| } |
| |
| if (RequiredSize != NULL) |
| { |
| *RequiredSize = dwFullLength + 1; |
| } |
| |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDescriptionA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetClassDescriptionA( |
| const GUID* ClassGuid, |
| PSTR ClassDescription, |
| DWORD ClassDescriptionSize, |
| PDWORD RequiredSize) |
| { |
| return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription, |
| ClassDescriptionSize, |
| RequiredSize, NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDescriptionW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetClassDescriptionW( |
| const GUID* ClassGuid, |
| PWSTR ClassDescription, |
| DWORD ClassDescriptionSize, |
| PDWORD RequiredSize) |
| { |
| return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription, |
| ClassDescriptionSize, |
| RequiredSize, NULL, NULL); |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDescriptionExA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetClassDescriptionExA( |
| const GUID* ClassGuid, |
| PSTR ClassDescription, |
| DWORD ClassDescriptionSize, |
| PDWORD RequiredSize, |
| PCSTR MachineName, |
| PVOID Reserved) |
| { |
| FIXME("\n"); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDescriptionExW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetClassDescriptionExW( |
| const GUID* ClassGuid, |
| PWSTR ClassDescription, |
| DWORD ClassDescriptionSize, |
| PDWORD RequiredSize, |
| PCWSTR MachineName, |
| PVOID Reserved) |
| { |
| HKEY hKey; |
| DWORD dwLength; |
| |
| hKey = SetupDiOpenClassRegKeyExW(ClassGuid, |
| KEY_ALL_ACCESS, |
| DIOCR_INSTALLER, |
| MachineName, |
| Reserved); |
| if (hKey == INVALID_HANDLE_VALUE) |
| { |
| WARN("SetupDiOpenClassRegKeyExW() failed (Error %u)\n", GetLastError()); |
| return FALSE; |
| } |
| |
| if (RequiredSize != NULL) |
| { |
| dwLength = 0; |
| if (RegQueryValueExW(hKey, |
| NULL, |
| NULL, |
| NULL, |
| NULL, |
| &dwLength)) |
| { |
| RegCloseKey(hKey); |
| return FALSE; |
| } |
| |
| *RequiredSize = dwLength / sizeof(WCHAR); |
| } |
| |
| dwLength = ClassDescriptionSize * sizeof(WCHAR); |
| if (RegQueryValueExW(hKey, |
| NULL, |
| NULL, |
| NULL, |
| (LPBYTE)ClassDescription, |
| &dwLength)) |
| { |
| RegCloseKey(hKey); |
| return FALSE; |
| } |
| |
| RegCloseKey(hKey); |
| |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDevsA (SETUPAPI.@) |
| */ |
| HDEVINFO WINAPI SetupDiGetClassDevsA( |
| CONST GUID *class, |
| LPCSTR enumstr, |
| HWND parent, |
| DWORD flags) |
| { |
| HDEVINFO ret; |
| LPWSTR enumstrW = NULL; |
| |
| if (enumstr) |
| { |
| int len = MultiByteToWideChar(CP_ACP, 0, enumstr, -1, NULL, 0); |
| enumstrW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); |
| if (!enumstrW) |
| { |
| ret = (HDEVINFO)INVALID_HANDLE_VALUE; |
| goto end; |
| } |
| MultiByteToWideChar(CP_ACP, 0, enumstr, -1, enumstrW, len); |
| } |
| ret = SetupDiGetClassDevsW(class, enumstrW, parent, flags); |
| HeapFree(GetProcessHeap(), 0, enumstrW); |
| |
| end: |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDevsW (SETUPAPI.@) |
| */ |
| HDEVINFO WINAPI SetupDiGetClassDevsW( |
| CONST GUID *class, |
| LPCWSTR enumstr, |
| HWND parent, |
| DWORD flags) |
| { |
| TRACE("%s %s %p 0x%08x\n", debugstr_guid(class), debugstr_w(enumstr), parent, flags); |
| |
| /* WinXP always succeeds, returns empty list for unknown classes */ |
| FIXME("returning empty list\n"); |
| return SetupDiCreateDeviceInfoList(class, parent); |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetClassDevsExW (SETUPAPI.@) |
| */ |
| HDEVINFO WINAPI SetupDiGetClassDevsExW( |
| CONST GUID *class, |
| PCWSTR enumstr, |
| HWND parent, |
| DWORD flags, |
| HDEVINFO deviceset, |
| PCWSTR machine, |
| PVOID reserved) |
| { |
| FIXME("stub\n"); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiEnumDeviceInterfaces (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiEnumDeviceInterfaces( |
| HDEVINFO devinfo, |
| PSP_DEVINFO_DATA DeviceInfoData, |
| CONST GUID * InterfaceClassGuid, |
| DWORD MemberIndex, |
| PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) |
| { |
| BOOL ret = FALSE; |
| |
| FIXME("%p, %p, %s, 0x%08x, %p\n", devinfo, DeviceInfoData, |
| debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData); |
| |
| if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE) |
| { |
| struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo; |
| if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC) |
| SetLastError(ERROR_NO_MORE_ITEMS); |
| else |
| SetLastError(ERROR_INVALID_HANDLE); |
| } |
| else |
| 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) |
| { |
| BOOL ret = FALSE; |
| |
| TRACE("%p\n", devinfo); |
| if (devinfo && devinfo != (HDEVINFO)INVALID_HANDLE_VALUE) |
| { |
| struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo; |
| |
| if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC) |
| { |
| HeapFree(GetProcessHeap(), 0, list); |
| ret = TRUE; |
| } |
| } |
| |
| if (ret == FALSE) |
| SetLastError(ERROR_INVALID_HANDLE); |
| |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetDeviceInterfaceDetailA( |
| HDEVINFO DeviceInfoSet, |
| PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, |
| PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, |
| DWORD DeviceInterfaceDetailDataSize, |
| PDWORD RequiredSize, |
| PSP_DEVINFO_DATA DeviceInfoData) |
| { |
| BOOL ret = FALSE; |
| |
| FIXME("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet, |
| DeviceInterfaceData, DeviceInterfaceDetailData, |
| DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData); |
| |
| SetLastError(ERROR_INVALID_HANDLE); |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetDeviceInterfaceDetailW( |
| HDEVINFO DeviceInfoSet, |
| PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, |
| PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, |
| DWORD DeviceInterfaceDetailDataSize, |
| PDWORD RequiredSize, |
| PSP_DEVINFO_DATA DeviceInfoData) |
| { |
| FIXME("(%p, %p, %p, %d, %p, %p): stub\n", DeviceInfoSet, |
| DeviceInterfaceData, DeviceInterfaceDetailData, |
| DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetDeviceRegistryPropertyA( |
| HDEVINFO devinfo, |
| PSP_DEVINFO_DATA DeviceInfoData, |
| DWORD Property, |
| PDWORD PropertyRegDataType, |
| PBYTE PropertyBuffer, |
| DWORD PropertyBufferSize, |
| PDWORD RequiredSize) |
| { |
| FIXME("%04x %p %d %p %p %d %p\n", (DWORD)devinfo, DeviceInfoData, |
| Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize, |
| RequiredSize); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiInstallClassA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiInstallClassA( |
| HWND hwndParent, |
| PCSTR InfFileName, |
| DWORD Flags, |
| HSPFILEQ FileQueue) |
| { |
| UNICODE_STRING FileNameW; |
| BOOL Result; |
| |
| if (!RtlCreateUnicodeStringFromAsciiz(&FileNameW, InfFileName)) |
| { |
| SetLastError(ERROR_NOT_ENOUGH_MEMORY); |
| return FALSE; |
| } |
| |
| Result = SetupDiInstallClassW(hwndParent, FileNameW.Buffer, Flags, FileQueue); |
| |
| RtlFreeUnicodeString(&FileNameW); |
| |
| return Result; |
| } |
| |
| static HKEY CreateClassKey(HINF hInf) |
| { |
| WCHAR FullBuffer[MAX_PATH]; |
| WCHAR Buffer[MAX_PATH]; |
| DWORD RequiredSize; |
| HKEY hClassKey; |
| |
| if (!SetupGetLineTextW(NULL, |
| hInf, |
| Version, |
| ClassGUID, |
| Buffer, |
| MAX_PATH, |
| &RequiredSize)) |
| { |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| lstrcpyW(FullBuffer, ControlClass); |
| lstrcatW(FullBuffer, Buffer); |
| |
| if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, |
| FullBuffer, |
| 0, |
| KEY_ALL_ACCESS, |
| &hClassKey)) |
| { |
| if (!SetupGetLineTextW(NULL, |
| hInf, |
| Version, |
| Class, |
| Buffer, |
| MAX_PATH, |
| &RequiredSize)) |
| { |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, |
| FullBuffer, |
| 0, |
| NULL, |
| REG_OPTION_NON_VOLATILE, |
| KEY_ALL_ACCESS, |
| NULL, |
| &hClassKey, |
| NULL)) |
| { |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| } |
| |
| if (RegSetValueExW(hClassKey, |
| Class, |
| 0, |
| REG_SZ, |
| (LPBYTE)Buffer, |
| RequiredSize * sizeof(WCHAR))) |
| { |
| RegCloseKey(hClassKey); |
| RegDeleteKeyW(HKEY_LOCAL_MACHINE, |
| FullBuffer); |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| return hClassKey; |
| } |
| |
| /*********************************************************************** |
| * SetupDiInstallClassW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiInstallClassW( |
| HWND hwndParent, |
| PCWSTR InfFileName, |
| DWORD Flags, |
| HSPFILEQ FileQueue) |
| { |
| WCHAR SectionName[MAX_PATH]; |
| DWORD SectionNameLength = 0; |
| HINF hInf; |
| BOOL bFileQueueCreated = FALSE; |
| HKEY hClassKey; |
| |
| |
| FIXME("\n"); |
| |
| if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE)) |
| { |
| SetLastError(ERROR_INVALID_PARAMETER); |
| return FALSE; |
| } |
| |
| /* Open the .inf file */ |
| hInf = SetupOpenInfFileW(InfFileName, |
| NULL, |
| INF_STYLE_WIN4, |
| NULL); |
| if (hInf == INVALID_HANDLE_VALUE) |
| { |
| |
| return FALSE; |
| } |
| |
| /* Create or open the class registry key 'HKLM\\CurrentControlSet\\Class\\{GUID}' */ |
| hClassKey = CreateClassKey(hInf); |
| if (hClassKey == INVALID_HANDLE_VALUE) |
| { |
| SetupCloseInfFile(hInf); |
| return FALSE; |
| } |
| |
| |
| /* Try to append a layout file */ |
| #if 0 |
| SetupOpenAppendInfFileW(NULL, hInf, NULL); |
| #endif |
| |
| /* Retrieve the actual section name */ |
| SetupDiGetActualSectionToInstallW(hInf, |
| ClassInstall32, |
| SectionName, |
| MAX_PATH, |
| &SectionNameLength, |
| NULL); |
| |
| #if 0 |
| if (!(Flags & DI_NOVCP)) |
| { |
| FileQueue = SetupOpenFileQueue(); |
| if (FileQueue == INVALID_HANDLE_VALUE) |
| { |
| SetupCloseInfFile(hInf); |
| return FALSE; |
| } |
| |
| bFileQueueCreated = TRUE; |
| |
| } |
| #endif |
| |
| SetupInstallFromInfSectionW(NULL, |
| hInf, |
| SectionName, |
| SPINST_REGISTRY, |
| hClassKey, |
| NULL, |
| 0, |
| NULL, |
| NULL, |
| INVALID_HANDLE_VALUE, |
| NULL); |
| |
| /* FIXME: More code! */ |
| |
| if (bFileQueueCreated) |
| SetupCloseFileQueue(FileQueue); |
| |
| SetupCloseInfFile(hInf); |
| |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * SetupDiOpenClassRegKey (SETUPAPI.@) |
| */ |
| HKEY WINAPI SetupDiOpenClassRegKey( |
| const GUID* ClassGuid, |
| REGSAM samDesired) |
| { |
| return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired, |
| DIOCR_INSTALLER, NULL, NULL); |
| } |
| |
| |
| /*********************************************************************** |
| * SetupDiOpenClassRegKeyExA (SETUPAPI.@) |
| */ |
| HKEY WINAPI SetupDiOpenClassRegKeyExA( |
| const GUID* ClassGuid, |
| REGSAM samDesired, |
| DWORD Flags, |
| PCSTR MachineName, |
| PVOID Reserved) |
| { |
| PWSTR MachineNameW = NULL; |
| HKEY hKey; |
| |
| TRACE("\n"); |
| |
| if (MachineName) |
| { |
| MachineNameW = MultiByteToUnicode(MachineName, CP_ACP); |
| if (MachineNameW == NULL) |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired, |
| Flags, MachineNameW, Reserved); |
| |
| MyFree(MachineNameW); |
| |
| return hKey; |
| } |
| |
| |
| /*********************************************************************** |
| * SetupDiOpenClassRegKeyExW (SETUPAPI.@) |
| */ |
| HKEY WINAPI SetupDiOpenClassRegKeyExW( |
| const GUID* ClassGuid, |
| REGSAM samDesired, |
| DWORD Flags, |
| PCWSTR MachineName, |
| PVOID Reserved) |
| { |
| LPWSTR lpGuidString; |
| WCHAR bracedGuidString[39]; |
| HKEY hClassesKey; |
| HKEY hClassKey; |
| LPCWSTR lpKeyName; |
| |
| if (MachineName != NULL) |
| { |
| FIXME("Remote access not supported yet!\n"); |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| if (Flags == DIOCR_INSTALLER) |
| { |
| lpKeyName = ControlClass; |
| } |
| else if (Flags == DIOCR_INTERFACE) |
| { |
| lpKeyName = DeviceClasses; |
| } |
| else |
| { |
| ERR("Invalid Flags parameter!\n"); |
| SetLastError(ERROR_INVALID_PARAMETER); |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, |
| lpKeyName, |
| 0, |
| KEY_ALL_ACCESS, |
| &hClassesKey)) |
| { |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| if (ClassGuid == NULL) |
| return hClassesKey; |
| |
| if (UuidToStringW((UUID*)ClassGuid, &lpGuidString) != RPC_S_OK) |
| { |
| RegCloseKey(hClassesKey); |
| return INVALID_HANDLE_VALUE; |
| } |
| bracedGuidString[0] = '{'; |
| memcpy(&bracedGuidString[1], lpGuidString, 36*sizeof(WCHAR)); |
| bracedGuidString[37] = '}'; |
| bracedGuidString[38] = 0; |
| RpcStringFreeW(&lpGuidString); |
| |
| if (RegOpenKeyExW(hClassesKey, |
| bracedGuidString, |
| 0, |
| KEY_ALL_ACCESS, |
| &hClassKey)) |
| { |
| RegCloseKey(hClassesKey); |
| return INVALID_HANDLE_VALUE; |
| } |
| |
| RegCloseKey(hClassesKey); |
| |
| return hClassKey; |
| } |
| |
| /*********************************************************************** |
| * SetupDiOpenDeviceInterfaceW (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiOpenDeviceInterfaceW( |
| HDEVINFO DeviceInfoSet, |
| PCWSTR DevicePath, |
| DWORD OpenFlags, |
| PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) |
| { |
| FIXME("%p %s %08x %p\n", |
| DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiOpenDeviceInterfaceA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiOpenDeviceInterfaceA( |
| HDEVINFO DeviceInfoSet, |
| PCSTR DevicePath, |
| DWORD OpenFlags, |
| PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) |
| { |
| FIXME("%p %s %08x %p\n", DeviceInfoSet, |
| debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiSetClassInstallParamsA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiSetClassInstallParamsA( |
| HDEVINFO DeviceInfoSet, |
| PSP_DEVINFO_DATA DeviceInfoData, |
| PSP_CLASSINSTALL_HEADER ClassInstallParams, |
| DWORD ClassInstallParamsSize) |
| { |
| FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData, |
| ClassInstallParams->InstallFunction, ClassInstallParamsSize); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiCallClassInstaller (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiCallClassInstaller( |
| DI_FUNCTION InstallFunction, |
| HDEVINFO DeviceInfoSet, |
| PSP_DEVINFO_DATA DeviceInfoData) |
| { |
| FIXME("%d %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiGetDeviceInstallParamsA (SETUPAPI.@) |
| */ |
| BOOL WINAPI SetupDiGetDeviceInstallParamsA( |
| HDEVINFO DeviceInfoSet, |
| PSP_DEVINFO_DATA DeviceInfoData, |
| PSP_DEVINSTALL_PARAMS_A DeviceInstallParams) |
| { |
| FIXME("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams); |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * SetupDiOpenDevRegKey (SETUPAPI.@) |
| */ |
| HKEY WINAPI SetupDiOpenDevRegKey( |
| HDEVINFO DeviceInfoSet, |
| PSP_DEVINFO_DATA DeviceInfoData, |
| DWORD Scope, |
| DWORD HwProfile, |
| DWORD KeyType, |
| REGSAM samDesired) |
| { |
| FIXME("%p %p %d %d %d %x\n", DeviceInfoSet, DeviceInfoData, |
| Scope, HwProfile, KeyType, samDesired); |
| return INVALID_HANDLE_VALUE; |
| } |