Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmisc.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS Device Manager Applet 00003 * Copyright (C) 2004 - 2005 ReactOS Team 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 /* $Id: devmgr.c 12852 2005-01-06 13:58:04Z mf $ 00020 * 00021 * PROJECT: ReactOS devmgr.dll 00022 * FILE: lib/devmgr/misc.c 00023 * PURPOSE: ReactOS Device Manager 00024 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 00025 * UPDATE HISTORY: 00026 * 2005/11/24 Created 00027 */ 00028 #include <precomp.h> 00029 00030 #define NDEBUG 00031 #include <debug.h> 00032 00033 HINSTANCE hDllInstance = NULL; 00034 00035 00036 INT 00037 LengthOfStrResource(IN HINSTANCE hInst, 00038 IN UINT uID) 00039 { 00040 HRSRC hrSrc; 00041 HGLOBAL hRes; 00042 LPWSTR lpName, lpStr; 00043 00044 if (hInst == NULL) 00045 { 00046 return -1; 00047 } 00048 00049 /* There are always blocks of 16 strings */ 00050 lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); 00051 00052 /* Find the string table block */ 00053 if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && 00054 (hRes = LoadResource(hInst, hrSrc)) && 00055 (lpStr = LockResource(hRes))) 00056 { 00057 UINT x; 00058 00059 /* Find the string we're looking for */ 00060 uID &= 0xF; /* position in the block, same as % 16 */ 00061 for (x = 0; x < uID; x++) 00062 { 00063 lpStr += (*lpStr) + 1; 00064 } 00065 00066 /* Found the string */ 00067 return (int)(*lpStr); 00068 } 00069 return -1; 00070 } 00071 00072 00073 static INT 00074 AllocAndLoadString(OUT LPWSTR *lpTarget, 00075 IN HINSTANCE hInst, 00076 IN UINT uID) 00077 { 00078 INT ln; 00079 00080 ln = LengthOfStrResource(hInst, 00081 uID); 00082 if (ln++ > 0) 00083 { 00084 (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, 00085 ln * sizeof(WCHAR)); 00086 if ((*lpTarget) != NULL) 00087 { 00088 INT Ret; 00089 if (!(Ret = LoadStringW(hInst, uID, *lpTarget, ln))) 00090 { 00091 LocalFree((HLOCAL)(*lpTarget)); 00092 } 00093 return Ret; 00094 } 00095 } 00096 return 0; 00097 } 00098 00099 00100 static INT 00101 AllocAndLoadStringsCat(OUT LPWSTR *lpTarget, 00102 IN HINSTANCE hInst, 00103 IN UINT *uID, 00104 IN UINT nIDs) 00105 { 00106 INT ln = 0; 00107 UINT i; 00108 00109 for (i = 0; 00110 i != nIDs; 00111 i++) 00112 { 00113 ln += LengthOfStrResource(hInst, 00114 uID[i]); 00115 } 00116 00117 if (ln != 0) 00118 { 00119 (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, 00120 (ln + 1) * sizeof(WCHAR)); 00121 if ((*lpTarget) != NULL) 00122 { 00123 LPWSTR s = *lpTarget; 00124 INT Ret = 0; 00125 00126 for (i = 0; 00127 i != nIDs; 00128 i++) 00129 { 00130 if (!(Ret = LoadStringW(hInst, uID[i], s, ln))) 00131 { 00132 LocalFree((HLOCAL)(*lpTarget)); 00133 } 00134 00135 s += Ret; 00136 } 00137 00138 return s - *lpTarget; 00139 } 00140 } 00141 return 0; 00142 } 00143 00144 00145 DWORD 00146 LoadAndFormatString(IN HINSTANCE hInstance, 00147 IN UINT uID, 00148 OUT LPWSTR *lpTarget, 00149 ...) 00150 { 00151 DWORD Ret = 0; 00152 LPWSTR lpFormat; 00153 va_list lArgs; 00154 00155 if (AllocAndLoadString(&lpFormat, 00156 hInstance, 00157 uID) != 0) 00158 { 00159 va_start(lArgs, lpTarget); 00160 /* let's use FormatMessage to format it because it has the ability to allocate 00161 memory automatically */ 00162 Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, 00163 lpFormat, 00164 0, 00165 0, 00166 (LPWSTR)lpTarget, 00167 0, 00168 &lArgs); 00169 va_end(lArgs); 00170 00171 LocalFree((HLOCAL)lpFormat); 00172 } 00173 00174 return Ret; 00175 } 00176 00177 00178 DWORD 00179 LoadAndFormatStringsCat(IN HINSTANCE hInstance, 00180 IN UINT *uID, 00181 IN UINT nIDs, 00182 OUT LPWSTR *lpTarget, 00183 ...) 00184 { 00185 DWORD Ret = 0; 00186 LPWSTR lpFormat; 00187 va_list lArgs; 00188 00189 if (AllocAndLoadStringsCat(&lpFormat, 00190 hInstance, 00191 uID, 00192 nIDs) != 0) 00193 { 00194 va_start(lArgs, lpTarget); 00195 /* let's use FormatMessage to format it because it has the ability to allocate 00196 memory automatically */ 00197 Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, 00198 lpFormat, 00199 0, 00200 0, 00201 (LPWSTR)lpTarget, 00202 0, 00203 &lArgs); 00204 va_end(lArgs); 00205 00206 LocalFree((HLOCAL)lpFormat); 00207 } 00208 00209 return Ret; 00210 } 00211 00212 00213 LPARAM 00214 ListViewGetSelectedItemData(IN HWND hwnd) 00215 { 00216 int Index; 00217 00218 Index = ListView_GetNextItem(hwnd, 00219 -1, 00220 LVNI_SELECTED); 00221 if (Index != -1) 00222 { 00223 LVITEM li; 00224 00225 li.mask = LVIF_PARAM; 00226 li.iItem = Index; 00227 li.iSubItem = 0; 00228 00229 if (ListView_GetItem(hwnd, 00230 &li)) 00231 { 00232 return li.lParam; 00233 } 00234 } 00235 00236 return 0; 00237 } 00238 00239 00240 LPWSTR 00241 ConvertMultiByteToUnicode(IN LPCSTR lpMultiByteStr, 00242 IN UINT uCodePage) 00243 { 00244 LPWSTR lpUnicodeStr; 00245 INT nLength; 00246 00247 nLength = MultiByteToWideChar(uCodePage, 00248 0, 00249 lpMultiByteStr, 00250 -1, 00251 NULL, 00252 0); 00253 if (nLength == 0) 00254 return NULL; 00255 00256 lpUnicodeStr = HeapAlloc(GetProcessHeap(), 00257 0, 00258 nLength * sizeof(WCHAR)); 00259 if (lpUnicodeStr == NULL) 00260 { 00261 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00262 return NULL; 00263 } 00264 00265 if (!MultiByteToWideChar(uCodePage, 00266 0, 00267 lpMultiByteStr, 00268 nLength, 00269 lpUnicodeStr, 00270 nLength)) 00271 { 00272 HeapFree(GetProcessHeap(), 00273 0, 00274 lpUnicodeStr); 00275 return NULL; 00276 } 00277 00278 return lpUnicodeStr; 00279 } 00280 00281 00282 BOOL 00283 GetDeviceManufacturerString(IN HDEVINFO DeviceInfoSet, 00284 IN PSP_DEVINFO_DATA DeviceInfoData, 00285 OUT LPWSTR szBuffer, 00286 IN DWORD BufferSize) 00287 { 00288 DWORD RegDataType; 00289 BOOL Ret = FALSE; 00290 00291 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 00292 DeviceInfoData, 00293 SPDRP_MFG, 00294 &RegDataType, 00295 (PBYTE)szBuffer, 00296 BufferSize * sizeof(WCHAR), 00297 NULL) || 00298 RegDataType != REG_SZ) 00299 { 00300 szBuffer[0] = L'\0'; 00301 if (LoadString(hDllInstance, 00302 IDS_UNKNOWN, 00303 szBuffer, 00304 BufferSize)) 00305 { 00306 Ret = TRUE; 00307 } 00308 } 00309 else 00310 { 00311 /* FIXME - check string for NULL termination! */ 00312 Ret = TRUE; 00313 } 00314 00315 return Ret; 00316 } 00317 00318 00319 BOOL 00320 GetDeviceLocationString(IN HDEVINFO DeviceInfoSet, 00321 IN PSP_DEVINFO_DATA DeviceInfoData, 00322 IN DEVINST dnParentDevInst OPTIONAL, 00323 OUT LPWSTR szBuffer, 00324 IN DWORD BufferSize) 00325 { 00326 DWORD RegDataType; 00327 ULONG DataSize; 00328 CONFIGRET cRet; 00329 LPWSTR szFormatted; 00330 HKEY hKey; 00331 DWORD dwSize, dwType; 00332 BOOL Ret = FALSE; 00333 00334 DataSize = BufferSize * sizeof(WCHAR); 00335 szBuffer[0] = L'\0'; 00336 00337 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 00338 DeviceInfoData, 00339 DICS_FLAG_GLOBAL, 00340 0, 00341 DIREG_DRV, 00342 KEY_QUERY_VALUE); 00343 if (hKey != INVALID_HANDLE_VALUE) 00344 { 00345 /* query the LocationInformationOverride value */ 00346 dwSize = BufferSize; 00347 if (RegQueryValueEx(hKey, 00348 L"LocationInformationOverride", 00349 NULL, 00350 &dwType, 00351 (LPBYTE)szBuffer, 00352 &dwSize) == ERROR_SUCCESS && 00353 dwType == REG_SZ && 00354 szBuffer[0] != L'\0') 00355 { 00356 Ret = TRUE; 00357 } 00358 else 00359 { 00360 szBuffer[0] = L'\0'; 00361 } 00362 00363 RegCloseKey(hKey); 00364 } 00365 00366 00367 if (!Ret) 00368 { 00369 if (dnParentDevInst != 0) 00370 { 00371 /* query the parent node name */ 00372 if (CM_Get_DevNode_Registry_Property(dnParentDevInst, 00373 CM_DRP_DEVICEDESC, 00374 &RegDataType, 00375 szBuffer, 00376 &DataSize, 00377 0) == CR_SUCCESS && 00378 RegDataType == REG_SZ && 00379 LoadAndFormatString(hDllInstance, 00380 IDS_DEVONPARENT, 00381 &szFormatted, 00382 szBuffer) != 0) 00383 { 00384 wcsncpy(szBuffer, 00385 szFormatted, 00386 BufferSize - 1); 00387 szBuffer[BufferSize - 1] = L'\0'; 00388 LocalFree((HLOCAL)szFormatted); 00389 Ret = TRUE; 00390 } 00391 } 00392 else if (DeviceInfoData->DevInst != 0) 00393 { 00394 cRet = CM_Get_DevNode_Registry_Property(DeviceInfoData->DevInst, 00395 CM_DRP_LOCATION_INFORMATION, 00396 &RegDataType, 00397 szBuffer, 00398 &DataSize, 00399 0); 00400 if (cRet == CR_SUCCESS && RegDataType == REG_SZ) 00401 { 00402 /* FIXME - check string for NULL termination! */ 00403 Ret = TRUE; 00404 } 00405 00406 if (Ret && szBuffer[0] >= L'0' && szBuffer[0] <= L'9') 00407 { 00408 /* convert the string to an integer value and create a 00409 formatted string */ 00410 ULONG ulLocation = (ULONG)wcstoul(szBuffer, 00411 NULL, 00412 10); 00413 if (LoadAndFormatString(hDllInstance, 00414 IDS_LOCATIONSTR, 00415 &szFormatted, 00416 ulLocation, 00417 szBuffer) != 0) 00418 { 00419 wcsncpy(szBuffer, 00420 szFormatted, 00421 BufferSize - 1); 00422 szBuffer[BufferSize - 1] = L'\0'; 00423 LocalFree((HLOCAL)szFormatted); 00424 } 00425 else 00426 Ret = FALSE; 00427 } 00428 } 00429 } 00430 00431 if (!Ret && 00432 LoadString(hDllInstance, 00433 IDS_UNKNOWN, 00434 szBuffer, 00435 BufferSize)) 00436 { 00437 Ret = TRUE; 00438 } 00439 00440 return Ret; 00441 } 00442 00443 00444 BOOL 00445 GetDeviceStatusString(IN DEVINST DevInst, 00446 IN HMACHINE hMachine, 00447 OUT LPWSTR szBuffer, 00448 IN DWORD BufferSize) 00449 { 00450 CONFIGRET cr; 00451 ULONG Status, ProblemNumber; 00452 UINT MessageId = IDS_UNKNOWN; 00453 BOOL Ret = FALSE; 00454 00455 szBuffer[0] = L'\0'; 00456 cr = CM_Get_DevNode_Status_Ex(&Status, 00457 &ProblemNumber, 00458 DevInst, 00459 0, 00460 hMachine); 00461 if (cr == CR_SUCCESS) 00462 { 00463 if (Status & DN_HAS_PROBLEM) 00464 { 00465 UINT uRet; 00466 00467 uRet = DeviceProblemText(hMachine, 00468 DevInst, 00469 ProblemNumber, 00470 szBuffer, 00471 (BufferSize != 0 ? BufferSize : BufferSize - 1)); 00472 00473 Ret = (uRet != 0 && uRet < BufferSize); 00474 } 00475 else 00476 { 00477 if (!(Status & (DN_DRIVER_LOADED | DN_STARTED))) 00478 { 00479 MessageId = IDS_NODRIVERLOADED; 00480 } 00481 else 00482 { 00483 MessageId = IDS_DEV_NO_PROBLEM; 00484 } 00485 00486 goto GeneralMessage; 00487 } 00488 } 00489 else 00490 { 00491 GeneralMessage: 00492 if (LoadString(hDllInstance, 00493 MessageId, 00494 szBuffer, 00495 (int)BufferSize)) 00496 { 00497 Ret = TRUE; 00498 } 00499 } 00500 00501 return Ret; 00502 } 00503 00504 00505 BOOL 00506 GetDriverProviderString(IN HDEVINFO DeviceInfoSet, 00507 IN PSP_DEVINFO_DATA DeviceInfoData, 00508 OUT LPWSTR szBuffer, 00509 IN DWORD BufferSize) 00510 { 00511 HKEY hKey; 00512 DWORD dwSize, dwType; 00513 BOOL Ret = FALSE; 00514 00515 szBuffer[0] = L'\0'; 00516 00517 /* get driver provider, date and version */ 00518 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 00519 DeviceInfoData, 00520 DICS_FLAG_GLOBAL, 00521 0, 00522 DIREG_DRV, 00523 KEY_QUERY_VALUE); 00524 if (hKey != INVALID_HANDLE_VALUE) 00525 { 00526 /* query the driver provider */ 00527 dwSize = BufferSize; 00528 if (RegQueryValueEx(hKey, 00529 REGSTR_VAL_PROVIDER_NAME, 00530 NULL, 00531 &dwType, 00532 (LPBYTE)szBuffer, 00533 &dwSize) == ERROR_SUCCESS && 00534 dwType == REG_SZ && 00535 szBuffer[0] != L'\0') 00536 { 00537 Ret = TRUE; 00538 } 00539 else 00540 { 00541 szBuffer[0] = L'\0'; 00542 } 00543 00544 RegCloseKey(hKey); 00545 } 00546 00547 if (szBuffer[0] == L'\0') 00548 { 00549 /* unable to query the information */ 00550 if (LoadString(hDllInstance, 00551 IDS_UNKNOWN, 00552 szBuffer, 00553 BufferSize)) 00554 { 00555 Ret = TRUE; 00556 } 00557 } 00558 00559 return Ret; 00560 } 00561 00562 00563 BOOL 00564 GetDriverVersionString(IN HDEVINFO DeviceInfoSet, 00565 IN PSP_DEVINFO_DATA DeviceInfoData, 00566 OUT LPWSTR szBuffer, 00567 IN DWORD BufferSize) 00568 { 00569 HKEY hKey; 00570 DWORD dwSize, dwType; 00571 BOOL Ret = FALSE; 00572 00573 szBuffer[0] = L'\0'; 00574 00575 /* get driver provider, date and version */ 00576 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 00577 DeviceInfoData, 00578 DICS_FLAG_GLOBAL, 00579 0, 00580 DIREG_DRV, 00581 KEY_QUERY_VALUE); 00582 if (hKey != INVALID_HANDLE_VALUE) 00583 { 00584 /* query the driver provider */ 00585 dwSize = BufferSize; 00586 if (RegQueryValueEx(hKey, 00587 L"DriverVersion", 00588 NULL, 00589 &dwType, 00590 (LPBYTE)szBuffer, 00591 &dwSize) == ERROR_SUCCESS && 00592 dwType == REG_SZ && 00593 szBuffer[0] != L'\0') 00594 { 00595 Ret = TRUE; 00596 } 00597 else 00598 { 00599 szBuffer[0] = L'\0'; 00600 } 00601 00602 RegCloseKey(hKey); 00603 } 00604 00605 if (szBuffer[0] == L'\0') 00606 { 00607 /* unable to query the information */ 00608 if (LoadString(hDllInstance, 00609 IDS_NOTAVAILABLE, 00610 szBuffer, 00611 BufferSize)) 00612 { 00613 Ret = TRUE; 00614 } 00615 } 00616 00617 return Ret; 00618 } 00619 00620 BOOL 00621 GetDriverDateString(IN HDEVINFO DeviceInfoSet, 00622 IN PSP_DEVINFO_DATA DeviceInfoData, 00623 OUT LPWSTR szBuffer, 00624 IN DWORD BufferSize) 00625 { 00626 HKEY hKey; 00627 FILETIME DriverDate; 00628 SYSTEMTIME SystemTime, LocalTime; 00629 DWORD dwSize, dwType; 00630 BOOL Ret = FALSE; 00631 00632 szBuffer[0] = L'\0'; 00633 00634 /* get driver provider, date and version */ 00635 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 00636 DeviceInfoData, 00637 DICS_FLAG_GLOBAL, 00638 0, 00639 DIREG_DRV, 00640 KEY_QUERY_VALUE); 00641 if (hKey != INVALID_HANDLE_VALUE) 00642 { 00643 /* query the driver provider */ 00644 dwSize = sizeof(FILETIME); 00645 if (RegQueryValueEx(hKey, 00646 L"DriverDateData", 00647 NULL, 00648 &dwType, 00649 (LPBYTE)&DriverDate, 00650 &dwSize) == ERROR_SUCCESS && 00651 dwType == REG_BINARY && 00652 dwSize == sizeof(FILETIME) && 00653 FileTimeToSystemTime(&DriverDate, 00654 &SystemTime) && 00655 SystemTimeToTzSpecificLocalTime(NULL, 00656 &SystemTime, 00657 &LocalTime) && 00658 GetDateFormat(LOCALE_USER_DEFAULT, 00659 DATE_SHORTDATE, 00660 &LocalTime, 00661 NULL, 00662 szBuffer, 00663 BufferSize) != 0) 00664 { 00665 Ret = TRUE; 00666 } 00667 00668 RegCloseKey(hKey); 00669 } 00670 00671 if (!Ret) 00672 { 00673 /* unable to query the information */ 00674 if (LoadString(hDllInstance, 00675 IDS_NOTAVAILABLE, 00676 szBuffer, 00677 BufferSize)) 00678 { 00679 Ret = TRUE; 00680 } 00681 } 00682 00683 return Ret; 00684 } 00685 00686 00687 00688 BOOL 00689 IsDeviceHidden(IN DEVINST DevInst, 00690 IN HMACHINE hMachine, 00691 OUT BOOL *IsHidden) 00692 { 00693 CONFIGRET cr; 00694 ULONG Status, ProblemNumber; 00695 BOOL Ret = FALSE; 00696 00697 cr = CM_Get_DevNode_Status_Ex(&Status, 00698 &ProblemNumber, 00699 DevInst, 00700 0, 00701 hMachine); 00702 if (cr == CR_SUCCESS) 00703 { 00704 *IsHidden = ((Status & DN_NO_SHOW_IN_DM) != 0); 00705 Ret = TRUE; 00706 } 00707 00708 return Ret; 00709 } 00710 00711 00712 BOOL 00713 CanDisableDevice(IN DEVINST DevInst, 00714 IN HMACHINE hMachine, 00715 OUT BOOL *CanDisable) 00716 { 00717 CONFIGRET cr; 00718 ULONG Status, ProblemNumber; 00719 BOOL Ret = FALSE; 00720 00721 cr = CM_Get_DevNode_Status_Ex(&Status, 00722 &ProblemNumber, 00723 DevInst, 00724 0, 00725 hMachine); 00726 if (cr == CR_SUCCESS) 00727 { 00728 *CanDisable = ((Status & DN_DISABLEABLE) != 0); 00729 Ret = TRUE; 00730 } 00731 00732 return Ret; 00733 } 00734 00735 00736 BOOL 00737 IsDeviceStarted(IN DEVINST DevInst, 00738 IN HMACHINE hMachine, 00739 OUT BOOL *IsStarted) 00740 { 00741 CONFIGRET cr; 00742 ULONG Status, ProblemNumber; 00743 BOOL Ret = FALSE; 00744 00745 cr = CM_Get_DevNode_Status_Ex(&Status, 00746 &ProblemNumber, 00747 DevInst, 00748 0, 00749 hMachine); 00750 if (cr == CR_SUCCESS) 00751 { 00752 *IsStarted = ((Status & DN_STARTED) != 0); 00753 Ret = TRUE; 00754 } 00755 00756 return Ret; 00757 } 00758 00759 00760 BOOL 00761 IsDriverInstalled(IN DEVINST DevInst, 00762 IN HMACHINE hMachine, 00763 OUT BOOL *Installed) 00764 { 00765 CONFIGRET cr; 00766 ULONG Status, ProblemNumber; 00767 BOOL Ret = FALSE; 00768 00769 cr = CM_Get_DevNode_Status_Ex(&Status, 00770 &ProblemNumber, 00771 DevInst, 00772 0, 00773 hMachine); 00774 if (cr == CR_SUCCESS) 00775 { 00776 *Installed = ((Status & DN_HAS_PROBLEM) != 0 || 00777 (Status & (DN_DRIVER_LOADED | DN_STARTED)) != 0); 00778 Ret = TRUE; 00779 } 00780 00781 return Ret; 00782 } 00783 00784 00785 BOOL 00786 EnableDevice(IN HDEVINFO DeviceInfoSet, 00787 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, 00788 IN BOOL bEnable, 00789 IN DWORD HardwareProfile OPTIONAL, 00790 OUT BOOL *bNeedReboot OPTIONAL) 00791 { 00792 SP_PROPCHANGE_PARAMS pcp; 00793 SP_DEVINSTALL_PARAMS dp; 00794 DWORD LastErr; 00795 BOOL Ret = FALSE; 00796 00797 pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); 00798 pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 00799 pcp.HwProfile = HardwareProfile; 00800 00801 if (bEnable) 00802 { 00803 /* try to enable the device on the global profile */ 00804 pcp.StateChange = DICS_ENABLE; 00805 pcp.Scope = DICS_FLAG_GLOBAL; 00806 00807 /* ignore errors */ 00808 LastErr = GetLastError(); 00809 if (SetupDiSetClassInstallParams(DeviceInfoSet, 00810 DevInfoData, 00811 &pcp.ClassInstallHeader, 00812 sizeof(SP_PROPCHANGE_PARAMS))) 00813 { 00814 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, 00815 DeviceInfoSet, 00816 DevInfoData); 00817 } 00818 SetLastError(LastErr); 00819 } 00820 00821 /* try config-specific */ 00822 pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE); 00823 pcp.Scope = DICS_FLAG_CONFIGSPECIFIC; 00824 00825 if (SetupDiSetClassInstallParams(DeviceInfoSet, 00826 DevInfoData, 00827 &pcp.ClassInstallHeader, 00828 sizeof(SP_PROPCHANGE_PARAMS)) && 00829 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, 00830 DeviceInfoSet, 00831 DevInfoData)) 00832 { 00833 dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 00834 if (SetupDiGetDeviceInstallParams(DeviceInfoSet, 00835 DevInfoData, 00836 &dp)) 00837 { 00838 if (bNeedReboot != NULL) 00839 { 00840 *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0); 00841 } 00842 00843 Ret = TRUE; 00844 } 00845 } 00846 return Ret; 00847 } 00848 00849 00850 BOOL 00851 GetDeviceTypeString(IN PSP_DEVINFO_DATA DeviceInfoData, 00852 OUT LPWSTR szBuffer, 00853 IN DWORD BufferSize) 00854 { 00855 BOOL Ret = FALSE; 00856 00857 if (!SetupDiGetClassDescription(&DeviceInfoData->ClassGuid, 00858 szBuffer, 00859 BufferSize, 00860 NULL)) 00861 { 00862 szBuffer[0] = L'\0'; 00863 if (LoadString(hDllInstance, 00864 IDS_UNKNOWN, 00865 szBuffer, 00866 BufferSize)) 00867 { 00868 Ret = TRUE; 00869 } 00870 } 00871 else 00872 { 00873 /* FIXME - check string for NULL termination! */ 00874 Ret = TRUE; 00875 } 00876 00877 return Ret; 00878 } 00879 00880 00881 BOOL 00882 GetDeviceDescriptionString(IN HDEVINFO DeviceInfoSet, 00883 IN PSP_DEVINFO_DATA DeviceInfoData, 00884 OUT LPWSTR szBuffer, 00885 IN DWORD BufferSize) 00886 { 00887 DWORD RegDataType; 00888 BOOL Ret = FALSE; 00889 00890 if ((SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 00891 DeviceInfoData, 00892 SPDRP_FRIENDLYNAME, 00893 &RegDataType, 00894 (PBYTE)szBuffer, 00895 BufferSize * sizeof(WCHAR), 00896 NULL) || 00897 SetupDiGetDeviceRegistryProperty(DeviceInfoSet, 00898 DeviceInfoData, 00899 SPDRP_DEVICEDESC, 00900 &RegDataType, 00901 (PBYTE)szBuffer, 00902 BufferSize * sizeof(WCHAR), 00903 NULL)) && 00904 RegDataType == REG_SZ) 00905 { 00906 /* FIXME - check string for NULL termination! */ 00907 Ret = TRUE; 00908 } 00909 else 00910 { 00911 szBuffer[0] = L'\0'; 00912 if (LoadString(hDllInstance, 00913 IDS_UNKNOWNDEVICE, 00914 szBuffer, 00915 BufferSize)) 00916 { 00917 Ret = TRUE; 00918 } 00919 } 00920 00921 return Ret; 00922 } 00923 00924 00925 BOOL 00926 FindCurrentDriver(IN HDEVINFO DeviceInfoSet, 00927 IN PSP_DEVINFO_DATA DeviceInfoData, 00928 OUT PSP_DRVINFO_DATA DriverInfoData) 00929 { 00930 HKEY hKey = INVALID_HANDLE_VALUE; 00931 SP_DEVINSTALL_PARAMS InstallParams = {0}; 00932 SP_DRVINFO_DETAIL_DATA DriverInfoDetailData = {0}; 00933 WCHAR InfPath[MAX_PATH]; 00934 WCHAR InfSection[LINE_LEN]; 00935 DWORD dwType, dwLength; 00936 DWORD i = 0; 00937 LONG rc; 00938 BOOL Ret = FALSE; 00939 00940 /* Steps to find the right driver: 00941 * 1) Get the device install parameters 00942 * 2) Open the driver registry key 00943 * 3) Read the .inf file name 00944 * 4) Update install params, by setting DI_ENUMSINGLEINF and .inf file name 00945 * 5) Build class driver list 00946 * 6) Read inf section and inf section extension from registry 00947 * 7) Enumerate drivers 00948 * 8) Find the one who is in the same section as current driver? 00949 */ 00950 00951 /* 1) Get the install params */ 00952 InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 00953 if (!SetupDiGetDeviceInstallParams(DeviceInfoSet, 00954 DeviceInfoData, 00955 &InstallParams)) 00956 { 00957 DPRINT1("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError()); 00958 goto Cleanup; 00959 } 00960 00961 #ifdef DI_FLAGSEX_INSTALLEDDRIVER 00962 InstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); 00963 if (SetupDiSetDeviceInstallParams(DeviceInfoSet, 00964 DeviceInfoData, 00965 &InstallParams)) 00966 { 00967 if (SetupDiBuildDriverInfoList(DeviceInfoSet, 00968 DeviceInfoData, 00969 SPDIT_CLASSDRIVER) && 00970 SetupDiEnumDriverInfo(DeviceInfoSet, 00971 DeviceInfoData, 00972 SPDIT_CLASSDRIVER, 00973 0, 00974 DriverInfoData)) 00975 { 00976 Ret = TRUE; 00977 } 00978 00979 goto Cleanup; 00980 } 00981 InstallParams.FlagsEx &= ~(DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); 00982 #endif 00983 00984 /* 2) Open the driver registry key */ 00985 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, 00986 DeviceInfoData, 00987 DICS_FLAG_GLOBAL, 00988 0, 00989 DIREG_DRV, 00990 KEY_QUERY_VALUE); 00991 if (hKey == INVALID_HANDLE_VALUE) 00992 { 00993 DPRINT1("SetupDiOpenDevRegKey() failed with error 0x%lx\n", GetLastError()); 00994 goto Cleanup; 00995 } 00996 00997 /* 3) Read the .inf file name */ 00998 dwLength = (sizeof(InfPath) / sizeof(InfPath[0])) - 1; 00999 rc = RegQueryValueEx(hKey, 01000 REGSTR_VAL_INFPATH, 01001 0, 01002 &dwType, 01003 (LPBYTE)InfPath, 01004 &dwLength); 01005 if (rc != ERROR_SUCCESS) 01006 { 01007 SetLastError(rc); 01008 DPRINT1("RegQueryValueEx() failed with error 0x%lx\n", GetLastError()); 01009 goto Cleanup; 01010 } 01011 else if (dwType != REG_SZ) 01012 { 01013 SetLastError(ERROR_GEN_FAILURE); 01014 DPRINT1("Expected registry type REG_SZ (%lu), got %lu\n", REG_SZ, dwType); 01015 goto Cleanup; 01016 } 01017 InfPath[(dwLength / sizeof(WCHAR)) - 1] = L'\0'; 01018 01019 /* 4) Update install params, by setting DI_ENUMSINGLEINF and .inf file name */ 01020 InstallParams.Flags |= DI_ENUMSINGLEINF; 01021 InstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; 01022 wcscpy(InstallParams.DriverPath, InfPath); 01023 if (!SetupDiSetDeviceInstallParams(DeviceInfoSet, 01024 DeviceInfoData, 01025 &InstallParams)) 01026 { 01027 DPRINT1("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError()); 01028 goto Cleanup; 01029 } 01030 01031 /* 5) Build class driver list */ 01032 if (!SetupDiBuildDriverInfoList(DeviceInfoSet, 01033 DeviceInfoData, 01034 SPDIT_CLASSDRIVER)) 01035 { 01036 DPRINT1("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError()); 01037 goto Cleanup; 01038 } 01039 01040 /* 6) Read inf section and from registry */ 01041 dwLength = (sizeof(InfSection) / sizeof(InfSection[0])) - 1; 01042 rc = RegQueryValueEx(hKey, 01043 REGSTR_VAL_INFSECTION, 01044 0, 01045 &dwType, 01046 (LPBYTE)InfSection, 01047 &dwLength); 01048 if (rc != ERROR_SUCCESS) 01049 { 01050 SetLastError(rc); 01051 DPRINT1("RegQueryValueEx() failed with error 0x%lx\n", GetLastError()); 01052 goto Cleanup; 01053 } 01054 else if (dwType != REG_SZ) 01055 { 01056 SetLastError(ERROR_GEN_FAILURE); 01057 DPRINT1("Expected registry type REG_SZ (%lu), got %lu\n", REG_SZ, dwType); 01058 goto Cleanup; 01059 } 01060 InfPath[(dwLength / sizeof(WCHAR)) - 1] = L'\0'; 01061 01062 /* 7) Enumerate drivers */ 01063 DriverInfoData->cbSize = sizeof(SP_DRVINFO_DATA); 01064 DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); 01065 while (SetupDiEnumDriverInfo(DeviceInfoSet, 01066 DeviceInfoData, 01067 SPDIT_CLASSDRIVER, 01068 i, 01069 DriverInfoData)) 01070 { 01071 /* 8) Find the one who is in the same section as current driver */ 01072 if (!SetupDiGetDriverInfoDetail(DeviceInfoSet, 01073 DeviceInfoData, 01074 DriverInfoData, 01075 &DriverInfoDetailData, 01076 DriverInfoDetailData.cbSize, 01077 NULL) && 01078 GetLastError() != ERROR_INSUFFICIENT_BUFFER) 01079 { 01080 DPRINT1("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", GetLastError()); 01081 goto Cleanup; 01082 } 01083 if (!wcsicmp(DriverInfoDetailData.SectionName, 01084 InfSection) != 0) 01085 { 01086 /* We have found the right driver */ 01087 Ret = TRUE; 01088 goto Cleanup; 01089 } 01090 01091 i++; 01092 } 01093 if (GetLastError() != ERROR_NO_MORE_ITEMS) 01094 { 01095 DPRINT1("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError()); 01096 goto Cleanup; 01097 } 01098 01099 SetLastError(ERROR_NO_DRIVER_SELECTED); 01100 01101 Cleanup: 01102 if (hKey != INVALID_HANDLE_VALUE) 01103 RegCloseKey(hKey); 01104 return Ret; 01105 } 01106 01107 01108 HINSTANCE 01109 LoadAndInitComctl32(VOID) 01110 { 01111 typedef VOID (WINAPI *PINITCOMMONCONTROLS)(VOID); 01112 PINITCOMMONCONTROLS pInitCommonControls; 01113 HINSTANCE hComCtl32; 01114 01115 hComCtl32 = LoadLibrary(L"comctl32.dll"); 01116 if (hComCtl32 != NULL) 01117 { 01118 /* initialize the common controls */ 01119 pInitCommonControls = (PINITCOMMONCONTROLS)GetProcAddress(hComCtl32, 01120 "InitCommonControls"); 01121 if (pInitCommonControls == NULL) 01122 { 01123 FreeLibrary(hComCtl32); 01124 return NULL; 01125 } 01126 01127 pInitCommonControls(); 01128 } 01129 01130 return hComCtl32; 01131 } 01132 01133 01134 BOOL 01135 WINAPI 01136 DllMain(IN HINSTANCE hinstDLL, 01137 IN DWORD dwReason, 01138 IN LPVOID lpvReserved) 01139 { 01140 switch (dwReason) 01141 { 01142 case DLL_PROCESS_ATTACH: 01143 DisableThreadLibraryCalls(hinstDLL); 01144 hDllInstance = hinstDLL; 01145 break; 01146 } 01147 01148 return TRUE; 01149 } Generated on Mon May 28 2012 04:16:50 for ReactOS by
1.7.6.1
|