ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

misc.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.