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

slayer.c
Go to the documentation of this file.
00001 /*
00002  * ReactOS Compatibility Layer Shell Extension
00003  * Copyright (C) 2004 - 2005 ReactOS Team
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2.1 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 /* $Id: slayer.c 43790 2009-10-27 10:34:16Z dgorbachev $
00020  *
00021  * PROJECT:         ReactOS Compatibility Layer Shell Extension
00022  * FILE:            lib/shellext/cplsample/cplsample.c
00023  * PURPOSE:         ReactOS Compatibility Layer Shell Extension
00024  * PROGRAMMER:      Thomas Weidenmueller <w3seek@reactos.com>
00025  * UPDATE HISTORY:
00026  *      09/25/2004  Created
00027  */
00028 #include <precomp.h>
00029 
00030 HINSTANCE hInstance = NULL;
00031 static LONG dllrefs = 0;
00032 
00033 static ifaceICompatibilityPageVbtl efvt =
00034 {
00035     /* IUnknown methods */
00036     ICompatibilityPage_fnQueryInterface,
00037     ICompatibilityPage_fnAddRef,
00038     ICompatibilityPage_fnRelease,
00039 };
00040 
00041 static ifaceIShellPropSheetExtVbtl efvtIShellPropSheetExt =
00042 {
00043     /* IShellPropSheetExt */
00044     ICompatibilityPage_fnAddPages,
00045     ICompatibilityPage_fnReplacePage,
00046 };
00047 
00048 static ifaceIShellExtInitVbtl efvtIShellExtInit =
00049 {
00050     /* IShellExtInit */
00051     ICompatibilityPage_fnInitialize,
00052 };
00053 
00054 static ifaceIClassFactoryVbtl efvtIClassFactory =
00055 {
00056     /* IClassFactory */
00057     ICompatibilityPage_fnCreateInstance,
00058     ICompatibilityPage_fnLockServer,
00059 };
00060 
00061 /******************************************************************************
00062    ICompatibilityPage
00063  ******************************************************************************/
00064 
00065 static VOID
00066 ClearCItemList(LPCOMPATIBILITYPAGE info)
00067 {
00068     PCITEM item, next;
00069 
00070     for (item = info->CItems;
00071          item != NULL;
00072          item = next)
00073     {
00074         next = item->next;
00075         HeapFree(GetProcessHeap(),
00076                  0,
00077                  item);
00078     }
00079 
00080     info->CSelectedItem = NULL;
00081     info->CItems = NULL;
00082     info->nItems = 0;
00083 }
00084 
00085 static BOOL
00086 ReadDWORDFlag(HKEY hk,
00087               LPTSTR szValueName,
00088               LPDWORD lpOutValue,
00089               DWORD dwDefault)
00090 {
00091     DWORD dwType, dwSize = sizeof(DWORD);
00092     LONG e = RegQueryValueEx(hk,
00093                              szValueName,
00094                              0,
00095                              &dwType,
00096                              (LPBYTE)lpOutValue,
00097                              &dwSize);
00098 
00099     if (e != ERROR_SUCCESS || dwSize != sizeof(DWORD))
00100     {
00101         *lpOutValue = dwDefault;
00102 
00103         return TRUE;
00104     }
00105 
00106     return FALSE;
00107 }
00108 
00109 static BOOL
00110 LoadAndParseAppCompatibilityFlags(LPCOMPATIBILITYPAGE info,
00111                                   LPTSTR szValueName)
00112 {
00113     LONG e;
00114     HKEY hk;
00115     DWORD dwType, dwSize;
00116     TCHAR szStr[256];
00117 
00118     e = RegOpenKey(HKEY_CURRENT_USER,
00119                    TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),
00120                    &hk);
00121     if (e == ERROR_SUCCESS)
00122     {
00123         dwSize = sizeof(szStr);
00124 
00125         e = RegQueryValueEx(hk,
00126                             szValueName,
00127                             0,
00128                             &dwType,
00129                             (LPBYTE)szStr,
00130                             &dwSize);
00131 
00132         if (e == ERROR_SUCCESS)
00133         {
00134             /* FIXME - make sure the string is NULL-terminated! */
00135             TCHAR *c;
00136             for (c = szStr;
00137                  *c != TEXT('\0');
00138                  c++)
00139             {
00140                 /* only the first word represents the compatibility mode */
00141                 /* FIXME - parse all words! */
00142                 if (*c == TEXT(' '))
00143                 {
00144                     *c = TEXT('\0');
00145                     break;
00146                 }
00147             }
00148 
00149             info->CSelectedItem = NULL;
00150             if (_tcslen(szStr) > 0)
00151             {
00152                 PCITEM item;
00153 
00154                 for (item = info->CItems;
00155                      item != NULL;
00156                      item = item->next)
00157                 {
00158                     if (!_tcsicmp(szStr, item->szKeyName))
00159                     {
00160                         info->CSelectedItem = item;
00161                         break;
00162                     }
00163                 }
00164             }
00165         }
00166         RegCloseKey(hk);
00167     }
00168 
00169     return FALSE;
00170 }
00171 
00172 static BOOL
00173 LoadCompatibilityModes(LPCOMPATIBILITYPAGE info)
00174 {
00175     BOOL Ret;
00176     LONG e;
00177     HKEY hk, hk2;
00178     TCHAR szKey[256];
00179 
00180     ClearCItemList(info);
00181 
00182     e = RegOpenKey(HKEY_CURRENT_USER,
00183                    TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),
00184                    &hk);
00185 
00186     if (e == ERROR_SUCCESS)
00187     {
00188         DWORD i;
00189         PCITEM lastitem = NULL;
00190 
00191         for(i = 0;
00192             (RegEnumKey(hk, i,szKey, sizeof(szKey) / sizeof(szKey[0])) == ERROR_SUCCESS);
00193             i++)
00194         {
00195             e = RegOpenKey(hk,
00196                            szKey,
00197                            &hk2);
00198 
00199             if (e == ERROR_SUCCESS)
00200             {
00201                 DWORD dwType;
00202 
00203                 e = RegQueryValueEx(hk2,
00204                                     NULL,
00205                                     0,
00206                                     &dwType,
00207                                     NULL,
00208                                     NULL);
00209 
00210                 if (e != ERROR_SUCCESS || (e == ERROR_SUCCESS && dwType == REG_SZ))
00211                 {
00212                     PCITEM item;
00213 
00214                     item = HeapAlloc(GetProcessHeap(),
00215                                      0,
00216                                      sizeof(CITEM));
00217                     if (item != NULL)
00218                     {
00219                         DWORD cdb = sizeof(item->szName);
00220 
00221                         /* description */
00222                         e = RegQueryValueEx(hk2,
00223                                             NULL,
00224                                             0,
00225                                             NULL,
00226                                             (LPBYTE)item->szName,
00227                                             &cdb);
00228 
00229                         /* make sure it is null-terminated */
00230                         if (cdb > sizeof(item->szName) - sizeof(item->szName[0]))
00231                         {
00232                             item->szName[(sizeof(item->szName) / sizeof(item->szName[0])) - 1] = TEXT('\0');
00233                         }
00234 
00235                         if (e != ERROR_SUCCESS ||
00236                             cdb < sizeof(item->szName[0]))
00237                         {
00238                             _tcscpy(item->szName, szKey);
00239                             e = ERROR_SUCCESS;
00240                         }
00241 
00242                         _tcscpy(item->szKeyName, szKey);
00243                         info->nItems++;
00244 
00245                         ReadDWORDFlag(hk2,
00246                                       TEXT("MajorVersion"),
00247                                       &item->MajorVersion,
00248                                       0);
00249                         ReadDWORDFlag(hk2,
00250                                       TEXT("MinorVersion"),
00251                                       &item->MinorVersion,
00252                                       0);
00253                         ReadDWORDFlag(hk2,
00254                                       TEXT("BuildNumber"),
00255                                       &item->BuildNumber,
00256                                       0);
00257                         ReadDWORDFlag(hk2,
00258                                       TEXT("PlatformId"),
00259                                       &item->PlatformId,
00260                                       0);
00261                         ReadDWORDFlag(hk2,
00262                                       TEXT("SPMajorVersion"),
00263                                       &item->SPMajorVersion,
00264                                       0);
00265                         ReadDWORDFlag(hk2,
00266                                       TEXT("SPMinorVersion"),
00267                                       &item->SPMinorVersion,
00268                                       0);
00269 
00270                         if (e == ERROR_SUCCESS)
00271                         {
00272                             item->next = NULL;
00273                             if (lastitem != NULL)
00274                             {
00275                                 lastitem->next = item;
00276                             }
00277                             else
00278                             {
00279                                 info->CItems = item;
00280                             }
00281                             lastitem = item;
00282                         }
00283                         else
00284                         {
00285                             HeapFree(GetProcessHeap(),
00286                                      0,
00287                                      item);
00288                         }
00289                     }
00290                 }
00291 
00292                 RegCloseKey(hk2);
00293             }
00294 
00295             if (e != ERROR_SUCCESS)
00296             {
00297                 e = ERROR_SUCCESS;
00298             }
00299         }
00300         RegCloseKey(hk);
00301     }
00302 
00303     Ret = ((e == ERROR_SUCCESS || e == ERROR_NO_MORE_ITEMS) ? TRUE : FALSE);
00304 
00305     return Ret;
00306 }
00307 
00308 static VOID
00309 FillComboBoxWithCompatibilityModes(LPCOMPATIBILITYPAGE info,
00310                                    HWND hwndDlg,
00311                                    HWND hCombo,
00312                                    BOOL bSelectItem,
00313                                    BOOL bDisableControlsIfEmpty)
00314 {
00315     PCITEM item;
00316     int i = 0;
00317     BOOL sel = FALSE;
00318 
00319     SendMessage(hCombo,
00320                 CB_RESETCONTENT,
00321                 0,
00322                 0);
00323 
00324     for (item = info->CItems;
00325          item != NULL;
00326          item = item->next)
00327     {
00328         int iIndex = (int)SendMessage(hCombo,
00329                                       CB_ADDSTRING,
00330                                       0,
00331                                       (LPARAM)item->szName);
00332 
00333         if (item == info->CSelectedItem && bSelectItem)
00334         {
00335             SendMessage(hCombo,
00336                         CB_SETCURSEL,
00337                         (WPARAM)iIndex,
00338                         0);
00339             sel = TRUE;
00340         }
00341         i++;
00342     }
00343 
00344     if (!sel && bSelectItem && i > 0)
00345     {
00346         /* select the first item */
00347         SendMessage(hCombo,
00348                     CB_SETCURSEL,
00349                     0,
00350                     0);
00351     }
00352 
00353     if (bDisableControlsIfEmpty)
00354     {
00355         BOOL enable = (i > 0);
00356 
00357         EnableWindow(GetDlgItem(hwndDlg,
00358                                 IDC_COMPATGROUP),
00359                      enable);
00360 
00361         EnableWindow(hCombo,
00362                      (enable && sel));
00363 
00364         EnableWindow(GetDlgItem(hwndDlg,
00365                                 IDC_CHKRUNCOMPATIBILITY),
00366                      enable);
00367 
00368         CheckDlgButton(hwndDlg,
00369                        IDC_CHKRUNCOMPATIBILITY,
00370                        ((enable && sel) ? BST_CHECKED : BST_UNCHECKED));
00371     }
00372 }
00373 
00374 static VOID
00375 FillEditListBoxWithCompatibilityModes(LPCOMPATIBILITYPAGE info,
00376                                       HWND hwndDlg,
00377                                       HWND hListBox,
00378                                       BOOL bDisableControlsIfEmpty)
00379 {
00380     PCITEM item;
00381     int i;
00382 
00383     SendMessage(hListBox,
00384                 LB_RESETCONTENT,
00385                 0,
00386                 0);
00387 
00388     for (item = info->CItems, i = 0;
00389          item != NULL;
00390          item = item->next, i++)
00391     {
00392         SendMessage(hListBox,
00393                     LB_ADDSTRING,
00394                     0,
00395                     (LPARAM)item->szName);
00396     }
00397 
00398     if (bDisableControlsIfEmpty)
00399     {
00400     }
00401 }
00402 
00403 static INT_PTR CALLBACK
00404 EditCompatibilityModesProc(HWND hwndDlg,
00405                            UINT uMsg,
00406                            WPARAM wParam,
00407                            LPARAM lParam)
00408 {
00409     LPCOMPATIBILITYPAGE this;
00410 
00411     switch (uMsg)
00412     {
00413         case WM_COMMAND:
00414         {
00415             switch(LOWORD(wParam))
00416             {
00417                 case IDOK:
00418                     EndDialog(hwndDlg,
00419                               IDOK);
00420                     break;
00421 
00422                 case IDCANCEL:
00423                     EndDialog(hwndDlg,
00424                               IDCANCEL);
00425                     break;
00426             }
00427             break;
00428         }
00429 
00430         case WM_CLOSE:
00431         {
00432             EndDialog(hwndDlg,
00433                       IDCANCEL);
00434             break;
00435         }
00436 
00437         case WM_INITDIALOG:
00438         {
00439             HWND hList = GetDlgItem(hwndDlg,
00440                                     IDC_COMPATIBILITYMODE);
00441 
00442             this = (LPCOMPATIBILITYPAGE)lParam;
00443             SetWindowLongPtr(hwndDlg,
00444                              GWLP_USERDATA,
00445                              (LONG_PTR)this);
00446 
00447             FillEditListBoxWithCompatibilityModes(this,
00448                                                   hwndDlg,
00449                                                   hList,
00450                                                   FALSE);
00451             break;
00452         }
00453     }
00454 
00455     return FALSE;
00456 }
00457 
00458 static VOID
00459 InitializePage(LPCOMPATIBILITYPAGE this,
00460                HWND hwndDlg)
00461 {
00462     HWND hList;
00463 
00464     LoadCompatibilityModes(this);
00465 
00466     /* initialize the controls */
00467     hList = GetDlgItem(hwndDlg,
00468                        IDC_COMPATIBILITYMODE);
00469 
00470     LoadAndParseAppCompatibilityFlags(this,
00471                                       this->szFile);
00472     FillComboBoxWithCompatibilityModes(this,
00473                                        hwndDlg,
00474                                        hList,
00475                                        TRUE,
00476                                        TRUE);
00477 }
00478 
00479 static VOID
00480 ReportPropertyChange(LPCOMPATIBILITYPAGE this,
00481                      HWND hwndDlg)
00482 {
00483     this->Changed = TRUE;
00484 
00485     SendMessage(GetParent(hwndDlg),
00486                 PSM_CHANGED,
00487                 (WPARAM)hwndDlg,
00488                 0);
00489 }
00490 
00491 static BOOL
00492 ComposeFlags(LPCOMPATIBILITYPAGE this,
00493              LPTSTR szFlags)
00494 {
00495     if (this->CSelectedItem != NULL)
00496     {
00497         _tcscpy(szFlags,
00498                 this->CSelectedItem->szKeyName);
00499         return TRUE;
00500     }
00501 
00502     return FALSE;
00503 }
00504 
00505 static BOOL
00506 ApplySettings(LPCOMPATIBILITYPAGE this,
00507               HWND hwndDlg)
00508 {
00509     HKEY hk;
00510     LONG e;
00511     TCHAR szFlags[256];
00512     BOOL enabled = IsDlgButtonChecked(hwndDlg,
00513                                       IDC_CHKRUNCOMPATIBILITY) == BST_CHECKED;
00514 
00515     if (enabled)
00516     {
00517         HWND hCombo = GetDlgItem(hwndDlg,
00518                                  IDC_COMPATIBILITYMODE);
00519         int index = (int)SendMessage(hCombo,
00520                                      CB_GETCURSEL,
00521                                      0,
00522                                      0);
00523         if (index >= 0)
00524         {
00525             int i;
00526             PCITEM sel = this->CItems;
00527 
00528             /* map the index to a CITEM structure */
00529             for(i = index;
00530                 i > 0 && sel != NULL;
00531                 i--)
00532             {
00533                 sel = sel->next;
00534             }
00535 
00536             /* update the CSelectedItem member */
00537             this->CSelectedItem = sel;
00538         }
00539         else
00540             enabled = FALSE;
00541     }
00542 
00543     e = RegOpenKey(HKEY_CURRENT_USER,
00544                    TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers"),
00545                    &hk);
00546     if (e == ERROR_SUCCESS)
00547     {
00548         if (!enabled)
00549         {
00550             /* FIXME - only delete if nothing else is selected! */
00551             e = RegDeleteValue(hk,
00552                                this->szFile);
00553         }
00554         else
00555         {
00556             if (ComposeFlags(this,
00557                              szFlags))
00558             {
00559                 e = RegSetValueEx(hk,
00560                                   this->szFile,
00561                                   0,
00562                                   REG_SZ,
00563                                   (LPBYTE)szFlags,
00564                                   (_tcslen(szFlags) + 1) * sizeof(TCHAR));
00565             }
00566             else
00567             {
00568                 e = RegDeleteValue(hk,
00569                                    this->szFile);
00570             }
00571         }
00572 
00573         RegCloseKey(hk);
00574     }
00575 
00576     this->Changed = FALSE;
00577     return (e == ERROR_SUCCESS);
00578 }
00579 
00580 static INT_PTR CALLBACK
00581 CompatibilityPageProc(HWND hwndDlg,
00582                       UINT uMsg,
00583                       WPARAM wParam,
00584                       LPARAM lParam)
00585 {
00586     LPCOMPATIBILITYPAGE this = (LPCOMPATIBILITYPAGE)GetWindowLongPtr(hwndDlg,
00587                                                                      GWLP_USERDATA);
00588 
00589     switch (uMsg)
00590     {
00591         case WM_COMMAND:
00592         {
00593             if (HIWORD(wParam) == CBN_SELCHANGE && LOWORD(wParam) == IDC_COMPATIBILITYMODE)
00594             {
00595                 ReportPropertyChange(this,
00596                                      hwndDlg);
00597             }
00598             else
00599             {
00600                 switch (LOWORD(wParam))
00601                 {
00602                     case IDC_CHKRUNCOMPATIBILITY:
00603                     {
00604                         HWND hList = GetDlgItem(hwndDlg,
00605                                                 IDC_COMPATIBILITYMODE);
00606 
00607                         if (hList != NULL)
00608                         {
00609                             EnableWindow(hList,
00610                                          IsDlgButtonChecked(hwndDlg,
00611                                                             IDC_CHKRUNCOMPATIBILITY) == BST_CHECKED);
00612                         }
00613                         /* fall through */
00614                     }
00615 
00616                     case IDC_CHKRUNIN256COLORS:
00617                     case IDC_CHKRUNIN640480RES:
00618                     case IDC_CHKDISABLEVISUALTHEMES:
00619                         ReportPropertyChange(this,
00620                                              hwndDlg);
00621                         break;
00622 
00623                     case IDC_EDITCOMPATIBILITYMODES:
00624                     {
00625                         if (DialogBoxParam(hInstance,
00626                                            MAKEINTRESOURCE(IDD_EDITCOMPATIBILITYMODES),
00627                                            hwndDlg,
00628                                            EditCompatibilityModesProc,
00629                                            (LPARAM)this) == IDOK)
00630                         {
00631                             InitializePage(this,
00632                                            hwndDlg);
00633                         }
00634                         break;
00635                     }
00636                 }
00637             }
00638             break;
00639         }
00640 
00641         case WM_NOTIFY:
00642         {
00643             NMHDR *hdr = (NMHDR*)lParam;
00644             switch (hdr->code)
00645             {
00646                 case PSN_APPLY:
00647                     if (this->Changed)
00648                     {
00649                         return ApplySettings(this,
00650                                              hwndDlg);
00651                     }
00652                     break;
00653             }
00654             break;
00655         }
00656 
00657         case WM_INITDIALOG:
00658         {
00659             LPPROPSHEETPAGE psp = (LPPROPSHEETPAGE)lParam;
00660             this = (LPCOMPATIBILITYPAGE)psp->lParam;
00661             SetWindowLongPtr(hwndDlg,
00662                              GWLP_USERDATA,
00663                              (LONG_PTR)this);
00664 
00665             InitializePage(this,
00666                            hwndDlg);
00667             break;
00668         }
00669     }
00670 
00671     return FALSE;
00672 }
00673 
00674 static UINT CALLBACK
00675 CompatibilityPageCallback(HWND hwnd,
00676                           UINT uMsg,
00677                           LPPROPSHEETPAGE ppsp)
00678 {
00679     LPCOMPATIBILITYPAGE this = (LPCOMPATIBILITYPAGE)ppsp->lParam;
00680 
00681     switch (uMsg)
00682     {
00683         case PSPCB_CREATE:
00684             return TRUE;
00685 
00686         case PSPCB_RELEASE:
00687             ICompatibilityPage_fnRelease(this);
00688             return FALSE;
00689 
00690         default:
00691             return FALSE;
00692     }
00693 }
00694 
00695 static LPCOMPATIBILITYPAGE
00696 ICompatibilityPage_fnConstructor(VOID)
00697 {
00698     LPCOMPATIBILITYPAGE cp;
00699 
00700     cp = HeapAlloc(GetProcessHeap(),
00701                    HEAP_ZERO_MEMORY,
00702                    sizeof(COMPATIBILITYPAGE));
00703     if (cp != NULL)
00704     {
00705         cp->lpVtbl = &efvt;
00706         cp->lpVtbl->fn.IShellPropSheetExt = efvtIShellPropSheetExt;
00707         cp->ref = 1;
00708         InterlockedIncrement(&dllrefs);
00709     }
00710 
00711     return cp;
00712 }
00713 
00714 HRESULT STDMETHODCALLTYPE
00715 ICompatibilityPage_fnQueryInterface(LPCOMPATIBILITYPAGE this,
00716                                     REFIID iid,
00717                                     PVOID *pvObject)
00718 {
00719     if (IsEqualIID(iid,
00720                    &IID_IShellPropSheetExt))
00721     {
00722         this->lpVtbl->fn.IShellPropSheetExt = efvtIShellPropSheetExt;
00723         ICompatibilityPage_fnAddRef(this);
00724         *pvObject = this;
00725         return S_OK;
00726     }
00727     else if (IsEqualIID(iid,
00728                         &IID_IShellExtInit))
00729     {
00730         this->lpVtbl->fn.IShellExtInit = efvtIShellExtInit;
00731         ICompatibilityPage_fnAddRef(this);
00732         *pvObject = this;
00733         return S_OK;
00734     }
00735     else if (IsEqualIID(iid,
00736                         &IID_IClassFactory))
00737     {
00738         this->lpVtbl->fn.IClassFactory = efvtIClassFactory;
00739         ICompatibilityPage_fnAddRef(this);
00740         *pvObject = this;
00741         return S_OK;
00742     }
00743     else if (IsEqualIID(iid,
00744                         &IID_IUnknown))
00745     {
00746         ICompatibilityPage_fnAddRef(this);
00747         *pvObject = this;
00748         return S_OK;
00749     }
00750 
00751     *pvObject = NULL;
00752     return E_NOINTERFACE;
00753 }
00754 
00755 ULONG STDMETHODCALLTYPE
00756 ICompatibilityPage_fnAddRef(LPCOMPATIBILITYPAGE this)
00757 {
00758     return (ULONG)InterlockedIncrement(&this->ref);
00759 }
00760 
00761 ULONG STDMETHODCALLTYPE
00762 ICompatibilityPage_fnRelease(LPCOMPATIBILITYPAGE this)
00763 {
00764     ULONG rfc;
00765 
00766     rfc = (ULONG)InterlockedDecrement(&this->ref);
00767     if (rfc == 0)
00768     {
00769         HeapFree(GetProcessHeap(),
00770                  0,
00771                  this);
00772         InterlockedDecrement(&dllrefs);
00773     }
00774     return rfc;
00775 }
00776 
00777 HRESULT STDMETHODCALLTYPE
00778 ICompatibilityPage_fnAddPages(LPCOMPATIBILITYPAGE this,
00779                               LPFNADDPROPSHEETPAGE lpfnAddPage,
00780                               LPARAM lParam)
00781 {
00782     PROPSHEETPAGE psp = {0};
00783     HPROPSHEETPAGE hPage;
00784 
00785     psp.dwSize = sizeof(psp);
00786     psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
00787     psp.hInstance = hInstance;
00788     psp.pszTemplate = MAKEINTRESOURCE(IDD_SLAYERSHEET);
00789     psp.pfnDlgProc = CompatibilityPageProc;
00790     psp.lParam = (LPARAM)this;
00791     psp.pfnCallback = CompatibilityPageCallback;
00792 
00793     hPage = CreatePropertySheetPage(&psp);
00794 
00795     if (hPage != NULL)
00796     {
00797         if (!lpfnAddPage(hPage,
00798                          lParam))
00799         {
00800             DestroyPropertySheetPage(hPage);
00801             return E_OUTOFMEMORY;
00802         }
00803 
00804         ICompatibilityPage_fnAddRef(this);
00805         return S_OK;
00806     }
00807 
00808     return E_FAIL;
00809 }
00810 
00811 HRESULT STDMETHODCALLTYPE
00812 ICompatibilityPage_fnReplacePage(LPCOMPATIBILITYPAGE this,
00813                                  UINT uPageID,
00814                                  LPFNADDPROPSHEETPAGE lpfnReplacePage,
00815                                  LPARAM lParam)
00816 {
00817     return E_NOTIMPL;
00818 }
00819 
00820 HRESULT STDMETHODCALLTYPE
00821 ICompatibilityPage_fnInitialize(LPCOMPATIBILITYPAGE this,
00822                                 LPCITEMIDLIST pidlFolder,
00823                                 IDataObject *pdtobj,
00824                                 HKEY hkeyProgID)
00825 {
00826     FORMATETC fetc;
00827     STGMEDIUM smdm;
00828 
00829     if (pdtobj == NULL)
00830     {
00831         return E_INVALIDARG;
00832     }
00833 
00834     fetc.cfFormat = CF_HDROP;
00835     fetc.ptd = NULL;
00836     fetc.dwAspect = DVASPECT_CONTENT;
00837     fetc.lindex = -1;
00838     fetc.tymed = TYMED_HGLOBAL;
00839 
00840     if (SUCCEEDED(pdtobj->lpVtbl->GetData(pdtobj,
00841                                           &fetc,
00842                                           &smdm)))
00843     {
00844         UINT nFiles = DragQueryFile(smdm.hGlobal,
00845                                     0xFFFFFFFF,
00846                                     this->szFile,
00847                                     sizeof(this->szFile) / sizeof(this->szFile[0]));
00848         if (nFiles == 1)
00849         {
00850             /* FIXME - support editing of multiple files later */
00851             DragQueryFile(smdm.hGlobal,
00852                           0, this->szFile,
00853                           sizeof(this->szFile) / sizeof(this->szFile[0]));
00854             ReleaseStgMedium(&smdm);
00855 
00856             return S_OK;
00857         }
00858     }
00859 
00860     return E_FAIL;
00861 }
00862 
00863 HRESULT STDMETHODCALLTYPE
00864 ICompatibilityPage_fnCreateInstance(LPCOMPATIBILITYPAGE this,
00865                                     LPUNKNOWN pUnkOuter,
00866                                     REFIID riid,
00867                                     PVOID *ppvObject)
00868 {
00869     LPCOMPATIBILITYPAGE cp;
00870 
00871     if (pUnkOuter != NULL &&
00872         !IsEqualIID(riid,
00873                     &IID_IUnknown))
00874     {
00875         return CLASS_E_NOAGGREGATION;
00876     }
00877 
00878     cp = ICompatibilityPage_fnConstructor();
00879     if (cp != NULL)
00880     {
00881         HRESULT ret = ICompatibilityPage_fnQueryInterface(cp,
00882                                                           riid,
00883                                                           ppvObject);
00884         ICompatibilityPage_fnRelease(cp);
00885         return ret;
00886     }
00887 
00888     return E_OUTOFMEMORY;
00889 }
00890 
00891 HRESULT STDMETHODCALLTYPE
00892 ICompatibilityPage_fnLockServer(LPCOMPATIBILITYPAGE this,
00893                                 BOOL fLock)
00894 {
00895     if (fLock)
00896     {
00897         InterlockedIncrement(&dllrefs);
00898     }
00899     else
00900     {
00901         InterlockedDecrement(&dllrefs);
00902     }
00903 
00904     return S_OK;
00905 }
00906 
00907 /******************************************************************************
00908    Exported
00909  ******************************************************************************/
00910 
00911 HRESULT WINAPI
00912 DllGetClassObject(REFCLSID rclsid,
00913                   REFIID iid,
00914                   LPVOID *ppv)
00915 {
00916     if (ppv == NULL)
00917     {
00918         return E_INVALIDARG;
00919     }
00920 
00921     if (IsEqualCLSID(&CLSID_ICompatibilityPage,
00922                      rclsid))
00923     {
00924         LPCOMPATIBILITYPAGE iface = ICompatibilityPage_fnConstructor();
00925         if (iface != NULL)
00926         {
00927             HRESULT ret = ICompatibilityPage_fnQueryInterface(iface,
00928                                                               iid,
00929                                                               ppv);
00930             ICompatibilityPage_fnRelease(iface);
00931             return ret;
00932         }
00933         return E_OUTOFMEMORY;
00934     }
00935 
00936     return CLASS_E_CLASSNOTAVAILABLE;
00937 }
00938 
00939 HRESULT WINAPI
00940 DllCanUnloadNow(VOID)
00941 {
00942     return ((dllrefs == 0) ? S_OK : S_FALSE);
00943 }
00944 
00945 static int
00946 UnregisterPropSheetHandler(LPTSTR szType)
00947 {
00948     TCHAR szKey[255];
00949 
00950     _stprintf(szKey,
00951               TEXT("%s\\shellex\\PropertySheetHandlers\\Compatibility Property Page"),
00952               szType);
00953 
00954     return RegDeleteKey(HKEY_CLASSES_ROOT,
00955                         szKey);
00956 }
00957 
00958 HRESULT WINAPI
00959 DllUnregisterServer(VOID)
00960 {
00961     LONG e;
00962     HKEY hk;
00963     WCHAR szGuid[40];
00964 
00965     StringFromGUID2(&CLSID_ICompatibilityPage,
00966                     szGuid,
00967                     sizeof(szGuid) / sizeof(szGuid[0]));
00968 
00969     e = RegOpenKey(HKEY_LOCAL_MACHINE,
00970                    TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
00971                    &hk);
00972     if (e == ERROR_SUCCESS)
00973     {
00974         e = RegDeleteValueW(hk,
00975                             szGuid);
00976         RegCloseKey(hk);
00977     }
00978 
00979     if (e == ERROR_SUCCESS)
00980     {
00981         e = UnregisterPropSheetHandler(TEXT("exefile"));
00982     }
00983 
00984     if (e == ERROR_SUCCESS)
00985     {
00986         e = RegOpenKey(HKEY_CLASSES_ROOT,
00987                        TEXT("CLSID"),
00988                        &hk);
00989         if (e == ERROR_SUCCESS)
00990         {
00991             TCHAR szInprocKey[255];
00992 
00993             _stprintf(szInprocKey,
00994                       TEXT("%ws\\InprocServer32"),
00995                       szGuid);
00996 
00997             e = RegDeleteKey(hk,
00998                              szInprocKey);
00999             if (e == ERROR_SUCCESS)
01000             {
01001                 e = RegDeleteKeyW(hk,
01002                                   szGuid);
01003             }
01004             RegCloseKey(hk);
01005         }
01006     }
01007 
01008     return ((e == ERROR_SUCCESS) ? S_OK : E_ACCESSDENIED);
01009 }
01010 
01011 static int
01012 RegisterPropSheetHandler(LPTSTR szType,
01013                          LPWSTR szGuid)
01014 {
01015     TCHAR szKey[255];
01016     HKEY hk;
01017     int e;
01018 
01019     _stprintf(szKey,
01020               TEXT("%s\\shellex\\PropertySheetHandlers\\Compatibility Property Page"),
01021               szType);
01022 
01023     e = RegCreateKey(HKEY_CLASSES_ROOT,
01024                      szKey,
01025                      &hk);
01026     if (e == ERROR_SUCCESS)
01027     {
01028         e = RegSetValueExW(hk,
01029                            NULL,
01030                            0,
01031                            REG_SZ,
01032                            (BYTE*)szGuid,
01033                            (wcslen(szGuid) + 1) * sizeof(WCHAR));
01034         RegCloseKey(hk);
01035     }
01036 
01037     return e;
01038 }
01039 
01040 HRESULT WINAPI
01041 DllRegisterServer(VOID)
01042 {
01043     LONG e = E_ACCESSDENIED;
01044     HKEY hk;
01045     WCHAR szGuid[40];
01046     WCHAR szDescription[255];
01047     TCHAR szModule[MAX_PATH + 1];
01048     int lnszDescription;
01049 
01050     if (!GetModuleFileName(hInstance,
01051                            szModule,
01052                            sizeof(szModule) / sizeof(szModule[0])))
01053     {
01054         return E_ACCESSDENIED;
01055     }
01056 
01057     /* unregister first */
01058     DllUnregisterServer();
01059 
01060     lnszDescription = LoadStringW(hInstance,
01061                                   IDS_DESCRIPTION,
01062                                   szDescription, sizeof(szDescription) / sizeof(szDescription[0]));
01063     if (lnszDescription > 0)
01064     {
01065         StringFromGUID2(&CLSID_ICompatibilityPage,
01066                         szGuid,
01067                         sizeof(szGuid) / sizeof(szGuid[0]));
01068 
01069         e = RegOpenKey(HKEY_LOCAL_MACHINE,
01070                        TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
01071                        &hk);
01072         if (e == ERROR_SUCCESS)
01073         {
01074             e = RegSetValueExW(hk,
01075                                szGuid,
01076                                0,
01077                                REG_SZ,
01078                                (BYTE*)szDescription,
01079                                (lnszDescription + 1) * sizeof(WCHAR));
01080             RegCloseKey(hk);
01081         }
01082 
01083         if (e == ERROR_SUCCESS)
01084         {
01085             TCHAR szInprocKey[255];
01086 
01087             _stprintf(szInprocKey,
01088                       TEXT("CLSID\\%ws\\InprocServer32"),
01089                       szGuid);
01090 
01091             e = RegCreateKey(HKEY_CLASSES_ROOT,
01092                              szInprocKey,
01093                              &hk);
01094             if (e == ERROR_SUCCESS)
01095             {
01096                 e = RegSetValueEx(hk,
01097                                   NULL,
01098                                   0,
01099                                   REG_SZ,
01100                                   (BYTE*)szModule,
01101                                   (_tcslen(szModule) + 1) * sizeof(TCHAR));
01102                 if (e == ERROR_SUCCESS)
01103                 {
01104                     const TCHAR szApartment[] = TEXT("Apartment");
01105 
01106                     e = RegSetValueEx(hk,
01107                                       TEXT("ThreadingModel"),
01108                                       0,
01109                                       REG_SZ,
01110                                       (BYTE*)szApartment,
01111                                       (_tcslen(szApartment) + 1) * sizeof(TCHAR));
01112                 }
01113 
01114                 RegCloseKey(hk);
01115             }
01116         }
01117 
01118         if (e == ERROR_SUCCESS)
01119         {
01120             e = RegisterPropSheetHandler(TEXT("exefile"),
01121                                          szGuid);
01122         }
01123     }
01124 
01125     return ((e == ERROR_SUCCESS) ? S_OK : E_ACCESSDENIED);
01126 }
01127 
01128 BOOL WINAPI
01129 DllMain(HINSTANCE hinstDLL,
01130         DWORD dwReason,
01131         LPVOID lpvReserved)
01132 {
01133     switch (dwReason)
01134     {
01135         case DLL_PROCESS_ATTACH:
01136             hInstance = hinstDLL;
01137             DisableThreadLibraryCalls(hInstance);
01138             break;
01139     }
01140 
01141     return TRUE;
01142 }
01143 

Generated on Sun May 27 2012 04:22:36 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.