16d98ca47edb3871323e723ec3b6e3cf6b92bcbb
[reactos.git] / reactos / dll / win32 / shell32 / shfldr_printers.c
1 /*
2 * Virtual Printers Folder
3 *
4 * Copyright 1997 Marcus Meissner
5 * Copyright 1998, 1999, 2002 Juergen Schmied
6 * Copyright 2005 Huw Davies
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <precomp.h>
24
25 WINE_DEFAULT_DEBUG_CHANNEL (shell);
26
27 /***********************************************************************
28 * Printers_IExtractIconW implementation
29 */
30 typedef struct
31 {
32 IExtractIconWVtbl *lpVtbl;
33 IExtractIconAVtbl *lpvtblExtractIconA;
34 volatile LONG ref;
35 LPITEMIDLIST pidl;
36 } IExtractIconWImpl;
37
38 #define _IExtractIconA_Offset ((INT_PTR)(&(((IExtractIconWImpl*)0)->lpvtblExtractIconA)))
39 #define _ICOM_THIS_From_IExtractIconA(class, name) class* This = (class*)(((char*)name)-_IExtractIconA_Offset);
40
41 static shvheader PrinterSFHeader[] = {
42 {IDS_SHV_COLUMN8, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
43 {IDS_SHV_COLUMN_DOCUMENTS , SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
44 {IDS_SHV_COLUMN_STATUS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
45 {IDS_SHV_COLUMN_COMMENTS, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
46 {IDS_SHV_COLUMN_LOCATION, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15},
47 {IDS_SHV_COLUMN_MODEL, SHCOLSTATE_TYPE_STR | SHCOLSTATE_ONBYDEFAULT, LVCFMT_RIGHT, 15}
48 };
49
50 #define COLUMN_NAME 0
51 #define COLUMN_DOCUMENTS 1
52 #define COLUMN_STATUS 2
53 #define COLUMN_COMMENTS 3
54 #define COLUMN_LOCATION 4
55 #define COLUMN_MODEL 5
56
57
58 #define PrinterSHELLVIEWCOLUMNS (6)
59
60
61 /**************************************************************************
62 * IExtractIconW_QueryInterface
63 */
64 static HRESULT WINAPI IEI_Printers_fnQueryInterface(IExtractIconW *iface, REFIID riid, LPVOID *ppvObj)
65 {
66 IExtractIconWImpl *This = (IExtractIconWImpl *)iface;
67
68 TRACE("(%p)->(\n\tIID:\t%s,%p)\n", This, debugstr_guid(riid), ppvObj);
69
70 *ppvObj = NULL;
71
72 if (IsEqualIID(riid, &IID_IUnknown))
73 {
74 *ppvObj = This;
75 }
76 else if (IsEqualIID(riid, &IID_IExtractIconW))
77 {
78 *ppvObj = (IExtractIconW*)This;
79 }
80 else if (IsEqualIID(riid, &IID_IExtractIconA))
81 {
82 *ppvObj = (IExtractIconA*)&(This->lpvtblExtractIconA);
83 }
84
85 if(*ppvObj)
86 {
87 ((IExtractIconW*)*ppvObj)->lpVtbl->AddRef(*ppvObj);
88 TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
89 return S_OK;
90 }
91 TRACE("-- Interface: E_NOINTERFACE\n");
92 return E_NOINTERFACE;
93 }
94
95 /**************************************************************************
96 * IExtractIconW_AddRef
97 */
98 static ULONG WINAPI IEI_Printers_fnAddRef(IExtractIconW * iface)
99 {
100 IExtractIconWImpl *This = (IExtractIconWImpl *)iface;
101 ULONG refCount = InterlockedIncrement(&This->ref);
102
103 TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
104
105 return refCount;
106 }
107
108 /**************************************************************************
109 * IExtractIconW_Release
110 */
111 static ULONG WINAPI IEI_Printers_fnRelease(IExtractIconW * iface)
112 {
113 IExtractIconWImpl *This = (IExtractIconWImpl *)iface;
114 ULONG refCount = InterlockedDecrement(&This->ref);
115
116 TRACE("(%p)->(count=%lu)\n", This, refCount + 1);
117
118 if (!refCount)
119 {
120 TRACE(" destroying IExtractIcon(%p)\n",This);
121 SHFree(This->pidl);
122 HeapFree(GetProcessHeap(),0,This);
123 return 0;
124 }
125 return refCount;
126 }
127
128 /**************************************************************************
129 * IExtractIconW_GetIconLocation
130 *
131 * mapping filetype to icon
132 */
133 static HRESULT WINAPI IEI_Printers_fnGetIconLocation(
134 IExtractIconW * iface,
135 UINT uFlags, /* GIL_ flags */
136 LPWSTR szIconFile,
137 UINT cchMax,
138 int *piIndex,
139 UINT *pwFlags) /* returned GIL_ flags */
140 {
141 IExtractIconWImpl *This = (IExtractIconWImpl *)iface;
142
143 TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
144
145 if (pwFlags)
146 *pwFlags = 0;
147
148 lstrcpynW(szIconFile, swShell32Name, cchMax);
149 *piIndex = -IDI_SHELL_PRINTERS_FOLDER; /* FIXME: other icons for default, network, print to file */
150
151 TRACE("-- %s %x\n", debugstr_w(szIconFile), *piIndex);
152 return NOERROR;
153 }
154
155 /**************************************************************************
156 * IExtractIconW_Extract
157 */
158 static HRESULT WINAPI IEI_Printers_fnExtract(IExtractIconW *iface, LPCWSTR pszFile,
159 UINT nIconIndex, HICON *phiconLarge,
160 HICON *phiconSmall, UINT nIconSize)
161 {
162 IExtractIconWImpl *This = (IExtractIconWImpl *)iface;
163 int index;
164
165 FIXME("(%p) (file=%p index=%d %p %p size=%x) semi-stub\n", This, debugstr_w(pszFile),
166 (signed)nIconIndex, phiconLarge, phiconSmall, nIconSize);
167
168 index = SIC_GetIconIndex(pszFile, nIconIndex, 0);
169
170 if (phiconLarge)
171 *phiconLarge = ImageList_GetIcon(ShellBigIconList, index, ILD_TRANSPARENT);
172
173 if (phiconSmall)
174 *phiconSmall = ImageList_GetIcon(ShellSmallIconList, index, ILD_TRANSPARENT);
175
176 return S_OK;
177 }
178
179 static struct IExtractIconWVtbl eivt =
180 {
181 IEI_Printers_fnQueryInterface,
182 IEI_Printers_fnAddRef,
183 IEI_Printers_fnRelease,
184 IEI_Printers_fnGetIconLocation,
185 IEI_Printers_fnExtract
186 };
187
188 /**************************************************************************
189 * IExtractIconA_QueryInterface
190 */
191 static HRESULT WINAPI IEIA_Printers_fnQueryInterface(IExtractIconA * iface, REFIID riid, LPVOID *ppvObj)
192 {
193 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
194
195 return This->lpVtbl->QueryInterface(This, riid, ppvObj);
196 }
197
198 /**************************************************************************
199 * IExtractIconA_AddRef
200 */
201 static ULONG WINAPI IEIA_Printers_fnAddRef(IExtractIconA * iface)
202 {
203 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
204
205 return This->lpVtbl->AddRef(This);
206 }
207 /**************************************************************************
208 * IExtractIconA_Release
209 */
210 static ULONG WINAPI IEIA_Printers_fnRelease(IExtractIconA * iface)
211 {
212 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
213
214 return This->lpVtbl->AddRef(This);
215 }
216
217 /**************************************************************************
218 * IExtractIconA_GetIconLocation
219 */
220 static HRESULT WINAPI IEIA_Printers_fnGetIconLocation(
221 IExtractIconA * iface,
222 UINT uFlags,
223 LPSTR szIconFile,
224 UINT cchMax,
225 int * piIndex,
226 UINT * pwFlags)
227 {
228 HRESULT ret;
229 LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, cchMax * sizeof(WCHAR));
230 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
231
232 TRACE("(%p) (flags=%u %p %u %p %p)\n", This, uFlags, szIconFile, cchMax, piIndex, pwFlags);
233
234 ret = This->lpVtbl->GetIconLocation(This, uFlags, lpwstrFile, cchMax, piIndex, pwFlags);
235 WideCharToMultiByte(CP_ACP, 0, lpwstrFile, -1, szIconFile, cchMax, NULL, NULL);
236 HeapFree(GetProcessHeap(), 0, lpwstrFile);
237
238 TRACE("-- %s %x\n", szIconFile, *piIndex);
239 return ret;
240 }
241 /**************************************************************************
242 * IExtractIconA_Extract
243 */
244 static HRESULT WINAPI IEIA_Printers_fnExtract(IExtractIconA *iface, LPCSTR pszFile,
245 UINT nIconIndex, HICON *phiconLarge,
246 HICON *phiconSmall, UINT nIconSize)
247 {
248 HRESULT ret;
249 INT len = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0);
250 LPWSTR lpwstrFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
251 _ICOM_THIS_From_IExtractIconA(IExtractIconW, iface);
252
253 TRACE("(%p) (file=%p index=%u %p %p size=%u)\n", This, pszFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
254
255 MultiByteToWideChar(CP_ACP, 0, pszFile, -1, lpwstrFile, len);
256 ret = This->lpVtbl->Extract(This, lpwstrFile, nIconIndex, phiconLarge, phiconSmall, nIconSize);
257 HeapFree(GetProcessHeap(), 0, lpwstrFile);
258 return ret;
259 }
260
261 static struct IExtractIconAVtbl eiavt =
262 {
263 IEIA_Printers_fnQueryInterface,
264 IEIA_Printers_fnAddRef,
265 IEIA_Printers_fnRelease,
266 IEIA_Printers_fnGetIconLocation,
267 IEIA_Printers_fnExtract
268 };
269
270 /**************************************************************************
271 * IExtractIcon_Constructor
272 */
273 static IUnknown *IEI_Printers_Constructor(LPCITEMIDLIST pidl)
274 {
275 IExtractIconWImpl* ei;
276
277 TRACE("%p\n", pidl);
278
279 ei = HeapAlloc(GetProcessHeap(),0,sizeof(IExtractIconWImpl));
280 ei->ref = 1;
281 ei->lpVtbl = &eivt;
282 ei->lpvtblExtractIconA = &eiavt;
283 ei->pidl=ILClone(pidl);
284
285 pdump(pidl);
286
287 TRACE("(%p)\n", ei);
288 return (IUnknown *)ei;
289 }
290
291 /***********************************************************************
292 * Printers folder implementation
293 */
294
295 typedef struct {
296 IShellFolder2Vtbl *lpVtbl;
297 IPersistFolder2Vtbl *lpVtblPersistFolder2;
298
299 LONG ref;
300
301 CLSID *pclsid;
302
303 LPITEMIDLIST pidlRoot; /* absolute pidl */
304
305 int dwAttributes; /* attributes returned by GetAttributesOf FIXME: use it */
306 } IGenericSFImpl;
307
308 #define _IPersistFolder2_Offset ((INT_PTR)(&(((IGenericSFImpl*)0)->lpVtblPersistFolder2)))
309 #define _ICOM_THIS_From_IPersistFolder2(class, name) class* This = (class*)(((char*)name)-_IPersistFolder2_Offset);
310
311 #define _IUnknown_(This) (IShellFolder*)&(This->lpVtbl)
312 #define _IShellFolder_(This) (IShellFolder*)&(This->lpVtbl)
313
314 #define _IPersist_(This) (IPersist*)&(This->lpVtblPersistFolder2)
315 #define _IPersistFolder_(This) (IPersistFolder*)&(This->lpVtblPersistFolder2)
316 #define _IPersistFolder2_(This) (IPersistFolder2*)&(This->lpVtblPersistFolder2)
317
318 /**************************************************************************
319 * ISF_Printers_fnQueryInterface
320 *
321 * NOTE does not support IPersist/IPersistFolder
322 */
323 static HRESULT WINAPI ISF_Printers_fnQueryInterface(
324 IShellFolder2 * iface, REFIID riid, LPVOID * ppvObj)
325 {
326 IGenericSFImpl *This = (IGenericSFImpl *)iface;
327
328 TRACE ("(%p)->(%s,%p)\n", This, shdebugstr_guid (riid), ppvObj);
329
330 *ppvObj = NULL;
331
332 if (IsEqualIID (riid, &IID_IUnknown) ||
333 IsEqualIID (riid, &IID_IShellFolder) ||
334 IsEqualIID (riid, &IID_IShellFolder2))
335 {
336 *ppvObj = This;
337 }
338
339 else if (IsEqualIID (riid, &IID_IPersist) ||
340 IsEqualIID (riid, &IID_IPersistFolder) ||
341 IsEqualIID (riid, &IID_IPersistFolder2))
342 {
343 *ppvObj = _IPersistFolder2_ (This);
344 }
345
346 if (*ppvObj)
347 {
348 IUnknown_AddRef ((IUnknown *) (*ppvObj));
349 TRACE ("-- Interface: (%p)->(%p)\n", ppvObj, *ppvObj);
350 return S_OK;
351 }
352 TRACE ("-- Interface: E_NOINTERFACE\n");
353 return E_NOINTERFACE;
354 }
355
356 static ULONG WINAPI ISF_Printers_fnAddRef (IShellFolder2 * iface)
357 {
358 IGenericSFImpl *This = (IGenericSFImpl *)iface;
359 ULONG refCount = InterlockedIncrement(&This->ref);
360
361 TRACE ("(%p)->(count=%lu)\n", This, refCount - 1);
362
363 return refCount;
364 }
365
366 static ULONG WINAPI ISF_Printers_fnRelease (IShellFolder2 * iface)
367 {
368 IGenericSFImpl *This = (IGenericSFImpl *)iface;
369 ULONG refCount = InterlockedDecrement(&This->ref);
370
371 TRACE ("(%p)->(count=%lu)\n", This, refCount + 1);
372
373 if (!refCount)
374 {
375 TRACE ("-- destroying IShellFolder(%p)\n", This);
376 if (This->pidlRoot)
377 SHFree (This->pidlRoot);
378 LocalFree ((HLOCAL) This);
379 return 0;
380 }
381 return refCount;
382 }
383
384 /**************************************************************************
385 * ISF_Printers_fnParseDisplayName
386 *
387 * This is E_NOTIMPL in Windows too.
388 */
389 static HRESULT WINAPI ISF_Printers_fnParseDisplayName (IShellFolder2 * iface,
390 HWND hwndOwner, LPBC pbc, LPOLESTR lpszDisplayName,
391 DWORD * pchEaten, LPITEMIDLIST * ppidl, DWORD * pdwAttributes)
392 {
393 IGenericSFImpl *This = (IGenericSFImpl *)iface;
394
395 TRACE("(%p)->(HWND=%p,%p,%p=%s,%p,pidl=%p,%p)\n",
396 This, hwndOwner, pbc, lpszDisplayName, debugstr_w(lpszDisplayName),
397 pchEaten, ppidl, pdwAttributes);
398
399 *ppidl = 0;
400 if (pchEaten)
401 *pchEaten = 0;
402
403 return E_NOTIMPL;
404 }
405
406 static LPITEMIDLIST _ILCreatePrinterItem(PRINTER_INFO_4W *pi)
407 {
408 PIDLDATA tmp;
409 LPITEMIDLIST pidl;
410 PIDLPrinterStruct * p;
411 int size0 = (char*)&tmp.u.cprinter.szName-(char*)&tmp.u.cprinter;
412 int size = size0;
413
414 tmp.type = 0x00;
415 tmp.u.cprinter.dummy = 0xFF;
416 if (pi->pPrinterName)
417 tmp.u.cprinter.offsServer = wcslen(pi->pPrinterName) + 1;
418 else
419 tmp.u.cprinter.offsServer = 1;
420
421 size += tmp.u.cprinter.offsServer * sizeof(WCHAR);
422 if (pi->pServerName)
423 size += ( + wcslen(pi->pServerName) + 1) * sizeof(WCHAR);
424 else
425 size += sizeof(WCHAR);
426
427 pidl = (LPITEMIDLIST)SHAlloc(size + 4);
428 if (!pidl)
429 return pidl;
430
431 pidl->mkid.cb = size+2;
432 memcpy(pidl->mkid.abID, &tmp, 2+size0);
433
434 p = &((PIDLDATA*)pidl->mkid.abID)->u.cprinter;
435
436 p->Attributes = pi->Attributes;
437 if (pi->pPrinterName)
438 wcscpy(p->szName, pi->pPrinterName);
439 else
440 p->szName[0] = L'\0';
441
442 if (pi->pServerName)
443 wcscpy(p->szName + p->offsServer, pi->pServerName);
444 else
445 p->szName[p->offsServer] = L'\0';
446
447 *(WORD*)((char*)pidl+(size+2)) = 0;
448 return pidl;
449 }
450
451 static PIDLPrinterStruct * _ILGetPrinterStruct(LPCITEMIDLIST pidl)
452 {
453 LPPIDLDATA pdata = _ILGetDataPointer(pidl);
454
455 if (pdata && pdata->type==0x00)
456 return (PIDLPrinterStruct*)&(pdata->u.cfont);
457
458 return NULL;
459 }
460
461 /**************************************************************************
462 * CreatePrintersEnumList()
463 */
464 static BOOL CreatePrintersEnumList(IEnumIDList *list, DWORD dwFlags)
465 {
466 BOOL ret = TRUE;
467
468 TRACE("(%p)->(flags=0x%08lx) \n",list,dwFlags);
469
470 /* enumerate the folders */
471 if (dwFlags & SHCONTF_NONFOLDERS)
472 {
473 DWORD needed = 0, num = 0, i;
474 PRINTER_INFO_4W *pi;
475
476 EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 4, NULL, 0, &needed, &num);
477 if (!needed)
478 return ret;
479
480 pi = HeapAlloc(GetProcessHeap(), 0, needed);
481 if(!EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 4, (LPBYTE)pi, needed, &needed, &num)) {
482 HeapFree(GetProcessHeap(), 0, pi);
483 return FALSE;
484 }
485
486 for(i = 0; i < num; i++) {
487 LPITEMIDLIST pidl = _ILCreatePrinterItem(&pi[i]);
488 if (pidl)
489 {
490 if (!AddToEnumList(list, pidl))
491 SHFree(pidl);
492 }
493 }
494 HeapFree(GetProcessHeap(), 0, pi);
495 }
496 return ret;
497 }
498
499 /**************************************************************************
500 * ISF_Printers_fnEnumObjects
501 */
502 static HRESULT WINAPI ISF_Printers_fnEnumObjects (IShellFolder2 * iface,
503 HWND hwndOwner, DWORD dwFlags, LPENUMIDLIST * ppEnumIDList)
504 {
505 IGenericSFImpl *This = (IGenericSFImpl *)iface;
506
507 TRACE ("(%p)->(HWND=%p flags=0x%08lx pplist=%p)\n",
508 This, hwndOwner, dwFlags, ppEnumIDList);
509
510 if(!ppEnumIDList) return E_OUTOFMEMORY;
511 *ppEnumIDList = IEnumIDList_Constructor();
512 if (*ppEnumIDList)
513 CreatePrintersEnumList(*ppEnumIDList, dwFlags);
514
515 TRACE ("-- (%p)->(new ID List: %p)\n", This, *ppEnumIDList);
516
517 return (*ppEnumIDList) ? S_OK : E_OUTOFMEMORY;
518 }
519
520 /**************************************************************************
521 * ISF_Printers_fnBindToObject
522 */
523 static HRESULT WINAPI ISF_Printers_fnBindToObject (IShellFolder2 * iface,
524 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
525 {
526 IGenericSFImpl *This = (IGenericSFImpl *)iface;
527
528 TRACE ("(%p)->(pidl=%p,%p,%s,%p)\n", This,
529 pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
530
531 return SHELL32_BindToChild (This->pidlRoot, NULL, pidl, riid, ppvOut);
532 }
533
534 /**************************************************************************
535 * ISF_Printers_fnBindToStorage
536 */
537 static HRESULT WINAPI ISF_Printers_fnBindToStorage (IShellFolder2 * iface,
538 LPCITEMIDLIST pidl, LPBC pbcReserved, REFIID riid, LPVOID * ppvOut)
539 {
540 IGenericSFImpl *This = (IGenericSFImpl *)iface;
541
542 FIXME ("(%p)->(pidl=%p,%p,%s,%p) stub\n",
543 This, pidl, pbcReserved, shdebugstr_guid (riid), ppvOut);
544
545 *ppvOut = NULL;
546 return E_NOTIMPL;
547 }
548
549 /**************************************************************************
550 * ISF_Printers_fnCompareIDs
551 */
552 static HRESULT WINAPI ISF_Printers_fnCompareIDs (IShellFolder2 * iface,
553 LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
554 {
555 IGenericSFImpl *This = (IGenericSFImpl *)iface;
556 int nReturn;
557
558 TRACE ("(%p)->(0x%08lx,pidl1=%p,pidl2=%p)\n", This, lParam, pidl1, pidl2);
559 nReturn = SHELL32_CompareIDs (_IShellFolder_ (This), lParam, pidl1, pidl2);
560 TRACE ("-- %i\n", nReturn);
561 return nReturn;
562 }
563
564 /**************************************************************************
565 * ISF_Printers_fnCreateViewObject
566 */
567 static HRESULT WINAPI ISF_Printers_fnCreateViewObject (IShellFolder2 * iface,
568 HWND hwndOwner, REFIID riid, LPVOID * ppvOut)
569 {
570
571 LPSHELLVIEW pShellView;
572 HRESULT hr = E_INVALIDARG;
573 IGenericSFImpl *This = (IGenericSFImpl *)iface;
574
575 TRACE ("(%p)->(hwnd=%p,%s,%p)\n", This,
576 hwndOwner, shdebugstr_guid (riid), ppvOut);
577
578 if (!ppvOut)
579 return hr;
580
581 *ppvOut = NULL;
582
583 if (IsEqualIID (riid, &IID_IDropTarget))
584 {
585 WARN ("IDropTarget not implemented\n");
586 hr = E_NOTIMPL;
587 }
588 else if (IsEqualIID (riid, &IID_IContextMenu))
589 {
590 WARN ("IContextMenu not implemented\n");
591 hr = E_NOTIMPL;
592 }
593 else if (IsEqualIID (riid, &IID_IShellView))
594 {
595 pShellView = IShellView_Constructor ((IShellFolder *) iface);
596 if (pShellView)
597 {
598 hr = IShellView_QueryInterface (pShellView, riid, ppvOut);
599 IShellView_Release (pShellView);
600 }
601 }
602 TRACE ("-- (%p)->(interface=%p)\n", This, ppvOut);
603 return hr;
604 }
605
606 /**************************************************************************
607 * ISF_Printers_fnGetAttributesOf
608 */
609 static HRESULT WINAPI ISF_Printers_fnGetAttributesOf (IShellFolder2 * iface,
610 UINT cidl, LPCITEMIDLIST * apidl, DWORD * rgfInOut)
611 {
612 IGenericSFImpl *This = (IGenericSFImpl *)iface;
613
614 FIXME ("(%p)->(cidl=%d apidl=%p mask=0x%08lx): stub\n",
615 This, cidl, apidl, *rgfInOut);
616
617 return E_NOTIMPL;
618 }
619
620 /**************************************************************************
621 * ISF_Printers_fnGetUIObjectOf
622 *
623 * PARAMETERS
624 * HWND hwndOwner, //[in ] Parent window for any output
625 * UINT cidl, //[in ] array size
626 * LPCITEMIDLIST* apidl, //[in ] simple pidl array
627 * REFIID riid, //[in ] Requested Interface
628 * UINT* prgfInOut, //[ ] reserved
629 * LPVOID* ppvObject) //[out] Resulting Interface
630 *
631 */
632 static HRESULT WINAPI ISF_Printers_fnGetUIObjectOf (IShellFolder2 * iface,
633 HWND hwndOwner, UINT cidl, LPCITEMIDLIST * apidl,
634 REFIID riid, UINT * prgfInOut, LPVOID * ppvOut)
635 {
636 IGenericSFImpl *This = (IGenericSFImpl *)iface;
637 IUnknown *pObj = NULL;
638 HRESULT hr = E_INVALIDARG;
639
640 TRACE ("(%p)->(%p,%u,apidl=%p,%s,%p,%p)\n",
641 This, hwndOwner, cidl, apidl, shdebugstr_guid (riid), prgfInOut, ppvOut);
642
643 if (!ppvOut)
644 return hr;
645
646 *ppvOut = NULL;
647
648 if ((IsEqualIID (riid, &IID_IExtractIconA) || IsEqualIID(riid, &IID_IExtractIconW)) && (cidl == 1))
649 {
650 IUnknown *pUnk = IEI_Printers_Constructor(apidl[0]);
651 hr = IUnknown_QueryInterface(pUnk, riid, (void**)&pObj);
652 IUnknown_Release(pUnk);
653 }
654 else
655 hr = E_NOINTERFACE;
656
657 if (SUCCEEDED(hr) && !pObj)
658 hr = E_OUTOFMEMORY;
659
660 *ppvOut = pObj;
661 TRACE ("(%p)->hr=0x%08lx\n", This, hr);
662 return hr;
663 }
664
665 /**************************************************************************
666 * ISF_Printers_fnGetDisplayNameOf
667 *
668 */
669 static HRESULT WINAPI ISF_Printers_fnGetDisplayNameOf (IShellFolder2 * iface,
670 LPCITEMIDLIST pidl, DWORD dwFlags, LPSTRRET strRet)
671 {
672 IGenericSFImpl *This = (IGenericSFImpl *)iface;
673 PIDLPrinterStruct * p;
674
675 TRACE ("(%p)->(pidl=%p,0x%08lx,%p)\n", This, pidl, dwFlags, strRet);
676 pdump (pidl);
677
678 if (!strRet)
679 return E_INVALIDARG;
680
681 p = _ILGetPrinterStruct(pidl);
682 if (!p)
683 return E_INVALIDARG;
684
685 strRet->u.pOleStr = SHAlloc(p->offsServer * sizeof(WCHAR));
686 if (!strRet->u.pOleStr)
687 return E_OUTOFMEMORY;
688
689 memcpy((LPVOID)strRet->u.pOleStr, (LPVOID)p->szName, p->offsServer * sizeof(WCHAR));
690 TRACE("ret %s\n", debugstr_w(strRet->u.pOleStr));
691
692 return S_OK;
693 }
694
695 /**************************************************************************
696 * ISF_Printers_fnSetNameOf
697 * Changes the name of a file object or subfolder, possibly changing its item
698 * identifier in the process.
699 *
700 * PARAMETERS
701 * HWND hwndOwner, //[in ] Owner window for output
702 * LPCITEMIDLIST pidl, //[in ] simple pidl of item to change
703 * LPCOLESTR lpszName, //[in ] the items new display name
704 * DWORD dwFlags, //[in ] SHGNO formatting flags
705 * LPITEMIDLIST* ppidlOut) //[out] simple pidl returned
706 */
707 static HRESULT WINAPI ISF_Printers_fnSetNameOf (IShellFolder2 * iface,
708 HWND hwndOwner, LPCITEMIDLIST pidl, /* simple pidl */
709 LPCOLESTR lpName, DWORD dwFlags, LPITEMIDLIST * pPidlOut)
710 {
711 IGenericSFImpl *This = (IGenericSFImpl *)iface;
712
713 FIXME ("(%p)->(%p,pidl=%p,%s,%lu,%p)\n", This, hwndOwner, pidl,
714 debugstr_w (lpName), dwFlags, pPidlOut);
715
716 return E_FAIL;
717 }
718
719 static HRESULT WINAPI ISF_Printers_fnGetDefaultSearchGUID(IShellFolder2 *iface,
720 GUID * pguid)
721 {
722 IGenericSFImpl *This = (IGenericSFImpl *)iface;
723
724 FIXME ("(%p)\n", This);
725 return E_NOTIMPL;
726 }
727
728 static HRESULT WINAPI ISF_Printers_fnEnumSearches (IShellFolder2 *iface,
729 IEnumExtraSearch ** ppenum)
730 {
731 IGenericSFImpl *This = (IGenericSFImpl *)iface;
732 FIXME ("(%p)\n", This);
733 return E_NOTIMPL;
734 }
735
736 static HRESULT WINAPI ISF_Printers_fnGetDefaultColumn (IShellFolder2 * iface,
737 DWORD dwRes, ULONG * pSort, ULONG * pDisplay)
738 {
739 if (pSort)
740 *pSort = 0;
741 if (pDisplay)
742 *pDisplay = 0;
743
744 return S_OK;
745 }
746 static HRESULT WINAPI ISF_Printers_fnGetDefaultColumnState (
747 IShellFolder2 * iface, UINT iColumn, DWORD * pcsFlags)
748 {
749 if (!pcsFlags || iColumn >= PrinterSHELLVIEWCOLUMNS)
750 return E_INVALIDARG;
751 *pcsFlags = PrinterSFHeader[iColumn].pcsFlags;
752 return S_OK;
753
754 }
755
756 static HRESULT WINAPI ISF_Printers_fnGetDetailsEx (IShellFolder2 * iface,
757 LPCITEMIDLIST pidl, const SHCOLUMNID * pscid, VARIANT * pv)
758 {
759 IGenericSFImpl *This = (IGenericSFImpl *)iface;
760 FIXME ("(%p): stub\n", This);
761
762 return E_NOTIMPL;
763 }
764
765 static HRESULT WINAPI ISF_Printers_fnGetDetailsOf (IShellFolder2 * iface,
766 LPCITEMIDLIST pidl, UINT iColumn, SHELLDETAILS * psd)
767 {
768 IGenericSFImpl *This = (IGenericSFImpl *)iface;
769 WCHAR buffer[MAX_PATH] = {0};
770 HRESULT hr = E_FAIL;
771
772 TRACE("(%p)->(%p %i %p): stub\n", This, pidl, iColumn, psd);
773
774 if (iColumn >= PrinterSHELLVIEWCOLUMNS)
775 return E_FAIL;
776
777 psd->fmt = PrinterSFHeader[iColumn].fmt;
778 psd->cxChar = PrinterSFHeader[iColumn].cxChar;
779 if (pidl == NULL)
780 {
781 psd->str.uType = STRRET_WSTR;
782 if (LoadStringW(shell32_hInstance, PrinterSFHeader[iColumn].colnameid, buffer, MAX_PATH))
783 hr = SHStrDupW(buffer, &psd->str.u.pOleStr);
784
785 return hr;
786 }
787
788 if (iColumn == COLUMN_NAME)
789 {
790 psd->str.uType = STRRET_WSTR;
791 return IShellFolder2_GetDisplayNameOf(iface, pidl, SHGDN_NORMAL, &psd->str);
792 }
793
794 psd->str.uType = STRRET_CSTR;
795 psd->str.u.cStr[0] = '\0';
796
797 return E_NOTIMPL;
798 }
799
800 static HRESULT WINAPI ISF_Printers_fnMapColumnToSCID (
801 IShellFolder2 * iface, UINT column, SHCOLUMNID * pscid)
802 {
803 IGenericSFImpl *This = (IGenericSFImpl *)iface;
804 FIXME ("(%p): stub\n", This);
805 return E_NOTIMPL;
806 }
807
808 static IShellFolder2Vtbl vt_ShellFolder2 =
809 {
810 ISF_Printers_fnQueryInterface,
811 ISF_Printers_fnAddRef,
812 ISF_Printers_fnRelease,
813 ISF_Printers_fnParseDisplayName,
814 ISF_Printers_fnEnumObjects,
815 ISF_Printers_fnBindToObject,
816 ISF_Printers_fnBindToStorage,
817 ISF_Printers_fnCompareIDs,
818 ISF_Printers_fnCreateViewObject,
819 ISF_Printers_fnGetAttributesOf,
820 ISF_Printers_fnGetUIObjectOf,
821 ISF_Printers_fnGetDisplayNameOf,
822 ISF_Printers_fnSetNameOf,
823 /* ShellFolder2 */
824 ISF_Printers_fnGetDefaultSearchGUID,
825 ISF_Printers_fnEnumSearches,
826 ISF_Printers_fnGetDefaultColumn,
827 ISF_Printers_fnGetDefaultColumnState,
828 ISF_Printers_fnGetDetailsEx,
829 ISF_Printers_fnGetDetailsOf,
830 ISF_Printers_fnMapColumnToSCID
831 };
832
833 /************************************************************************
834 * IPF_Printers_QueryInterface
835 */
836 static HRESULT WINAPI IPF_Printers_QueryInterface (
837 IPersistFolder2 * iface, REFIID iid, LPVOID * ppvObj)
838 {
839 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
840
841 TRACE ("(%p)\n", This);
842
843 return IUnknown_QueryInterface (_IUnknown_ (This), iid, ppvObj);
844 }
845
846 /************************************************************************
847 * IPF_Printers_AddRef
848 */
849 static ULONG WINAPI IPF_Printers_AddRef (IPersistFolder2 * iface)
850 {
851 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
852
853 TRACE ("(%p)->(count=%lu)\n", This, This->ref);
854
855 return IUnknown_AddRef (_IUnknown_ (This));
856 }
857
858 /************************************************************************
859 * IPF_Printers_Release
860 */
861 static ULONG WINAPI IPF_Printers_Release (IPersistFolder2 * iface)
862 {
863 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
864
865 TRACE ("(%p)->(count=%lu)\n", This, This->ref);
866
867 return IUnknown_Release (_IUnknown_ (This));
868 }
869
870 /************************************************************************
871 * IPF_Printers_GetClassID
872 */
873 static HRESULT WINAPI IPF_Printers_GetClassID (
874 IPersistFolder2 * iface, CLSID * lpClassId)
875 {
876 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
877
878 TRACE ("(%p)\n", This);
879
880 *lpClassId = CLSID_Printers;
881
882 return S_OK;
883 }
884
885 /************************************************************************
886 * IPF_Printers_Initialize
887 *
888 */
889 static HRESULT WINAPI IPF_Printers_Initialize (
890 IPersistFolder2 * iface, LPCITEMIDLIST pidl)
891 {
892 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
893 if (This->pidlRoot)
894 SHFree((LPVOID)This->pidlRoot);
895
896 This->pidlRoot = ILClone(pidl);
897 return S_OK;
898 }
899
900 /**************************************************************************
901 * IPF_Printers_fnGetCurFolder
902 */
903 static HRESULT WINAPI IPF_Printers_GetCurFolder (
904 IPersistFolder2 * iface, LPITEMIDLIST * pidl)
905 {
906 _ICOM_THIS_From_IPersistFolder2 (IGenericSFImpl, iface);
907
908 TRACE ("(%p)->(%p)\n", This, pidl);
909
910 *pidl = ILClone (This->pidlRoot);
911 return S_OK;
912 }
913
914 static IPersistFolder2Vtbl vt_PersistFolder2 =
915 {
916 IPF_Printers_QueryInterface,
917 IPF_Printers_AddRef,
918 IPF_Printers_Release,
919 IPF_Printers_GetClassID,
920 IPF_Printers_Initialize,
921 IPF_Printers_GetCurFolder
922 };
923
924 /**************************************************************************
925 * ISF_Printers_Constructor
926 */
927 HRESULT WINAPI ISF_Printers_Constructor (
928 IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
929 {
930 IGenericSFImpl *sf;
931 HRESULT hr;
932
933 TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
934
935 if (pUnkOuter)
936 return CLASS_E_NOAGGREGATION;
937
938 sf = HeapAlloc( GetProcessHeap(), 0, sizeof(*sf) );
939 if (!sf)
940 return E_OUTOFMEMORY;
941
942 sf->ref = 1;
943 sf->lpVtbl = &vt_ShellFolder2;
944 sf->lpVtblPersistFolder2 = &vt_PersistFolder2;
945
946 sf->pidlRoot = _ILCreatePrinters(); /* my qualified pidl */
947
948 hr = IUnknown_QueryInterface( _IUnknown_(sf), riid, ppv );
949 IUnknown_Release( _IUnknown_(sf) );
950
951 TRACE ("--(%p)\n", *ppv);
952 return hr;
953 }