Author: janderwald
Date: Fri Dec 18 05:37:15 2009
New Revision: 44644
URL:
http://svn.reactos.org/svn/reactos?rev=44644&view=rev
Log:
[SETUPAPI]
- Implement SetupDiInstallDeviceInterfaces, SetupDiCreateDeviceInterfaceRegKeyW which are
required to store device specific information
Modified:
trunk/reactos/dll/win32/setupapi/devinst.c
trunk/reactos/dll/win32/setupapi/interface.c
trunk/reactos/dll/win32/setupapi/setupapi_private.h
Modified: trunk/reactos/dll/win32/setupapi/devinst.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/devinst…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/devinst.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/setupapi/devinst.c [iso-8859-1] Fri Dec 18 05:37:15 2009
@@ -2628,7 +2628,14 @@
HINF InfHandle,
PCWSTR InfSectionName)
{
+ HKEY hKey, hDevKey;
+ LPWSTR SymbolicLink;
+ DWORD Length, Index;
+ LONG rc;
+ WCHAR bracedGuidString[39];
+ struct DeviceInterface *DevItf;
struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+
TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData,
Reserved,
samDesired, InfHandle, InfSectionName);
@@ -2650,11 +2657,79 @@
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
-
- FIXME("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData,
Reserved,
- samDesired, InfHandle, InfSectionName);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return INVALID_HANDLE_VALUE;
+
+ hKey = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid,
samDesired, DIOCR_INTERFACE, NULL, NULL);
+ if (hKey == INVALID_HANDLE_VALUE)
+ {
+ hKey = SetupDiOpenClassRegKeyExW(NULL, samDesired, DIOCR_INTERFACE, NULL, NULL);
+ if (hKey == INVALID_HANDLE_VALUE)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return INVALID_HANDLE_VALUE;
+ }
+ SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid,
bracedGuidString);
+
+ if (RegCreateKeyExW(hKey, bracedGuidString, 0, NULL, 0, samDesired, NULL,
&hDevKey, NULL) != ERROR_SUCCESS)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return INVALID_HANDLE_VALUE;
+ }
+ RegCloseKey(hKey);
+ hKey = hDevKey;
+ }
+
+ DevItf = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
+
+ Length = (wcslen(DevItf->SymbolicLink)+1) * sizeof(WCHAR);
+ SymbolicLink = HeapAlloc(GetProcessHeap(), 0, Length);
+ if (!SymbolicLink)
+ {
+ RegCloseKey(hKey);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return INVALID_HANDLE_VALUE;
+ }
+
+ wcscpy(SymbolicLink, DevItf->SymbolicLink);
+
+ Index = 0;
+ while(SymbolicLink[Index])
+ {
+ if (SymbolicLink[Index] == L'\\')
+ {
+ SymbolicLink[Index] = L'#';
+ }
+ Index++;
+ }
+
+ rc = RegCreateKeyExW(hKey, SymbolicLink, 0, NULL, 0, samDesired, NULL, &hDevKey,
NULL);
+
+ RegCloseKey(hKey);
+ HeapFree(GetProcessHeap(), 0, SymbolicLink);
+
+ if (rc == ERROR_SUCCESS)
+ {
+ if (InfHandle && InfSectionName)
+ {
+ if (!SetupInstallFromInfSection(NULL /*FIXME */,
+ InfHandle,
+ InfSectionName,
+ SPINST_INIFILES | SPINST_REGISTRY |
SPINST_INI2REG | SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | SPINST_UNREGSVR |
SPINST_PROFILEITEMS | SPINST_COPYINF,
+ hDevKey,
+ NULL,
+ 0,
+
set->SelectedDevice->InstallParams.InstallMsgHandler,
+
set->SelectedDevice->InstallParams.InstallMsgHandlerContext,
+ INVALID_HANDLE_VALUE,
+ NULL))
+ {
+ RegCloseKey(hDevKey);
+ return INVALID_HANDLE_VALUE;
+ }
+ }
+ }
+
+ SetLastError(rc);
+ return hDevKey;
}
/***********************************************************************
@@ -3611,6 +3686,7 @@
key = INVALID_HANDLE_VALUE;
}
}
+
return key;
}
Modified: trunk/reactos/dll/win32/setupapi/interface.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/interfa…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/interface.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/setupapi/interface.c [iso-8859-1] Fri Dec 18 05:37:15 2009
@@ -292,22 +292,118 @@
return rc;
}
+static LPWSTR
+CreateSymbolicLink(
+ IN LPGUID InterfaceGuid,
+ IN LPCWSTR ReferenceString,
+ IN struct DeviceInfo *devInfo)
+{
+ DWORD Length, Index, Offset;
+ LPWSTR Key;
+
+ Length = wcslen(devInfo->instanceId) + 4 /* prepend ##?# */ + 41 /* #{GUID} + */ +
1 /* zero byte */;
+
+ Key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Length * sizeof(WCHAR));
+ if (!Key)
+ return NULL;
+
+ wcscpy(Key, L"##?#");
+ wcscat(Key, devInfo->instanceId);
+
+ for(Index = 4; Index < Length; Index++)
+ {
+ if (Key[Index] == L'\\')
+ {
+ Key[Index] = L'#';
+ }
+ }
+
+ wcscat(Key, L"#");
+
+ Offset = wcslen(Key);
+ pSetupStringFromGuid(InterfaceGuid, Key + Offset, Length - Offset);
+
+ return Key;
+}
+
+
static BOOL
InstallOneInterface(
IN LPGUID InterfaceGuid,
IN LPCWSTR ReferenceString,
IN LPCWSTR InterfaceSection,
- IN UINT InterfaceFlags)
+ IN UINT InterfaceFlags,
+ IN HINF hInf,
+ IN HDEVINFO DeviceInfoSet,
+ IN struct DeviceInfo *devInfo)
{
+ BOOL ret;
+ HKEY hKey, hRefKey;
+ LPWSTR Path;
+ SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
+ PLIST_ENTRY InterfaceListEntry;
+ struct DeviceInterface *DevItf = NULL;
+
if (InterfaceFlags != 0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- FIXME("Need to InstallOneInterface(%s %s %s %u)\n",
debugstr_guid(InterfaceGuid),
- debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags);
- return TRUE;
+ TRACE("Need to InstallOneInterface(%s %s %s %u) hInf %p DeviceInfoSet %p devInfo
%p instanceId %s\n", debugstr_guid(InterfaceGuid),
+ debugstr_w(ReferenceString), debugstr_w(InterfaceSection), InterfaceFlags, hInf,
DeviceInfoSet, devInfo, debugstr_w(devInfo->instanceId));
+
+
+ Path = CreateSymbolicLink(InterfaceGuid, ReferenceString, devInfo);
+ if (!Path)
+ return FALSE;
+
+ CreateDeviceInterface(devInfo, Path, InterfaceGuid, &DevItf);
+ HeapFree(GetProcessHeap(), 0, Path);
+ if (!DevItf)
+ {
+ return FALSE;
+ }
+
+ InsertTailList(&devInfo->InterfaceListHead, &DevItf->ListEntry);
+
+ memcpy(&DeviceInterfaceData.InterfaceClassGuid,
&DevItf->InterfaceClassGuid, sizeof(GUID));
+ DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+ DeviceInterfaceData.Flags = DevItf->Flags;
+ DeviceInterfaceData.Reserved = (ULONG_PTR)DevItf;
+
+ hKey = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet, &DeviceInterfaceData,
0, KEY_ALL_ACCESS, NULL, 0);
+ HeapFree(GetProcessHeap(), 0, DevItf);
+ if (hKey == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
+
+ if (ReferenceString)
+ {
+ Path = HeapAlloc(GetProcessHeap(), 0, (wcslen(ReferenceString) + 2) *
sizeof(WCHAR));
+ if (!Path)
+ {
+ RegCloseKey(hKey);
+ return FALSE;
+ }
+
+ wcscpy(Path, L"#");
+ wcscat(Path, ReferenceString);
+
+ if (RegCreateKeyExW(hKey, Path, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hRefKey,
NULL) != ERROR_SUCCESS)
+ {
+ ERR("failed to create key %s %lx\n", debugstr_w(Path),
GetLastError());
+ HeapFree(GetProcessHeap(), 0, Path);
+ return FALSE;
+ }
+
+ RegCloseKey(hKey);
+ hKey = hRefKey;
+ HeapFree(GetProcessHeap(), 0, Path);
+ }
+
+ return SetupInstallFromInfSectionW(NULL, /* FIXME */ hInf, InterfaceSection,
SPINST_REGISTRY, hKey, NULL, 0, NULL, NULL, NULL, NULL);
}
/***********************************************************************
@@ -335,7 +431,8 @@
SetLastError(ERROR_INVALID_USER_BUFFER);
else
{
- struct DriverInfoElement *SelectedDriver;
+ struct DeviceInfo *devInfo;
+ struct DriverInfoElement *SelectedDriver = NULL;
SP_DEVINSTALL_PARAMS_W InstallParams;
WCHAR SectionName[MAX_PATH];
DWORD SectionNameLength = 0;
@@ -347,6 +444,8 @@
GUID InterfaceGuid;
BOOL Result;
+ devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+
InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData,
&InstallParams);
if (!Result)
@@ -402,11 +501,15 @@
ret = GetStringField(&ContextInterface, 3, &InterfaceSection);
if (!ret)
- goto cleanup;
+ {
+ /* ReferenceString is optional */
+ InterfaceSection = ReferenceString;
+ ReferenceString = NULL;
+ }
ret = SetupGetIntField(
&ContextInterface,
- 4, /* Field index */
+ (ReferenceString ? 4 : 3), /* Field index */
&InterfaceFlags);
if (!ret)
{
@@ -421,11 +524,12 @@
}
/* Install Interface */
- ret = InstallOneInterface(&InterfaceGuid, ReferenceString,
InterfaceSection, InterfaceFlags);
+ ret = InstallOneInterface(&InterfaceGuid, ReferenceString,
InterfaceSection, InterfaceFlags, SelectedDriver->InfFileDetails->hInf,
DeviceInfoSet, devInfo);
cleanup:
MyFree(InterfaceGuidString);
- MyFree(ReferenceString);
+ if (ReferenceString)
+ MyFree(ReferenceString);
MyFree(InterfaceSection);
InterfaceGuidString = ReferenceString = InterfaceSection = NULL;
Result = SetupFindNextMatchLineW(&ContextInterface, AddInterface,
&ContextInterface);
Modified: trunk/reactos/dll/win32/setupapi/setupapi_private.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/setupap…
==============================================================================
--- trunk/reactos/dll/win32/setupapi/setupapi_private.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/setupapi/setupapi_private.h [iso-8859-1] Fri Dec 18 05:37:15
2009
@@ -334,6 +334,10 @@
IN HMODULE ModulePointer,
IN PVOID FunctionPointer);
+DWORD
+WINAPI
+pSetupStringFromGuid(LPGUID lpGUID, PWSTR pString, DWORD dwStringLen);
+
DWORD WINAPI CaptureAndConvertAnsiArg(LPCSTR pSrc, LPWSTR *pDst);
VOID WINAPI MyFree(LPVOID lpMem);