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