2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Display Control Panel
4 * FILE: lib/cpl/desk/devsett.c
5 * PURPOSE: ReactOS Display Control Panel Shell Extension Support
15 #define DEBUG_DEVSETTINGS
17 typedef struct _CDevSettings
19 const struct IDataObjectVtbl
*lpIDataObjectVtbl
;
22 CLIPFORMAT cfExtInterface
; /* "Desk.cpl extension interface" */
23 CLIPFORMAT cfDisplayDevice
; /* "Display Device" */
24 CLIPFORMAT cfDisplayName
; /* "Display Name" */
25 CLIPFORMAT cfDisplayId
; /* "Display ID" */
26 CLIPFORMAT cfMonitorName
; /* "Monitor Name" */
27 CLIPFORMAT cfMonitorDevice
; /* "Monitor Device" */
28 CLIPFORMAT cfDisplayKey
; /* "Display Key" */
29 CLIPFORMAT cfDisplayStateFlags
; /* "Display State Flags" */
30 CLIPFORMAT cfPruningMode
; /* "Pruning Mode" */
39 DESK_EXT_INTERFACE ExtInterface
;
48 DWORD bModesPruned
: 1;
49 DWORD bKeyIsReadOnly
: 1;
53 } CDevSettings
, *PCDevSettings
;
55 #define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl)
57 static __inline PCDevSettings
58 impl_from_IDataObject(struct IDataObject
*iface
)
60 return (PCDevSettings
)((ULONG_PTR
)iface
- FIELD_OFFSET(CDevSettings
,
65 pCDevSettings_FreeString(PWCHAR
*psz
)
69 LocalFree((HLOCAL
)*psz
);
75 pCDevSettings_AllocAndCopyString(const TCHAR
*pszSrc
)
80 c
= _tcslen(pszSrc
) + 1;
81 str
= (PWSTR
)LocalAlloc(LMEM_FIXED
,
89 MultiByteToWideChar(CP_APC
,
102 pCDevSettings_GetMonitorName(const WCHAR
*pszDisplayDevice
)
104 DISPLAY_DEVICEW dd
, dd2
;
108 if (EnumDisplayDevicesW(pszDisplayDevice
,
113 dd2
.cb
= sizeof(dd2
);
114 if (EnumDisplayDevicesW(pszDisplayDevice
,
119 /* There's more than one monitor connected... */
121 IDS_MULTIPLEMONITORS
,
123 sizeof(dd
.DeviceString
) / sizeof(dd
.DeviceString
[0]));
128 /* We can't enumerate a monitor, make sure this fact is reported
133 sizeof(dd
.DeviceString
) / sizeof(dd
.DeviceString
[0]));
136 str
= LocalAlloc(LMEM_FIXED
,
137 (wcslen(dd
.DeviceString
) + 1) * sizeof(WCHAR
));
148 pCDevSettings_GetMonitorDevice(const WCHAR
*pszDisplayDevice
)
154 if (EnumDisplayDevicesW(pszDisplayDevice
,
159 str
= LocalAlloc(LMEM_FIXED
,
160 (wcslen(dd
.DeviceName
) + 1) * sizeof(WCHAR
));
172 pCDevSettings_GetDeviceInstanceId(const WCHAR
*pszDevice
)
177 LPWSTR lpDevInstId
= NULL
;
179 DPRINT1("CDevSettings::GetDeviceInstanceId(%ws) UNIMPLEMENTED!\n", pszDevice
);
181 cr
= CM_Locate_DevNodeW(&DevInst
,
182 (DEVINSTID_W
)pszDevice
,
183 CM_LOCATE_DEVNODE_NORMAL
);
184 if (cr
== CR_SUCCESS
)
186 DbgPrint("Success1\n");
187 cr
= CM_Get_Device_ID_Size(&BufLen
,
190 if (cr
== CR_SUCCESS
)
192 DbgPrint("Success2\n");
193 lpDevInstId
= LocalAlloc(LMEM_FIXED
,
194 (BufLen
+ 1) * sizeof(WCHAR
));
196 if (lpDevInstId
!= NULL
)
198 DbgPrint("Success3\n");
199 cr
= CM_Get_Device_IDW(DevInst
,
204 if (cr
!= CR_SUCCESS
)
206 LocalFree((HLOCAL
)lpDevInstId
);
209 DbgPrint("instance id: %ws\n", lpDevInstId
);
219 pCDevSettings_OpenDeviceKey(PCDevSettings This
,
222 static const WCHAR szRegPrefix
[] = L
"\\Registry\\Machine\\";
224 REGSAM Access
= KEY_READ
;
227 lpRegKey
= This
->pDisplayKey
;
228 if (lpRegKey
!= NULL
)
230 if (wcslen(lpRegKey
) >= wcslen(szRegPrefix
) &&
233 wcslen(szRegPrefix
)))
235 lpRegKey
+= wcslen(szRegPrefix
);
241 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
245 &hKey
) == ERROR_SUCCESS
)
254 PDEVMODEW DESK_EXT_CALLBACK
255 CDevSettings_EnumAllModes(PVOID Context
,
258 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
259 /* FIXME: Implement */
260 DPRINT1("CDevSettings::EnumAllModes(%u)\n", Index
);
264 PDEVMODEW DESK_EXT_CALLBACK
265 CDevSettings_GetCurrentMode(PVOID Context
)
267 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
268 /* FIXME: Implement */
269 DPRINT1("CDevSettings::GetCurrentMode\n");
273 BOOL DESK_EXT_CALLBACK
274 CDevSettings_SetCurrentMode(PVOID Context
,
275 const DEVMODEW
*pDevMode
)
277 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
278 /* FIXME: Implement */
279 DPRINT1("CDevSettings::SetCurrentMode(0x%p)\n", pDevMode
);
283 VOID DESK_EXT_CALLBACK
284 CDevSettings_GetPruningMode(PVOID Context
,
286 PBOOL pbKeyIsReadOnly
,
289 PCDevSettings This
= impl_from_IDataObject((IDataObject
*)Context
);
291 DPRINT1("CDevSettings::GetPruningMode(%p,%p,%p)\n", pbModesPruned
, pbKeyIsReadOnly
, pbPruningOn
);
293 *pbModesPruned
= This
->bModesPruned
;
294 *pbKeyIsReadOnly
= This
->bKeyIsReadOnly
;
295 *pbPruningOn
= This
->bPruningOn
;
298 VOID DESK_EXT_CALLBACK
299 CDevSettings_SetPruningMode(PVOID Context
,
304 PCDevSettings This
= impl_from_IDataObject((IDataObject
*)Context
);
306 DPRINT1("CDevSettings::SetPruningMode(%d)\n", PruningOn
);
308 if (This
->bModesPruned
&& !This
->bKeyIsReadOnly
&&
309 PruningOn
!= This
->bPruningOn
)
311 This
->bPruningOn
= (PruningOn
!= FALSE
);
313 hKey
= pCDevSettings_OpenDeviceKey(This
,
317 dwValue
= (DWORD
)This
->bPruningOn
;
323 (const BYTE
*)&dwValue
,
332 pCDevSettings_ReadHardwareInfo(HKEY hKey
,
336 DWORD type
= REG_BINARY
;
337 DWORD size
= 128 * sizeof(WCHAR
);
338 RegQueryValueEx(hKey
,
347 pCDevSettings_InitializeExtInterface(PCDevSettings This
)
349 PDESK_EXT_INTERFACE Interface
= &This
->ExtInterface
;
352 ZeroMemory(Interface
,
354 Interface
->cbSize
= sizeof(*Interface
);
356 /* Initialize the callback table */
357 Interface
->Context
= impl_to_interface(This
, IDataObject
);
358 Interface
->EnumAllModes
= CDevSettings_EnumAllModes
;
359 Interface
->SetCurrentMode
= CDevSettings_SetCurrentMode
;
360 Interface
->GetCurrentMode
= CDevSettings_GetCurrentMode
;
361 Interface
->SetPruningMode
= CDevSettings_SetPruningMode
;
362 Interface
->GetPruningMode
= CDevSettings_GetPruningMode
;
364 /* Read the HardwareInformation.* values from the registry key */
365 hKeyDev
= pCDevSettings_OpenDeviceKey(This
,
369 DWORD dwType
, dwMemSize
= 0;
370 DWORD dwSize
= sizeof(dwMemSize
);
372 if (RegQueryValueEx(hKeyDev
,
373 TEXT("HardwareInformation.MemorySize"),
377 &dwSize
) == ERROR_SUCCESS
&&
378 (dwType
== REG_BINARY
|| dwType
== REG_DWORD
) &&
379 dwSize
== sizeof(dwMemSize
))
383 if (dwMemSize
> 1024)
386 if (dwMemSize
> 1024)
388 wsprintf(Interface
->MemorySize
,
394 wsprintf(Interface
->MemorySize
,
401 wsprintf(Interface
->MemorySize
,
407 pCDevSettings_ReadHardwareInfo(hKeyDev
,
408 TEXT("HardwareInformation.ChipType"),
409 Interface
->ChipType
);
410 pCDevSettings_ReadHardwareInfo(hKeyDev
,
411 TEXT("HardwareInformation.DacType"),
413 pCDevSettings_ReadHardwareInfo(hKeyDev
,
414 TEXT("HardwareInformation.AdapterString"),
415 Interface
->AdapterString
);
416 pCDevSettings_ReadHardwareInfo(hKeyDev
,
417 TEXT("HardwareInformation.BiosString"),
418 Interface
->BiosString
);
419 RegCloseKey(hKeyDev
);
424 pCDevSettings_Initialize(PCDevSettings This
,
425 PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo
)
430 This
->StateFlags
= DisplayDeviceInfo
->DeviceStateFlags
;
431 DPRINT1("This->StateFlags: %x\n", This
->StateFlags
);
433 /* Register clipboard formats */
434 This
->cfExtInterface
= RegisterClipboardFormat(DESK_EXT_EXTINTERFACE
);
435 This
->cfDisplayDevice
= RegisterClipboardFormat(DESK_EXT_DISPLAYDEVICE
);
436 This
->cfDisplayName
= RegisterClipboardFormat(DESK_EXT_DISPLAYNAME
);
437 This
->cfDisplayId
= RegisterClipboardFormat(DESK_EXT_DISPLAYID
);
438 This
->cfDisplayKey
= RegisterClipboardFormat(DESK_EXT_DISPLAYKEY
);
439 This
->cfDisplayStateFlags
= RegisterClipboardFormat(DESK_EXT_DISPLAYSTATEFLAGS
);
440 This
->cfMonitorName
= RegisterClipboardFormat(DESK_EXT_MONITORNAME
);
441 This
->cfMonitorDevice
= RegisterClipboardFormat(DESK_EXT_MONITORDEVICE
);
442 This
->cfPruningMode
= RegisterClipboardFormat(DESK_EXT_PRUNINGMODE
);
444 /* Copy the device name */
445 This
->pDisplayDevice
= pCDevSettings_AllocAndCopyString(DisplayDeviceInfo
->DeviceName
);
446 DPRINT1("This->pDisplayDevice: %ws\n", This
->pDisplayDevice
);
447 This
->pDisplayName
= pCDevSettings_AllocAndCopyString(DisplayDeviceInfo
->DeviceDescription
);
448 DPRINT1("This->pDisplayName: %ws\n", This
->pDisplayName
);
449 This
->pDisplayKey
= pCDevSettings_AllocAndCopyString(DisplayDeviceInfo
->DeviceKey
);
450 DPRINT1("This->pDisplayKey: %ws\n", This
->pDisplayKey
);
451 This
->pDisplayId
= pCDevSettings_GetDeviceInstanceId(DisplayDeviceInfo
->DeviceID
);
452 DPRINT1("This->pDisplayId: %ws\n", This
->pDisplayId
);
453 This
->pMonitorName
= pCDevSettings_GetMonitorName(This
->pDisplayDevice
);
454 DPRINT1("This->pMonitorName: %ws\n", This
->pMonitorName
);
455 This
->pMonitorDevice
= pCDevSettings_GetMonitorDevice(This
->pDisplayDevice
);
456 DPRINT1("This->pMonitorDevice: %ws\n", This
->pMonitorDevice
);
458 /* Check pruning mode */
459 This
->bModesPruned
= ((DisplayDeviceInfo
->DeviceStateFlags
& DISPLAY_DEVICE_MODESPRUNED
) != 0);
460 hKey
= pCDevSettings_OpenDeviceKey(This
,
464 hKey
= pCDevSettings_OpenDeviceKey(This
,
466 This
->bKeyIsReadOnly
= TRUE
;
471 DWORD dwType
, dwSize
;
474 if (RegQueryValueEx(hKey
,
479 &dwSize
) == ERROR_SUCCESS
)
481 if (dwType
== REG_DWORD
&& dwSize
== sizeof(dw
))
482 This
->bPruningOn
= (dw
!= 0);
488 /* Initialize the shell extension interface */
489 pCDevSettings_InitializeExtInterface(This
);
495 pCDevSettings_Free(PCDevSettings This
)
497 pCDevSettings_FreeString(&This
->pDisplayDevice
);
498 pCDevSettings_FreeString(&This
->pDisplayName
);
499 pCDevSettings_FreeString(&This
->pDisplayKey
);
500 pCDevSettings_FreeString(&This
->pDisplayId
);
501 pCDevSettings_FreeString(&This
->pMonitorName
);
502 pCDevSettings_FreeString(&This
->pMonitorDevice
);
505 static HRESULT STDMETHODCALLTYPE
506 CDevSettings_QueryInterface(IDataObject
* iface
,
510 PCDevSettings This
= impl_from_IDataObject(iface
);
514 if (IsEqualGUID(riid
,
519 *ppvObject
= (PVOID
)impl_to_interface(This
, IDataObject
);
524 DPRINT1("CDevSettings::QueryInterface: Queried unknown interface\n");
527 return E_NOINTERFACE
;
530 static ULONG STDMETHODCALLTYPE
531 CDevSettings_AddRef(IDataObject
* iface
)
533 PCDevSettings This
= impl_from_IDataObject(iface
);
534 return (ULONG
)InterlockedIncrement((PLONG
)&This
->ref
);
537 static ULONG STDMETHODCALLTYPE
538 CDevSettings_Release(IDataObject
* iface
)
541 PCDevSettings This
= impl_from_IDataObject(iface
);
542 refs
= (ULONG
)InterlockedDecrement((PLONG
)&This
->ref
);
544 pCDevSettings_Free(This
);
549 static HRESULT STDMETHODCALLTYPE
550 CDevSettings_GetData(IDataObject
* iface
,
551 FORMATETC
* pformatetcIn
,
554 static const WCHAR szEmpty
[] = {0};
556 PCWSTR pszRet
= NULL
;
558 PCDevSettings This
= impl_from_IDataObject(iface
);
563 hr
= IDataObject_QueryGetData(iface
,
567 /* Return the reqested data back to the shell extension */
569 if (pformatetcIn
->cfFormat
== This
->cfDisplayDevice
)
571 pszRet
= This
->pDisplayDevice
;
572 DPRINT1("CDevSettings::GetData returns display device %ws\n", pszRet
);
574 else if (pformatetcIn
->cfFormat
== This
->cfDisplayName
)
576 pszRet
= This
->pDisplayName
;
577 DPRINT1("CDevSettings::GetData returns display name %ws\n", pszRet
);
579 else if (pformatetcIn
->cfFormat
== This
->cfDisplayKey
)
581 pszRet
= This
->pDisplayKey
;
582 DPRINT1("CDevSettings::GetData returns display key %ws\n", pszRet
);
584 else if (pformatetcIn
->cfFormat
== This
->cfDisplayId
)
586 pszRet
= This
->pDisplayId
;
587 DPRINT1("CDevSettings::GetData returns display id %ws\n", pszRet
);
589 else if (pformatetcIn
->cfFormat
== This
->cfMonitorName
)
591 pszRet
= This
->pMonitorName
;
592 DPRINT1("CDevSettings::GetData returns monitor name %ws\n", pszRet
);
594 else if (pformatetcIn
->cfFormat
== This
->cfMonitorDevice
)
596 pszRet
= This
->pMonitorDevice
;
597 DPRINT1("CDevSettings::GetData returns monitor device %ws\n", pszRet
);
599 else if (pformatetcIn
->cfFormat
== This
->cfExtInterface
)
601 PDESK_EXT_INTERFACE pIface
;
603 pIface
= GlobalAlloc(GPTR
,
609 sizeof(This
->ExtInterface
));
611 DPRINT1("CDevSettings::GetData returns the desk.cpl extension interface\n");
613 pmedium
->tymed
= TYMED_HGLOBAL
;
614 pmedium
->hGlobal
= pIface
;
619 return E_OUTOFMEMORY
;
621 else if (pformatetcIn
->cfFormat
== This
->cfDisplayStateFlags
)
625 pdw
= GlobalAlloc(GPTR
,
629 *pdw
= This
->StateFlags
;
631 DPRINT1("CDevSettings::GetData returns the display state flags %x\n", This
->StateFlags
);
633 pmedium
->tymed
= TYMED_HGLOBAL
;
634 pmedium
->hGlobal
= pdw
;
639 return E_OUTOFMEMORY
;
641 else if (pformatetcIn
->cfFormat
== This
->cfPruningMode
)
645 pb
= GlobalAlloc(GPTR
,
649 *pb
= (This
->bModesPruned
&& This
->bPruningOn
);
651 pmedium
->tymed
= TYMED_HGLOBAL
;
652 pmedium
->hGlobal
= pb
;
657 return E_OUTOFMEMORY
;
660 /* NOTE: This only returns null-terminated strings! */
664 pszBuf
= GlobalAlloc(GPTR
,
665 (_tcslen(pszRet
) + 1) * sizeof(WCHAR
));
671 pmedium
->tymed
= TYMED_HGLOBAL
;
672 pmedium
->hGlobal
= pszBuf
;
683 static HRESULT STDMETHODCALLTYPE
684 CDevSettings_GetDataHere(IDataObject
* iface
,
685 FORMATETC
* pformatetc
,
688 ZeroMemory(pformatetc
,
689 sizeof(*pformatetc
));
693 static HRESULT STDMETHODCALLTYPE
694 CDevSettings_QueryGetData(IDataObject
* iface
,
695 FORMATETC
* pformatetc
)
698 TCHAR szFormatName
[255];
700 PCDevSettings This
= impl_from_IDataObject(iface
);
702 if (pformatetc
->dwAspect
!= DVASPECT_CONTENT
)
703 return DV_E_DVASPECT
;
705 if (pformatetc
->lindex
!= -1)
708 if (!(pformatetc
->tymed
& TYMED_HGLOBAL
))
711 /* Check if the requested data can be provided */
712 if (pformatetc
->cfFormat
== This
->cfExtInterface
||
713 pformatetc
->cfFormat
== This
->cfDisplayDevice
||
714 pformatetc
->cfFormat
== This
->cfDisplayName
||
715 pformatetc
->cfFormat
== This
->cfDisplayId
||
716 pformatetc
->cfFormat
== This
->cfDisplayKey
||
717 pformatetc
->cfFormat
== This
->cfDisplayStateFlags
||
718 pformatetc
->cfFormat
== This
->cfMonitorDevice
||
719 pformatetc
->cfFormat
== This
->cfMonitorName
||
720 pformatetc
->cfFormat
== This
->cfPruningMode
)
727 if (GetClipboardFormatName(pformatetc
->cfFormat
,
729 sizeof(szFormatName
) / sizeof(szFormatName
[0])))
731 DPRINT1("CDevSettings::QueryGetData(\"%ws\")\n", szFormatName
);
735 DPRINT1("CDevSettings::QueryGetData(Format %u)\n", (unsigned int)pformatetc
->cfFormat
);
740 return DV_E_FORMATETC
;
743 static HRESULT STDMETHODCALLTYPE
744 CDevSettings_GetCanonicalFormatEtc(IDataObject
* iface
,
745 FORMATETC
* pformatectIn
,
746 FORMATETC
* pformatetcOut
)
750 DPRINT1("CDevSettings::GetCanonicalFormatEtc\n");
752 hr
= IDataObject_QueryGetData(iface
,
756 CopyMemory(pformatetcOut
,
760 /* Make sure the data is target device independent */
761 if (pformatectIn
->ptd
== NULL
)
762 hr
= DATA_S_SAMEFORMATETC
;
765 pformatetcOut
->ptd
= NULL
;
771 ZeroMemory(pformatetcOut
,
778 static HRESULT STDMETHODCALLTYPE
779 CDevSettings_SetData(IDataObject
* iface
,
780 FORMATETC
* pformatetc
,
784 DPRINT1("CDevSettings::SetData UNIMPLEMENTED\n");
789 pCDevSettings_FillFormatEtc(FORMATETC
*pFormatEtc
,
792 pFormatEtc
->cfFormat
= cf
;
793 pFormatEtc
->ptd
= NULL
;
794 pFormatEtc
->dwAspect
= DVASPECT_CONTENT
;
795 pFormatEtc
->lindex
= -1;
796 pFormatEtc
->tymed
= TYMED_HGLOBAL
;
799 static HRESULT STDMETHODCALLTYPE
800 CDevSettings_EnumFormatEtc(IDataObject
* iface
,
802 IEnumFORMATETC
** ppenumFormatEtc
)
806 PCDevSettings This
= impl_from_IDataObject(iface
);
808 *ppenumFormatEtc
= NULL
;
810 if (dwDirection
== DATADIR_GET
)
812 pCDevSettings_FillFormatEtc(&fetc
[0],
813 This
->cfExtInterface
);
814 pCDevSettings_FillFormatEtc(&fetc
[1],
815 This
->cfDisplayDevice
);
816 pCDevSettings_FillFormatEtc(&fetc
[2],
817 This
->cfDisplayName
);
818 pCDevSettings_FillFormatEtc(&fetc
[3],
820 pCDevSettings_FillFormatEtc(&fetc
[4],
822 pCDevSettings_FillFormatEtc(&fetc
[5],
823 This
->cfDisplayStateFlags
);
824 pCDevSettings_FillFormatEtc(&fetc
[6],
825 This
->cfMonitorName
);
826 pCDevSettings_FillFormatEtc(&fetc
[7],
827 This
->cfMonitorDevice
);
828 pCDevSettings_FillFormatEtc(&fetc
[8],
829 This
->cfPruningMode
);
831 hr
= SHCreateStdEnumFmtEtc(sizeof(fetc
) / sizeof(fetc
[0]),
841 static HRESULT STDMETHODCALLTYPE
842 CDevSettings_DAdvise(IDataObject
* iface
,
843 FORMATETC
* pformatetc
,
845 IAdviseSink
* pAdvSink
,
846 DWORD
* pdwConnection
)
849 return OLE_E_ADVISENOTSUPPORTED
;
852 static HRESULT STDMETHODCALLTYPE
853 CDevSettings_DUnadvise(IDataObject
* iface
,
856 return OLE_E_ADVISENOTSUPPORTED
;
859 static HRESULT STDMETHODCALLTYPE
860 CDevSettings_EnumDAdvise(IDataObject
* iface
,
861 IEnumSTATDATA
** ppenumAdvise
)
863 *ppenumAdvise
= NULL
;
864 return OLE_E_ADVISENOTSUPPORTED
;
867 static const struct IDataObjectVtbl vtblIDataObject
= {
868 CDevSettings_QueryInterface
,
870 CDevSettings_Release
,
871 CDevSettings_GetData
,
872 CDevSettings_GetDataHere
,
873 CDevSettings_QueryGetData
,
874 CDevSettings_GetCanonicalFormatEtc
,
875 CDevSettings_SetData
,
876 CDevSettings_EnumFormatEtc
,
877 CDevSettings_DAdvise
,
878 CDevSettings_DUnadvise
,
879 CDevSettings_EnumDAdvise
,
883 CreateDevSettings(PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo
)
887 This
= HeapAlloc(GetProcessHeap(),
892 This
->lpIDataObjectVtbl
= &vtblIDataObject
;
895 if (SUCCEEDED(pCDevSettings_Initialize(This
,
898 return impl_to_interface(This
, IDataObject
);
901 CDevSettings_Release(impl_to_interface(This
, IDataObject
));
908 DisplaySaveSettings(PVOID pContext
,
911 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context);
912 DPRINT("DisplaySaveSettings() UNIMPLEMENTED!\n");
913 return DISP_CHANGE_BADPARAM
;