~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shdocvw/tests/shortcut.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Unit tests to document shdocvw's 'Shell Instance Objects' features
  3  *
  4  * Copyright 2005 Michael Jung
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 /* At least since Windows 2000 it's possible to add FolderShortcut objects
 22  * by creating some registry entries. Those objects, which refer to some
 23  * point in the filesystem, can be registered in the shell namespace like other 
 24  * shell namespace extensions. Icons, names and filesystem location can be
 25  * configured. This is documented at http://www.virtualplastic.net/html/ui_shell.html
 26  * You can also google for a tool called "ShellObjectEditor" by "Tropical 
 27  * Technologies". This mechanism would be cool for wine, since we could 
 28  * map Gnome's virtual devices to FolderShortcuts and have them appear in the
 29  * file dialogs. These unit tests are meant to document how this mechanism
 30  * works on windows.
 31  *
 32  * Search MSDN for "Creating Shell Extensions with Shell Instance Objects" for
 33  * more documentation.*/
 34 
 35 #include <stdarg.h>
 36 
 37 #define COBJMACROS
 38 
 39 #include "windef.h"
 40 #include "winbase.h"
 41 #include "winreg.h"
 42 
 43 #include "shlobj.h"
 44 #include "shobjidl.h"
 45 #include "shlguid.h"
 46 #include "ole2.h"
 47 
 48 #include "wine/test.h"
 49 
 50 /* The following definitions and helper functions are meant to make the de-/registration
 51  * of the various necessary registry keys easier. */
 52 
 53 struct registry_value {
 54     const char  *szName;
 55     const DWORD dwType;
 56     const char  *szValue;
 57     const DWORD dwValue;
 58 };
 59 
 60 #define REG_VALUE_ADDR(x) ((x->dwType==REG_SZ)?(const BYTE *)x->szValue:(const BYTE *)&x->dwValue)
 61 #define REG_VALUE_SIZE(x) ((x->dwType==REG_SZ)?strlen(x->szValue)+1:sizeof(DWORD))
 62 
 63 struct registry_key {
 64     const char                  *szName;
 65     const struct registry_value *pValues;
 66     const unsigned int          cValues;
 67     const struct registry_key   *pSubKeys;
 68     const unsigned int          cSubKeys;
 69 };
 70 
 71 static const struct registry_value ShellFolder_values[] = {
 72     { "WantsFORPARSING", REG_SZ,    "",   0          },
 73     { "Attributes",      REG_DWORD, NULL, 0xF8000100 }
 74 };
 75 
 76 static const struct registry_value Instance_values[] = {
 77     { "CLSID", REG_SZ, "{0AFACED1-E828-11D1-9187-B532F1E9575D}", 0 }
 78 };
 79 
 80 static const struct registry_value InitPropertyBag_values[] = {
 81     { "Attributes", REG_DWORD, NULL,   0x00000015 },
 82     { "Target",     REG_SZ,    "C:\\", 0          }
 83 };
 84 
 85 static const struct registry_key Instance_keys[] = {
 86     { "InitPropertyBag", InitPropertyBag_values, 2, NULL, 0 }
 87 };
 88 
 89 static const struct registry_value InProcServer32_values[] = {
 90     { NULL,             REG_SZ, "shdocvw.dll", 0 },
 91     { "ThreadingModel", REG_SZ, "Apartment",   0 }
 92 };
 93 
 94 static const struct registry_value DefaultIcon_values[] = {
 95     { NULL, REG_SZ,"shell32.dll,8", 0 }
 96 };
 97 
 98 static const struct registry_key ShortcutCLSID_keys[] = {
 99     { "DefaultIcon",    DefaultIcon_values,    1, NULL,          0 },
100     { "InProcServer32", InProcServer32_values, 2, NULL,          0 },
101     { "Instance",       Instance_values,       1, Instance_keys, 1 },
102     { "ShellFolder",    ShellFolder_values,    2, NULL,          0 }
103 };
104 
105 static const struct registry_value ShortcutCLSID_values[] = {
106     { NULL, REG_SZ, "WineTest", 0 }
107 };
108 
109 static const struct registry_key HKEY_CLASSES_ROOT_keys[] = {
110     { "CLSID\\{9B352EBF-2765-45C1-B4C6-85CC7F7ABC64}", ShortcutCLSID_values, 1, ShortcutCLSID_keys, 4}
111 };
112 
113 /* register_keys - helper function, which recursively creates the registry keys and values in 
114  * parameter 'keys' in the registry under hRootKey. */
115 static BOOL register_keys(HKEY hRootKey, const struct registry_key *keys, unsigned int numKeys) {
116     HKEY hKey;
117     unsigned int iKey, iValue;
118 
119     for (iKey = 0; iKey < numKeys; iKey++) {
120         if (ERROR_SUCCESS == RegCreateKeyExA(hRootKey, keys[iKey].szName, 0, NULL, 0, 
121                                              KEY_WRITE, NULL, &hKey, NULL))
122         {
123             for (iValue = 0; iValue < keys[iKey].cValues; iValue++) {
124                 const struct registry_value * value = &keys[iKey].pValues[iValue];
125                 if (ERROR_SUCCESS != RegSetValueExA(hKey, value->szName, 0, value->dwType,
126                                                     REG_VALUE_ADDR(value), REG_VALUE_SIZE(value)))
127                 {
128                     RegCloseKey(hKey);
129                     return FALSE;
130                 }
131             }
132             
133             if (!register_keys(hKey, keys[iKey].pSubKeys, keys[iKey].cSubKeys)) {
134                 RegCloseKey(hKey);
135                 return FALSE;
136             }
137             
138             RegCloseKey(hKey);
139         }
140     }
141         
142     return TRUE;
143 }
144 
145 /* unregister_keys - clean up after register_keys */
146 static void unregister_keys(HKEY hRootKey, const struct registry_key *keys, unsigned int numKeys) {
147     HKEY hKey;
148     unsigned int iKey;
149 
150     for (iKey = 0; iKey < numKeys; iKey++) {
151         if (ERROR_SUCCESS == RegOpenKeyExA(hRootKey, keys[iKey].szName, 0, DELETE, &hKey)) {
152             unregister_keys(hKey, keys[iKey].pSubKeys, keys[iKey].cSubKeys);
153             RegCloseKey(hKey);
154         }
155         RegDeleteKeyA(hRootKey, keys[iKey].szName);
156     }
157 }
158     
159 static void test_ShortcutFolder(void) {
160     LPSHELLFOLDER pDesktopFolder, pWineTestFolder;
161     IPersistFolder3 *pWineTestPersistFolder;
162     LPITEMIDLIST pidlWineTestFolder, pidlCurFolder;
163     HRESULT hr;
164     CLSID clsid;
165     const CLSID CLSID_WineTest = 
166         { 0x9b352ebf, 0x2765, 0x45c1, { 0xb4, 0xc6, 0x85, 0xcc, 0x7f, 0x7a, 0xbc, 0x64 } };
167     WCHAR wszWineTestFolder[] = {
168         ':',':','{','9','B','3','5','2','E','B','F','-','2','7','6','5','-','4','5','C','1','-',
169         'B','4','C','6','-','8','5','C','C','7','F','7','A','B','C','6','4','}',0 };
170 
171     /* First, we register all the necessary registry keys/values for our 'WineTest'
172      * shell object. */
173     register_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);
174 
175     hr = SHGetDesktopFolder(&pDesktopFolder);
176     ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08x\n", hr);
177     if (FAILED(hr)) goto cleanup;
178 
179     /* Convert the wszWineTestFolder string to an ITEMIDLIST. */
180     hr = IShellFolder_ParseDisplayName(pDesktopFolder, NULL, NULL, wszWineTestFolder, NULL, 
181                                        &pidlWineTestFolder, NULL);
182     todo_wine
183     {
184         ok (hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
185             "Expected %08x, got %08x\n", HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), hr);
186     }
187     if (FAILED(hr)) {
188         IShellFolder_Release(pDesktopFolder);
189         goto cleanup;
190     }
191 
192     /* FIXME: these tests are never run */
193 
194     /* Bind to a WineTest folder object. There has to be some support for this in shdocvw.dll.
195      * This isn't implemented in wine yet.*/
196     hr = IShellFolder_BindToObject(pDesktopFolder, pidlWineTestFolder, NULL, &IID_IShellFolder, 
197                                    (LPVOID*)&pWineTestFolder);
198     IShellFolder_Release(pDesktopFolder);
199     ILFree(pidlWineTestFolder);
200     ok (SUCCEEDED(hr), "IShellFolder::BindToObject(WineTestFolder) failed! hr = %08x\n", hr);
201     if (FAILED(hr)) goto cleanup;
202 
203     hr = IShellFolder_QueryInterface(pWineTestFolder, &IID_IPersistFolder3, (LPVOID*)&pWineTestPersistFolder);
204     ok (SUCCEEDED(hr), "IShellFolder::QueryInterface(IPersistFolder3) failed! hr = %08x\n", hr);
205     IShellFolder_Release(pWineTestFolder);
206     if (FAILED(hr)) goto cleanup;
207 
208     /* The resulting folder object has the FolderShortcut CLSID, instead of it's own. */
209     hr = IPersistFolder3_GetClassID(pWineTestPersistFolder, &clsid);
210     ok (SUCCEEDED(hr), "IPersist::GetClassID failed! hr = %08x\n", hr);
211     ok (IsEqualCLSID(&CLSID_FolderShortcut, &clsid), "GetClassId returned wrong CLSID!\n"); 
212   
213     pidlCurFolder = (LPITEMIDLIST)0xdeadbeef;
214     hr = IPersistFolder3_GetCurFolder(pWineTestPersistFolder, &pidlCurFolder);
215     ok (SUCCEEDED(hr), "IPersistFolder3::GetCurFolder failed! hr = %08x\n", hr);
216     ok (pidlCurFolder->mkid.cb == 20 && ((LPSHITEMID)((BYTE*)pidlCurFolder+20))->cb == 0 && 
217         IsEqualCLSID(&CLSID_WineTest, (REFCLSID)((LPBYTE)pidlCurFolder+4)), 
218         "GetCurFolder returned unexpected pidl!\n");
219     
220     IPersistFolder3_Release(pWineTestPersistFolder);
221     
222 cleanup:
223     unregister_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);
224 }    
225     
226 START_TEST(shortcut)
227 {
228     OleInitialize(NULL);
229     test_ShortcutFolder();
230     OleUninitialize();
231 }
232 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.