* SetupAPI device installer
*
* Copyright 2000 Andreas Mohr for CodeWeavers
- * 2005 Hervé Poussineau (hpoussin@reactos.com)
+ * 2005 Hervé Poussineau (hpoussin@reactos.org)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
LONG lError;
DWORD dwGuidListIndex = 0;
- TRACE("\n");
+ TRACE("0x%lx %p %lu %p %s %p\n", Flags, ClassGuidList,
+ ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
if (RequiredSize != NULL)
*RequiredSize = 0;
hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
- KEY_ALL_ACCESS,
+ KEY_ENUMERATE_SUB_KEYS,
DIOCR_INSTALLER,
MachineName,
Reserved);
TRACE("RegEnumKeyExW() returns %ld\n", lError);
if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
{
- TRACE("Key name: %p\n", szKeyName);
+ TRACE("Key name: %s\n", debugstr_w(szKeyName));
if (RegOpenKeyExW(hClassesKey,
szKeyName,
0,
- KEY_ALL_ACCESS,
+ KEY_QUERY_VALUE,
&hClassKey))
{
RegCloseKey(hClassesKey);
RegCloseKey(hClassKey);
- TRACE("Guid: %p\n", szKeyName);
+ TRACE("Guid: %s\n", debugstr_w(szKeyName));
if (dwGuidListIndex < ClassGuidListSize)
{
if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
{
szKeyName[37] = 0;
}
- TRACE("Guid: %p\n", &szKeyName[1]);
+ TRACE("Guid: %s\n", debugstr_w(&szKeyName[1]));
UuidFromStringW(&szKeyName[1],
&ClassGuidList[dwGuidListIndex]);
LONG lError;
DWORD dwGuidListIndex = 0;
+ TRACE("%s %p %lu %p %s %p\n", debugstr_w(ClassName), ClassGuidList,
+ ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
+
if (RequiredSize != NULL)
*RequiredSize = 0;
TRACE("RegEnumKeyExW() returns %ld\n", lError);
if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
{
- TRACE("Key name: %p\n", szKeyName);
+ TRACE("Key name: %s\n", debugstr_w(szKeyName));
if (RegOpenKeyExW(hClassesKey,
szKeyName,
(LPBYTE)szClassName,
&dwLength))
{
- TRACE("Class name: %p\n", szClassName);
+ TRACE("Class name: %s\n", debugstr_w(szClassName));
if (strcmpiW(szClassName, ClassName) == 0)
{
TRACE("Found matching class name\n");
- TRACE("Guid: %p\n", szKeyName);
+ TRACE("Guid: %s\n", debugstr_w(szKeyName));
if (dwGuidListIndex < ClassGuidListSize)
{
if (szKeyName[0] == L'{' && szKeyName[37] == L'}')
{
szKeyName[37] = 0;
}
- TRACE("Guid: %p\n", &szKeyName[1]);
+ TRACE("Guid: %s\n", debugstr_w(&szKeyName[1]));
UuidFromStringW(&szKeyName[1],
&ClassGuidList[dwGuidListIndex]);
DWORD dwLength;
LONG rc;
+ TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassName,
+ ClassNameSize, RequiredSize, debugstr_w(MachineName), Reserved);
+
hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
KEY_QUERY_VALUE,
DIOCR_INSTALLER,
LPWSTR MachineNameW = NULL;
HDEVINFO hDevInfo;
- TRACE("%p %p %s %p\n", ClassGuid, hwndParent, MachineName, Reserved);
+ TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
+ debugstr_a(MachineName), Reserved);
if (MachineName)
{
PVOID Reserved)
{
struct DeviceInfoSet *list;
+ LPWSTR UNCServerName = NULL;
DWORD rc;
+ //CONFIGRET cr;
+ HDEVINFO ret = (HDEVINFO)INVALID_HANDLE_VALUE;;
- TRACE("%p %p %S %p\n", ClassGuid, hwndParent, MachineName, Reserved);
+ TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
+ debugstr_w(MachineName), Reserved);
list = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInfoSet));
if (!list)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return (HDEVINFO)INVALID_HANDLE_VALUE;
+ goto cleanup;
}
memset(list, 0, sizeof(struct DeviceInfoSet));
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
- HeapFree(GetProcessHeap(), 0, list);
- return (HDEVINFO)INVALID_HANDLE_VALUE;
+ goto cleanup;
}
+ UNCServerName = HeapAlloc(GetProcessHeap(), 0, (strlenW(MachineName) + 3) * sizeof(WCHAR));
+ if (!UNCServerName)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+
+ strcpyW(UNCServerName + 2, MachineName);
}
else
{
+ DWORD Size = MAX_PATH;
list->HKLM = HKEY_LOCAL_MACHINE;
+ UNCServerName = HeapAlloc(GetProcessHeap(), 0, (MAX_PATH + 2) * sizeof(WCHAR));
+ if (!UNCServerName)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ if (!GetComputerNameW(UNCServerName + 2, &Size))
+ goto cleanup;
}
+#if 0
+ UNCServerName[0] = UNCServerName[1] = '\\';
+ cr = CM_Connect_MachineW(UNCServerName, &list->hMachine);
+ if (cr != CR_SUCCESS)
+ {
+ switch (cr)
+ {
+ case CR_OUT_OF_MEMORY: rc = ERROR_NOT_ENOUGH_MEMORY; break;
+ case CR_INVALID_MACHINENAME: rc = ERROR_INVALID_COMPUTERNAME; break;
+ default: rc = ERROR_GEN_FAILURE; break;
+ }
+ SetLastError(rc);
+ goto cleanup;
+ }
+#endif
InitializeListHead(&list->DriverListHead);
InitializeListHead(&list->ListHead);
- return (HDEVINFO)list;
+
+ ret = (HDEVINFO)list;
+
+cleanup:
+ if (ret == INVALID_HANDLE_VALUE)
+ {
+ if (list && list->HKLM != 0 && list->HKLM != HKEY_LOCAL_MACHINE)
+ RegCloseKey(list->HKLM);
+ HeapFree(GetProcessHeap(), 0, list);
+ }
+ HeapFree(GetProcessHeap(), 0, UNCServerName);
+ return ret;
}
/***********************************************************************
memcpy(&DeviceInfoData->ClassGuid,
&DevInfo->ClassGuid,
sizeof(GUID));
- DeviceInfoData->DevInst = 0; /* FIXME */
- /* 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.
- */
+ DeviceInfoData->DevInst = (DWORD)list->hMachine;
DeviceInfoData->Reserved = (ULONG_PTR)DevInfo;
ret = TRUE;
}
DWORD dwFullLength;
LONG lLineCount = -1;
+ TRACE("%p %s %p %lu %p %p\n", InfHandle, debugstr_w(InfSectionName),
+ InfSectionWithExt, InfSectionWithExtSize, RequiredSize, Extension);
+
lstrcpyW(szBuffer, InfSectionName);
dwLength = lstrlenW(szBuffer);
HKEY hKey;
DWORD dwLength;
+ TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription,
+ ClassDescriptionSize, RequiredSize, debugstr_w(MachineName), Reserved);
+
hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
- KEY_ALL_ACCESS,
+ KEY_QUERY_VALUE,
DIOCR_INSTALLER,
MachineName,
Reserved);
if (pClassGuid)
/* Skip this bad entry as we can't verify it */
continue;
+ /* Set a default GUID for this device */
+ memcpy(&KeyGuid, &GUID_NULL, sizeof(GUID));
}
else if (rc != ERROR_SUCCESS)
{
RegCloseKey(hDeviceIdKey);
return ERROR_GEN_FAILURE;
}
-
- KeyBuffer[37] = '\0'; /* Replace the } by a NULL character */
- if (UuidFromStringW(&KeyBuffer[1], &KeyGuid) != RPC_S_OK)
+ else
{
- RegCloseKey(hDeviceIdKey);
- return GetLastError();
+ KeyBuffer[37] = '\0'; /* Replace the } by a NULL character */
+ if (UuidFromStringW(&KeyBuffer[1], &KeyGuid) != RPC_S_OK)
+ /* Bad GUID, skip the entry */
+ continue;
}
+
if (pClassGuid && !IsEqualIID(&KeyGuid, pClassGuid))
{
/* Skip this entry as it is not the right device class */
DWORD dwLength;
DWORD rc;
- if (IsEqualIID(class, &GUID_NULL))
+ if (class && IsEqualIID(class, &GUID_NULL))
class = NULL;
/* Open Enum key */
return rc;
/* If enumerator is provided, call directly SETUP_CreateDevListFromEnumerator.
- * Else, enumerate all enumerators all call SETUP_CreateDevListFromEnumerator
+ * Else, enumerate all enumerators and call SETUP_CreateDevListFromEnumerator
* for each one.
*/
if (Enumerator)
&DevItf->InterfaceClassGuid,
sizeof(GUID));
DeviceInterfaceData->Flags = 0; /* FIXME */
- /* 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)DevItf;
Found = TRUE;
}
}
if (list->HKLM != HKEY_LOCAL_MACHINE)
RegCloseKey(list->HKLM);
+ CM_Disconnect_Machine(list->hMachine);
HeapFree(GetProcessHeap(), 0, list);
return TRUE;
}
DWORD sizeW = 0, sizeA;
BOOL ret = FALSE;
- TRACE("(%p, %p, %p, %ld, %p, %p)\n", DeviceInfoSet,
+ TRACE("%p %p %p %lu %p %p\n", DeviceInfoSet,
DeviceInterfaceData, DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
PDWORD RequiredSize,
PSP_DEVINFO_DATA DeviceInfoData)
{
+ struct DeviceInfoSet *list;
BOOL ret = FALSE;
- TRACE("(%p, %p, %p, %ld, %p, %p): stub\n", DeviceInfoSet,
+ TRACE("%p %p %p %lu %p %p\n", DeviceInfoSet,
DeviceInterfaceData, DeviceInterfaceDetailData,
DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
SetLastError(ERROR_INVALID_PARAMETER);
else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
SetLastError(ERROR_INVALID_HANDLE);
- else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
+ else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
SetLastError(ERROR_INVALID_HANDLE);
else if (DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
SetLastError(ERROR_INVALID_USER_BUFFER);
memcpy(&DeviceInfoData->ClassGuid,
&deviceInterface->DeviceInfo->ClassGuid,
sizeof(GUID));
- DeviceInfoData->DevInst = 0; /* FIXME */
- /* 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.
- */
+ DeviceInfoData->DevInst = (DWORD)list->hMachine;
DeviceInfoData->Reserved = (ULONG_PTR)deviceInterface->DeviceInfo;
}
ret = TRUE;
default:
{
- FIXME("Property 0x%lx not implemented\n", Property);
+ ERR("Property 0x%lx not implemented\n", Property);
SetLastError(ERROR_NOT_SUPPORTED);
}
}
default:
{
- FIXME("Property 0x%lx not implemented\n", Property);
+ ERR("Property 0x%lx not implemented\n", Property);
SetLastError(ERROR_NOT_SUPPORTED);
}
}
0,
NULL,
REG_OPTION_NON_VOLATILE,
- KEY_ALL_ACCESS,
+ KEY_SET_VALUE,
NULL,
&hClassKey,
NULL))
BOOL bFileQueueCreated = FALSE;
HKEY hClassKey;
+ TRACE("%p %s 0x%lx %p\n", hwndParent, debugstr_w(InfFileName),
+ Flags, FileQueue);
+
FIXME("not fully implemented\n");
if ((Flags & DI_NOVCP) && (FileQueue == NULL || FileQueue == INVALID_HANDLE_VALUE))
DWORD rc;
LPCWSTR lpKeyName;
+ TRACE("%s 0x%lx 0x%lx %s %p\n", debugstr_guid(ClassGuid), samDesired,
+ Flags, debugstr_w(MachineName), Reserved);
+
if (Flags == DIOCR_INSTALLER)
{
lpKeyName = ControlClass;
else
{
ERR("Invalid Flags parameter!\n");
- SetLastError(ERROR_INVALID_PARAMETER);
+ SetLastError(ERROR_INVALID_FLAGS);
return INVALID_HANDLE_VALUE;
}
rc = RegOpenKeyExW(HKLM,
lpKeyName,
0,
- KEY_ALL_ACCESS,
+ ClassGuid ? KEY_ENUMERATE_SUB_KEYS : samDesired,
&hClassesKey);
if (MachineName != NULL) RegCloseKey(HKLM);
if (rc != ERROR_SUCCESS)
rc = RegOpenKeyExW(hClassesKey,
lpFullGuidString,
0,
- KEY_ALL_ACCESS,
+ samDesired,
&hClassKey);
if (rc != ERROR_SUCCESS)
{
{
BOOL ret = FALSE;
- TRACE("%ld %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
+ TRACE("%u %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
if (!DeviceInfoSet)
SetLastError(ERROR_INVALID_PARAMETER);
DefaultHandler = SetupDiSelectBestCompatDrv;
break;
default:
- FIXME("Install function %ld not implemented\n", InstallFunction);
- SetLastError(ERROR_INVALID_PARAMETER);
+ ERR("Install function %u not supported\n", InstallFunction);
+ SetLastError(ERROR_NOT_SUPPORTED);
}
InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
return ret;
}
+/***********************************************************************
+ * SetupDiGetDeviceInfoListDetailW (SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetDeviceInfoListDetailW(
+ IN HDEVINFO DeviceInfoSet,
+ OUT PSP_DEVINFO_LIST_DETAIL_DATA_W DeviceInfoListDetailData)
+{
+ struct DeviceInfoSet *list;
+ BOOL ret = FALSE;
+
+ TRACE("%p %p\n", DeviceInfoSet, DeviceInfoListDetailData);
+
+ if (!DeviceInfoSet)
+ SetLastError(ERROR_INVALID_HANDLE);
+ else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
+ SetLastError(ERROR_INVALID_HANDLE);
+ else if (!DeviceInfoListDetailData)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else if (DeviceInfoListDetailData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_W))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else
+ {
+ memcpy(
+ &DeviceInfoListDetailData->ClassGuid,
+ &list->ClassGuid,
+ sizeof(GUID));
+ DeviceInfoListDetailData->RemoteMachineHandle = list->hMachine;
+ DeviceInfoListDetailData->RemoteMachineName[0] = 0; /* FIXME */
+
+ ret = TRUE;
+ }
+
+ TRACE("Returning %d\n", ret);
+ return ret;
+}
+
/***********************************************************************
* SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
*/
return ret;
}
+/***********************************************************************
+ * SetupDiGetDeviceInstanceIdA(SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetDeviceInstanceIdA(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ OUT PSTR DeviceInstanceId,
+ IN DWORD DeviceInstanceIdSize,
+ OUT PDWORD RequiredSize)
+{
+ FIXME ("Stub %p %p %p %d %p\n",
+ DeviceInfoSet, DeviceInfoData, DeviceInstanceId, DeviceInstanceIdSize, RequiredSize);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
+
+/***********************************************************************
+ * SetupDiGetDeviceInstanceIdW(SETUPAPI.@)
+ */
+BOOL WINAPI SetupDiGetDeviceInstanceIdW(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ OUT PWSTR DeviceInstanceId,
+ IN DWORD DeviceInstanceIdSize,
+ OUT PDWORD RequiredSize)
+{
+ BOOL ret = FALSE;
+
+ TRACE("%p %p %p %lu %p\n", DeviceInfoSet, DeviceInfoData,
+ DeviceInstanceId, DeviceInstanceIdSize, RequiredSize);
+
+ if (!DeviceInfoSet)
+ SetLastError(ERROR_INVALID_HANDLE);
+ else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
+ SetLastError(ERROR_INVALID_HANDLE);
+ else if (!DeviceInfoData)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
+ SetLastError(ERROR_INVALID_USER_BUFFER);
+ else if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else if (DeviceInstanceId && DeviceInstanceIdSize == 0)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ struct DeviceInfoElement *DevInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
+ DWORD required;
+
+ required = (wcslen(DevInfo->DeviceName) + 1) * sizeof(WCHAR);
+ if (RequiredSize)
+ *RequiredSize = required;
+
+ if (required <= DeviceInstanceIdSize)
+ {
+ wcscpy(DeviceInstanceId, DevInfo->DeviceName);
+ ret = TRUE;
+ }
+ else
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ }
+
+ TRACE("Returning 0x%p\n", ret);
+ return ret;
+}
+
/***********************************************************************
* SetupDiCreateDevRegKeyA (SETUPAPI.@)
*/
else if (CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS))
{
TRACE("Unknown flags: 0x%08lx\n", CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS));
- SetLastError(ERROR_INVALID_PARAMETER);
+ SetLastError(ERROR_INVALID_FLAGS);
}
else
{
{
struct DeviceInfoElement *deviceInfo;
- /* FIXME: ClassGuid can be NULL */
if (CreateDeviceInfoElement(DeviceName, ClassGuid, &deviceInfo))
{
InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
else
{
memcpy(&DeviceInfoData->ClassGuid, ClassGuid, sizeof(GUID));
- DeviceInfoData->DevInst = 0; /* FIXME */
+ DeviceInfoData->DevInst = (DWORD)list->hMachine;
DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
ret = TRUE;
}
wcscpy(pFullFilename, filename);
TRACE("Opening file %S\n", FullInfFileName);
- currentInfFileDetails = HeapAlloc(GetProcessHeap(), 0, sizeof(struct InfFileDetails));
+ currentInfFileDetails = HeapAlloc(
+ GetProcessHeap(),
+ 0,
+ FIELD_OFFSET(struct InfFileDetails, FullInfFileName) + wcslen(FullInfFileName) * sizeof(WCHAR) + UNICODE_NULL);
if (!currentInfFileDetails)
continue;
memset(currentInfFileDetails, 0, sizeof(struct InfFileDetails));
+ wcscpy(currentInfFileDetails->FullInfFileName, FullInfFileName);
currentInfFileDetails->hInf = SetupOpenInfFileW(FullInfFileName, NULL, INF_STYLE_WIN4, NULL);
ReferenceInfFile(currentInfFileDetails);
DriverAlreadyAdded = FALSE;
for (DriverRank = 0, currentId = (LPCWSTR)HardwareIDs; !DriverAlreadyAdded && *currentId; currentId += wcslen(currentId) + 1, DriverRank++)
{
- if (wcscmp(DeviceId, currentId) == 0)
+ if (wcsicmp(DeviceId, currentId) == 0)
{
AddDriverToList(
&((struct DeviceInfoElement *)DeviceInfoData->Reserved)->DriverListHead,
{
for (DriverRank = 0, currentId = (LPCWSTR)CompatibleIDs; !DriverAlreadyAdded && *currentId; currentId += wcslen(currentId) + 1, DriverRank++)
{
- if (wcscmp(DeviceId, currentId) == 0)
+ if (wcsicmp(DeviceId, currentId) == 0)
{
AddDriverToList(
&((struct DeviceInfoElement *)DeviceInfoData->Reserved)->DriverListHead,
else if (OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS))
{
TRACE("Unknown flags: 0x%08lx\n", OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS));
- SetLastError(ERROR_INVALID_PARAMETER);
+ SetLastError(ERROR_INVALID_FLAGS);
}
else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
SetLastError(ERROR_INVALID_USER_BUFFER);
RegCloseKey(hEnumKey);
if (rc != ERROR_SUCCESS)
{
+ if (rc == ERROR_FILE_NOT_FOUND)
+ rc = ERROR_NO_SUCH_DEVINST;
SetLastError(rc);
return FALSE;
}
- /* FIXME: GUID_NULL is not allowed */
- if (!CreateDeviceInfoElement(DeviceInstanceId, &GUID_NULL /* FIXME */, &deviceInfo))
+ /* FIXME: try to get ClassGUID from registry, instead of
+ * sending GUID_NULL to CreateDeviceInfoElement
+ */
+ if (!CreateDeviceInfoElement(DeviceInstanceId, &GUID_NULL, &deviceInfo))
{
RegCloseKey(hKey);
return FALSE;
if (ret && deviceInfo && DeviceInfoData)
{
memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID));
- DeviceInfoData->DevInst = 0; /* FIXME */
+ DeviceInfoData->DevInst = (DWORD)list->hMachine;
DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
}
}
SetLastError(ERROR_INVALID_PARAMETER);
else if (DriverInfoDetailData && DriverInfoDetailData->cbSize != sizeof(SP_DRVINFO_DETAIL_DATA_W))
SetLastError(ERROR_INVALID_USER_BUFFER);
- else if (DriverInfoDetailData && DriverInfoDetailData->Reserved == 0)
+ else if (DriverInfoData->Reserved == 0)
SetLastError(ERROR_NO_DRIVER_SELECTED);
else
{
return TRUE;
}
+BOOL
+InfIsFromOEMLocation(
+ IN PCWSTR FullName,
+ OUT LPBOOL IsOEMLocation)
+{
+ PWCHAR last;
+
+ last = strrchrW(FullName, '\\');
+ if (!last)
+ {
+ /* No directory specified */
+ *IsOEMLocation = FALSE;
+ }
+ else
+ {
+ WCHAR Windir[MAX_PATH];
+ UINT ret;
+
+ ret = GetWindowsDirectory(Windir, MAX_PATH);
+ if (ret == 0 || ret >= MAX_PATH)
+ {
+ SetLastError(ERROR_GEN_FAILURE);
+ return FALSE;
+ }
+
+ if (strncmpW(FullName, Windir, last - FullName) == 0)
+ {
+ /* The path is %SYSTEMROOT%\Inf */
+ *IsOEMLocation = FALSE;
+ }
+ else
+ {
+ /* The file is in another place */
+ *IsOEMLocation = TRUE;
+ }
+ }
+ return TRUE;
+}
+
/***********************************************************************
* SetupDiInstallDevice (SETUPAPI.@)
*/
BOOL RebootRequired = FALSE;
HKEY hKey = INVALID_HANDLE_VALUE;
HKEY hClassKey = INVALID_HANDLE_VALUE;
+ BOOL NeedtoCopyFile;
LONG rc;
BOOL ret = FALSE; /* Return value */
NULL, 0,
&RequiredSize);
if (!Result)
- goto nextfile;
+ {
+ if (GetLastError() == ERROR_INVALID_PARAMETER)
+ {
+ /* This first is probably missing. It is not
+ * required, so ignore the error */
+ RequiredSize = 0;
+ Result = TRUE;
+ }
+ else
+ goto nextfile;
+ }
if (RequiredSize > 0)
{
/* We got the needed size for the buffer */
&RequiredSize);
if (!Result)
goto nextfile;
+
+ SetLastError(ERROR_SUCCESS);
+ Result = SetupInstallServicesFromInfSectionExW(
+ SelectedDriver->InfFileDetails->hInf,
+ ServiceSection, Flags, DeviceInfoSet, DeviceInfoData, ServiceName, NULL);
}
- SetLastError(ERROR_SUCCESS);
- Result = SetupInstallServicesFromInfSectionExW(
- SelectedDriver->InfFileDetails->hInf,
- ServiceSection, Flags, DeviceInfoSet, DeviceInfoData, ServiceName, NULL);
if (Result && (Flags & SPSVCINST_ASSOCSERVICE))
{
AssociatedService = ServiceName;
Result = SetupFindNextLine(&ContextService, &ContextService);
}
- /* Copy .inf file to Inf\ directory */
- FIXME("FIXME: Copy .inf file to Inf\\ directory\n"); /* SetupCopyOEMInf */
+ /* Copy .inf file to Inf\ directory (if needed) */
+ Result = InfIsFromOEMLocation(SelectedDriver->InfFileDetails->FullInfFileName, &NeedtoCopyFile);
+ if (!Result)
+ goto cleanup;
+ if (NeedtoCopyFile)
+ {
+ Result = SetupCopyOEMInfW(
+ SelectedDriver->InfFileDetails->FullInfFileName,
+ NULL,
+ SPOST_NONE,
+ SP_COPY_NOOVERWRITE,
+ NULL, 0,
+ NULL,
+ NULL);
+ if (!Result)
+ goto cleanup;
+ /* FIXME: create a new struct InfFileDetails, and set it to SelectedDriver->InfFileDetails,
+ * to release use of current InfFile */
+ }
/* Open device registry key */
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
/* Write information to enum key */
TRACE("Write information to enum key\n");
- TRACE("Service : '%S'\n", AssociatedService);
TRACE("Class : '%S'\n", ClassName);
TRACE("ClassGUID : '%S'\n", lpFullGuidString);
TRACE("DeviceDesc : '%S'\n", SelectedDriver->Info.Description);
TRACE("Mfg : '%S'\n", SelectedDriver->Info.MfgName);
- rc = RegSetValueEx(hKey, L"Service", 0, REG_SZ, (const BYTE *)AssociatedService, (wcslen(AssociatedService) + 1) * sizeof(WCHAR));
- if (rc == ERROR_SUCCESS)
- rc = RegSetValueEx(hKey, L"Class", 0, REG_SZ, (const BYTE *)ClassName, (wcslen(ClassName) + 1) * sizeof(WCHAR));
+ TRACE("Service : '%S'\n", AssociatedService);
+ rc = RegSetValueEx(hKey, L"Class", 0, REG_SZ, (const BYTE *)ClassName, (wcslen(ClassName) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
rc = RegSetValueEx(hKey, L"ClassGUID", 0, REG_SZ, (const BYTE *)lpFullGuidString, (wcslen(lpFullGuidString) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
rc = RegSetValueEx(hKey, L"DeviceDesc", 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (wcslen(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
if (rc == ERROR_SUCCESS)
rc = RegSetValueEx(hKey, L"Mfg", 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (wcslen(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
+ if (rc == ERROR_SUCCESS && *AssociatedService)
+ rc = RegSetValueEx(hKey, L"Service", 0, REG_SZ, (const BYTE *)AssociatedService, (wcslen(AssociatedService) + 1) * sizeof(WCHAR));
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);