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