ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

devsett.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.