Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187/* * ReactOS Device Manager Applet * Copyright (C) 2004 - 2005 ReactOS Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//* * PROJECT: ReactOS devmgr.dll * FILE: lib/devmgr/misc.c * PURPOSE: ReactOS Device Manager * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> * UPDATE HISTORY: * 2005/11/24 Created */
#include "precomp.h"#include "properties.h"#include "resource.h"
INTLengthOfStrResource(IN HINSTANCE hInst, IN UINT uID){ HRSRC hrSrc; HGLOBAL hRes; LPWSTR lpName, lpStr;
if (hInst == NULL) { return -1; }
/* There are always blocks of 16 strings */ lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
/* Find the string table block */ if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && (hRes = LoadResource(hInst, hrSrc)) && (lpStr = (LPWSTR)LockResource(hRes))) { UINT x;
/* Find the string we're looking for */ uID &= 0xF; /* position in the block, same as % 16 */ for (x = 0; x < uID; x++) { lpStr += (*lpStr) + 1; }
/* Found the string */ return (int)(*lpStr); } return -1;}
static INTAllocAndLoadString(OUT LPWSTR *lpTarget, IN HINSTANCE hInst, IN UINT uID){ INT ln;
ln = LengthOfStrResource(hInst, uID); if (ln++ > 0) { (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, ln * sizeof(WCHAR)); if ((*lpTarget) != NULL) { INT Ret; if (!(Ret = LoadStringW(hInst, uID, *lpTarget, ln))) { LocalFree((HLOCAL)(*lpTarget)); } return Ret; } } return 0;}
static INTAllocAndLoadStringsCat(OUT LPWSTR *lpTarget, IN HINSTANCE hInst, IN UINT *uID, IN UINT nIDs){ INT ln = 0; UINT i;
for (i = 0; i != nIDs; i++) { ln += LengthOfStrResource(hInst, uID[i]); }
if (ln != 0) { (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, (ln + 1) * sizeof(WCHAR)); if ((*lpTarget) != NULL) { LPWSTR s = *lpTarget; INT Ret = 0;
for (i = 0; i != nIDs; i++) { if (!(Ret = LoadStringW(hInst, uID[i], s, ln))) { LocalFree((HLOCAL)(*lpTarget)); return 0; }
s += Ret; }
return s - *lpTarget; } } return 0;}
DWORDLoadAndFormatString(IN HINSTANCE hInstance, IN UINT uID, OUT LPWSTR *lpTarget, ...){ DWORD Ret = 0; LPWSTR lpFormat; va_list lArgs;
if (AllocAndLoadString(&lpFormat, hInstance, uID) != 0) { va_start(lArgs, lpTarget); /* let's use FormatMessage to format it because it has the ability to allocate memory automatically */ Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, lpFormat, 0, 0, (LPWSTR)lpTarget, 0, &lArgs); va_end(lArgs);
LocalFree((HLOCAL)lpFormat); }
return Ret;}
DWORDLoadAndFormatStringsCat(IN HINSTANCE hInstance, IN UINT *uID, IN UINT nIDs, OUT LPWSTR *lpTarget, ...){ DWORD Ret = 0; LPWSTR lpFormat; va_list lArgs;
if (AllocAndLoadStringsCat(&lpFormat, hInstance, uID, nIDs) != 0) { va_start(lArgs, lpTarget); /* let's use FormatMessage to format it because it has the ability to allocate memory automatically */ Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, lpFormat, 0, 0, (LPWSTR)lpTarget, 0, &lArgs); va_end(lArgs);
LocalFree((HLOCAL)lpFormat); }
return Ret;}
LPARAMListViewGetSelectedItemData(IN HWND hwnd){ int Index;
Index = ListView_GetNextItem(hwnd, -1, LVNI_SELECTED); if (Index != -1) { LVITEM li;
li.mask = LVIF_PARAM; li.iItem = Index; li.iSubItem = 0;
if (ListView_GetItem(hwnd, &li)) { return li.lParam; } }
return 0;}
LPWSTRConvertMultiByteToUnicode(IN LPCSTR lpMultiByteStr, IN UINT uCodePage){ LPWSTR lpUnicodeStr; INT nLength;
nLength = MultiByteToWideChar(uCodePage, 0, lpMultiByteStr, -1, NULL, 0); if (nLength == 0) return NULL;
lpUnicodeStr = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, nLength * sizeof(WCHAR)); if (lpUnicodeStr == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; }
if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr, nLength, lpUnicodeStr, nLength)) { HeapFree(GetProcessHeap(), 0, lpUnicodeStr); return NULL; }
return lpUnicodeStr;}
BOOLGetDeviceManufacturerString(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR szBuffer, IN DWORD BufferSize){ DWORD RegDataType; BOOL Ret = FALSE;
if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_MFG, &RegDataType, (PBYTE)szBuffer, BufferSize * sizeof(WCHAR), NULL) || RegDataType != REG_SZ) { szBuffer[0] = L'\0'; if (LoadString(hDllInstance, IDS_UNKNOWN, szBuffer, BufferSize)) { Ret = TRUE; } } else { /* FIXME - check string for NULL termination! */ Ret = TRUE; }
return Ret;}
BOOLGetDeviceLocationString(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, IN DEVINST dnParentDevInst OPTIONAL, OUT LPWSTR szBuffer, IN DWORD BufferSize){ DWORD RegDataType; ULONG DataSize; CONFIGRET cRet; LPWSTR szFormatted; HKEY hKey; DWORD dwSize, dwType; BOOL Ret = FALSE;
DataSize = BufferSize * sizeof(WCHAR); szBuffer[0] = L'\0';
hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE); if (hKey != INVALID_HANDLE_VALUE) { /* query the LocationInformationOverride value */ dwSize = BufferSize; if (RegQueryValueEx(hKey, L"LocationInformationOverride", NULL, &dwType, (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS && dwType == REG_SZ && szBuffer[0] != L'\0') { Ret = TRUE; } else { szBuffer[0] = L'\0'; }
RegCloseKey(hKey); }
if (!Ret) { if (dnParentDevInst != 0) { /* query the parent node name */ if (CM_Get_DevNode_Registry_Property(dnParentDevInst, CM_DRP_DEVICEDESC, &RegDataType, szBuffer, &DataSize, 0) == CR_SUCCESS && RegDataType == REG_SZ && LoadAndFormatString(hDllInstance, IDS_DEVONPARENT, &szFormatted, szBuffer) != 0) { wcsncpy(szBuffer, szFormatted, BufferSize - 1); szBuffer[BufferSize - 1] = L'\0'; LocalFree((HLOCAL)szFormatted); Ret = TRUE; } } else if (DeviceInfoData->DevInst != 0) { cRet = CM_Get_DevNode_Registry_Property(DeviceInfoData->DevInst, CM_DRP_LOCATION_INFORMATION, &RegDataType, szBuffer, &DataSize, 0); if (cRet == CR_SUCCESS && RegDataType == REG_SZ) { /* FIXME - check string for NULL termination! */ Ret = TRUE; }
if (Ret && szBuffer[0] >= L'0' && szBuffer[0] <= L'9') { /* convert the string to an integer value and create a formatted string */ ULONG ulLocation = (ULONG)wcstoul(szBuffer, NULL, 10); if (LoadAndFormatString(hDllInstance, IDS_LOCATIONSTR, &szFormatted, ulLocation, szBuffer) != 0) { wcsncpy(szBuffer, szFormatted, BufferSize - 1); szBuffer[BufferSize - 1] = L'\0'; LocalFree((HLOCAL)szFormatted); } else Ret = FALSE; } } }
if (!Ret && LoadString(hDllInstance, IDS_UNKNOWN, szBuffer, BufferSize)) { Ret = TRUE; }
return Ret;}
BOOLGetDeviceStatusString(IN DEVINST DevInst, IN HMACHINE hMachine, OUT LPWSTR szBuffer, IN DWORD BufferSize){ CONFIGRET cr; ULONG Status, ProblemNumber; UINT MessageId = IDS_UNKNOWN; BOOL Ret = FALSE;
szBuffer[0] = L'\0'; cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { if (Status & DN_HAS_PROBLEM) { UINT uRet;
uRet = DeviceProblemTextW(hMachine, DevInst, ProblemNumber, szBuffer, (BufferSize != 0 ? BufferSize : BufferSize - 1));
Ret = (uRet != 0 && uRet < BufferSize); } else { if (!(Status & (DN_DRIVER_LOADED | DN_STARTED))) { MessageId = IDS_NODRIVERLOADED; } else { MessageId = IDS_DEV_NO_PROBLEM; }
goto GeneralMessage; } } else {GeneralMessage: if (LoadString(hDllInstance, MessageId, szBuffer, (int)BufferSize)) { Ret = TRUE; } }
return Ret;}
BOOLGetDriverProviderString(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR szBuffer, IN DWORD BufferSize){ HKEY hKey; DWORD dwSize, dwType; BOOL Ret = FALSE;
szBuffer[0] = L'\0';
/* get driver provider, date and version */ hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE); if (hKey != INVALID_HANDLE_VALUE) { /* query the driver provider */ dwSize = BufferSize; if (RegQueryValueEx(hKey, REGSTR_VAL_PROVIDER_NAME, NULL, &dwType, (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS && dwType == REG_SZ && szBuffer[0] != L'\0') { Ret = TRUE; } else { szBuffer[0] = L'\0'; }
RegCloseKey(hKey); }
if (szBuffer[0] == L'\0') { /* unable to query the information */ if (LoadString(hDllInstance, IDS_UNKNOWN, szBuffer, BufferSize)) { Ret = TRUE; } }
return Ret;}
BOOLGetDriverVersionString(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR szBuffer, IN DWORD BufferSize){ HKEY hKey; DWORD dwSize, dwType; BOOL Ret = FALSE;
szBuffer[0] = L'\0';
/* get driver provider, date and version */ hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE); if (hKey != INVALID_HANDLE_VALUE) { /* query the driver provider */ dwSize = BufferSize; if (RegQueryValueEx(hKey, L"DriverVersion", NULL, &dwType, (LPBYTE)szBuffer, &dwSize) == ERROR_SUCCESS && dwType == REG_SZ && szBuffer[0] != L'\0') { Ret = TRUE; } else { szBuffer[0] = L'\0'; }
RegCloseKey(hKey); }
if (szBuffer[0] == L'\0') { /* unable to query the information */ if (LoadString(hDllInstance, IDS_NOTAVAILABLE, szBuffer, BufferSize)) { Ret = TRUE; } }
return Ret;}
BOOLGetDriverDateString(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR szBuffer, IN DWORD BufferSize){ HKEY hKey; FILETIME DriverDate; SYSTEMTIME SystemTime, LocalTime; DWORD dwSize, dwType; BOOL Ret = FALSE;
szBuffer[0] = L'\0';
/* get driver provider, date and version */ hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE); if (hKey != INVALID_HANDLE_VALUE) { /* query the driver provider */ dwSize = sizeof(FILETIME); if (RegQueryValueEx(hKey, L"DriverDateData", NULL, &dwType, (LPBYTE)&DriverDate, &dwSize) == ERROR_SUCCESS && dwType == REG_BINARY && dwSize == sizeof(FILETIME) && FileTimeToSystemTime(&DriverDate, &SystemTime) && SystemTimeToTzSpecificLocalTime(NULL, &SystemTime, &LocalTime) && GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &LocalTime, NULL, szBuffer, BufferSize) != 0) { Ret = TRUE; }
RegCloseKey(hKey); }
if (!Ret) { /* unable to query the information */ if (LoadString(hDllInstance, IDS_NOTAVAILABLE, szBuffer, BufferSize)) { Ret = TRUE; } }
return Ret;}
BOOLIsDeviceHidden(IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *IsHidden){ CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE;
cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *IsHidden = ((Status & DN_NO_SHOW_IN_DM) != 0); Ret = TRUE; }
return Ret;}
BOOLCanDisableDevice(IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *CanDisable){ CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE;
cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *CanDisable = ((Status & DN_DISABLEABLE) != 0); Ret = TRUE; }
return Ret;}
BOOLIsDeviceStarted(IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *IsStarted){ CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE;
cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *IsStarted = ((Status & DN_STARTED) != 0); Ret = TRUE; }
return Ret;}
BOOLIsDriverInstalled(IN DEVINST DevInst, IN HMACHINE hMachine, OUT BOOL *Installed){ CONFIGRET cr; ULONG Status, ProblemNumber; BOOL Ret = FALSE;
cr = CM_Get_DevNode_Status_Ex(&Status, &ProblemNumber, DevInst, 0, hMachine); if (cr == CR_SUCCESS) { *Installed = ((Status & DN_HAS_PROBLEM) != 0 || (Status & (DN_DRIVER_LOADED | DN_STARTED)) != 0); Ret = TRUE; }
return Ret;}
BOOLEnableDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, IN BOOL bEnable, IN DWORD HardwareProfile OPTIONAL, OUT BOOL *bNeedReboot OPTIONAL){ SP_PROPCHANGE_PARAMS pcp; SP_DEVINSTALL_PARAMS dp; DWORD LastErr; BOOL Ret = FALSE;
pcp.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); pcp.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; pcp.HwProfile = HardwareProfile;
if (bEnable) { /* try to enable the device on the global profile */ pcp.StateChange = DICS_ENABLE; pcp.Scope = DICS_FLAG_GLOBAL;
/* ignore errors */ LastErr = GetLastError(); if (SetupDiSetClassInstallParams(DeviceInfoSet, DevInfoData, &pcp.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS))) { SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DeviceInfoSet, DevInfoData); } SetLastError(LastErr); }
/* try config-specific */ pcp.StateChange = (bEnable ? DICS_ENABLE : DICS_DISABLE); pcp.Scope = DICS_FLAG_CONFIGSPECIFIC;
if (SetupDiSetClassInstallParams(DeviceInfoSet, DevInfoData, &pcp.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS)) && SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, DeviceInfoSet, DevInfoData)) { dp.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (SetupDiGetDeviceInstallParams(DeviceInfoSet, DevInfoData, &dp)) { if (bNeedReboot != NULL) { *bNeedReboot = ((dp.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) != 0); }
Ret = TRUE; } } return Ret;}
BOOLGetDeviceTypeString(IN PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR szBuffer, IN DWORD BufferSize){ BOOL Ret = FALSE;
if (!SetupDiGetClassDescription(&DeviceInfoData->ClassGuid, szBuffer, BufferSize, NULL)) { szBuffer[0] = L'\0'; if (LoadString(hDllInstance, IDS_UNKNOWN, szBuffer, BufferSize)) { Ret = TRUE; } } else { /* FIXME - check string for NULL termination! */ Ret = TRUE; }
return Ret;}
BOOLGetDeviceDescriptionString(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, OUT LPWSTR szBuffer, IN DWORD BufferSize){ DWORD RegDataType; BOOL Ret = FALSE;
if ((SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, &RegDataType, (PBYTE)szBuffer, BufferSize * sizeof(WCHAR), NULL) || SetupDiGetDeviceRegistryProperty(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC, &RegDataType, (PBYTE)szBuffer, BufferSize * sizeof(WCHAR), NULL)) && RegDataType == REG_SZ) { /* FIXME - check string for NULL termination! */ Ret = TRUE; } else { szBuffer[0] = L'\0'; if (LoadString(hDllInstance, IDS_UNKNOWNDEVICE, szBuffer, BufferSize)) { Ret = TRUE; } }
return Ret;}
BOOLFindCurrentDriver(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, OUT PSP_DRVINFO_DATA DriverInfoData){ HKEY hKey = (HKEY)INVALID_HANDLE_VALUE; SP_DEVINSTALL_PARAMS InstallParams = {0}; SP_DRVINFO_DETAIL_DATA DriverInfoDetailData = {0}; WCHAR InfPath[MAX_PATH]; WCHAR InfSection[LINE_LEN]; DWORD dwType, dwLength; DWORD i = 0; LONG rc; BOOL Ret = FALSE;
/* Steps to find the right driver: * 1) Get the device install parameters * 2) Open the driver registry key * 3) Read the .inf file name * 4) Update install params, by setting DI_ENUMSINGLEINF and .inf file name * 5) Build class driver list * 6) Read inf section and inf section extension from registry * 7) Enumerate drivers * 8) Find the one who is in the same section as current driver? */
/* 1) Get the install params */ InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (!SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams)) { ERR("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError()); goto Cleanup; }
#ifdef DI_FLAGSEX_INSTALLEDDRIVER InstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); if (SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams)) { if (SetupDiBuildDriverInfoList(DeviceInfoSet, DeviceInfoData, SPDIT_CLASSDRIVER) && SetupDiEnumDriverInfo(DeviceInfoSet, DeviceInfoData, SPDIT_CLASSDRIVER, 0, DriverInfoData)) { Ret = TRUE; }
goto Cleanup; } InstallParams.FlagsEx &= ~(DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);#endif
/* 2) Open the driver registry key */ hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE); if (hKey == INVALID_HANDLE_VALUE) { ERR("SetupDiOpenDevRegKey() failed with error 0x%lx\n", GetLastError()); goto Cleanup; }
/* 3) Read the .inf file name */ dwLength = (sizeof(InfPath) / sizeof(InfPath[0])) - 1; rc = RegQueryValueEx(hKey, REGSTR_VAL_INFPATH, 0, &dwType, (LPBYTE)InfPath, &dwLength); if (rc != ERROR_SUCCESS) { ERR("RegQueryValueEx() failed with error 0x%lx\n", GetLastError()); SetLastError(rc); goto Cleanup; } else if (dwType != REG_SZ) { ERR("Expected registry type REG_SZ (%lu), got %lu\n", REG_SZ, dwType); SetLastError(ERROR_GEN_FAILURE); goto Cleanup; } InfPath[(dwLength / sizeof(WCHAR)) - 1] = L'\0';
/* 4) Update install params, by setting DI_ENUMSINGLEINF and .inf file name */ InstallParams.Flags |= DI_ENUMSINGLEINF; InstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; wcscpy(InstallParams.DriverPath, InfPath); if (!SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &InstallParams)) { ERR("SetupDiSetDeviceInstallParams() failed with error 0x%lx\n", GetLastError()); goto Cleanup; }
/* 5) Build class driver list */ if (!SetupDiBuildDriverInfoList(DeviceInfoSet, DeviceInfoData, SPDIT_CLASSDRIVER)) { ERR("SetupDiBuildDriverInfoList() failed with error 0x%lx\n", GetLastError()); goto Cleanup; }
/* 6) Read inf section and from registry */ dwLength = (sizeof(InfSection) / sizeof(InfSection[0])) - 1; rc = RegQueryValueEx(hKey, REGSTR_VAL_INFSECTION, 0, &dwType, (LPBYTE)InfSection, &dwLength); if (rc != ERROR_SUCCESS) { ERR("RegQueryValueEx() failed with error 0x%lx\n", GetLastError()); SetLastError(rc); goto Cleanup; } else if (dwType != REG_SZ) { ERR("Expected registry type REG_SZ (%lu), got %lu\n", REG_SZ, dwType); SetLastError(ERROR_GEN_FAILURE); goto Cleanup; } InfPath[(dwLength / sizeof(WCHAR)) - 1] = L'\0';
/* 7) Enumerate drivers */ DriverInfoData->cbSize = sizeof(SP_DRVINFO_DATA); DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); while (SetupDiEnumDriverInfo(DeviceInfoSet, DeviceInfoData, SPDIT_CLASSDRIVER, i, DriverInfoData)) { /* 8) Find the one who is in the same section as current driver */ if (!SetupDiGetDriverInfoDetail(DeviceInfoSet, DeviceInfoData, DriverInfoData, &DriverInfoDetailData, DriverInfoDetailData.cbSize, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { ERR("SetupDiGetDriverInfoDetail() failed with error 0x%lx\n", GetLastError()); goto Cleanup; } if (_wcsicmp(DriverInfoDetailData.SectionName, InfSection) == 0) { /* We have found the right driver */ Ret = TRUE; goto Cleanup; }
i++; } if (GetLastError() != ERROR_NO_MORE_ITEMS) { ERR("SetupDiEnumDriverInfo() failed with error 0x%lx\n", GetLastError()); goto Cleanup; }
SetLastError(ERROR_NO_DRIVER_SELECTED);
Cleanup: if (hKey != INVALID_HANDLE_VALUE) RegCloseKey(hKey); return Ret;}
HINSTANCELoadAndInitComctl32(VOID){ typedef VOID (WINAPI *PINITCOMMONCONTROLS)(VOID); PINITCOMMONCONTROLS pInitCommonControls; HINSTANCE hComCtl32;
hComCtl32 = LoadLibrary(L"comctl32.dll"); if (hComCtl32 != NULL) { /* initialize the common controls */ pInitCommonControls = (PINITCOMMONCONTROLS)GetProcAddress(hComCtl32, "InitCommonControls"); if (pInitCommonControls == NULL) { FreeLibrary(hComCtl32); return NULL; }
pInitCommonControls(); }
return hComCtl32;}
BOOLGetDeviceAndComputerName(LPWSTR lpString, WCHAR szDeviceID[], WCHAR szMachineName[]){ BOOL ret = FALSE;
szDeviceID[0] = L'\0'; szMachineName[0] = L'\0';
while (*lpString != L'\0') { if (*lpString == L'/') { lpString++; if (!_wcsnicmp(lpString, L"DeviceID", 8)) { lpString += 9; if (*lpString != L'\0') { int i = 0; while ((*lpString != L' ') && (*lpString != L'\0') && (i <= MAX_DEVICE_ID_LEN)) { szDeviceID[i++] = *lpString++; } szDeviceID[i] = L'\0'; ret = TRUE; } } else if (!_wcsnicmp(lpString, L"MachineName", 11)) { lpString += 12; if (*lpString != L'\0') { int i = 0; while ((*lpString != L' ') && (*lpString != L'\0') && (i <= MAX_COMPUTERNAME_LENGTH)) { szMachineName[i++] = *lpString++; } szMachineName[i] = L'\0'; } } /* knock the pointer back one and let the next * pointer deal with incrementing, otherwise we * go past the end of the string */ lpString--; } lpString++; }
return ret;}