/* * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "wine/port.h" #include #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 "rpc.h" #include "rpcdce.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}; /*********************************************************************** * SetupDiBuildClassInfoList (SETUPAPI.@) */ BOOL WINAPI SetupDiBuildClassInfoList( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize) { TRACE("\n"); return SetupDiBuildClassInfoListExW(Flags, ClassGuidList, ClassGuidListSize, RequiredSize, NULL, NULL); } /*********************************************************************** * SetupDiBuildClassInfoListExA (SETUPAPI.@) */ BOOL WINAPI SetupDiBuildClassInfoListExA( DWORD Flags, LPGUID ClassGuidList, DWORD ClassGuidListSize, PDWORD RequiredSize, LPCSTR MachineName, PVOID Reserved) { FIXME("\n"); return FALSE; } /*********************************************************************** * SetupDiBuildClassInfoListExW (SETUPAPI.@) */ 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 %ld\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] == L'{' && szKeyName[37] == L'}') { 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) { FIXME("\n"); return FALSE; } /*********************************************************************** * 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 %ld\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] == L'{' && szKeyName[37] == L'}') { 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) { FIXME("\n"); return FALSE; } /*********************************************************************** * 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) { FIXME("\n"); return (HDEVINFO)INVALID_HANDLE_VALUE; } /*********************************************************************** * SetupDiCreateDeviceInfoListExW (SETUPAPI.@) */ HDEVINFO WINAPI SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, HWND hwndParent, PCWSTR MachineName, PVOID Reserved) { FIXME("\n"); return (HDEVINFO)INVALID_HANDLE_VALUE; } /*********************************************************************** * SetupDiDestroyDeviceInfoList (SETUPAPI.@) */ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo) { FIXME("%p\n", devinfo); return FALSE; } /*********************************************************************** * SetupDiEnumDeviceInfo (SETUPAPI.@) */ BOOL WINAPI SetupDiEnumDeviceInfo( HDEVINFO devinfo, DWORD index, PSP_DEVINFO_DATA info) { FIXME("%p %ld %p\n", devinfo, index, info); if(info==NULL) return FALSE; if(info->cbSize < sizeof(*info)) return FALSE; return FALSE; } /*********************************************************************** * SetupDiEnumDeviceInterfaces (SETUPAPI.@) */ BOOL WINAPI SetupDiEnumDeviceInterfaces( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, CONST GUID * InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) { FIXME("\n"); 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]; OSVERSIONINFOW OsVersionInfo; DWORD dwLength; DWORD dwFullLength; LONG lLineCount = -1; OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); if (!GetVersionExW(&OsVersionInfo)) { return FALSE; } 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 %lu)\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) { FIXME("%s %s %p %08lx\n",debugstr_guid(class),enumstr,parent,flags); return (HDEVINFO) INVALID_HANDLE_VALUE; } /*********************************************************************** * SetupDiGetClassDevsW (SETUPAPI.@) */ HDEVINFO WINAPI SetupDiGetClassDevsW( CONST GUID *class, LPCWSTR enumstr, HWND parent, DWORD flags) { FIXME("%s %s %p %08lx\n",debugstr_guid(class),debugstr_w(enumstr),parent,flags); return (HDEVINFO) INVALID_HANDLE_VALUE; } /*********************************************************************** * 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) { FIXME("\n"); return FALSE; } /*********************************************************************** * 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("\n"); return FALSE; } /*********************************************************************** * SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@) */ BOOL WINAPI SetupDiGetDeviceRegistryPropertyA( HDEVINFO devinfo, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize) { FIXME("%04lx %p %ld %p %p %ld %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) { FIXME("\n"); return INVALID_HANDLE_VALUE; } /*********************************************************************** * SetupDiOpenClassRegKeyExW (SETUPAPI.@) */ HKEY WINAPI SetupDiOpenClassRegKeyExW( const GUID* ClassGuid, REGSAM samDesired, DWORD Flags, PCWSTR MachineName, PVOID Reserved) { LPWSTR lpGuidString; 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 FALSE; } if (RegOpenKeyExW(hClassesKey, lpGuidString, 0, KEY_ALL_ACCESS, &hClassKey)) { RpcStringFreeW(&lpGuidString); RegCloseKey(hClassesKey); return FALSE; } RpcStringFreeW(&lpGuidString); RegCloseKey(hClassesKey); return hClassKey; } /*********************************************************************** * SetupDiOpenDeviceInterfaceA (SETUPAPI.@) */ BOOL WINAPI SetupDiOpenDeviceInterfaceW( HDEVINFO DeviceInfoSet, PCWSTR DevicePath, DWORD OpenFlags, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) { FIXME("%p %s %08lx %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 %08lx %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 %lu\n",DeviceInfoSet, DeviceInfoData, ClassInstallParams->InstallFunction, ClassInstallParamsSize); return FALSE; } /*********************************************************************** * SetupDiCallClassInstaller (SETUPAPI.@) */ BOOL WINAPI SetupDiCallClassInstaller( DWORD InstallFunction, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData) { FIXME("%ld %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 %ld %ld %ld %lx\n", DeviceInfoSet, DeviceInfoData, Scope, HwProfile, KeyType, samDesired); return INVALID_HANDLE_VALUE; }