Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenslayer.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
1.7.6.1
|