#include "windef.h"
#include "winbase.h"
+#include "winreg.h"
+#include "winternl.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
-#include "winreg.h"
#include "setupapi.h"
#include "wine/debug.h"
+#include "rpc.h"
+#include "rpcdce.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+/* Unicode constants */
+static const WCHAR NtExtension[] = {'.','N','T',0};
+static const WCHAR NtPlatformExtension[] = {'.','N','T','x','8','6',0};
+static const WCHAR WinExtension[] = {'.','W','i','n',0};
+static const WCHAR ClassInstall32[] = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
+static const WCHAR Class[] = {'C','l','a','s','s',0};
+
+
/***********************************************************************
- * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
+ * SetupDiBuildClassInfoList (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 WINAPI SetupDiBuildClassInfoList(
+ DWORD Flags,
+ LPGUID ClassGuidList,
+ DWORD ClassGuidListSize,
+ PDWORD RequiredSize)
{
- FIXME("\n");
- return FALSE;
+ TRACE("SetupDiBuildClassInfoList() called\n");
+ return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
+ ClassGuidListSize, RequiredSize,
+ NULL, NULL);
}
/***********************************************************************
- * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
+ * SetupDiBuildClassInfoListExA (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 )
+BOOL WINAPI SetupDiBuildClassInfoListExA(
+ DWORD Flags,
+ LPGUID ClassGuidList,
+ DWORD ClassGuidListSize,
+ PDWORD RequiredSize,
+ LPCSTR MachineName,
+ PVOID Reserved)
{
- FIXME("\n");
+ 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("SetupDiBuildClassInfoListExW() called\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);
+ DPRINT("RegEnumKeyExW() returns %ld\n", lError);
+ if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
+ {
+ TRACE("Key name: %S\n", szKeyName);
+
+ if (RegOpenKeyExW(hClassesKey,
+ szKeyName,
+ 0,
+ KEY_ALL_ACCESS,
+ &hClassKey))
+ {
+ RegCloseKey(hClassesKey);
+ return FALSE;
+ }
+
+ if (!RegQueryValueExW(hClassKey,
+ L"NoUseClass",
+ NULL,
+ NULL,
+ NULL,
+ NULL))
+ {
+ TRACE("'NoUseClass' value found!\n");
+ RegCloseKey(hClassKey);
+ continue;
+ }
+
+ if ((Flags & DIBCI_NOINSTALLCLASS) &&
+ (!RegQueryValueExW(hClassKey,
+ L"NoInstallClass",
+ NULL,
+ NULL,
+ NULL,
+ NULL)))
+ {
+ TRACE("'NoInstallClass' value found!\n");
+ RegCloseKey(hClassKey);
+ continue;
+ }
+
+ if ((Flags & DIBCI_NODISPLAYCLASS) &&
+ (!RegQueryValueExW(hClassKey,
+ L"NoDisplayClass",
+ NULL,
+ NULL,
+ NULL,
+ NULL)))
+ {
+ TRACE("'NoDisplayClass' value found!\n");
+ RegCloseKey(hClassKey);
+ continue;
+ }
+
+ RegCloseKey(hClassKey);
+
+ TRACE("Guid: %S\n", szKeyName);
+ if (dwGuidListIndex < ClassGuidListSize)
+ {
+ if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
+ {
+ szKeyName[37] = 0;
+ }
+ TRACE("Guid: %S\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: %S\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: %S\n", szClassName);
+
+ if (_wcsicmp(szClassName, ClassName) == 0)
+ {
+ TRACE("Found matching class name\n");
+
+ TRACE("Guid: %S\n", szKeyName);
+ if (dwGuidListIndex < ClassGuidListSize)
+ {
+ if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
+ {
+ szKeyName[37] = 0;
+ }
+ TRACE("Guid: %S\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("%04lx\n", (DWORD)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;
}
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];
+ OSVERSIONINFO OsVersionInfo;
+ DWORD dwLength;
+ DWORD dwFullLength;
+ LONG lLineCount = -1;
+
+ OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (!GetVersionEx(&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)
+ {
+ DPRINT1("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.@)
*/
return (HDEVINFO) INVALID_HANDLE_VALUE;
}
+
/***********************************************************************
- * SetupDiEnumDeviceInfo (SETUPAPI.@)
+ * SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
*/
-BOOL WINAPI SetupDiEnumDeviceInfo(
- HDEVINFO devinfo,
- DWORD index,
- PSP_DEVINFO_DATA info)
+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("%p %ld %p\n", devinfo, index, info );
-
- if(info==NULL)
- return FALSE;
- if(info->cbSize < sizeof(*info))
- return FALSE;
-
+ FIXME("\n");
return FALSE;
}
/***********************************************************************
- * SetupDiDestroyDeviceInfoList (SETUPAPI.@)
+ * SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
*/
-BOOL WINAPI SetupDiDestroyDeviceInfoList( HDEVINFO devinfo )
+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("%04lx\n", (DWORD)devinfo);
+ FIXME("\n");
return FALSE;
}
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,
+ L"Version",
+ L"ClassGUID",
+ Buffer,
+ MAX_PATH,
+ &RequiredSize))
+ {
+ return INVALID_HANDLE_VALUE;
+ }
+
+ lstrcpyW(FullBuffer, L"System\\CurrentControlSet\\Control\\Class\\");
+ lstrcatW(FullBuffer, Buffer);
+
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ FullBuffer,
+ 0,
+ KEY_ALL_ACCESS,
+ &hClassKey))
+ {
+ if (!SetupGetLineTextW(NULL,
+ hInf,
+ L"Version",
+ L"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,
+ L"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! */
+
+ByeBye:
+ 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;
+ LPWSTR lpKeyName;
+
+ if (MachineName != NULL)
+ {
+ FIXME("Remote access not supported yet!\n");
+ return INVALID_HANDLE_VALUE;
+ }
+
+ if (Flags == DIOCR_INSTALLER)
+ {
+ lpKeyName = L"SYSTEM\\CurrentControlSet\\Control\\Class";
+ }
+ else if (Flags == DIOCR_INTERFACE)
+ {
+ lpKeyName = L"SYSTEM\\CurrentControlSet\\Control\\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;
+}