2 #include "Shib_PropSheet.h"
13 void Shib_PropSheet::ReplaceSlashes(string& buf)
17 while ((p = buf.find('/',p)) != string::npos) {
23 Shib_PropSheet::Shib_PropSheet() : m_cref(0)
25 for (int i=0;i<NUM_DIRECTIVES;i++) {
26 directive[i].Init_Directive(i);
40 Shib_PropSheet::~Shib_PropSheet()
43 ::LocalFree(pwzService);
45 ::LocalFree(pwzParentPath);
49 ::LocalFree(pwzMetaPath);
51 ::LocalFree(pwzMachineName);
53 ::LocalFree(pwzInstance);
55 ::LocalFree(pwzRegPath);
60 ///////////////////////
61 // IUnknown implementation
62 ///////////////////////
64 STDMETHODIMP Shib_PropSheet::QueryInterface(REFIID riid, LPVOID *ppv)
71 if (IsEqualIID(riid, IID_IUnknown))
72 *ppv = static_cast<IExtendPropertySheet *>(this);
73 else if (IsEqualIID(riid, IID_IExtendPropertySheet))
74 *ppv = static_cast<IExtendPropertySheet *>(this);
78 reinterpret_cast<IUnknown *>(*ppv)->AddRef();
85 STDMETHODIMP_(ULONG) Shib_PropSheet::AddRef()
87 return InterlockedIncrement((LONG *)&m_cref);
90 STDMETHODIMP_(ULONG) Shib_PropSheet::Release()
92 if (InterlockedDecrement((LONG *)&m_cref) == 0)
94 // we need to decrement our object count in the DLL
102 HRESULT Shib_PropSheet::ExtractData( IDataObject* piDataObject,
103 CLIPFORMAT cfClipFormat,
109 FORMATETC formatetc = {cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
110 STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
112 stgmedium.hGlobal = ::GlobalAlloc(GPTR, cbData);
115 if (NULL == stgmedium.hGlobal)
120 hr = piDataObject->GetDataHere( &formatetc, &stgmedium );
126 BYTE* pbNewData = reinterpret_cast<BYTE*>(stgmedium.hGlobal);
127 if (NULL == pbNewData)
132 ::memcpy( pbData, pbNewData, cbData );
135 if (NULL != stgmedium.hGlobal)
137 ::GlobalFree(stgmedium.hGlobal);
143 void Shib_PropSheet::PopulateComboBox()
146 for (int i = 0; i < NUM_DIRECTIVES; i++)
148 LRESULT index = SendMessage(hProps, CB_ADDSTRING, 0, (LPARAM) (LPWSTR) directive[i].name.c_str());
149 LRESULT debug = SendMessage(hProps, CB_SETITEMDATA, (WPARAM)index, (LPARAM)i );
152 LRESULT debug = SendMessage(hProps, CB_SETCURSEL, 0, 0); // wparam = index, lparam = not used
156 BOOL Shib_PropSheet::UpdateNewValue() {
157 _TCHAR value[MAX_REG_BUFF];
159 DWORD index = SendMessage(hProps, CB_GETCURSEL, 0,0);
160 UINT i = SendMessage(hProps, CB_GETITEMDATA, (WPARAM)index, 0 );
162 if (directive[i].type == D_BOUND_INT || directive[i].type == D_BOUND_STRING) {
163 index = SendMessage(hValueBox, CB_GETCURSEL, 0,0);
164 if (index == CB_ERR) { return FALSE; }
165 LRESULT debug = SendMessage(hValueBox, CB_GETLBTEXT, (WPARAM)index, (LPARAM)value );
167 LRESULT debug = SendMessage(hValueEdit, WM_GETTEXT, (WPARAM)MAX_REG_BUFF, (LPARAM)value );
170 directive[i].new_value = value;
171 if (!_tcsicmp(directive[i].value.c_str(),value)) {
178 void Shib_PropSheet::GetHandles() {
179 hValueBox = GetDlgItem(hwndDlg, IDC_ValueBox);
180 hValueEdit = GetDlgItem(hwndDlg, IDC_ValueEdit);
181 hInheritedFrom = GetDlgItem(hwndDlg, IDC_InheritedFrom);
182 hMoreInfo = GetDlgItem(hwndDlg, IDC_MoreInfo);
183 hProps = GetDlgItem(hwndDlg, IDC_PROPS);
184 hDelete = GetDlgItem(hwndDlg, IDC_Delete);
187 void Shib_PropSheet::PopulatePage() {
189 DWORD index = SendMessage(hProps, CB_GETCURSEL, 0,0);
190 LRESULT i = SendMessage(hProps, CB_GETITEMDATA, (WPARAM)index, 0 );
192 Set_Delete_Button(i);
194 if (directive[i].type == D_BOUND_INT || directive[i].type == D_BOUND_STRING) {
195 ShowWindow(hValueEdit,SW_HIDE);
196 ShowWindow(hValueBox,SW_SHOW);
197 SendMessage(hValueBox,CB_RESETCONTENT,0,0);
198 for(int vi=0;vi < NUM_BOUND_VAL;vi++) {
199 if (directive[i].bound_val[vi].length()) {
200 LRESULT index = SendMessage(hValueBox, CB_INSERTSTRING, -1, (LPARAM) (LPWSTR) directive[i].bound_val[vi].c_str());
204 SendMessage(hValueBox, WM_SETTEXT, 0, (LPARAM) directive[i].new_value.c_str());
206 ShowWindow(hValueEdit,SW_SHOW);
207 ShowWindow(hValueBox,SW_HIDE);
208 SendMessage(hValueEdit, WM_SETTEXT, 0, (LPARAM) directive[i].new_value.c_str());
211 SendMessage(hMoreInfo, WM_SETTEXT, 0, (LPARAM) directive[i].description.c_str());
212 SendMessage(hInheritedFrom, WM_SETTEXT, 0, (LPARAM) directive[i].defined_in.c_str());
216 void Shib_PropSheet::DeleteValue() {
218 DWORD index = SendMessage(hProps, CB_GETCURSEL, 0,0);
219 LRESULT i = SendMessage(hProps, CB_GETITEMDATA, (WPARAM)index, 0 );
221 directive[i].DeleteValue();
225 void Shib_PropSheet::SetupPropSheet() {
234 BOOL CALLBACK Shib_PropSheet::DialogProc(
235 HWND hwndDlg, // handle to dialog box
236 UINT uMsg, // message
237 WPARAM wParam, // first message parameter
238 LPARAM lParam // second message parameter
242 if (uMsg == WM_INITDIALOG) {
243 Shib_PropSheet *pThis=reinterpret_cast<Shib_PropSheet *>(reinterpret_cast<PROPSHEETPAGE *>(lParam)->lParam);
244 pThis->hwndDlg=hwndDlg; //store property page handle in class
245 SetWindowLongPtr(hwndDlg,DWLP_USER,(LONG_PTR)pThis); //store class pointer in property page
246 pThis->SetupPropSheet();
248 Shib_PropSheet *pThis = reinterpret_cast<Shib_PropSheet *>(reinterpret_cast<PROPSHEETPAGE *>(GetWindowLongPtr(hwndDlg,DWLP_USER))); //retrieve class pointer from property page
251 if (HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == CBN_SELCHANGE) {
252 if ((HWND)lParam == GetDlgItem(hwndDlg,IDC_PROPS)) { //if the user changes directives
253 pThis->PopulatePage(); //redraw page
255 if (pThis->UpdateNewValue()) {
256 //if anything else changes, light the apply button
257 SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0);
261 if (wParam == IDC_Delete) {
262 pThis->DeleteValue();
263 pThis->PopulatePage();
264 SendMessage(GetParent(hwndDlg), PSM_CHANGED, (WPARAM)hwndDlg, 0); //light apply
265 } else if (wParam == IDC_Refresh) {
266 pThis->ReadCurrentValues(); //refresh values
267 pThis->PopulatePage(); //refresh page
275 switch (((NMHDR *) lParam)->code) {
277 pThis->UpdateNewValue(); //collect last-minute changes
278 pThis->WriteValues(); //write new values
279 pThis->ReadCurrentValues(); //refresh values
280 pThis->PopulatePage(); //refresh page
281 return PSNRET_NOERROR;
286 return FALSE; //Seems to not fall through to parent page if you use DefWindowProc
287 //return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
290 ///////////////////////////////
291 // Interface IExtendPropertySheet
292 ///////////////////////////////
293 HRESULT Shib_PropSheet::CreatePropertyPages(
294 /* [in] */ LPPROPERTYSHEETCALLBACK lpProvider,
295 /* [in] */ LONG_PTR handle,
296 /* [in] */ LPDATAOBJECT lpIDataObject)
299 HPROPSHEETPAGE hPage = NULL;
301 // cache this handle so we can call MMCPropertyChangeNotify
305 RegisterClipboardFormat(_T("ISM_SNAPIN_INSTANCE"));
306 UINT s_cfMachineName =
307 RegisterClipboardFormat(_T("ISM_SNAPIN_MACHINE_NAME"));
309 RegisterClipboardFormat(_T("ISM_SNAPIN_META_PATH"));
311 RegisterClipboardFormat(_T("ISM_SNAPIN_NODE"));
312 UINT s_cfParentPath =
313 RegisterClipboardFormat(_T("ISM_SNAPIN_PARENT_PATH"));
315 RegisterClipboardFormat(_T("ISM_SNAPIN_SERVICE"));
317 if ( !lpProvider || !lpIDataObject )
322 DWORD dwLength = MAX_PATH * sizeof(_TCHAR);
323 DWORD dwWLength = MAX_PATH * sizeof(wchar_t);
325 LPWSTR pwztInstance = reinterpret_cast<LPWSTR>(::LocalAlloc(LPTR, dwWLength));
326 LPWSTR pwztMachineName = reinterpret_cast<LPWSTR>(::LocalAlloc(LPTR, dwWLength));
327 LPWSTR pwztMetaPath = reinterpret_cast<LPWSTR>(::LocalAlloc(LPTR, dwWLength));
328 LPWSTR pwztNode = reinterpret_cast<LPWSTR>(::LocalAlloc(LPTR, dwWLength));
329 LPWSTR pwztParentPath = reinterpret_cast<LPWSTR>(::LocalAlloc(LPTR, dwWLength));
330 LPWSTR pwztService = reinterpret_cast<LPWSTR>(::LocalAlloc(LPTR, dwWLength));
333 Shib_PropSheet::ExtractWString(lpIDataObject, s_cfInstance, pwztInstance, dwLength);
334 if ( pwztMachineName )
335 Shib_PropSheet::ExtractWString(lpIDataObject, s_cfMachineName, pwztMachineName, dwLength);
337 Shib_PropSheet::ExtractWString(lpIDataObject, s_cfMetaPath, pwztMetaPath, dwLength);
339 Shib_PropSheet::ExtractWString(lpIDataObject, s_cfNode, pwztNode, dwLength);
340 if ( pwztParentPath )
341 Shib_PropSheet::ExtractWString(lpIDataObject, s_cfParentPath, pwztParentPath, dwLength);
343 Shib_PropSheet::ExtractWString(lpIDataObject, s_cfService, pwztService, dwLength);
345 /* IIS only supports Unicode clipboard formats */
347 pwzInstance = pwztInstance;
348 pwzMachineName = pwztMachineName;
349 pwzMetaPath = pwztMetaPath;
351 pwzParentPath = pwztParentPath;
352 pwzService = pwztService;
354 pwzInstance = reinterpret_cast<LPSTR>(::LocalAlloc(LPTR, dwLength));
355 pwzMachineName = reinterpret_cast<LPSTR>(::LocalAlloc(LPTR, dwLength));
356 pwzMetaPath = reinterpret_cast<LPSTR>(::LocalAlloc(LPTR, dwLength));
357 pwzNode = reinterpret_cast<LPSTR>(::LocalAlloc(LPTR, dwLength));
358 pwzParentPath = reinterpret_cast<LPSTR>(::LocalAlloc(LPTR, dwLength));
359 pwzService = reinterpret_cast<LPSTR>(::LocalAlloc(LPTR, dwLength));
361 UnicodeToAnsi(pwztInstance,&pwzInstance);
362 UnicodeToAnsi(pwztMachineName,&pwzMachineName);
363 UnicodeToAnsi(pwztMetaPath,&pwzMetaPath);
364 UnicodeToAnsi(pwztNode,&pwzNode);
365 UnicodeToAnsi(pwztParentPath,&pwzParentPath);
366 UnicodeToAnsi(pwztService,&pwzService);
369 ::LocalFree(pwztService);
370 if ( pwztParentPath )
371 ::LocalFree(pwztParentPath);
373 ::LocalFree(pwztNode);
375 ::LocalFree(pwztMetaPath);
376 if ( pwztMachineName )
377 ::LocalFree(pwztMachineName);
379 ::LocalFree(pwztInstance);
383 for (int i=0;i<NUM_DIRECTIVES;i++) {
384 directive[i].MachineName = pwzMachineName;
386 pwzRegPath = reinterpret_cast<LPTSTR>(::LocalAlloc(LPTR, (dwLength*2)+1));
388 LPTSTR ppath = _tcschr(pwzParentPath,_T('/'));
390 StringCbCopy(pwzRegPath, MAX_PATH*2 ,ppath+1);
391 StringCbCat (pwzRegPath, MAX_PATH*2 ,_T("/"));
395 StringCbCat(pwzRegPath, MAX_PATH*2 ,pwzNode);
397 psp.dwSize = sizeof(PROPSHEETPAGE);
398 psp.dwFlags = PSP_DEFAULT | PSP_USETITLE | PSP_USEICONID;
399 psp.hInstance = g_hinst;
400 psp.pszTemplate = MAKEINTRESOURCE(IDD_PROPPAGE);
401 psp.pfnDlgProc = DialogProc;
402 psp.lParam = reinterpret_cast<LPARAM>(this);
403 psp.pszTitle = MAKEINTRESOURCE(IDS_PST_TAB_NAME);
405 hPage = CreatePropertySheetPage(&psp);
408 hr = lpProvider->AddPage(hPage);
413 HRESULT Shib_PropSheet::QueryPagesFor(
414 /* [in] */ LPDATAOBJECT lpDataObject)
419 void Shib_PropSheet::Set_Delete_Button(int i) {
421 if (!_tcsicmp((directive[i].defined_in.c_str() + 1),pwzRegPath)) {
422 EnableWindow(hDelete,TRUE);
424 EnableWindow(hDelete,FALSE);
428 void Shib_PropSheet::ReadSelectedValue() {
430 DWORD index = SendMessage(hProps, CB_GETCURSEL, 0,0);
431 unsigned int i = SendMessage(hProps, CB_GETITEMDATA, (WPARAM)index, 0 );
432 directive[i].Set_Path(pwzRegPath);
433 directive[i].new_value = directive[i].value;
437 void Shib_PropSheet::ReadCurrentValues() {
439 for (int i=0;i<NUM_DIRECTIVES;i++) {
440 directive[i].Set_Path(pwzRegPath);
441 directive[i].new_value = directive[i].value;
446 void Shib_PropSheet::WriteValues() {
449 RegPath = _T(SHIB_DEFAULT_WEB_KEY);
451 if (_tcslen(pwzRegPath)) {
453 RegPath += pwzRegPath;
454 ReplaceSlashes(RegPath);
457 for (int i=0;i<NUM_DIRECTIVES;i++) {
458 if (_tcscmp(STR_PENDING_DELETION,directive[i].new_value.c_str())){
459 if (_tcsicmp(directive[i].value.c_str(),directive[i].new_value.c_str())) {
460 directive[i].WriteValue(RegPath);
462 } else { // Commit Delete
463 directive[i].DeleteRegVal(RegPath);