1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Display Control Panel 4 * FILE: dll/cpl/desk/classinst.c 5 * PURPOSE: Class installers 6 * 7 * PROGRAMMERS: Herv� Poussineau (hpoussin@reactos.org) 8 */ 9 10 #include "desk.h" 11 12 //#define NDEBUG 13 #include <debug.h> 14 15 DWORD WINAPI 16 DisplayClassInstaller( 17 IN DI_FUNCTION InstallFunction, 18 IN HDEVINFO DeviceInfoSet, 19 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) 20 { 21 SP_DEVINSTALL_PARAMS InstallParams; 22 SP_DRVINFO_DATA DriverInfoData; 23 HINF hInf = INVALID_HANDLE_VALUE; 24 TCHAR SectionName[MAX_PATH]; 25 TCHAR ServiceName[MAX_SERVICE_NAME_LEN]; 26 TCHAR DeviceName[12]; 27 SP_DRVINFO_DETAIL_DATA DriverInfoDetailData; 28 DISPLAY_DEVICE DisplayDevice; 29 HKEY hDriverKey = INVALID_HANDLE_VALUE; /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */ 30 HKEY hSettingsKey = NULL; 31 HKEY hServicesKey = NULL; 32 HKEY hServiceKey = NULL; 33 HKEY hDeviceSubKey = NULL; 34 DWORD disposition, cchMax, cbData; 35 WORD wIndex; 36 BOOL result; 37 LONG rc; 38 HRESULT hr; 39 40 if (InstallFunction != DIF_INSTALLDEVICE) 41 return ERROR_DI_DO_DEFAULT; 42 43 /* Set DI_DONOTCALLCONFIGMG flag */ 44 InstallParams.cbSize = sizeof(InstallParams); 45 result = SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams); 46 if (!result) 47 { 48 rc = GetLastError(); 49 DPRINT("SetupDiGetDeviceInstallParams() failed with error 0x%lx\n", rc); 50 goto cleanup; 51 } 52 53 InstallParams.Flags |= DI_DONOTCALLCONFIGMG; 54 55 result = SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams); 56 if (!result) 57 { 58 rc = GetLastError(); 59 DPRINT("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", rc); 60 goto cleanup; 61 } 62 63 /* Do normal install */ 64 result = SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData); 65 if (!result) 66 { 67 rc = GetLastError(); 68 DPRINT("SetupDiInstallDevice() failed with error 0x%lx\n", rc); 69 goto cleanup; 70 } 71 72 /* Get .inf file name and section name */ 73 DriverInfoData.cbSize = sizeof(DriverInfoData); 74 result = SetupDiGetSelectedDriver(DeviceInfoSet, DeviceInfoData, &DriverInfoData); 75 if (!result) 76 { 77 rc = GetLastError(); 78 DPRINT("SetupDiGetSelectedDriver() failed with error 0x%lx\n", rc); 79 goto cleanup; 80 } 81 82 DriverInfoDetailData.cbSize = sizeof(DriverInfoDetailData); 83 result = SetupDiGetDriverInfoDetail(DeviceInfoSet, DeviceInfoData, 84 &DriverInfoData, &DriverInfoDetailData, 85 sizeof(DriverInfoDetailData), NULL); 86 if (!result && GetLastError() != ERROR_INSUFFICIENT_BUFFER) 87 { 88 rc = GetLastError(); 89 DPRINT("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", rc); 90 goto cleanup; 91 } 92 93 hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName, NULL, INF_STYLE_WIN4, NULL); 94 if (hInf == INVALID_HANDLE_VALUE) 95 { 96 rc = GetLastError(); 97 DPRINT("SetupOpenInfFile() failed with error 0x%lx\n", rc); 98 goto cleanup; 99 } 100 101 cchMax = MAX_PATH - (sizeof(_T(".SoftwareSettings")) / sizeof(TCHAR)); 102 result = SetupDiGetActualSectionToInstall(hInf, 103 DriverInfoDetailData.SectionName, 104 SectionName, 105 cchMax, 106 NULL, 107 NULL); 108 if (!result) 109 { 110 rc = GetLastError(); 111 DPRINT("SetupDiGetActualSectionToInstall() failed with error 0x%lx\n", rc); 112 goto cleanup; 113 } 114 hr = StringCbCat(SectionName, sizeof(SectionName), _T(".SoftwareSettings")); 115 if (FAILED(hr)) 116 { 117 rc = ERROR_INSUFFICIENT_BUFFER; 118 goto cleanup; 119 } 120 121 /* Open driver registry key and create Settings subkey */ 122 hDriverKey = SetupDiOpenDevRegKey( 123 DeviceInfoSet, DeviceInfoData, 124 DICS_FLAG_GLOBAL, 0, DIREG_DRV, 125 KEY_CREATE_SUB_KEY); 126 if (hDriverKey == INVALID_HANDLE_VALUE) 127 { 128 rc = GetLastError(); 129 DPRINT("SetupDiOpenDevRegKey() failed with error 0x%lx\n", rc); 130 goto cleanup; 131 } 132 rc = RegCreateKeyEx( 133 hDriverKey, L"Settings", 134 0, NULL, REG_OPTION_NON_VOLATILE, 135 #if _WIN32_WINNT >= 0x502 136 KEY_READ | KEY_WRITE, 137 #else 138 KEY_ALL_ACCESS, 139 #endif 140 NULL, &hSettingsKey, &disposition); 141 if (rc != ERROR_SUCCESS) 142 { 143 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc); 144 goto cleanup; 145 } 146 147 /* Install .SoftwareSettings to Settings subkey */ 148 result = SetupInstallFromInfSection( 149 InstallParams.hwndParent, hInf, SectionName, 150 SPINST_REGISTRY, hSettingsKey, 151 NULL, 0, NULL, NULL, 152 NULL, NULL); 153 if (!result) 154 { 155 rc = GetLastError(); 156 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc); 157 goto cleanup; 158 } 159 160 /* Get service name and open service registry key */ 161 result = SetupDiGetDeviceRegistryProperty( 162 DeviceInfoSet, DeviceInfoData, 163 SPDRP_SERVICE, NULL, 164 (PBYTE)ServiceName, MAX_SERVICE_NAME_LEN * sizeof(TCHAR), NULL); 165 if (!result) 166 { 167 rc = GetLastError(); 168 DPRINT("SetupDiGetDeviceRegistryProperty() failed with error 0x%lx\n", rc); 169 goto cleanup; 170 } 171 172 rc = RegOpenKeyEx( 173 HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services"), 174 0, KEY_ENUMERATE_SUB_KEYS, &hServicesKey); 175 if (rc != ERROR_SUCCESS) 176 { 177 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc); 178 goto cleanup; 179 } 180 rc = RegOpenKeyEx( 181 hServicesKey, ServiceName, 182 0, KEY_CREATE_SUB_KEY, &hServiceKey); 183 if (rc != ERROR_SUCCESS) 184 { 185 DPRINT("RegOpenKeyEx() failed with error 0x%lx\n", rc); 186 goto cleanup; 187 } 188 189 /* Create a new DeviceX subkey */ 190 for (wIndex = 0; wIndex < 9999; wIndex++) 191 { 192 _stprintf(DeviceName, _T("Device%hu"), wIndex); 193 194 rc = RegCreateKeyEx( 195 hServiceKey, DeviceName, 0, NULL, 196 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, 197 &hDeviceSubKey, &disposition); 198 if (rc != ERROR_SUCCESS) 199 { 200 DPRINT("RegCreateKeyEx() failed with error 0x%lx\n", rc); 201 goto cleanup; 202 } 203 204 if (disposition == REG_CREATED_NEW_KEY) 205 break; 206 207 if (wIndex == 9999) 208 { 209 rc = ERROR_GEN_FAILURE; 210 DPRINT("RegCreateKeyEx() failed\n"); 211 goto cleanup; 212 } 213 214 RegCloseKey(hDeviceSubKey); 215 hDeviceSubKey = NULL; 216 } 217 218 /* Install SoftwareSettings section */ 219 /* Yes, we're installing this section for the second time. 220 * We don't want to create a link to Settings subkey */ 221 result = SetupInstallFromInfSection( 222 InstallParams.hwndParent, hInf, SectionName, 223 SPINST_REGISTRY, hDeviceSubKey, 224 NULL, 0, NULL, NULL, 225 NULL, NULL); 226 if (!result) 227 { 228 rc = GetLastError(); 229 DPRINT("SetupInstallFromInfSection() failed with error 0x%lx\n", rc); 230 goto cleanup; 231 } 232 233 /* Add Device Description string */ 234 cbData = (DWORD)(_tcslen(DriverInfoData.Description) + 1) * sizeof(TCHAR); 235 rc = RegSetValueEx(hDeviceSubKey, 236 _T("Device Description"), 237 0, 238 REG_SZ, 239 (const BYTE*)DriverInfoData.Description, 240 cbData); 241 if (rc != ERROR_SUCCESS) 242 { 243 DPRINT("RegSetValueEx() failed with error 0x%lx\n", rc); 244 goto cleanup; 245 } 246 247 /* FIXME: install OpenGLSoftwareSettings section */ 248 249 /* Reenumerate display devices ; this will rescan for potential new devices */ 250 DisplayDevice.cb = sizeof(DISPLAY_DEVICE); 251 EnumDisplayDevices(NULL, 0, &DisplayDevice, 0); 252 253 rc = ERROR_SUCCESS; 254 255 cleanup: 256 if (hInf != INVALID_HANDLE_VALUE) 257 SetupCloseInfFile(hInf); 258 if (hDriverKey != INVALID_HANDLE_VALUE) 259 { 260 /* SetupDiOpenDevRegKey returns INVALID_HANDLE_VALUE in case of error! */ 261 RegCloseKey(hDriverKey); 262 } 263 if (hSettingsKey != NULL) 264 RegCloseKey(hSettingsKey); 265 if (hServicesKey != NULL) 266 RegCloseKey(hServicesKey); 267 if (hServiceKey != NULL) 268 RegCloseKey(hServiceKey); 269 if (hDeviceSubKey != NULL) 270 RegCloseKey(hDeviceSubKey); 271 272 return rc; 273 } 274 275 DWORD WINAPI 276 MonitorClassInstaller( 277 IN DI_FUNCTION InstallFunction, 278 IN HDEVINFO DeviceInfoSet, 279 IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL) 280 { 281 return ERROR_DI_DO_DEFAULT; 282 } 283