2 * ReactOS Device Manager Applet
3 * Copyright (C) 2004 - 2005 ReactOS Team
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /* $Id: devmgr.c 12852 2005-01-06 13:58:04Z mf $
21 * PROJECT: ReactOS devmgr.dll
22 * FILE: lib/devmgr/misc.c
23 * PURPOSE: ReactOS Device Manager
24 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
30 HINSTANCE hDllInstance
= NULL
;
34 LengthOfStrResource(IN HINSTANCE hInst
,
46 /* There are always blocks of 16 strings */
47 lpName
= (LPWSTR
)MAKEINTRESOURCE((uID
>> 4) + 1);
49 /* Find the string table block */
50 if ((hrSrc
= FindResourceW(hInst
, lpName
, (LPWSTR
)RT_STRING
)) &&
51 (hRes
= LoadResource(hInst
, hrSrc
)) &&
52 (lpStr
= LockResource(hRes
)))
56 /* Find the string we're looking for */
57 uID
&= 0xF; /* position in the block, same as % 16 */
58 for (x
= 0; x
< uID
; x
++)
60 lpStr
+= (*lpStr
) + 1;
63 /* Found the string */
71 AllocAndLoadString(OUT LPWSTR
*lpTarget
,
77 ln
= LengthOfStrResource(hInst
,
81 (*lpTarget
) = (LPWSTR
)LocalAlloc(LMEM_FIXED
,
83 if ((*lpTarget
) != NULL
)
86 if (!(Ret
= LoadStringW(hInst
, uID
, *lpTarget
, ln
)))
88 LocalFree((HLOCAL
)(*lpTarget
));
98 AllocAndLoadStringsCat(OUT LPWSTR
*lpTarget
,
110 ln
+= LengthOfStrResource(hInst
,
116 (*lpTarget
) = (LPWSTR
)LocalAlloc(LMEM_FIXED
,
117 (ln
+ 1) * sizeof(WCHAR
));
118 if ((*lpTarget
) != NULL
)
120 LPWSTR s
= *lpTarget
;
127 if (!(Ret
= LoadStringW(hInst
, uID
[i
], s
, ln
)))
129 LocalFree((HLOCAL
)(*lpTarget
));
135 return s
- *lpTarget
;
143 LoadAndFormatString(IN HINSTANCE hInstance
,
145 OUT LPWSTR
*lpTarget
,
152 if (AllocAndLoadString(&lpFormat
,
156 va_start(lArgs
, lpTarget
);
157 /* let's use FormatMessage to format it because it has the ability to allocate
158 memory automatically */
159 Ret
= FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
168 LocalFree((HLOCAL
)lpFormat
);
176 LoadAndFormatStringsCat(IN HINSTANCE hInstance
,
179 OUT LPWSTR
*lpTarget
,
186 if (AllocAndLoadStringsCat(&lpFormat
,
191 va_start(lArgs
, lpTarget
);
192 /* let's use FormatMessage to format it because it has the ability to allocate
193 memory automatically */
194 Ret
= FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_STRING
,
203 LocalFree((HLOCAL
)lpFormat
);
211 ListViewGetSelectedItemData(IN HWND hwnd
)
215 Index
= ListView_GetNextItem(hwnd
,
222 li
.mask
= LVIF_PARAM
;
226 if (ListView_GetItem(hwnd
,
238 ConvertMultiByteToUnicode(IN LPCSTR lpMultiByteStr
,
244 nLength
= MultiByteToWideChar(uCodePage
,
253 lpUnicodeStr
= HeapAlloc(GetProcessHeap(),
255 nLength
* sizeof(WCHAR
));
256 if (lpUnicodeStr
== NULL
)
258 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
262 if (!MultiByteToWideChar(uCodePage
,
269 HeapFree(GetProcessHeap(),
280 GetDeviceManufacturerString(IN HDEVINFO DeviceInfoSet
,
281 IN PSP_DEVINFO_DATA DeviceInfoData
,
288 if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
293 BufferSize
* sizeof(WCHAR
),
295 RegDataType
!= REG_SZ
)
298 if (LoadString(hDllInstance
,
308 /* FIXME - check string for NULL termination! */
317 GetDeviceLocationString(IN DEVINST dnDevInst OPTIONAL
,
318 IN DEVINST dnParentDevInst OPTIONAL
,
328 DataSize
= BufferSize
* sizeof(WCHAR
);
330 if (dnParentDevInst
!= 0)
332 /* query the parent node name */
333 if (CM_Get_DevNode_Registry_Property(dnParentDevInst
,
339 RegDataType
== REG_SZ
&&
340 LoadAndFormatString(hDllInstance
,
348 szBuffer
[BufferSize
- 1] = L
'\0';
349 LocalFree((HLOCAL
)szFormatted
);
353 else if (dnDevInst
!= 0)
355 cRet
= CM_Get_DevNode_Registry_Property(dnDevInst
,
356 CM_DRP_LOCATION_INFORMATION
,
361 if (cRet
== CR_SUCCESS
&& RegDataType
== REG_SZ
)
363 /* FIXME - check string for NULL termination! */
367 if (Ret
&& szBuffer
[0] >= L
'0' && szBuffer
[0] <= L
'9')
369 /* convert the string to an integer value and create a
371 ULONG ulLocation
= (ULONG
)wcstoul(szBuffer
,
374 if (LoadAndFormatString(hDllInstance
,
383 szBuffer
[BufferSize
- 1] = L
'\0';
384 LocalFree((HLOCAL
)szFormatted
);
392 LoadString(hDllInstance
,
405 GetDeviceStatusString(IN DEVINST DevInst
,
406 IN HMACHINE hMachine
,
411 ULONG Status
, ProblemNumber
;
412 UINT MessageId
= IDS_UNKNOWN
;
416 cr
= CM_Get_DevNode_Status_Ex(&Status
,
421 if (cr
== CR_SUCCESS
)
423 if (Status
& DN_HAS_PROBLEM
)
427 uRet
= DeviceProblemText(hMachine
,
431 (BufferSize
!= 0 ? BufferSize
: BufferSize
- 1));
433 Ret
= (uRet
!= 0 && uRet
< BufferSize
);
437 if (!(Status
& (DN_DRIVER_LOADED
| DN_STARTED
)))
439 MessageId
= IDS_NODRIVERLOADED
;
443 MessageId
= IDS_DEV_NO_PROBLEM
;
452 if (LoadString(hDllInstance
,
466 GetDriverProviderString(IN HDEVINFO DeviceInfoSet
,
467 IN PSP_DEVINFO_DATA DeviceInfoData
,
472 DWORD dwSize
, dwType
;
477 /* get driver provider, date and version */
478 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
484 if (hKey
!= INVALID_HANDLE_VALUE
)
486 /* query the driver provider */
488 if (RegQueryValueEx(hKey
,
489 REGSTR_VAL_PROVIDER_NAME
,
493 &dwSize
) == ERROR_SUCCESS
&&
495 szBuffer
[0] != L
'\0')
507 if (szBuffer
[0] == L
'\0')
509 /* unable to query the information */
510 if (LoadString(hDllInstance
,
524 GetDriverVersionString(IN HDEVINFO DeviceInfoSet
,
525 IN PSP_DEVINFO_DATA DeviceInfoData
,
530 DWORD dwSize
, dwType
;
535 /* get driver provider, date and version */
536 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
542 if (hKey
!= INVALID_HANDLE_VALUE
)
544 /* query the driver provider */
546 if (RegQueryValueEx(hKey
,
551 &dwSize
) == ERROR_SUCCESS
&&
553 szBuffer
[0] != L
'\0')
565 if (szBuffer
[0] == L
'\0')
567 /* unable to query the information */
568 if (LoadString(hDllInstance
,
581 GetDriverDateString(IN HDEVINFO DeviceInfoSet
,
582 IN PSP_DEVINFO_DATA DeviceInfoData
,
588 SYSTEMTIME SystemTime
, LocalTime
;
589 DWORD dwSize
, dwType
;
594 /* get driver provider, date and version */
595 hKey
= SetupDiOpenDevRegKey(DeviceInfoSet
,
601 if (hKey
!= INVALID_HANDLE_VALUE
)
603 /* query the driver provider */
604 dwSize
= sizeof(FILETIME
);
605 if (RegQueryValueEx(hKey
,
610 &dwSize
) == ERROR_SUCCESS
&&
611 dwType
== REG_BINARY
&&
612 dwSize
== sizeof(FILETIME
) &&
613 FileTimeToSystemTime(&DriverDate
,
615 SystemTimeToTzSpecificLocalTime(NULL
,
618 GetDateFormat(LOCALE_USER_DEFAULT
,
633 /* unable to query the information */
634 if (LoadString(hDllInstance
,
649 IsDeviceHidden(IN DEVINST DevInst
,
650 IN HMACHINE hMachine
,
654 ULONG Status
, ProblemNumber
;
657 cr
= CM_Get_DevNode_Status_Ex(&Status
,
662 if (cr
== CR_SUCCESS
)
664 *IsHidden
= ((Status
& DN_NO_SHOW_IN_DM
) != 0);
673 CanDisableDevice(IN DEVINST DevInst
,
674 IN HMACHINE hMachine
,
675 OUT BOOL
*CanDisable
)
678 ULONG Status
, ProblemNumber
;
681 cr
= CM_Get_DevNode_Status_Ex(&Status
,
686 if (cr
== CR_SUCCESS
)
688 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
697 IsDeviceStarted(IN DEVINST DevInst
,
698 IN HMACHINE hMachine
,
702 ULONG Status
, ProblemNumber
;
705 cr
= CM_Get_DevNode_Status_Ex(&Status
,
710 if (cr
== CR_SUCCESS
)
712 *IsStarted
= ((Status
& DN_STARTED
) != 0);
721 IsDriverInstalled(IN DEVINST DevInst
,
722 IN HMACHINE hMachine
,
726 ULONG Status
, ProblemNumber
;
729 cr
= CM_Get_DevNode_Status_Ex(&Status
,
734 if (cr
== CR_SUCCESS
)
736 *Installed
= ((Status
& DN_HAS_PROBLEM
) != 0 ||
737 (Status
& (DN_DRIVER_LOADED
| DN_STARTED
)) != 0);
746 EnableDevice(IN HDEVINFO DeviceInfoSet
,
747 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
749 IN DWORD HardwareProfile OPTIONAL
,
750 OUT BOOL
*bNeedReboot OPTIONAL
)
752 SP_PROPCHANGE_PARAMS pcp
;
753 SP_DEVINSTALL_PARAMS dp
;
757 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
758 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
759 pcp
.HwProfile
= HardwareProfile
;
763 /* try to enable the device on the global profile */
764 pcp
.StateChange
= DICS_ENABLE
;
765 pcp
.Scope
= DICS_FLAG_GLOBAL
;
768 LastErr
= GetLastError();
769 if (SetupDiSetClassInstallParams(DeviceInfoSet
,
771 &pcp
.ClassInstallHeader
,
772 sizeof(SP_PROPCHANGE_PARAMS
)))
774 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
778 SetLastError(LastErr
);
781 /* try config-specific */
782 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
783 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
785 if (SetupDiSetClassInstallParams(DeviceInfoSet
,
787 &pcp
.ClassInstallHeader
,
788 sizeof(SP_PROPCHANGE_PARAMS
)) &&
789 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
793 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
794 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
798 if (bNeedReboot
!= NULL
)
800 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
811 GetDeviceTypeString(IN PSP_DEVINFO_DATA DeviceInfoData
,
817 if (!SetupDiGetClassDescription(&DeviceInfoData
->ClassGuid
,
823 if (LoadString(hDllInstance
,
833 /* FIXME - check string for NULL termination! */
842 GetDeviceDescriptionString(IN HDEVINFO DeviceInfoSet
,
843 IN PSP_DEVINFO_DATA DeviceInfoData
,
850 if ((SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
855 BufferSize
* sizeof(WCHAR
),
857 SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
862 BufferSize
* sizeof(WCHAR
),
864 RegDataType
== REG_SZ
)
866 /* FIXME - check string for NULL termination! */
872 if (LoadString(hDllInstance
,
886 LoadAndInitComctl32(VOID
)
888 typedef VOID (WINAPI
*PINITCOMMONCONTROLS
)(VOID
);
889 PINITCOMMONCONTROLS pInitCommonControls
;
892 hComCtl32
= LoadLibrary(L
"comctl32.dll");
893 if (hComCtl32
!= NULL
)
895 /* initialize the common controls */
896 pInitCommonControls
= (PINITCOMMONCONTROLS
)GetProcAddress(hComCtl32
,
897 "InitCommonControls");
898 if (pInitCommonControls
== NULL
)
900 FreeLibrary(hComCtl32
);
904 pInitCommonControls();
913 DllMain(IN HINSTANCE hinstDLL
,
915 IN LPVOID lpvReserved
)
919 case DLL_PROCESS_ATTACH
:
920 DisableThreadLibraryCalls(hinstDLL
);
921 hDllInstance
= hinstDLL
;