Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendevsett.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Display Control Panel 00004 * FILE: dll/cpl/desk/devsett.c 00005 * PURPOSE: ReactOS Display Control Panel Shell Extension Support 00006 */ 00007 00008 #include "desk.h" 00009 00010 #define NDEBUG 00011 #include <debug.h> 00012 00013 #define DEBUG_DEVSETTINGS 00014 00015 typedef struct _CDevSettings 00016 { 00017 const struct IDataObjectVtbl *lpIDataObjectVtbl; 00018 DWORD ref; 00019 00020 CLIPFORMAT cfExtInterface; /* "Desk.cpl extension interface" */ 00021 CLIPFORMAT cfDisplayDevice; /* "Display Device" */ 00022 CLIPFORMAT cfDisplayName; /* "Display Name" */ 00023 CLIPFORMAT cfDisplayId; /* "Display ID" */ 00024 CLIPFORMAT cfMonitorName; /* "Monitor Name" */ 00025 CLIPFORMAT cfMonitorDevice; /* "Monitor Device" */ 00026 CLIPFORMAT cfDisplayKey; /* "Display Key" */ 00027 CLIPFORMAT cfDisplayStateFlags; /* "Display State Flags" */ 00028 CLIPFORMAT cfPruningMode; /* "Pruning Mode" */ 00029 00030 PWSTR pDisplayDevice; 00031 PWSTR pDisplayName; 00032 PWSTR pDisplayKey; 00033 PWSTR pDisplayId; 00034 PWSTR pMonitorName; 00035 PWSTR pMonitorDevice; 00036 00037 DESK_EXT_INTERFACE ExtInterface; 00038 00039 DWORD StateFlags; 00040 00041 union 00042 { 00043 DWORD Flags; 00044 struct 00045 { 00046 DWORD bModesPruned : 1; 00047 DWORD bKeyIsReadOnly : 1; 00048 DWORD bPruningOn : 1; 00049 }; 00050 }; 00051 } CDevSettings, *PCDevSettings; 00052 00053 #define impl_to_interface(impl,iface) (struct iface *)(&(impl)->lp##iface##Vtbl) 00054 00055 static __inline PCDevSettings 00056 impl_from_IDataObject(struct IDataObject *iface) 00057 { 00058 return (PCDevSettings)((ULONG_PTR)iface - FIELD_OFFSET(CDevSettings, 00059 lpIDataObjectVtbl)); 00060 } 00061 00062 static __inline VOID 00063 pCDevSettings_FreeString(PWCHAR *psz) 00064 { 00065 if (*psz != NULL) 00066 { 00067 LocalFree((HLOCAL)*psz); 00068 *psz = NULL; 00069 } 00070 } 00071 00072 static PWSTR 00073 pCDevSettings_AllocAndCopyString(const TCHAR *pszSrc) 00074 { 00075 INT c; 00076 PWSTR str; 00077 00078 c = _tcslen(pszSrc) + 1; 00079 str = (PWSTR)LocalAlloc(LMEM_FIXED, 00080 c * sizeof(WCHAR)); 00081 if (str != NULL) 00082 { 00083 #ifdef UNICODE 00084 wcscpy(str, 00085 pszSrc); 00086 #else 00087 MultiByteToWideChar(CP_ACP, 00088 0, 00089 pszSrc, 00090 -1, 00091 str, 00092 c); 00093 #endif 00094 } 00095 00096 return str; 00097 } 00098 00099 static PWSTR 00100 pCDevSettings_GetMonitorName(const WCHAR *pszDisplayDevice) 00101 { 00102 DISPLAY_DEVICEW dd, dd2; 00103 PWSTR str = NULL; 00104 00105 dd.cb = sizeof(dd); 00106 if (EnumDisplayDevicesW(pszDisplayDevice, 00107 0, 00108 &dd, 00109 0)) 00110 { 00111 dd2.cb = sizeof(dd2); 00112 if (EnumDisplayDevicesW(pszDisplayDevice, 00113 1, 00114 &dd2, 00115 0)) 00116 { 00117 /* There's more than one monitor connected... */ 00118 LoadStringW(hApplet, 00119 IDS_MULTIPLEMONITORS, 00120 dd.DeviceString, 00121 sizeof(dd.DeviceString) / sizeof(dd.DeviceString[0])); 00122 } 00123 } 00124 else 00125 { 00126 /* We can't enumerate a monitor, make sure this fact is reported 00127 to the user! */ 00128 LoadStringW(hApplet, 00129 IDS_UNKNOWNMONITOR, 00130 dd.DeviceString, 00131 sizeof(dd.DeviceString) / sizeof(dd.DeviceString[0])); 00132 } 00133 00134 str = LocalAlloc(LMEM_FIXED, 00135 (wcslen(dd.DeviceString) + 1) * sizeof(WCHAR)); 00136 if (str != NULL) 00137 { 00138 wcscpy(str, 00139 dd.DeviceString); 00140 } 00141 00142 return str; 00143 } 00144 00145 static PWSTR 00146 pCDevSettings_GetMonitorDevice(const WCHAR *pszDisplayDevice) 00147 { 00148 DISPLAY_DEVICEW dd; 00149 PWSTR str = NULL; 00150 00151 dd.cb = sizeof(dd); 00152 if (EnumDisplayDevicesW(pszDisplayDevice, 00153 0, 00154 &dd, 00155 0)) 00156 { 00157 str = LocalAlloc(LMEM_FIXED, 00158 (wcslen(dd.DeviceName) + 1) * sizeof(WCHAR)); 00159 if (str != NULL) 00160 { 00161 wcscpy(str, 00162 dd.DeviceName); 00163 } 00164 } 00165 00166 return str; 00167 } 00168 00169 static PWSTR 00170 pCDevSettings_GetDeviceInstanceId(const WCHAR *pszDevice) 00171 { 00172 DEVINST DevInst; 00173 CONFIGRET cr; 00174 ULONG BufLen; 00175 LPWSTR lpDevInstId = NULL; 00176 00177 DPRINT1("CDevSettings::GetDeviceInstanceId(%ws) UNIMPLEMENTED!\n", pszDevice); 00178 00179 cr = CM_Locate_DevNodeW(&DevInst, 00180 (DEVINSTID_W)pszDevice, 00181 CM_LOCATE_DEVNODE_NORMAL); 00182 if (cr == CR_SUCCESS) 00183 { 00184 DPRINT1("Success1\n"); 00185 cr = CM_Get_Device_ID_Size(&BufLen, 00186 DevInst, 00187 0); 00188 if (cr == CR_SUCCESS) 00189 { 00190 DPRINT1("Success2\n"); 00191 lpDevInstId = LocalAlloc(LMEM_FIXED, 00192 (BufLen + 1) * sizeof(WCHAR)); 00193 00194 if (lpDevInstId != NULL) 00195 { 00196 DPRINT1("Success3\n"); 00197 cr = CM_Get_Device_IDW(DevInst, 00198 lpDevInstId, 00199 BufLen, 00200 0); 00201 00202 if (cr != CR_SUCCESS) 00203 { 00204 LocalFree((HLOCAL)lpDevInstId); 00205 lpDevInstId = NULL; 00206 } 00207 DPRINT1("instance id: %ws\n", lpDevInstId); 00208 } 00209 } 00210 } 00211 00212 return lpDevInstId; 00213 } 00214 00215 00216 static HKEY 00217 pCDevSettings_OpenDeviceKey(PCDevSettings This, 00218 BOOL ReadOnly) 00219 { 00220 static const WCHAR szRegPrefix[] = L"\\Registry\\Machine\\"; 00221 PWSTR lpRegKey; 00222 REGSAM Access = KEY_READ; 00223 HKEY hKey; 00224 00225 lpRegKey = This->pDisplayKey; 00226 if (lpRegKey != NULL) 00227 { 00228 if (wcslen(lpRegKey) >= wcslen(szRegPrefix) && 00229 !_wcsnicmp(lpRegKey, 00230 szRegPrefix, 00231 wcslen(szRegPrefix))) 00232 { 00233 lpRegKey += wcslen(szRegPrefix); 00234 } 00235 00236 if (!ReadOnly) 00237 Access |= KEY_WRITE; 00238 00239 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00240 lpRegKey, 00241 0, 00242 Access, 00243 &hKey) == ERROR_SUCCESS) 00244 { 00245 return hKey; 00246 } 00247 } 00248 00249 return NULL; 00250 } 00251 00252 PDEVMODEW DESK_EXT_CALLBACK 00253 CDevSettings_EnumAllModes(PVOID Context, 00254 DWORD Index) 00255 { 00256 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context); 00257 /* FIXME: Implement */ 00258 DPRINT1("CDevSettings::EnumAllModes(%u)\n", Index); 00259 return NULL; 00260 } 00261 00262 PDEVMODEW DESK_EXT_CALLBACK 00263 CDevSettings_GetCurrentMode(PVOID Context) 00264 { 00265 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context); 00266 /* FIXME: Implement */ 00267 DPRINT1("CDevSettings::GetCurrentMode\n"); 00268 return NULL; 00269 } 00270 00271 BOOL DESK_EXT_CALLBACK 00272 CDevSettings_SetCurrentMode(PVOID Context, 00273 const DEVMODEW *pDevMode) 00274 { 00275 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context); 00276 /* FIXME: Implement */ 00277 DPRINT1("CDevSettings::SetCurrentMode(0x%p)\n", pDevMode); 00278 return FALSE; 00279 } 00280 00281 VOID DESK_EXT_CALLBACK 00282 CDevSettings_GetPruningMode(PVOID Context, 00283 PBOOL pbModesPruned, 00284 PBOOL pbKeyIsReadOnly, 00285 PBOOL pbPruningOn) 00286 { 00287 PCDevSettings This = impl_from_IDataObject((IDataObject *)Context); 00288 00289 DPRINT1("CDevSettings::GetPruningMode(%p,%p,%p)\n", pbModesPruned, pbKeyIsReadOnly, pbPruningOn); 00290 00291 *pbModesPruned = This->bModesPruned; 00292 *pbKeyIsReadOnly = This->bKeyIsReadOnly; 00293 *pbPruningOn = This->bPruningOn; 00294 } 00295 00296 VOID DESK_EXT_CALLBACK 00297 CDevSettings_SetPruningMode(PVOID Context, 00298 BOOL PruningOn) 00299 { 00300 HKEY hKey; 00301 DWORD dwValue; 00302 PCDevSettings This = impl_from_IDataObject((IDataObject *)Context); 00303 00304 DPRINT1("CDevSettings::SetPruningMode(%d)\n", PruningOn); 00305 00306 if (This->bModesPruned && !This->bKeyIsReadOnly && 00307 PruningOn != This->bPruningOn) 00308 { 00309 This->bPruningOn = (PruningOn != FALSE); 00310 00311 hKey = pCDevSettings_OpenDeviceKey(This, 00312 FALSE); 00313 if (hKey != NULL) 00314 { 00315 dwValue = (DWORD)This->bPruningOn; 00316 00317 RegSetValueEx(hKey, 00318 TEXT("PruningMode"), 00319 0, 00320 REG_DWORD, 00321 (const BYTE *)&dwValue, 00322 sizeof(dwValue)); 00323 00324 RegCloseKey(hKey); 00325 } 00326 } 00327 } 00328 00329 static VOID 00330 pCDevSettings_ReadHardwareInfo(HKEY hKey, 00331 LPCTSTR lpValueName, 00332 LPWSTR lpBuffer) 00333 { 00334 DWORD type = REG_BINARY; 00335 DWORD size = 128 * sizeof(WCHAR); 00336 RegQueryValueEx(hKey, 00337 lpValueName, 00338 NULL, 00339 &type, 00340 (PBYTE)lpBuffer, 00341 &size); 00342 } 00343 00344 static VOID 00345 pCDevSettings_InitializeExtInterface(PCDevSettings This) 00346 { 00347 PDESK_EXT_INTERFACE Interface = &This->ExtInterface; 00348 HKEY hKeyDev; 00349 00350 ZeroMemory(Interface, 00351 sizeof(*Interface)); 00352 Interface->cbSize = sizeof(*Interface); 00353 00354 /* Initialize the callback table */ 00355 Interface->Context = impl_to_interface(This, IDataObject); 00356 Interface->EnumAllModes = CDevSettings_EnumAllModes; 00357 Interface->SetCurrentMode = CDevSettings_SetCurrentMode; 00358 Interface->GetCurrentMode = CDevSettings_GetCurrentMode; 00359 Interface->SetPruningMode = CDevSettings_SetPruningMode; 00360 Interface->GetPruningMode = CDevSettings_GetPruningMode; 00361 00362 /* Read the HardwareInformation.* values from the registry key */ 00363 hKeyDev = pCDevSettings_OpenDeviceKey(This, 00364 TRUE); 00365 if (hKeyDev != NULL) 00366 { 00367 DWORD dwType, dwMemSize = 0; 00368 DWORD dwSize = sizeof(dwMemSize); 00369 00370 if (RegQueryValueEx(hKeyDev, 00371 TEXT("HardwareInformation.MemorySize"), 00372 NULL, 00373 &dwType, 00374 (PBYTE)&dwMemSize, 00375 &dwSize) == ERROR_SUCCESS && 00376 (dwType == REG_BINARY || dwType == REG_DWORD) && 00377 dwSize == sizeof(dwMemSize)) 00378 { 00379 dwMemSize /= 1024; 00380 00381 if (dwMemSize > 1024) 00382 { 00383 dwMemSize /= 1024; 00384 if (dwMemSize > 1024) 00385 { 00386 wsprintf(Interface->MemorySize, 00387 _T("%u GB"), 00388 dwMemSize / 1024); 00389 } 00390 else 00391 { 00392 wsprintf(Interface->MemorySize, 00393 _T("%u MB"), 00394 dwMemSize); 00395 } 00396 } 00397 else 00398 { 00399 wsprintf(Interface->MemorySize, 00400 _T("%u KB"), 00401 dwMemSize); 00402 } 00403 } 00404 00405 pCDevSettings_ReadHardwareInfo(hKeyDev, 00406 TEXT("HardwareInformation.ChipType"), 00407 Interface->ChipType); 00408 pCDevSettings_ReadHardwareInfo(hKeyDev, 00409 TEXT("HardwareInformation.DacType"), 00410 Interface->DacType); 00411 pCDevSettings_ReadHardwareInfo(hKeyDev, 00412 TEXT("HardwareInformation.AdapterString"), 00413 Interface->AdapterString); 00414 pCDevSettings_ReadHardwareInfo(hKeyDev, 00415 TEXT("HardwareInformation.BiosString"), 00416 Interface->BiosString); 00417 RegCloseKey(hKeyDev); 00418 } 00419 } 00420 00421 static HRESULT 00422 pCDevSettings_Initialize(PCDevSettings This, 00423 PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo) 00424 { 00425 HKEY hKey; 00426 00427 This->Flags = 0; 00428 This->StateFlags = DisplayDeviceInfo->DeviceStateFlags; 00429 DPRINT1("This->StateFlags: %x\n", This->StateFlags); 00430 00431 /* Register clipboard formats */ 00432 This->cfExtInterface = RegisterClipboardFormat(DESK_EXT_EXTINTERFACE); 00433 This->cfDisplayDevice = RegisterClipboardFormat(DESK_EXT_DISPLAYDEVICE); 00434 This->cfDisplayName = RegisterClipboardFormat(DESK_EXT_DISPLAYNAME); 00435 This->cfDisplayId = RegisterClipboardFormat(DESK_EXT_DISPLAYID); 00436 This->cfDisplayKey = RegisterClipboardFormat(DESK_EXT_DISPLAYKEY); 00437 This->cfDisplayStateFlags = RegisterClipboardFormat(DESK_EXT_DISPLAYSTATEFLAGS); 00438 This->cfMonitorName = RegisterClipboardFormat(DESK_EXT_MONITORNAME); 00439 This->cfMonitorDevice = RegisterClipboardFormat(DESK_EXT_MONITORDEVICE); 00440 This->cfPruningMode = RegisterClipboardFormat(DESK_EXT_PRUNINGMODE); 00441 00442 /* Copy the device name */ 00443 This->pDisplayDevice = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceName); 00444 DPRINT1("This->pDisplayDevice: %ws\n", This->pDisplayDevice); 00445 This->pDisplayName = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceDescription); 00446 DPRINT1("This->pDisplayName: %ws\n", This->pDisplayName); 00447 This->pDisplayKey = pCDevSettings_AllocAndCopyString(DisplayDeviceInfo->DeviceKey); 00448 DPRINT1("This->pDisplayKey: %ws\n", This->pDisplayKey); 00449 This->pDisplayId = pCDevSettings_GetDeviceInstanceId(DisplayDeviceInfo->DeviceID); 00450 DPRINT1("This->pDisplayId: %ws\n", This->pDisplayId); 00451 This->pMonitorName = pCDevSettings_GetMonitorName(This->pDisplayDevice); 00452 DPRINT1("This->pMonitorName: %ws\n", This->pMonitorName); 00453 This->pMonitorDevice = pCDevSettings_GetMonitorDevice(This->pDisplayDevice); 00454 DPRINT1("This->pMonitorDevice: %ws\n", This->pMonitorDevice); 00455 00456 /* Check pruning mode */ 00457 This->bModesPruned = ((DisplayDeviceInfo->DeviceStateFlags & DISPLAY_DEVICE_MODESPRUNED) != 0); 00458 hKey = pCDevSettings_OpenDeviceKey(This, 00459 FALSE); 00460 if (hKey == NULL) 00461 { 00462 hKey = pCDevSettings_OpenDeviceKey(This, 00463 FALSE); 00464 This->bKeyIsReadOnly = TRUE; 00465 } 00466 if (hKey != NULL) 00467 { 00468 DWORD dw = 0; 00469 DWORD dwType, dwSize; 00470 00471 dwSize = sizeof(dw); 00472 if (RegQueryValueEx(hKey, 00473 TEXT("PruningMode"), 00474 NULL, 00475 &dwType, 00476 (PBYTE)&dw, 00477 &dwSize) == ERROR_SUCCESS) 00478 { 00479 if (dwType == REG_DWORD && dwSize == sizeof(dw)) 00480 This->bPruningOn = (dw != 0); 00481 } 00482 00483 RegCloseKey(hKey); 00484 } 00485 00486 /* Initialize the shell extension interface */ 00487 pCDevSettings_InitializeExtInterface(This); 00488 00489 return S_OK; 00490 } 00491 00492 static VOID 00493 pCDevSettings_Free(PCDevSettings This) 00494 { 00495 pCDevSettings_FreeString(&This->pDisplayDevice); 00496 pCDevSettings_FreeString(&This->pDisplayName); 00497 pCDevSettings_FreeString(&This->pDisplayKey); 00498 pCDevSettings_FreeString(&This->pDisplayId); 00499 pCDevSettings_FreeString(&This->pMonitorName); 00500 pCDevSettings_FreeString(&This->pMonitorDevice); 00501 } 00502 00503 static HRESULT STDMETHODCALLTYPE 00504 CDevSettings_QueryInterface(IDataObject* iface, 00505 REFIID riid, 00506 void** ppvObject) 00507 { 00508 PCDevSettings This = impl_from_IDataObject(iface); 00509 00510 *ppvObject = NULL; 00511 00512 if (IsEqualGUID(riid, 00513 &IID_IUnknown) || 00514 IsEqualGUID(riid, 00515 &IID_IDataObject)) 00516 { 00517 *ppvObject = (PVOID)impl_to_interface(This, IDataObject); 00518 return S_OK; 00519 } 00520 else 00521 { 00522 DPRINT1("CDevSettings::QueryInterface: Queried unknown interface\n"); 00523 } 00524 00525 return E_NOINTERFACE; 00526 } 00527 00528 static ULONG STDMETHODCALLTYPE 00529 CDevSettings_AddRef(IDataObject* iface) 00530 { 00531 PCDevSettings This = impl_from_IDataObject(iface); 00532 return (ULONG)InterlockedIncrement((PLONG)&This->ref); 00533 } 00534 00535 static ULONG STDMETHODCALLTYPE 00536 CDevSettings_Release(IDataObject* iface) 00537 { 00538 ULONG refs; 00539 PCDevSettings This = impl_from_IDataObject(iface); 00540 refs = (ULONG)InterlockedDecrement((PLONG)&This->ref); 00541 if (refs == 0) 00542 pCDevSettings_Free(This); 00543 00544 return refs; 00545 } 00546 00547 static HRESULT STDMETHODCALLTYPE 00548 CDevSettings_GetData(IDataObject* iface, 00549 FORMATETC* pformatetcIn, 00550 STGMEDIUM* pmedium) 00551 { 00552 static const WCHAR szEmpty[] = {0}; 00553 HRESULT hr; 00554 PCWSTR pszRet = NULL; 00555 PWSTR pszBuf; 00556 PCDevSettings This = impl_from_IDataObject(iface); 00557 00558 ZeroMemory(pmedium, 00559 sizeof(STGMEDIUM)); 00560 00561 hr = IDataObject_QueryGetData(iface, 00562 pformatetcIn); 00563 if (SUCCEEDED(hr)) 00564 { 00565 /* Return the reqested data back to the shell extension */ 00566 00567 if (pformatetcIn->cfFormat == This->cfDisplayDevice) 00568 { 00569 pszRet = This->pDisplayDevice; 00570 DPRINT1("CDevSettings::GetData returns display device %ws\n", pszRet); 00571 } 00572 else if (pformatetcIn->cfFormat == This->cfDisplayName) 00573 { 00574 pszRet = This->pDisplayName; 00575 DPRINT1("CDevSettings::GetData returns display name %ws\n", pszRet); 00576 } 00577 else if (pformatetcIn->cfFormat == This->cfDisplayKey) 00578 { 00579 pszRet = This->pDisplayKey; 00580 DPRINT1("CDevSettings::GetData returns display key %ws\n", pszRet); 00581 } 00582 else if (pformatetcIn->cfFormat == This->cfDisplayId) 00583 { 00584 pszRet = This->pDisplayId; 00585 DPRINT1("CDevSettings::GetData returns display id %ws\n", pszRet); 00586 } 00587 else if (pformatetcIn->cfFormat == This->cfMonitorName) 00588 { 00589 pszRet = This->pMonitorName; 00590 DPRINT1("CDevSettings::GetData returns monitor name %ws\n", pszRet); 00591 } 00592 else if (pformatetcIn->cfFormat == This->cfMonitorDevice) 00593 { 00594 pszRet = This->pMonitorDevice; 00595 DPRINT1("CDevSettings::GetData returns monitor device %ws\n", pszRet); 00596 } 00597 else if (pformatetcIn->cfFormat == This->cfExtInterface) 00598 { 00599 PDESK_EXT_INTERFACE pIface; 00600 00601 pIface = GlobalAlloc(GPTR, 00602 sizeof(*pIface)); 00603 if (pIface != NULL) 00604 { 00605 CopyMemory(pIface, 00606 &This->ExtInterface, 00607 sizeof(This->ExtInterface)); 00608 00609 DPRINT1("CDevSettings::GetData returns the desk.cpl extension interface\n"); 00610 00611 pmedium->tymed = TYMED_HGLOBAL; 00612 pmedium->hGlobal = pIface; 00613 00614 return S_OK; 00615 } 00616 else 00617 return E_OUTOFMEMORY; 00618 } 00619 else if (pformatetcIn->cfFormat == This->cfDisplayStateFlags) 00620 { 00621 PDWORD pdw; 00622 00623 pdw = GlobalAlloc(GPTR, 00624 sizeof(*pdw)); 00625 if (pdw != NULL) 00626 { 00627 *pdw = This->StateFlags; 00628 00629 DPRINT1("CDevSettings::GetData returns the display state flags %x\n", This->StateFlags); 00630 00631 pmedium->tymed = TYMED_HGLOBAL; 00632 pmedium->hGlobal = pdw; 00633 00634 return S_OK; 00635 } 00636 else 00637 return E_OUTOFMEMORY; 00638 } 00639 else if (pformatetcIn->cfFormat == This->cfPruningMode) 00640 { 00641 PBYTE pb; 00642 00643 pb = GlobalAlloc(GPTR, 00644 sizeof(*pb)); 00645 if (pb != NULL) 00646 { 00647 *pb = (This->bModesPruned && This->bPruningOn); 00648 00649 pmedium->tymed = TYMED_HGLOBAL; 00650 pmedium->hGlobal = pb; 00651 00652 return S_OK; 00653 } 00654 else 00655 return E_OUTOFMEMORY; 00656 } 00657 00658 /* NOTE: This only returns null-terminated strings! */ 00659 if (pszRet == NULL) 00660 pszRet = szEmpty; 00661 00662 pszBuf = GlobalAlloc(GPTR, 00663 (_tcslen(pszRet) + 1) * sizeof(WCHAR)); 00664 if (pszBuf != NULL) 00665 { 00666 _tcscpy(pszBuf, 00667 pszRet); 00668 00669 pmedium->tymed = TYMED_HGLOBAL; 00670 pmedium->hGlobal = pszBuf; 00671 00672 hr = S_OK; 00673 } 00674 else 00675 hr = E_OUTOFMEMORY; 00676 } 00677 00678 return hr; 00679 } 00680 00681 static HRESULT STDMETHODCALLTYPE 00682 CDevSettings_GetDataHere(IDataObject* iface, 00683 FORMATETC* pformatetc, 00684 STGMEDIUM* pmedium) 00685 { 00686 ZeroMemory(pformatetc, 00687 sizeof(*pformatetc)); 00688 return E_NOTIMPL; 00689 } 00690 00691 static HRESULT STDMETHODCALLTYPE 00692 CDevSettings_QueryGetData(IDataObject* iface, 00693 FORMATETC* pformatetc) 00694 { 00695 #if DEBUG 00696 TCHAR szFormatName[255]; 00697 #endif 00698 PCDevSettings This = impl_from_IDataObject(iface); 00699 00700 if (pformatetc->dwAspect != DVASPECT_CONTENT) 00701 return DV_E_DVASPECT; 00702 00703 if (pformatetc->lindex != -1) 00704 return DV_E_LINDEX; 00705 00706 if (!(pformatetc->tymed & TYMED_HGLOBAL)) 00707 return DV_E_TYMED; 00708 00709 /* Check if the requested data can be provided */ 00710 if (pformatetc->cfFormat == This->cfExtInterface || 00711 pformatetc->cfFormat == This->cfDisplayDevice || 00712 pformatetc->cfFormat == This->cfDisplayName || 00713 pformatetc->cfFormat == This->cfDisplayId || 00714 pformatetc->cfFormat == This->cfDisplayKey || 00715 pformatetc->cfFormat == This->cfDisplayStateFlags || 00716 pformatetc->cfFormat == This->cfMonitorDevice || 00717 pformatetc->cfFormat == This->cfMonitorName || 00718 pformatetc->cfFormat == This->cfPruningMode) 00719 { 00720 return S_OK; 00721 } 00722 #if DEBUG 00723 else 00724 { 00725 if (GetClipboardFormatName(pformatetc->cfFormat, 00726 szFormatName, 00727 sizeof(szFormatName) / sizeof(szFormatName[0]))) 00728 { 00729 DPRINT1("CDevSettings::QueryGetData(\"%ws\")\n", szFormatName); 00730 } 00731 else 00732 { 00733 DPRINT1("CDevSettings::QueryGetData(Format %u)\n", (unsigned int)pformatetc->cfFormat); 00734 } 00735 } 00736 #endif 00737 00738 return DV_E_FORMATETC; 00739 } 00740 00741 static HRESULT STDMETHODCALLTYPE 00742 CDevSettings_GetCanonicalFormatEtc(IDataObject* iface, 00743 FORMATETC* pformatectIn, 00744 FORMATETC* pformatetcOut) 00745 { 00746 HRESULT hr; 00747 00748 DPRINT1("CDevSettings::GetCanonicalFormatEtc\n"); 00749 00750 hr = IDataObject_QueryGetData(iface, 00751 pformatectIn); 00752 if (SUCCEEDED(hr)) 00753 { 00754 CopyMemory(pformatetcOut, 00755 pformatectIn, 00756 sizeof(FORMATETC)); 00757 00758 /* Make sure the data is target device independent */ 00759 if (pformatectIn->ptd == NULL) 00760 hr = DATA_S_SAMEFORMATETC; 00761 else 00762 { 00763 pformatetcOut->ptd = NULL; 00764 hr = S_OK; 00765 } 00766 } 00767 else 00768 { 00769 ZeroMemory(pformatetcOut, 00770 sizeof(FORMATETC)); 00771 } 00772 00773 return hr; 00774 } 00775 00776 static HRESULT STDMETHODCALLTYPE 00777 CDevSettings_SetData(IDataObject* iface, 00778 FORMATETC* pformatetc, 00779 STGMEDIUM* pmedium, 00780 BOOL fRelease) 00781 { 00782 DPRINT1("CDevSettings::SetData UNIMPLEMENTED\n"); 00783 return E_NOTIMPL; 00784 } 00785 00786 static __inline VOID 00787 pCDevSettings_FillFormatEtc(FORMATETC *pFormatEtc, 00788 CLIPFORMAT cf) 00789 { 00790 pFormatEtc->cfFormat = cf; 00791 pFormatEtc->ptd = NULL; 00792 pFormatEtc->dwAspect = DVASPECT_CONTENT; 00793 pFormatEtc->lindex = -1; 00794 pFormatEtc->tymed = TYMED_HGLOBAL; 00795 } 00796 00797 static HRESULT STDMETHODCALLTYPE 00798 CDevSettings_EnumFormatEtc(IDataObject* iface, 00799 DWORD dwDirection, 00800 IEnumFORMATETC** ppenumFormatEtc) 00801 { 00802 HRESULT hr; 00803 FORMATETC fetc[9]; 00804 PCDevSettings This = impl_from_IDataObject(iface); 00805 00806 *ppenumFormatEtc = NULL; 00807 00808 if (dwDirection == DATADIR_GET) 00809 { 00810 pCDevSettings_FillFormatEtc(&fetc[0], 00811 This->cfExtInterface); 00812 pCDevSettings_FillFormatEtc(&fetc[1], 00813 This->cfDisplayDevice); 00814 pCDevSettings_FillFormatEtc(&fetc[2], 00815 This->cfDisplayName); 00816 pCDevSettings_FillFormatEtc(&fetc[3], 00817 This->cfDisplayId); 00818 pCDevSettings_FillFormatEtc(&fetc[4], 00819 This->cfDisplayKey); 00820 pCDevSettings_FillFormatEtc(&fetc[5], 00821 This->cfDisplayStateFlags); 00822 pCDevSettings_FillFormatEtc(&fetc[6], 00823 This->cfMonitorName); 00824 pCDevSettings_FillFormatEtc(&fetc[7], 00825 This->cfMonitorDevice); 00826 pCDevSettings_FillFormatEtc(&fetc[8], 00827 This->cfPruningMode); 00828 00829 hr = SHCreateStdEnumFmtEtc(sizeof(fetc) / sizeof(fetc[0]), 00830 fetc, 00831 ppenumFormatEtc); 00832 } 00833 else 00834 hr = E_NOTIMPL; 00835 00836 return hr; 00837 } 00838 00839 static HRESULT STDMETHODCALLTYPE 00840 CDevSettings_DAdvise(IDataObject* iface, 00841 FORMATETC* pformatetc, 00842 DWORD advf, 00843 IAdviseSink* pAdvSink, 00844 DWORD* pdwConnection) 00845 { 00846 *pdwConnection = 0; 00847 return OLE_E_ADVISENOTSUPPORTED; 00848 } 00849 00850 static HRESULT STDMETHODCALLTYPE 00851 CDevSettings_DUnadvise(IDataObject* iface, 00852 DWORD dwConnection) 00853 { 00854 return OLE_E_ADVISENOTSUPPORTED; 00855 } 00856 00857 static HRESULT STDMETHODCALLTYPE 00858 CDevSettings_EnumDAdvise(IDataObject* iface, 00859 IEnumSTATDATA** ppenumAdvise) 00860 { 00861 *ppenumAdvise = NULL; 00862 return OLE_E_ADVISENOTSUPPORTED; 00863 } 00864 00865 static const struct IDataObjectVtbl vtblIDataObject = { 00866 CDevSettings_QueryInterface, 00867 CDevSettings_AddRef, 00868 CDevSettings_Release, 00869 CDevSettings_GetData, 00870 CDevSettings_GetDataHere, 00871 CDevSettings_QueryGetData, 00872 CDevSettings_GetCanonicalFormatEtc, 00873 CDevSettings_SetData, 00874 CDevSettings_EnumFormatEtc, 00875 CDevSettings_DAdvise, 00876 CDevSettings_DUnadvise, 00877 CDevSettings_EnumDAdvise, 00878 }; 00879 00880 IDataObject * 00881 CreateDevSettings(PDISPLAY_DEVICE_ENTRY DisplayDeviceInfo) 00882 { 00883 PCDevSettings This; 00884 00885 This = HeapAlloc(GetProcessHeap(), 00886 0, 00887 sizeof(*This)); 00888 if (This != NULL) 00889 { 00890 This->lpIDataObjectVtbl = &vtblIDataObject; 00891 This->ref = 1; 00892 00893 if (SUCCEEDED(pCDevSettings_Initialize(This, 00894 DisplayDeviceInfo))) 00895 { 00896 return impl_to_interface(This, IDataObject); 00897 } 00898 00899 CDevSettings_Release(impl_to_interface(This, IDataObject)); 00900 } 00901 00902 return NULL; 00903 } 00904 00905 LONG WINAPI 00906 DisplaySaveSettings(PVOID pContext, 00907 HWND hwndPropSheet) 00908 { 00909 //PCDevSettings This = impl_from_IDataObject((IDataObject *)Context); 00910 DPRINT("DisplaySaveSettings() UNIMPLEMENTED!\n"); 00911 return DISP_CHANGE_BADPARAM; 00912 } Generated on Sun May 27 2012 04:20:53 for ReactOS by
1.7.6.1
|