Reactos
1/*
2*
3* COPYRIGHT: See COPYING in the top level directory
4* PROJECT: ReactOS devmgr.dll
5* FILE: dll/win32/devmgr/api.cpp
6* PURPOSE: devmgr.dll interface
7* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
8* Ged Murphy (gedmurphy@reactos.org)
9* NOTES:
10* Some helpful resources:
11* http://support.microsoft.com/default.aspx?scid=kb;%5BLN%5D;815320
12* https://web.archive.org/web/20050321020634/http://www.jsifaq.com/SUBO/tip7400/rh7482.htm
13* http://www.jsiinc.com/SUBM/tip6400/rh6490.htm
14*
15* UPDATE HISTORY:
16* 04-04-2004 Created
17*/
18
19#include "precomp.h"
20#include "devmgmt/MainWindow.h"
21#include "properties/properties.h"
22
23HINSTANCE hDllInstance = NULL;
24
25
26
27/***************************************************************************
28* NAME EXPORTED
29* DeviceAdvancedPropertiesW
30*
31* DESCRIPTION
32* Invokes the device properties dialog, this version may add some property pages
33* for some devices
34*
35* ARGUMENTS
36* hWndParent: Handle to the parent window
37* lpMachineName: Machine Name, NULL is the local machine
38* lpDeviceID: Specifies the device whose properties are to be shown
39*
40* RETURN VALUE
41* Always returns -1, a call to GetLastError returns 0 if successful
42*
43* @implemented
44*/
45INT_PTR
46WINAPI
47DeviceAdvancedPropertiesW(IN HWND hWndParent OPTIONAL,
48 IN LPCWSTR lpMachineName OPTIONAL,
49 IN LPCWSTR lpDeviceID)
50{
51 HDEVINFO hDevInfo;
52 SP_DEVINFO_DATA DevInfoData;
53 HINSTANCE hComCtl32;
54 INT_PTR Ret = -1;
55
56 if (lpDeviceID == NULL)
57 {
58 SetLastError(ERROR_INVALID_PARAMETER);
59 return FALSE;
60 }
61
62 /* dynamically load comctl32 */
63 hComCtl32 = LoadAndInitComctl32();
64 if (hComCtl32 != NULL)
65 {
66 hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
67 hWndParent,
68 lpMachineName,
69 NULL);
70 if (hDevInfo != INVALID_HANDLE_VALUE)
71 {
72 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
73 if (SetupDiOpenDeviceInfo(hDevInfo,
74 lpDeviceID,
75 hWndParent,
76 0,
77 &DevInfoData))
78 {
79 Ret = DisplayDeviceAdvancedProperties(hWndParent,
80 lpDeviceID,
81 hDevInfo,
82 &DevInfoData,
83 hComCtl32,
84 lpMachineName,
85 0);
86 }
87
88 SetupDiDestroyDeviceInfoList(hDevInfo);
89 }
90
91 FreeLibrary(hComCtl32);
92 }
93
94 return Ret;
95}
96
97
98/***************************************************************************
99* NAME EXPORTED
100* DeviceAdvancedPropertiesA
101*
102* DESCRIPTION
103* Invokes the device properties dialog, this version may add some property pages
104* for some devices
105*
106* ARGUMENTS
107* hWndParent: Handle to the parent window
108* lpMachineName: Machine Name, NULL is the local machine
109* lpDeviceID: Specifies the device whose properties are to be shown
110*
111* RETURN VALUE
112* Always returns -1, a call to GetLastError returns 0 if successful
113*
114* @implemented
115*/
116INT_PTR
117WINAPI
118DeviceAdvancedPropertiesA(IN HWND hWndParent OPTIONAL,
119 IN LPCSTR lpMachineName OPTIONAL,
120 IN LPCSTR lpDeviceID)
121{
122 LPWSTR lpMachineNameW = NULL;
123 LPWSTR lpDeviceIDW = NULL;
124 INT_PTR Ret = -1;
125
126 if (lpMachineName != NULL)
127 {
128 if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName,
129 CP_ACP)))
130 {
131 goto Cleanup;
132 }
133 }
134 if (lpDeviceID != NULL)
135 {
136 if (!(lpDeviceIDW = ConvertMultiByteToUnicode(lpDeviceID,
137 CP_ACP)))
138 {
139 goto Cleanup;
140 }
141 }
142
143 Ret = DeviceAdvancedPropertiesW(hWndParent,
144 lpMachineNameW,
145 lpDeviceIDW);
146
147Cleanup:
148 if (lpMachineNameW != NULL)
149 {
150 HeapFree(GetProcessHeap(),
151 0,
152 lpMachineNameW);
153 }
154 if (lpDeviceIDW != NULL)
155 {
156 HeapFree(GetProcessHeap(),
157 0,
158 lpDeviceIDW);
159 }
160
161 return Ret;
162}
163
164
165/***************************************************************************
166* NAME EXPORTED
167* DevicePropertiesExA
168*
169* DESCRIPTION
170* Invokes the extended device properties dialog
171*
172* ARGUMENTS
173* hWndParent: Handle to the parent window
174* lpMachineName: Machine Name, NULL is the local machine
175* lpDeviceID: Specifies the device whose properties are to be shown, optional if
176* bShowDevMgr is nonzero
177* dwFlags: This parameter can be a combination of the following flags:
178* * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
179* the default device status action button
180* to be clicked (Troubleshoot, Enable
181* Device, etc)
182* bShowDevMgr: If non-zero it displays the device manager instead of
183* the advanced device property dialog
184*
185* RETURN VALUE
186* 1: if bShowDevMgr is non-zero and no error occured
187* -1: a call to GetLastError returns 0 if successful
188*
189* @implemented
190*/
191INT_PTR
192WINAPI
193DevicePropertiesExA(IN HWND hWndParent OPTIONAL,
194 IN LPCSTR lpMachineName OPTIONAL,
195 IN LPCSTR lpDeviceID OPTIONAL,
196 IN DWORD dwFlags OPTIONAL,
197 IN BOOL bShowDevMgr)
198{
199 LPWSTR lpMachineNameW = NULL;
200 LPWSTR lpDeviceIDW = NULL;
201 INT_PTR Ret = -1;
202
203 if (lpMachineName != NULL)
204 {
205 if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName,
206 CP_ACP)))
207 {
208 goto Cleanup;
209 }
210 }
211 if (lpDeviceID != NULL)
212 {
213 if (!(lpDeviceIDW = ConvertMultiByteToUnicode(lpDeviceID,
214 CP_ACP)))
215 {
216 goto Cleanup;
217 }
218 }
219
220 Ret = DevicePropertiesExW(hWndParent,
221 lpMachineNameW,
222 lpDeviceIDW,
223 dwFlags,
224 bShowDevMgr);
225
226Cleanup:
227 if (lpMachineNameW != NULL)
228 {
229 HeapFree(GetProcessHeap(),
230 0,
231 lpMachineNameW);
232 }
233 if (lpDeviceIDW != NULL)
234 {
235 HeapFree(GetProcessHeap(),
236 0,
237 lpDeviceIDW);
238 }
239
240 return Ret;
241}
242
243
244/***************************************************************************
245* NAME EXPORTED
246* DevicePropertiesExW
247*
248* DESCRIPTION
249* Invokes the extended device properties dialog
250*
251* ARGUMENTS
252* hWndParent: Handle to the parent window
253* lpMachineName: Machine Name, NULL is the local machine
254* lpDeviceID: Specifies the device whose properties are to be shown, optional if
255* bShowDevMgr is nonzero
256* dwFlags: This parameter can be a combination of the following flags:
257* * DPF_DEVICE_STATUS_ACTION: Only valid if bShowDevMgr, causes
258* the default device status action button
259* to be clicked (Troubleshoot, Enable
260* Device, etc)
261* bShowDevMgr: If non-zero it displays the device manager instead of
262* the advanced device property dialog
263*
264* RETURN VALUE
265* 1: if bShowDevMgr is non-zero and no error occured
266* -1: a call to GetLastError returns 0 if successful
267*
268* @implemented
269*/
270INT_PTR
271WINAPI
272DevicePropertiesExW(IN HWND hWndParent OPTIONAL,
273 IN LPCWSTR lpMachineName OPTIONAL,
274 IN LPCWSTR lpDeviceID OPTIONAL,
275 IN DWORD dwFlags OPTIONAL,
276 IN BOOL bShowDevMgr)
277{
278 INT_PTR Ret = -1;
279
280 if (dwFlags & ~(DPF_EXTENDED | DPF_DEVICE_STATUS_ACTION))
281 {
282 FIXME("DevPropertiesExW: Invalid flags: 0x%x\n",
283 dwFlags & ~(DPF_EXTENDED | DPF_DEVICE_STATUS_ACTION));
284 SetLastError(ERROR_INVALID_FLAGS);
285 return -1;
286 }
287
288 if (bShowDevMgr)
289 {
290 FIXME("DevPropertiesExW doesn't support bShowDevMgr!\n");
291 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
292 }
293 else
294 {
295 HDEVINFO hDevInfo;
296 SP_DEVINFO_DATA DevInfoData;
297 HINSTANCE hComCtl32;
298
299 if (lpDeviceID == NULL)
300 {
301 SetLastError(ERROR_INVALID_PARAMETER);
302 return -1;
303 }
304
305 /* dynamically load comctl32 */
306 hComCtl32 = LoadAndInitComctl32();
307 if (hComCtl32 != NULL)
308 {
309 hDevInfo = SetupDiCreateDeviceInfoListEx(NULL,
310 hWndParent,
311 lpMachineName,
312 NULL);
313 if (hDevInfo != INVALID_HANDLE_VALUE)
314 {
315 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
316 if (SetupDiOpenDeviceInfo(hDevInfo,
317 lpDeviceID,
318 hWndParent,
319 0,
320 &DevInfoData))
321 {
322 Ret = DisplayDeviceAdvancedProperties(hWndParent,
323 lpDeviceID,
324 hDevInfo,
325 &DevInfoData,
326 hComCtl32,
327 lpMachineName,
328 dwFlags);
329 }
330
331 SetupDiDestroyDeviceInfoList(hDevInfo);
332 }
333
334 FreeLibrary(hComCtl32);
335 }
336 }
337
338 return Ret;
339}
340
341
342/***************************************************************************
343* NAME EXPORTED
344* DevicePropertiesA
345*
346* DESCRIPTION
347* Invokes the device properties dialog directly
348*
349* ARGUMENTS
350* hWndParent: Handle to the parent window
351* lpMachineName: Machine Name, NULL is the local machine
352* lpDeviceID: Specifies the device whose properties are to be shown
353* bShowDevMgr: If non-zero it displays the device manager instead of
354* the device property dialog
355*
356* RETURN VALUE
357* >=0: if no errors occured
358* -1: if errors occured
359*
360* REVISIONS
361*
362* @implemented
363*/
364int
365WINAPI
366DevicePropertiesA(HWND hWndParent,
367 LPCSTR lpMachineName,
368 LPCSTR lpDeviceID,
369 BOOL bShowDevMgr)
370{
371 return DevicePropertiesExA(hWndParent,
372 lpMachineName,
373 lpDeviceID,
374 DPF_EXTENDED,
375 bShowDevMgr);
376}
377
378
379/***************************************************************************
380* NAME EXPORTED
381* DevicePropertiesW
382*
383* DESCRIPTION
384* Invokes the device properties dialog directly
385*
386* ARGUMENTS
387* hWndParent: Handle to the parent window
388* lpMachineName: Machine Name, NULL is the local machine
389* lpDeviceID: Specifies the device whose properties are to be shown
390* bShowDevMgr: If non-zero it displays the device manager instead of
391* the device property dialog
392*
393* RETURN VALUE
394* >=0: if no errors occured
395* -1: if errors occured
396*
397* REVISIONS
398*
399* @implemented
400*/
401int
402WINAPI
403DevicePropertiesW(HWND hWndParent,
404 LPCWSTR lpMachineName,
405 LPCWSTR lpDeviceID,
406 BOOL bShowDevMgr)
407{
408 return DevicePropertiesExW(hWndParent,
409 lpMachineName,
410 lpDeviceID,
411 DPF_EXTENDED,
412 bShowDevMgr);
413}
414
415
416/***************************************************************************
417* NAME EXPORTED
418* DeviceProperties_RunDLLA
419*
420* DESCRIPTION
421* Invokes the device properties dialog
422*
423* ARGUMENTS
424* hWndParent: Handle to the parent window
425* hInst: Handle to the application instance
426* lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
427* also see NOTEs
428* nCmdShow: Specifies how the window should be shown
429*
430* RETURN VALUE
431*
432* REVISIONS
433*
434* NOTE
435* - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
436* (/MachineName is optional). This function only parses this string and eventually
437* calls DeviceProperties().
438*
439* @implemented
440*/
441VOID
442WINAPI
443DeviceProperties_RunDLLA(HWND hWndParent,
444 HINSTANCE hInst,
445 LPCSTR lpDeviceCmd,
446 int nCmdShow)
447{
448 LPWSTR lpDeviceCmdW = NULL;
449
450 if (lpDeviceCmd != NULL)
451 {
452 if ((lpDeviceCmdW = ConvertMultiByteToUnicode(lpDeviceCmd,
453 CP_ACP)))
454 {
455 DeviceProperties_RunDLLW(hWndParent,
456 hInst,
457 lpDeviceCmdW,
458 nCmdShow);
459 }
460 }
461
462 if (lpDeviceCmdW != NULL)
463 {
464 HeapFree(GetProcessHeap(),
465 0,
466 lpDeviceCmdW);
467 }
468}
469
470
471/***************************************************************************
472* NAME EXPORTED
473* DeviceProperties_RunDLLW
474*
475* DESCRIPTION
476* Invokes the device properties dialog
477*
478* ARGUMENTS
479* hWndParent: Handle to the parent window
480* hInst: Handle to the application instance
481* lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
482* also see NOTEs
483* nCmdShow: Specifies how the window should be shown
484*
485* RETURN VALUE
486*
487* REVISIONS
488*
489* NOTE
490* - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
491* (/MachineName is optional). This function only parses this string and eventually
492* calls DeviceProperties().
493*
494* @implemented
495*/
496VOID
497WINAPI
498DeviceProperties_RunDLLW(HWND hWndParent,
499 HINSTANCE hInst,
500 LPCWSTR lpDeviceCmd,
501 int nCmdShow)
502{
503 WCHAR szDeviceID[MAX_DEVICE_ID_LEN + 1];
504 WCHAR szMachineName[MAX_COMPUTERNAME_LENGTH + 1];
505 LPWSTR lpString = (LPWSTR)lpDeviceCmd;
506
507 if (!GetDeviceAndComputerName(lpString,
508 szDeviceID,
509 szMachineName))
510 {
511 ERR("DeviceProperties_RunDLLW DeviceID: %S, MachineName: %S\n", szDeviceID, szMachineName);
512 return;
513 }
514
515 DevicePropertiesW(hWndParent,
516 szMachineName,
517 szDeviceID,
518 FALSE);
519}
520
521
522
523/***************************************************************************
524* NAME EXPORTED
525* DeviceManager_ExecuteA
526*
527* DESCRIPTION
528* Starts the Device Manager
529*
530* ARGUMENTS
531* hWndParent: Handle to the parent window
532* hInst: Handle to the application instance
533* lpMachineName: Machine Name, NULL is the local machine
534* nCmdShow: Specifies how the window should be shown
535*
536* RETURN VALUE
537* TRUE: if no errors occured
538* FALSE: if the device manager could not be executed
539*
540* REVISIONS
541*
542* NOTE
543* - Win runs the device manager in a separate process, so hWndParent is somehow
544* obsolete.
545*
546* @implemented
547*/
548BOOL
549WINAPI
550DeviceManager_ExecuteA(HWND hWndParent,
551 HINSTANCE hInst,
552 LPCSTR lpMachineName,
553 int nCmdShow)
554{
555 LPWSTR lpMachineNameW = NULL;
556 BOOL Ret;
557
558 if (lpMachineName != NULL)
559 {
560 if (!(lpMachineNameW = ConvertMultiByteToUnicode(lpMachineName,
561 CP_ACP)))
562 {
563 return FALSE;
564 }
565 }
566
567 Ret = DeviceManager_ExecuteW(hWndParent,
568 hInst,
569 lpMachineNameW,
570 nCmdShow);
571
572 if (lpMachineNameW != NULL)
573 {
574 HeapFree(GetProcessHeap(),
575 0,
576 lpMachineNameW);
577 }
578
579
580 return Ret;
581}
582
583
584/***************************************************************************
585* NAME EXPORTED
586* DeviceManager_ExecuteW
587*
588* DESCRIPTION
589* Starts the Device Manager
590*
591* ARGUMENTS
592* hWndParent: Handle to the parent window
593* hInst: Handle to the application instance
594* lpMachineName: Machine Name, NULL is the local machine
595* nCmdShow: Specifies how the window should be shown
596*
597* RETURN VALUE
598* TRUE: if no errors occured
599* FALSE: if the device manager could not be executed
600*
601* REVISIONS
602*
603* NOTE
604* - Win runs the device manager in a separate process, so hWndParent is somehow
605* obsolete.
606*
607* @implemented
608*/
609BOOL
610WINAPI
611DeviceManager_ExecuteW(HWND hWndParent,
612 HINSTANCE hInst,
613 LPCWSTR lpMachineName,
614 int nCmdShow)
615{
616 // FIXME: Call mmc with devmgmt.msc
617
618 CDeviceManager DevMgr;
619 return DevMgr.Create(hWndParent, hInst, lpMachineName, nCmdShow);
620}
621
622
623/***************************************************************************
624* NAME EXPORTED
625* DeviceProblemWizard_RunDLLA
626*
627* DESCRIPTION
628* Calls the device problem wizard
629*
630* ARGUMENTS
631* hWndParent: Handle to the parent window
632* hInst: Handle to the application instance
633* lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
634* also see NOTEs
635* nCmdShow: Specifies how the window should be shown
636*
637* RETURN VALUE
638*
639* REVISIONS
640*
641* NOTE
642* - Win XP exports this function as DeviceProblenWizard_RunDLLA, apparently it's
643* a typo so we additionally export an alias function
644* - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
645* (/MachineName is optional). This function only parses this string and eventually
646* calls DeviceProperties().
647*
648* @unimplemented
649*/
650VOID
651WINAPI
652DeviceProblemWizard_RunDLLA(HWND hWndParent,
653 HINSTANCE hInst,
654 LPCSTR lpDeviceCmd,
655 int nCmdShow)
656{
657 UNIMPLEMENTED;
658}
659
660
661/***************************************************************************
662* NAME EXPORTED
663* DeviceProblemWizard_RunDLLW
664*
665* DESCRIPTION
666* Calls the device problem wizard
667*
668* ARGUMENTS
669* hWndParent: Handle to the parent window
670* hInst: Handle to the application instance
671* lpDeviceCmd: A command that includes the DeviceID of the properties to be shown,
672* also see NOTEs
673* nCmdShow: Specifies how the window should be shown
674*
675* RETURN VALUE
676*
677* REVISIONS
678*
679* NOTE
680* - Win XP exports this function as DeviceProblenWizard_RunDLLA, apparently it's
681* a typo so we additionally export an alias function
682* - lpDeviceCmd is a string in the form of "/MachineName MACHINE /DeviceID DEVICEPATH"
683* (/MachineName is optional). This function only parses this string and eventually
684* calls DeviceProperties().
685*
686* @unimplemented
687*/
688VOID
689WINAPI
690DeviceProblemWizard_RunDLLW(HWND hWndParent,
691 HINSTANCE hInst,
692 LPCWSTR lpDeviceCmd,
693 int nCmdShow)
694{
695 UNIMPLEMENTED;
696}
697
698
699/***************************************************************************
700* NAME EXPORTED
701* DeviceManagerPrintA
702*
703* DESCRIPTION
704* Calls the device problem wizard
705*
706* ARGUMENTS
707* lpMachineName: Machine Name, NULL is the local machine
708* lpPrinter: Filename of the printer where it should be printed on
709* nPrintMode: Specifies what kind of information is to be printed
710* DEV_PRINT_ABSTRACT: Prints an abstract of system information, the parameters
711* uNumberOfGuids, Guids are ignored
712* DEV_PRINT_SELECTED: Prints information about the devices listed in Guids
713* DEV_PRINT_ALL: Prints an abstract of system information and all
714* system devices
715* uNumberOfGuids: Numbers of guids in the Guids array, this parameter is ignored unless
716* nPrintMode is DEV_PRINT_SELECTED
717* lpGuids: Array of device guids, this parameter is ignored unless
718* nPrintMode is DEV_PRINT_SELECTED
719*
720* RETURN VALUE
721* TRUE: if no errors occured
722* FALSE: if errors occured
723*
724* REVISIONS
725*
726* NOTE
727*
728* @unimplemented
729*/
730BOOL
731WINAPI
732DeviceManagerPrintA(LPCSTR lpMachineName,
733 LPCSTR lpPrinter,
734 int nPrintMode,
735 UINT uNumberOfGuids,
736 LPGUID lpGuids)
737{
738 UNIMPLEMENTED;
739 return FALSE;
740}
741
742
743/***************************************************************************
744* NAME EXPORTED
745* DeviceManagerPrintW
746*
747* DESCRIPTION
748* Calls the device problem wizard
749*
750* ARGUMENTS
751* lpMachineName: Machine Name, NULL is the local machine
752* lpPrinter: Filename of the printer where it should be printed on
753* nPrintMode: Specifies what kind of information is to be printed
754* DEV_PRINT_ABSTRACT: Prints an abstract of system information, the parameters
755* uNumberOfGuids, Guids are ignored
756* DEV_PRINT_SELECTED: Prints information about the devices listed in Guids
757* DEV_PRINT_ALL: Prints an abstract of system information and all
758* system devices
759* uNumberOfGuids: Numbers of guids in the Guids array, this parameter is ignored unless
760* nPrintMode is DEV_PRINT_SELECTED
761* lpGuids: Array of device guids, this parameter is ignored unless
762* nPrintMode is DEV_PRINT_SELECTED
763*
764* RETURN VALUE
765* TRUE: if no errors occured
766* FALSE: if errors occured
767*
768* REVISIONS
769*
770* NOTE
771*
772* @unimplemented
773*/
774BOOL
775WINAPI
776DeviceManagerPrintW(LPCWSTR lpMachineName,
777 LPCWSTR lpPrinter,
778 int nPrintMode,
779 UINT uNumberOfGuids,
780 LPGUID lpGuids)
781{
782 UNIMPLEMENTED;
783 return FALSE;
784}
785
786class CDevMgrUIModule : public CComModule
787{
788public:
789};
790
791CDevMgrUIModule gModule;
792
793STDAPI DllCanUnloadNow()
794{
795 return gModule.DllCanUnloadNow();
796}
797
798STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
799{
800 return gModule.DllGetClassObject(rclsid, riid, ppv);
801}
802
803STDAPI DllRegisterServer()
804{
805 return gModule.DllRegisterServer(FALSE);
806}
807
808STDAPI DllUnregisterServer()
809{
810 return gModule.DllUnregisterServer(FALSE);
811}
812
813extern "C" {
814
815BOOL
816WINAPI
817DllMain(_In_ HINSTANCE hinstDLL,
818 _In_ DWORD dwReason,
819 _In_ LPVOID lpvReserved)
820{
821 switch (dwReason)
822 {
823 case DLL_PROCESS_ATTACH:
824 DisableThreadLibraryCalls(hinstDLL);
825 hDllInstance = hinstDLL;
826 break;
827 }
828
829 return TRUE;
830}
831}