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
,
404 static const UINT ProblemStringId
[NUM_CM_PROB
] =
407 IDS_DEV_NOT_CONFIGURED
,
408 IDS_DEV_OUT_OF_MEMORY
,
409 IDS_DEV_ENTRY_IS_WRONG_TYPE
,
410 IDS_DEV_LACKED_ARBITRATOR
,
411 IDS_DEV_BOOT_CONFIG_CONFLICT
,
412 IDS_DEV_FAILED_FILTER
,
413 IDS_DEV_DEVLOADER_NOT_FOUND
,
414 IDS_DEV_INVALID_DATA
,
415 IDS_DEV_FAILED_START
,
417 IDS_DEV_NORMAL_CONFLICT
,
418 IDS_DEV_NOT_VERIFIED
,
419 IDS_DEV_NEED_RESTART
,
420 IDS_DEV_REENUMERATION
,
421 IDS_DEV_PARTIAL_LOG_CONF
,
422 IDS_DEV_UNKNOWN_RESOURCE
,
425 IDS_UNKNOWN
, /* CM_PROB_VXDLDR, not used on NT */
426 IDS_DEV_WILL_BE_REMOVED
,
428 IDS_DEV_DEVLOADER_NOT_READY
,
429 IDS_DEV_DEVICE_NOT_THERE
,
432 IDS_DEV_NO_VALID_LOG_CONF
,
433 IDS_DEV_FAILED_INSTALL
,
434 IDS_DEV_HARDWARE_DISABLED
,
435 IDS_DEV_CANT_SHARE_IRQ
,
437 IDS_DEV_DISABLED_SERVICE
,
438 IDS_DEV_TRANSLATION_FAILED
,
439 IDS_DEV_NO_SOFTCONFIG
,
441 IDS_DEV_IRQ_TRANSLATION_FAILED
,
442 IDS_DEV_FAILED_DRIVER_ENTRY
,
443 IDS_DEV_DRIVER_FAILED_PRIOR_UNLOAD
,
444 IDS_DEV_DRIVER_FAILED_LOAD
,
445 IDS_DEV_DRIVER_SERVICE_KEY_INVALID
,
446 IDS_DEV_LEGACY_SERVICE_NO_DEVICES
,
447 IDS_DEV_DUPLICATE_DEVICE
,
448 IDS_DEV_FAILED_POST_START
,
451 IDS_DEV_SYSTEM_SHUTDOWN
,
452 IDS_DEV_HELD_FOR_EJECT
,
453 IDS_DEV_DRIVER_BLOCKED
,
454 IDS_DEV_REGISTRY_TOO_LARGE
,
455 IDS_DEV_SETPROPERTIES_FAILED
,
460 GetDeviceStatusString(IN DEVINST DevInst
,
461 IN HMACHINE hMachine
,
466 ULONG Status
, ProblemNumber
;
467 UINT MessageId
= IDS_UNKNOWN
;
471 cr
= CM_Get_DevNode_Status_Ex(&Status
,
476 if (cr
== CR_SUCCESS
)
478 if (Status
& DN_HAS_PROBLEM
)
480 if (ProblemNumber
< sizeof(ProblemStringId
) / sizeof(ProblemStringId
[0]))
481 MessageId
= ProblemStringId
[ProblemNumber
];
483 if (ProblemNumber
== 0)
496 if (LoadAndFormatStringsCat(hDllInstance
,
498 sizeof(StringIDs
) / sizeof(StringIDs
[0]),
505 szBuffer
[BufferSize
- 1] = L
'\0';
507 LocalFree((HLOCAL
)szProblem
);
515 if (!(Status
& (DN_DRIVER_LOADED
| DN_STARTED
)))
517 MessageId
= IDS_NODRIVERLOADED
;
521 MessageId
= IDS_DEV_NO_PROBLEM
;
530 if (LoadString(hDllInstance
,
544 IsDeviceHidden(IN DEVINST DevInst
,
545 IN HMACHINE hMachine
,
549 ULONG Status
, ProblemNumber
;
552 cr
= CM_Get_DevNode_Status_Ex(&Status
,
557 if (cr
== CR_SUCCESS
)
559 *IsHidden
= ((Status
& DN_NO_SHOW_IN_DM
) != 0);
568 CanDisableDevice(IN DEVINST DevInst
,
569 IN HMACHINE hMachine
,
570 OUT BOOL
*CanDisable
)
573 ULONG Status
, ProblemNumber
;
576 cr
= CM_Get_DevNode_Status_Ex(&Status
,
581 if (cr
== CR_SUCCESS
)
583 *CanDisable
= ((Status
& DN_DISABLEABLE
) != 0);
592 IsDeviceEnabled(IN DEVINST DevInst
,
593 IN HMACHINE hMachine
,
597 ULONG Status
, ProblemNumber
;
600 cr
= CM_Get_DevNode_Status_Ex(&Status
,
605 if (cr
== CR_SUCCESS
)
607 *IsEnabled
= ((Status
& DN_STARTED
) != 0);
616 EnableDevice(IN HDEVINFO DeviceInfoSet
,
617 IN PSP_DEVINFO_DATA DevInfoData OPTIONAL
,
619 IN DWORD HardwareProfile OPTIONAL
,
620 OUT BOOL
*bNeedReboot OPTIONAL
)
622 SP_PROPCHANGE_PARAMS pcp
;
623 SP_DEVINSTALL_PARAMS dp
;
627 pcp
.ClassInstallHeader
.cbSize
= sizeof(SP_CLASSINSTALL_HEADER
);
628 pcp
.ClassInstallHeader
.InstallFunction
= DIF_PROPERTYCHANGE
;
629 pcp
.HwProfile
= HardwareProfile
;
633 /* try to enable/disable the device on the global profile */
634 pcp
.StateChange
= DICS_ENABLE
;
635 pcp
.Scope
= DICS_FLAG_GLOBAL
;
638 LastErr
= GetLastError();
639 if (SetupDiSetClassInstallParams(DeviceInfoSet
,
641 &pcp
.ClassInstallHeader
,
642 sizeof(SP_PROPCHANGE_PARAMS
)))
644 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
648 SetLastError(LastErr
);
651 /* try config-specific */
652 pcp
.StateChange
= (bEnable
? DICS_ENABLE
: DICS_DISABLE
);
653 pcp
.Scope
= DICS_FLAG_CONFIGSPECIFIC
;
655 if (SetupDiSetClassInstallParams(DeviceInfoSet
,
657 &pcp
.ClassInstallHeader
,
658 sizeof(SP_PROPCHANGE_PARAMS
)) &&
659 SetupDiCallClassInstaller(DIF_PROPERTYCHANGE
,
663 dp
.cbSize
= sizeof(SP_DEVINSTALL_PARAMS
);
664 if (SetupDiGetDeviceInstallParams(DeviceInfoSet
,
668 if (bNeedReboot
!= NULL
)
670 *bNeedReboot
= ((dp
.Flags
& (DI_NEEDRESTART
| DI_NEEDREBOOT
)) != 0);
681 GetDeviceTypeString(IN PSP_DEVINFO_DATA DeviceInfoData
,
687 if (!SetupDiGetClassDescription(&DeviceInfoData
->ClassGuid
,
693 if (LoadString(hDllInstance
,
703 /* FIXME - check string for NULL termination! */
712 GetDeviceDescriptionString(IN HDEVINFO DeviceInfoSet
,
713 IN PSP_DEVINFO_DATA DeviceInfoData
,
720 if ((SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
725 BufferSize
* sizeof(WCHAR
),
727 SetupDiGetDeviceRegistryProperty(DeviceInfoSet
,
732 BufferSize
* sizeof(WCHAR
),
734 RegDataType
== REG_SZ
)
736 /* FIXME - check string for NULL termination! */
742 if (LoadString(hDllInstance
,
756 LoadAndInitComctl32(VOID
)
758 typedef VOID (WINAPI
*PINITCOMMONCONTROLS
)(VOID
);
759 PINITCOMMONCONTROLS pInitCommonControls
;
762 hComCtl32
= LoadLibrary(L
"comctl32.dll");
763 if (hComCtl32
!= NULL
)
765 /* initialize the common controls */
766 pInitCommonControls
= (PINITCOMMONCONTROLS
)GetProcAddress(hComCtl32
,
767 "InitCommonControls");
768 if (pInitCommonControls
== NULL
)
770 FreeLibrary(hComCtl32
);
774 pInitCommonControls();
783 DllMain(IN HINSTANCE hinstDLL
,
785 IN LPVOID lpvReserved
)
789 case DLL_PROCESS_ATTACH
:
790 DisableThreadLibraryCalls(hinstDLL
);
791 hDllInstance
= hinstDLL
;