Warn if open_count is already 0 when OSS_CloseDevice is called.
[wine/hacks.git] / dlls / shell32 / folders.c
blobff8ea2a1b331bede593b6f446da648d949e536fd
1 /*
2 * Copyright 1997 Marcus Meissner
3 * Copyright 1998 Juergen Schmied
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
24 #include "windef.h"
25 #include "objbase.h"
26 #include "undocshell.h"
27 #include "shlguid.h"
29 #include "wine/debug.h"
30 #include "winerror.h"
32 #include "pidl.h"
33 #include "shell32_main.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(shell);
37 /***********************************************************************
38 * IExtractIconW implementation
40 typedef struct
42 ICOM_VFIELD(IExtractIconW);
43 DWORD ref;
44 ICOM_VTABLE(IPersistFile)* lpvtblPersistFile;
45 ICOM_VTABLE(IExtractIconA)* lpvtblExtractIconA;
46 LPITEMIDLIST pidl;
47 } IExtractIconWImpl;
49 static struct ICOM_VTABLE(IExtractIconA) eiavt;
50 static struct ICOM_VTABLE(IExtractIconW) eivt;
51 static struct ICOM_VTABLE(IPersistFile) pfvt;
53 #define _IPersistFile_Offset ((int)(&(((IExtractIconWImpl*)0)->lpvtblPersistFile)))
54 #define _ICOM_THIS_From_IPersistFile(class, name) class* This = (class*)(((char*)name)-_IPersistFile_Offset);
56 #define _IExtractIconA_Offset ((int)(&(((IExtractIconWImpl*)0)->lpvtblExtractIconA)))
57 #define _ICOM_THIS_From_IExtractIconA(class, name) class* This = (class*)(((char*)name)-_IExtractIconA_Offset);
59 /**************************************************************************
60 * IExtractIconW_Constructor
62 IExtractIconW* IExtractIconW_Constructor(LPCITEMIDLIST pidl)
64 IExtractIconWImpl* ei;
66 TRACE("%p\n", pidl);
68 ei = (IExtractIconWImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIconWImpl));
69 ei->ref=1;
70 ICOM_VTBL(ei) = &eivt;
71 ei->lpvtblPersistFile = &pfvt;
72 ei->lpvtblExtractIconA = &eiavt;
73 ei->pidl=ILClone(pidl);
75 pdump(pidl);
77 TRACE("(%p)\n", ei);
78 return (IExtractIconW *)ei;
80 /**************************************************************************
81 * IExtractIconW_QueryInterface
83 static HRESULT WINAPI IExtractIconW_fnQueryInterface(IExtractIconW *iface, REFIID riid, LPVOID *ppvObj)
85 ICOM_THIS(IExtractIconWImpl, iface);
87 TRACE("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid(riid), ppvObj);
89 *ppvObj = NULL;
91 if (IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/
93 *ppvObj = This;
95 else if (IsEqualIID(riid, &IID_IPersistFile)) /*IExtractIcon*/
97 *ppvObj = (IPersistFile*)&(This->lpvtblPersistFile);
99 else if (IsEqualIID(riid, &IID_IExtractIconA)) /*IExtractIcon*/
101 *ppvObj = (IExtractIconA*)&(This->lpvtblExtractIconA);
103 else if (IsEqualIID(riid, &IID_IExtractIconW)) /*IExtractIcon*/
105 *ppvObj = (IExtractIconW*)This;
108 if(*ppvObj)
110 IExtractIconW_AddRef((IExtractIconW*) *ppvObj);
111 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
112 return S_OK;
114 TRACE("-- Interface: E_NOINTERFACE\n");
115 return E_NOINTERFACE;
118 /**************************************************************************
119 * IExtractIconW_AddRef
121 static ULONG WINAPI IExtractIconW_fnAddRef(IExtractIconW * iface)
123 ICOM_THIS(IExtractIconWImpl, iface);
125 TRACE("(%p)->(count=%lu)\n",This, This->ref );
127 return ++(This->ref);
129 /**************************************************************************
130 * IExtractIconW_Release
132 static ULONG WINAPI IExtractIconW_fnRelease(IExtractIconW * iface)
134 ICOM_THIS(IExtractIconWImpl, iface);
136 TRACE("(%p)->()\n",This);
138 if (!--(This->ref))
140 TRACE(" destroying IExtractIcon(%p)\n",This);
141 SHFree(This->pidl);
142 HeapFree(GetProcessHeap(),0,This);
143 return 0;
145 return This->ref;
148 static WCHAR swShell32Name[] = {'s','h','e','l','l','3','2','.','d','l','l',0};
150 /**************************************************************************
151 * IExtractIconW_GetIconLocation
153 * mapping filetype to icon
155 static HRESULT WINAPI IExtractIconW_fnGetIconLocation(
156 IExtractIconW * iface,
157 UINT uFlags, /* GIL_ flags */
158 LPWSTR szIconFile,
159 UINT cchMax,
160 int * piIndex,
161 UINT * pwFlags) /* returned GIL_ flags */
163 ICOM_THIS(IExtractIconWImpl, iface);
165 char sTemp[MAX_PATH];
166 DWORD dwNr;
167 GUID const * riid;
168 LPITEMIDLIST pSimplePidl = ILFindLastID(This->pidl);
170 TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
172 if (pwFlags)
173 *pwFlags = 0;
175 if (_ILIsDesktop(pSimplePidl))
177 lstrcpynW(szIconFile, swShell32Name, cchMax);
178 *piIndex = 34;
181 /* my computer and other shell extensions */
182 else if ((riid = _ILGetGUIDPointer(pSimplePidl)))
184 char xriid[50];
186 sprintf(xriid, "CLSID\\{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
187 riid->Data1, riid->Data2, riid->Data3,
188 riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
189 riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7]);
191 if (HCR_GetDefaultIconA(xriid, sTemp, MAX_PATH, &dwNr))
193 MultiByteToWideChar(CP_ACP, 0, sTemp, MAX_PATH, szIconFile, cchMax);
194 *piIndex = dwNr;
196 else
198 lstrcpynW(szIconFile, swShell32Name, cchMax);
199 *piIndex = 15;
203 else if (_ILIsDrive (pSimplePidl))
205 if (HCR_GetDefaultIconA("Drive", sTemp, MAX_PATH, &dwNr))
207 MultiByteToWideChar(CP_ACP, 0, sTemp, MAX_PATH, szIconFile, cchMax);
208 *piIndex = dwNr;
210 else
212 lstrcpynW(szIconFile, swShell32Name, cchMax);
213 *piIndex = 8;
216 else if (_ILIsFolder (pSimplePidl))
218 if (HCR_GetDefaultIconA("Folder", sTemp, MAX_PATH, &dwNr))
220 MultiByteToWideChar(CP_ACP, 0, sTemp, MAX_PATH, szIconFile, cchMax);
222 else
224 lstrcpynW(szIconFile, swShell32Name, cchMax);
225 dwNr = 3;
227 *piIndex = (uFlags & GIL_OPENICON) ? dwNr + 1 : dwNr;
229 else /* object is file */
231 if (_ILGetExtension(pSimplePidl, sTemp, MAX_PATH)
232 && HCR_MapTypeToValueA(sTemp, sTemp, MAX_PATH, TRUE)
233 && HCR_GetDefaultIconA(sTemp, sTemp, MAX_PATH, &dwNr))
235 if (!lstrcmpA("%1", sTemp)) /* icon is in the file */
237 SHGetPathFromIDListW(This->pidl, szIconFile);
238 *piIndex = 0;
240 else
242 MultiByteToWideChar(CP_ACP, 0, sTemp, MAX_PATH, szIconFile, cchMax);
243 *piIndex = dwNr;
246 else /* default icon */
248 lstrcpynW(szIconFile, swShell32Name, cchMax);
249 *piIndex = 0;
253 TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex);
254 return NOERROR;
256 /**************************************************************************
257 * IExtractIconW_Extract
259 static HRESULT WINAPI IExtractIconW_fnExtract(IExtractIconW * iface, LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
261 ICOM_THIS(IExtractIconWImpl, iface);
263 FIXME("(%p) (file=%p index=%u %p %p size=%u) semi-stub\n", This, debugstr_w(pszFile), nIconIndex, phiconLarge, phiconSmall, nIconSize);
265 if (phiconLarge)
266 *phiconLarge = ImageList_GetIcon(ShellBigIconList, nIconIndex, ILD_TRANSPARENT);
268 if (phiconSmall)
269 *phiconSmall = ImageList_GetIcon(ShellSmallIconList, nIconIndex, ILD_TRANSPARENT);
271 return S_OK;
274 static struct ICOM_VTABLE(IExtractIconW) eivt =
276 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
277 IExtractIconW_fnQueryInterface,
278 IExtractIconW_fnAddRef,
279 IExtractIconW_fnRelease,
280 IExtractIconW_fnGetIconLocation,
281 IExtractIconW_fnExtract
284 /**************************************************************************
285 * IExtractIconA_Constructor
287 IExtractIconA* IExtractIconA_Constructor(LPCITEMIDLIST pidl)
289 ICOM_THIS(IExtractIconWImpl, IExtractIconW_Constructor(pidl));
290 IExtractIconA *eia = (IExtractIconA *)&This->lpvtblExtractIconA;
292 TRACE("(%p)->(%p)\n", This, eia);
293 return eia;
295 /**************************************************************************
296 * IExtractIconA_QueryInterface
298 static HRESULT WINAPI IExtractIconA_fnQueryInterface(IExtractIconA * iface, REFIID riid, LPVOID *ppvObj)
300 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
302 return IExtractIconW_QueryInterface(This, riid, ppvObj);
305 /**************************************************************************
306 * IExtractIconA_AddRef
308 static ULONG WINAPI IExtractIconA_fnAddRef(IExtractIconA * iface)
310 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
312 return IExtractIconW_AddRef(This);
314 /**************************************************************************
315 * IExtractIconA_Release
317 static ULONG WINAPI IExtractIconA_fnRelease(IExtractIconA * iface)
319 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
321 return IExtractIconW_AddRef(This);
323 /**************************************************************************
324 * IExtractIconA_GetIconLocation
326 * mapping filetype to icon
328 static HRESULT WINAPI IExtractIconA_fnGetIconLocation(
329 IExtractIconA * iface,
330 UINT uFlags,
331 LPSTR szIconFile,
332 UINT cchMax,
333 int * piIndex,
334 UINT * pwFlags)
336 HRESULT ret;
337 LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, cchMax * sizeof(WCHAR));
338 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
340 TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
342 ret = IExtractIconW_GetIconLocation(This, uFlags, lpwstrFile, cchMax, piIndex, pwFlags);
343 WideCharToMultiByte(CP_ACP, 0, lpwstrFile, cchMax, szIconFile, cchMax, NULL, NULL);
344 HeapFree(GetProcessHeap(), 0, lpwstrFile);
346 TRACE("-- %s %x\n", szIconFile, *piIndex);
347 return ret;
349 /**************************************************************************
350 * IExtractIconA_Extract
352 static HRESULT WINAPI IExtractIconA_fnExtract(IExtractIconA * iface, LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
354 HRESULT ret;
355 INT len = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0);
356 LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
357 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
359 TRACE("(%p) (file=%p index=%u %p %p size=%u)\n", This, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
361 MultiByteToWideChar(CP_ACP, 0, pszFile, -1, lpwstrFile, len);
362 ret = IExtractIconW_Extract(This, lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
363 HeapFree(GetProcessHeap(), 0, lpwstrFile);
364 return ret;
367 static struct ICOM_VTABLE(IExtractIconA) eiavt =
369 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
370 IExtractIconA_fnQueryInterface,
371 IExtractIconA_fnAddRef,
372 IExtractIconA_fnRelease,
373 IExtractIconA_fnGetIconLocation,
374 IExtractIconA_fnExtract
377 /************************************************************************
378 * IEIPersistFile_QueryInterface (IUnknown)
380 static HRESULT WINAPI IEIPersistFile_fnQueryInterface(
381 IPersistFile *iface,
382 REFIID iid,
383 LPVOID *ppvObj)
385 _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
387 return IExtractIconW_QueryInterface(This, iid, ppvObj);
390 /************************************************************************
391 * IEIPersistFile_AddRef (IUnknown)
393 static ULONG WINAPI IEIPersistFile_fnAddRef(
394 IPersistFile *iface)
396 _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
398 return IExtractIconW_AddRef(This);
401 /************************************************************************
402 * IEIPersistFile_Release (IUnknown)
404 static ULONG WINAPI IEIPersistFile_fnRelease(
405 IPersistFile *iface)
407 _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
409 return IExtractIconW_Release(This);
412 /************************************************************************
413 * IEIPersistFile_GetClassID (IPersist)
415 static HRESULT WINAPI IEIPersistFile_fnGetClassID(
416 IPersistFile *iface,
417 LPCLSID lpClassId)
419 CLSID StdFolderID = { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
421 if (lpClassId==NULL)
422 return E_POINTER;
424 memcpy(lpClassId, &StdFolderID, sizeof(StdFolderID));
426 return S_OK;
429 /************************************************************************
430 * IEIPersistFile_Load (IPersistFile)
432 static HRESULT WINAPI IEIPersistFile_fnLoad(IPersistFile* iface, LPCOLESTR pszFileName, DWORD dwMode)
434 _ICOM_THIS_From_IPersistFile(IExtractIconW, iface);
435 FIXME("%p\n", This);
436 return E_NOTIMPL;
440 static struct ICOM_VTABLE(IPersistFile) pfvt =
442 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
443 IEIPersistFile_fnQueryInterface,
444 IEIPersistFile_fnAddRef,
445 IEIPersistFile_fnRelease,
446 IEIPersistFile_fnGetClassID,
447 (void *) 0xdeadbeef /* IEIPersistFile_fnIsDirty */,
448 IEIPersistFile_fnLoad,
449 (void *) 0xdeadbeef /* IEIPersistFile_fnSave */,
450 (void *) 0xdeadbeef /* IEIPersistFile_fnSaveCompleted */,
451 (void *) 0xdeadbeef /* IEIPersistFile_fnGetCurFile */