source: trunk/src/shell32/shellord.c@ 7788

Last change on this file since 7788 was 7502, checked in by phaller, 24 years ago

Fixed out-of-scope FIXME,TRACE,WARN macros

File size: 41.5 KB
Line 
1/*
2 * The parameters of many functions changes between different OS versions
3 * (NT uses Unicode strings, 95 uses ASCII strings)
4 *
5 * Copyright 1997 Marcus Meissner
6 * 1998 Jürgen Schmied
7 */
8
9/****************************************************************************
10 * includes
11 ****************************************************************************/
12
13#include <odin.h>
14#include <os2sel.h>
15#include <odinwrap.h>
16
17ODINDEBUGCHANNEL(SHELL32-SHELLORD)
18
19
20#include <string.h>
21#include <stdio.h>
22#include "winerror.h"
23#include "winreg.h"
24#include "debugtools.h"
25#include "winnls.h"
26
27#ifdef __WIN32OS2__
28#include "heapstring.h"
29#else
30#include "heap.h"
31#endif
32
33#include "shlwapi.h"
34#include "shellapi.h"
35#include "shlguid.h"
36#include "shlobj.h"
37#include "shell32_main.h"
38#ifdef __WIN32OS2__
39#include "wine\undocshell.h"
40#else
41#include "undocshell.h"
42#endif
43
44DEFAULT_DEBUG_CHANNEL(shell);
45
46/*************************************************************************
47 * ParseFieldA [internal]
48 *
49 * copys a field from a ',' delimited string
50 *
51 * first field is nField = 1
52 */
53DWORD WINAPI ParseFieldA(
54 LPCSTR src,
55 DWORD nField,
56 LPSTR dst,
57 DWORD len)
58{
59 WARN("('%s',0x%08lx,%p,%ld) semi-stub.\n",src,nField,dst,len);
60
61 if (!src || !src[0] || !dst || !len)
62 return 0;
63
64 /* skip n fields delimited by ',' */
65 while (nField > 1)
66 {
67 if (*src=='\0') return FALSE;
68 if (*(src++)==',') nField--;
69 }
70
71 /* copy part till the next ',' to dst */
72 while ( *src!='\0' && *src!=',' && (len--)>0 ) *(dst++)=*(src++);
73
74 /* finalize the string */
75 *dst=0x0;
76
77 return TRUE;
78}
79
80/*************************************************************************
81 * ParseFieldW [internal]
82 *
83 * copys a field from a ',' delimited string
84 *
85 * first field is nField = 1
86 */
87DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len)
88{
89 FIXME("(%s,0x%08lx,%p,%ld) stub\n",
90 debugstr_w(src), nField, dst, len);
91 return FALSE;
92}
93
94/*************************************************************************
95 * ParseField [SHELL32.58]
96 */
97DWORD WINAPI ParseFieldAW(LPCVOID src, DWORD nField, LPVOID dst, DWORD len)
98{
99 if (SHELL_OsIsUnicode())
100 return ParseFieldW(src, nField, dst, len);
101 return ParseFieldA(src, nField, dst, len);
102}
103
104/*************************************************************************
105 * GetFileNameFromBrowse [SHELL32.63]
106 *
107 */
108ODINFUNCTION7(BOOL, GetFileNameFromBrowse,
109 HWND, hwndOwner,
110 LPSTR, lpstrFile,
111 DWORD, nMaxFile,
112 LPCSTR, lpstrInitialDir,
113 LPCSTR, lpstrDefExt,
114 LPCSTR, lpstrFilter,
115 LPCSTR, lpstrTitle)
116{
117 FIXME("(%04x,%s,%ld,%s,%s,%s,%s):stub.\n",
118 hwndOwner, lpstrFile, nMaxFile, lpstrInitialDir, lpstrDefExt,
119 lpstrFilter, lpstrTitle);
120
121 /* puts up a Open Dialog and requests input into targetbuf */
122 /* OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_FILEMUSTEXIST|OFN_unknown */
123 strcpy(lpstrFile,"x:\\dummy.exe");
124 return 1;
125}
126
127/*************************************************************************
128 * SHGetSetSettings [SHELL32.68]
129 */
130VOID WINAPI SHGetSetSettings(DWORD x, DWORD y, DWORD z)
131{
132 FIXME("0x%08lx 0x%08lx 0x%08lx\n", x, y, z);
133}
134
135/*************************************************************************
136 * SHGetSettings [SHELL32.@]
137 *
138 * NOTES
139 * the registry path are for win98 (tested)
140 * and possibly are the same in nt40
141 *
142 */
143VOID WINAPI SHGetSettings(LPSHELLFLAGSTATE lpsfs, DWORD dwMask)
144{
145 HKEY hKey;
146 DWORD dwData;
147 DWORD dwDataSize = sizeof (DWORD);
148
149 TRACE("(%p 0x%08lx)\n",lpsfs,dwMask);
150
151 if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
152 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
153 return;
154
155 if ( (SSF_SHOWEXTENSIONS & dwMask) && !RegQueryValueExA(hKey, "HideFileExt", 0, 0, (LPBYTE)&dwData, &dwDataSize))
156 lpsfs->fShowExtensions = ((dwData == 0) ? 0 : 1);
157
158 if ( (SSF_SHOWINFOTIP & dwMask) && !RegQueryValueExA(hKey, "ShowInfoTip", 0, 0, (LPBYTE)&dwData, &dwDataSize))
159 lpsfs->fShowInfoTip = ((dwData == 0) ? 0 : 1);
160
161 if ( (SSF_DONTPRETTYPATH & dwMask) && !RegQueryValueExA(hKey, "DontPrettyPath", 0, 0, (LPBYTE)&dwData, &dwDataSize))
162 lpsfs->fDontPrettyPath = ((dwData == 0) ? 0 : 1);
163
164 if ( (SSF_HIDEICONS & dwMask) && !RegQueryValueExA(hKey, "HideIcons", 0, 0, (LPBYTE)&dwData, &dwDataSize))
165 lpsfs->fHideIcons = ((dwData == 0) ? 0 : 1);
166
167 if ( (SSF_MAPNETDRVBUTTON & dwMask) && !RegQueryValueExA(hKey, "MapNetDrvBtn", 0, 0, (LPBYTE)&dwData, &dwDataSize))
168 lpsfs->fMapNetDrvBtn = ((dwData == 0) ? 0 : 1);
169
170 if ( (SSF_SHOWATTRIBCOL & dwMask) && !RegQueryValueExA(hKey, "ShowAttribCol", 0, 0, (LPBYTE)&dwData, &dwDataSize))
171 lpsfs->fShowAttribCol = ((dwData == 0) ? 0 : 1);
172
173 if (((SSF_SHOWALLOBJECTS | SSF_SHOWSYSFILES) & dwMask) && !RegQueryValueExA(hKey, "Hidden", 0, 0, (LPBYTE)&dwData, &dwDataSize))
174 { if (dwData == 0)
175 { if (SSF_SHOWALLOBJECTS & dwMask) lpsfs->fShowAllObjects = 0;
176 if (SSF_SHOWSYSFILES & dwMask) lpsfs->fShowSysFiles = 0;
177 }
178 else if (dwData == 1)
179 { if (SSF_SHOWALLOBJECTS & dwMask) lpsfs->fShowAllObjects = 1;
180 if (SSF_SHOWSYSFILES & dwMask) lpsfs->fShowSysFiles = 0;
181 }
182 else if (dwData == 2)
183 { if (SSF_SHOWALLOBJECTS & dwMask) lpsfs->fShowAllObjects = 0;
184 if (SSF_SHOWSYSFILES & dwMask) lpsfs->fShowSysFiles = 1;
185 }
186 }
187 RegCloseKey (hKey);
188
189 TRACE("-- 0x%04x\n", *(WORD*)lpsfs);
190}
191
192/*************************************************************************
193 * SHShellFolderView_Message [SHELL32.73]
194 *
195 * PARAMETERS
196 * hwndCabinet defines the explorer cabinet window that contains the
197 * shellview you need to communicate with
198 * uMsg identifying the SFVM enum to perform
199 * lParam
200 *
201 * NOTES
202 * Message SFVM_REARRANGE = 1
203 * This message gets sent when a column gets clicked to instruct the
204 * shell view to re-sort the item list. lParam identifies the column
205 * that was clicked.
206 */
207int WINAPI SHShellFolderView_Message(
208 HWND hwndCabinet,
209 DWORD dwMessage,
210 DWORD dwParam)
211{
212 FIXME("%04x %08lx %08lx stub\n",hwndCabinet, dwMessage, dwParam);
213 return 0;
214}
215
216/*************************************************************************
217 * RegisterShellHook [SHELL32.181]
218 *
219 * PARAMS
220 * hwnd [I] window handle
221 * y [I] flag ????
222 *
223 * NOTES
224 * exported by ordinal
225 */
226BOOL WINAPI RegisterShellHook(
227 HWND hWnd,
228 DWORD dwType)
229{
230 FIXME("(0x%08x,0x%08lx):stub.\n",hWnd, dwType);
231 return TRUE;
232}
233/*************************************************************************
234 * ShellMessageBoxW [SHELL32.182]
235 *
236 * Format and output errormessage.
237 *
238 * idText resource ID of title or LPSTR
239 * idTitle resource ID of title or LPSTR
240 *
241 * NOTES
242 * exported by ordinal
243 */
244int WINAPIV ShellMessageBoxW(
245 HINSTANCE hInstance,
246 HWND hWnd,
247 LPCWSTR lpText,
248 LPCWSTR lpCaption,
249 UINT uType,
250 ...)
251{
252 WCHAR szText[100],szTitle[100];
253 LPCWSTR pszText = szText, pszTitle = szTitle, pszTemp;
254 va_list args;
255 int ret;
256
257 va_start(args, uType);
258 /* wvsprintfA(buf,fmt, args); */
259
260 TRACE("(%08lx,%08lx,%p,%p,%08x)\n",
261 (DWORD)hInstance,(DWORD)hWnd,lpText,lpCaption,uType);
262
263 if (!HIWORD(lpCaption))
264 LoadStringW(hInstance, (DWORD)lpCaption, szTitle, sizeof(szTitle)/sizeof(szTitle[0]));
265 else
266 pszTitle = lpCaption;
267
268 if (!HIWORD(lpText))
269 LoadStringW(hInstance, (DWORD)lpText, szText, sizeof(szText)/sizeof(szText[0]));
270 else
271 pszText = lpText;
272
273 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
274 pszText, 0, 0, (LPWSTR)&pszTemp, 0, &args);
275
276 va_end(args);
277
278 ret = MessageBoxW(hWnd,pszTemp,pszTitle,uType);
279 LocalFree((HLOCAL)pszTemp);
280 return ret;
281}
282
283/*************************************************************************
284 * ShellMessageBoxA [SHELL32.183]
285 */
286int WINAPIV ShellMessageBoxA(
287 HINSTANCE hInstance,
288 HWND hWnd,
289 LPCSTR lpText,
290 LPCSTR lpCaption,
291 UINT uType,
292 ...)
293{
294 char szText[100],szTitle[100];
295 LPCSTR pszText = szText, pszTitle = szTitle, pszTemp;
296 va_list args;
297 int ret;
298
299 va_start(args, uType);
300 /* wvsprintfA(buf,fmt, args); */
301
302 TRACE("(%08lx,%08lx,%p,%p,%08x)\n",
303 (DWORD)hInstance,(DWORD)hWnd,lpText,lpCaption,uType);
304
305 if (!HIWORD(lpCaption))
306 LoadStringA(hInstance, (DWORD)lpCaption, szTitle, sizeof(szTitle));
307 else
308 pszTitle = lpCaption;
309
310 if (!HIWORD(lpText))
311 LoadStringA(hInstance, (DWORD)lpText, szText, sizeof(szText));
312 else
313 pszText = lpText;
314
315 FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
316 pszText, 0, 0, (LPSTR)&pszTemp, 0, &args);
317
318 va_end(args);
319
320 ret = MessageBoxA(hWnd,pszTemp,pszTitle,uType);
321 LocalFree((HLOCAL)pszTemp);
322 return ret;
323}
324
325/*************************************************************************
326 * SHFree [SHELL32.195]
327 *
328 * NOTES
329 * free_ptr() - frees memory using IMalloc
330 * exported by ordinal
331 */
332#define MEM_DEBUG 0
333
334ODINPROCEDURE1(SHFree,
335 LPVOID, x)
336{
337#if MEM_DEBUG
338 WORD len = *(LPWORD)((LPBYTE)x-2);
339
340 if ( *(LPWORD)((LPBYTE)x+len) != 0x7384)
341 ERR("MAGIC2!\n");
342
343 if ( (*(LPWORD)((LPBYTE)x-4)) != 0x8271)
344 ERR("MAGIC1!\n");
345 else
346 memset((LPBYTE)x-4, 0xde, len+6);
347
348 TRACE("%p len=%u\n",x, len);
349
350 x = (LPBYTE) x - 4;
351#else
352 TRACE("%p\n",x);
353#endif
354
355#if __WIN32OS2_
356 HEAP_free(x);
357#else
358 HeapFree(GetProcessHeap(), 0, x);
359#endif
360}
361
362/*************************************************************************
363 * SHAlloc [SHELL32.196]
364 *
365 * NOTES
366 * void *task_alloc(DWORD len), uses SHMalloc allocator
367 * exported by ordinal
368 */
369ODINFUNCTION1(LPVOID, SHAlloc,
370 DWORD, len)
371{
372 LPBYTE ret;
373
374#ifdef __WIN32OS2__
375#if MEM_DEBUG
376 ret = (LPVOID) HEAP_malloc(len+6);
377#else
378 ret = (LPVOID) HEAP_malloc(len);
379#endif
380#else
381#if MEM_DEBUG
382 ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len+6);
383#else
384 ret = (LPVOID) HeapAlloc(GetProcessHeap(),0,len);
385#endif
386#endif
387
388#if MEM_DEBUG
389 *(LPWORD)(ret) = 0x8271;
390 *(LPWORD)(ret+2) = (WORD)len;
391 *(LPWORD)(ret+4+len) = 0x7384;
392 ret += 4;
393 memset(ret, 0xdf, len);
394#endif
395 TRACE("%lu bytes at %p\n",len, ret);
396 return (LPVOID)ret;
397}
398
399/*************************************************************************
400 * SHRegisterDragDrop [SHELL32.86]
401 *
402 * NOTES
403 * exported by ordinal
404 */
405HRESULT WINAPI SHRegisterDragDrop(
406 HWND hWnd,
407 LPDROPTARGET pDropTarget)
408{
409 FIXME("(0x%08x,%p):stub.\n", hWnd, pDropTarget);
410 if (GetShellOle()) return pRegisterDragDrop(hWnd, pDropTarget);
411 return 0;
412}
413
414/*************************************************************************
415 * SHRevokeDragDrop [SHELL32.87]
416 *
417 * NOTES
418 * exported by ordinal
419 */
420HRESULT WINAPI SHRevokeDragDrop(HWND hWnd)
421{
422 FIXME("(0x%08x):stub.\n",hWnd);
423 return 0;
424}
425
426/*************************************************************************
427 * SHDoDragDrop [SHELL32.88]
428 *
429 * NOTES
430 * exported by ordinal
431 */
432HRESULT WINAPI SHDoDragDrop(
433 HWND hWnd,
434 LPDATAOBJECT lpDataObject,
435 LPDROPSOURCE lpDropSource,
436 DWORD dwOKEffect,
437 LPDWORD pdwEffect)
438{
439 FIXME("(0x%04x %p %p 0x%08lx %p):stub.\n",
440 hWnd, lpDataObject, lpDropSource, dwOKEffect, pdwEffect);
441 return 0;
442}
443
444/*************************************************************************
445 * ArrangeWindows [SHELL32.184]
446 *
447 */
448WORD WINAPI ArrangeWindows(
449 HWND hwndParent,
450 DWORD dwReserved,
451 LPCRECT lpRect,
452 WORD cKids,
453 CONST HWND * lpKids)
454{
455 FIXME("(0x%08x 0x%08lx %p 0x%04x %p):stub.\n",
456 hwndParent, dwReserved, lpRect, cKids, lpKids);
457 return 0;
458}
459
460/*************************************************************************
461 * SignalFileOpen [SHELL32.103]
462 *
463 * NOTES
464 * exported by ordinal
465 */
466DWORD WINAPI
467SignalFileOpen (DWORD dwParam1)
468{
469 FIXME("(0x%08lx):stub.\n", dwParam1);
470
471 return 0;
472}
473
474/*************************************************************************
475 * SHADD_get_policy - helper function for SHAddToRecentDocs
476 *
477 * PARAMETERS
478 * policy [IN] policy name (null termed string) to find
479 * type [OUT] ptr to DWORD to receive type
480 * buffer [OUT] ptr to area to hold data retrieved
481 * len [IN/OUT] ptr to DWORD holding size of buffer and getting
482 * length filled
483 *
484 * RETURNS
485 * result of the SHQueryValueEx call
486 */
487static INT SHADD_get_policy(LPSTR policy, LPDWORD type, LPVOID buffer, LPDWORD len)
488{
489 HKEY Policy_basekey;
490 INT ret;
491
492 /* Get the key for the policies location in the registry
493 */
494 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
495 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
496 0, KEY_READ, &Policy_basekey)) {
497
498 if (RegOpenKeyExA(HKEY_CURRENT_USER,
499 "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
500 0, KEY_READ, &Policy_basekey)) {
501 TRACE("No Explorer Policies location exists. Policy wanted=%s\n",
502 policy);
503 *len = 0;
504 return ERROR_FILE_NOT_FOUND;
505 }
506 }
507
508 /* Retrieve the data if it exists
509 */
510 ret = SHQueryValueExA(Policy_basekey, policy, 0, type, buffer, len);
511 RegCloseKey(Policy_basekey);
512 return ret;
513}
514
515
516/*************************************************************************
517 * SHADD_compare_mru - helper function for SHAddToRecentDocs
518 *
519 * PARAMETERS
520 * data1 [IN] data being looked for
521 * data2 [IN] data in MRU
522 * cbdata [IN] length from FindMRUData call (not used)
523 *
524 * RETURNS
525 * position within MRU list that data was added.
526 */
527static INT CALLBACK SHADD_compare_mru(LPCVOID data1, LPCVOID data2, DWORD cbData)
528{
529 return lstrcmpiA(data1, data2);
530}
531
532/*************************************************************************
533 * SHADD_create_add_mru_data - helper function for SHAddToRecentDocs
534 *
535 * PARAMETERS
536 * mruhandle [IN] handle for created MRU list
537 * doc_name [IN] null termed pure doc name
538 * new_lnk_name [IN] null termed path and file name for .lnk file
539 * buffer [IN/OUT] 2048 byte area to consturct MRU data
540 * len [OUT] ptr to int to receive space used in buffer
541 *
542 * RETURNS
543 * position within MRU list that data was added.
544 */
545static INT SHADD_create_add_mru_data(HANDLE mruhandle, LPSTR doc_name, LPSTR new_lnk_name,
546 LPSTR buffer, INT *len)
547{
548 LPSTR ptr;
549 INT wlen;
550
551 /*FIXME: Document:
552 * RecentDocs MRU data structure seems to be:
553 * +0h document file name w/ terminating 0h
554 * +nh short int w/ size of remaining
555 * +n+2h 02h 30h, or 01h 30h, or 00h 30h - unknown
556 * +n+4h 10 bytes zeros - unknown
557 * +n+eh shortcut file name w/ terminating 0h
558 * +n+e+nh 3 zero bytes - unknown
559 */
560
561 /* Create the MRU data structure for "RecentDocs"
562 */
563 ptr = buffer;
564 lstrcpyA(ptr, doc_name);
565 ptr += (lstrlenA(buffer) + 1);
566 wlen= lstrlenA(new_lnk_name) + 1 + 12;
567 *((short int*)ptr) = wlen;
568 ptr += 2; /* step past the length */
569 *(ptr++) = 0x30; /* unknown reason */
570 *(ptr++) = 0; /* unknown, but can be 0x00, 0x01, 0x02 */
571 memset(ptr, 0, 10);
572 ptr += 10;
573 lstrcpyA(ptr, new_lnk_name);
574 ptr += (lstrlenA(new_lnk_name) + 1);
575 memset(ptr, 0, 3);
576 ptr += 3;
577 *len = ptr - buffer;
578
579 /* Add the new entry into the MRU list
580 */
581 return pAddMRUData(mruhandle, (LPCVOID)buffer, *len);
582}
583
584/*************************************************************************
585 * SHAddToRecentDocs [SHELL32.@]
586 *
587 * PARAMETERS
588 * uFlags [IN] SHARD_PATH or SHARD_PIDL
589 * pv [IN] string or pidl, NULL clears the list
590 *
591 * NOTES
592 * exported by name
593 *
594 * FIXME: ?? MSDN shows this as a VOID
595 */
596DWORD WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
597{
598
599#ifndef __WIN32OS2__
600/* FIXME: !!! move CREATEMRULIST and flags to header file !!! */
601/* !!! it is in both here and comctl32undoc.c !!! */
602typedef struct tagCREATEMRULIST
603{
604 DWORD cbSize; /* size of struct */
605 DWORD nMaxItems; /* max no. of items in list */
606 DWORD dwFlags; /* see below */
607 HKEY hKey; /* root reg. key under which list is saved */
608 LPCSTR lpszSubKey; /* reg. subkey */
609 PROC lpfnCompare; /* item compare proc */
610} CREATEMRULIST, *LPCREATEMRULIST;
611
612/* dwFlags */
613#define MRUF_STRING_LIST 0 /* list will contain strings */
614#define MRUF_BINARY_LIST 1 /* list will contain binary data */
615#define MRUF_DELAYED_SAVE 2 /* only save list order to reg. is FreeMRUList */
616
617/* If list is a string list lpfnCompare has the following prototype
618 * int CALLBACK MRUCompareString(LPCSTR s1, LPCSTR s2)
619 * for binary lists the prototype is
620 * int CALLBACK MRUCompareBinary(LPCVOID data1, LPCVOID data2, DWORD cbData)
621 * where cbData is the no. of bytes to compare.
622 * Need to check what return value means identical - 0?
623 */
624#endif
625
626 UINT olderrormode;
627 HKEY HCUbasekey;
628 CHAR doc_name[MAX_PATH];
629 CHAR link_dir[MAX_PATH];
630 CHAR new_lnk_filepath[MAX_PATH];
631 CHAR new_lnk_name[MAX_PATH];
632 IMalloc *ppM;
633 LPITEMIDLIST pidl;
634 HWND hwnd = 0; /* FIXME: get real window handle */
635 INT ret;
636 DWORD data[64], datalen, type;
637
638 /*FIXME: Document:
639 * RecentDocs MRU data structure seems to be:
640 * +0h document file name w/ terminating 0h
641 * +nh short int w/ size of remaining
642 * +n+2h 02h 30h, or 01h 30h, or 00h 30h - unknown
643 * +n+4h 10 bytes zeros - unknown
644 * +n+eh shortcut file name w/ terminating 0h
645 * +n+e+nh 3 zero bytes - unknown
646 */
647
648 /* See if we need to do anything.
649 */
650 datalen = 64;
651 ret=SHADD_get_policy( "NoRecentDocsHistory", &type, &data, &datalen);
652 if ((ret > 0) && (ret != ERROR_FILE_NOT_FOUND)) {
653 ERR("Error %d getting policy \"NoRecentDocsHistory\"\n", ret);
654 return 0;
655 }
656 if (ret == ERROR_SUCCESS) {
657 if (!( (type == REG_DWORD) ||
658 ((type == REG_BINARY) && (datalen == 4)) )) {
659 ERR("Error policy data for \"NoRecentDocsHistory\" not formated correctly, type=%ld, len=%ld\n",
660 type, datalen);
661 return 0;
662 }
663
664 TRACE("policy value for NoRecentDocsHistory = %08lx\n", data[0]);
665 /* now test the actual policy value */
666 if ( data[0] != 0)
667 return 0;
668 }
669
670 /* Open key to where the necessary info is
671 */
672 /* FIXME: This should be done during DLL PROCESS_ATTACH (or THREAD_ATTACH)
673 * and the close should be done during the _DETACH. The resulting
674 * key is stored in the DLL global data.
675 */
676 if (RegCreateKeyExA(HKEY_CURRENT_USER,
677 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
678 0, 0, 0, KEY_READ, 0, &HCUbasekey ,0)) {
679 ERR("Failed to create 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer'\n");
680 return 0;
681 }
682
683 /* Get path to user's "Recent" directory
684 */
685 if(SUCCEEDED(SHGetMalloc(&ppM))) {
686 if (SUCCEEDED(SHGetSpecialFolderLocation(hwnd, CSIDL_RECENT,
687 &pidl))) {
688 SHGetPathFromIDListA(pidl, link_dir);
689 IMalloc_Free(ppM, pidl);
690 }
691 else {
692 /* serious issues */
693 link_dir[0] = 0;
694 ERR("serious issues 1\n");
695 }
696 IMalloc_Release(ppM);
697 }
698 else {
699 /* serious issues */
700 link_dir[0] = 0;
701 ERR("serious issues 2\n");
702 }
703 TRACE("Users Recent dir %s\n", link_dir);
704
705 /* If no input, then go clear the lists */
706 if (!pv) {
707 /* clear user's Recent dir
708 */
709
710 /* FIXME: delete all files in "link_dir"
711 *
712 * while( more files ) {
713 * lstrcpyA(old_lnk_name, link_dir);
714 * PathAppendA(old_lnk_name, filenam);
715 * DeleteFileA(old_lnk_name);
716 * }
717 */
718 FIXME("should delete all files in %s\\ \n", link_dir);
719
720 /* clear MRU list
721 */
722 /* MS Bug ?? v4.72.3612.1700 of shell32 does the delete against
723 * HKEY_LOCAL_MACHINE version of ...CurrentVersion\Explorer
724 * and naturally it fails w/ rc=2. It should do it against
725 * HKEY_CURRENT_USER which is where it is stored, and where
726 * the MRU routines expect it!!!!
727 */
728 RegDeleteKeyA(HCUbasekey, "RecentDocs");
729 RegCloseKey(HCUbasekey);
730 return 0;
731 }
732
733 /* Have data to add, the jobs to be done:
734 * 1. Add document to MRU list in registry "HKCU\Software\
735 * Microsoft\Windows\CurrentVersion\Explorer\RecentDocs".
736 * 2. Add shortcut to document in the user's Recent directory
737 * (CSIDL_RECENT).
738 * 3. Add shortcut to Start menu's Documents submenu.
739 */
740
741 /* Get the pure document name from the input
742 */
743 if (uFlags & SHARD_PIDL) {
744 SHGetPathFromIDListA((LPCITEMIDLIST) pv, doc_name);
745 }
746 else {
747 lstrcpyA(doc_name, (LPSTR) pv);
748 }
749 TRACE("full document name %s\n", doc_name);
750 PathStripPathA(doc_name);;
751 TRACE("stripped document name %s\n", doc_name);
752
753
754 /* *** JOB 1: Update registry for ...\Explorer\RecentDocs list *** */
755
756 { /* on input needs:
757 * doc_name - pure file-spec, no path
758 * link_dir - path to the user's Recent directory
759 * HCUbasekey - key of ...Windows\CurrentVersion\Explorer" node
760 * creates:
761 * new_lnk_name- pure file-spec, no path for new .lnk file
762 * new_lnk_filepath
763 * - path and file name of new .lnk file
764 */
765 CREATEMRULIST mymru;
766 HANDLE mruhandle;
767 INT len, pos, bufused, err;
768 INT i;
769 DWORD attr;
770 CHAR buffer[2048];
771 CHAR *ptr;
772 CHAR old_lnk_name[MAX_PATH];
773 short int slen;
774
775 mymru.cbSize = sizeof(CREATEMRULIST);
776 mymru.nMaxItems = 15;
777 mymru.dwFlags = MRUF_BINARY_LIST | MRUF_DELAYED_SAVE;
778 mymru.hKey = HCUbasekey;
779 mymru.lpszSubKey = "RecentDocs";
780 mymru.lpfnCompare = &SHADD_compare_mru;
781 mruhandle = pCreateMRUListA(&mymru);
782 if (!mruhandle) {
783 /* MRU failed */
784 ERR("MRU processing failed, handle zero\n");
785 RegCloseKey(HCUbasekey);
786 return 0;
787 }
788 len = lstrlenA(doc_name);
789 pos = pFindMRUData(mruhandle, doc_name, len, 0);
790
791 /* Now get the MRU entry that will be replaced
792 * and delete the .lnk file for it
793 */
794 if ((bufused = pEnumMRUListA(mruhandle, (pos == -1) ? 14 : pos,
795 buffer, 2048)) != -1) {
796 ptr = buffer;
797 ptr += (lstrlenA(buffer) + 1);
798 slen = *((short int*)ptr);
799 ptr += 2; /* skip the length area */
800 if (bufused >= slen + (ptr-buffer)) {
801 /* buffer size looks good */
802 ptr += 12; /* get to string */
803 len = bufused - (ptr-buffer); /* get length of buf remaining */
804 if ((lstrlenA(ptr) > 0) && (lstrlenA(ptr) <= len-1)) {
805 /* appears to be good string */
806 lstrcpyA(old_lnk_name, link_dir);
807 PathAppendA(old_lnk_name, ptr);
808 if (!DeleteFileA(old_lnk_name)) {
809 if ((attr = GetFileAttributesA(old_lnk_name)) == -1) {
810 if ((err = GetLastError()) != ERROR_FILE_NOT_FOUND) {
811 ERR("Delete for %s failed, err=%d, attr=%08lx\n",
812 old_lnk_name, err, attr);
813 }
814 else {
815 TRACE("old .lnk file %s did not exist\n",
816 old_lnk_name);
817 }
818 }
819 else {
820 ERR("Delete for %s failed, attr=%08lx\n",
821 old_lnk_name, attr);
822 }
823 }
824 else {
825 TRACE("deleted old .lnk file %s\n", old_lnk_name);
826 }
827 }
828 }
829 }
830
831 /* Create usable .lnk file name for the "Recent" directory
832 */
833 wsprintfA(new_lnk_name, "%s.lnk", doc_name);
834 lstrcpyA(new_lnk_filepath, link_dir);
835 PathAppendA(new_lnk_filepath, new_lnk_name);
836 i = 1;
837 olderrormode = SetErrorMode(SEM_FAILCRITICALERRORS);
838 while (GetFileAttributesA(new_lnk_filepath) != -1) {
839 i++;
840 wsprintfA(new_lnk_name, "%s (%u).lnk", doc_name, i);
841 lstrcpyA(new_lnk_filepath, link_dir);
842 PathAppendA(new_lnk_filepath, new_lnk_name);
843 }
844 SetErrorMode(olderrormode);
845 TRACE("new shortcut will be %s\n", new_lnk_filepath);
846
847 /* Now add the new MRU entry and data
848 */
849 pos = SHADD_create_add_mru_data(mruhandle, doc_name, new_lnk_name,
850 buffer, &len);
851 pFreeMRUListA(mruhandle);
852 TRACE("Updated MRU list, new doc is position %d\n", pos);
853 }
854
855 /* *** JOB 2: Create shortcut in user's "Recent" directory *** */
856
857 { /* on input needs:
858 * doc_name - pure file-spec, no path
859 * new_lnk_filepath
860 * - path and file name of new .lnk file
861 * uFlags[in] - flags on call to SHAddToRecentDocs
862 * pv[in] - document path/pidl on call to SHAddToRecentDocs
863 */
864 IShellLinkA *psl = NULL;
865 IPersistFile *pPf = NULL;
866 HRESULT hres;
867 CHAR desc[MAX_PATH];
868 WCHAR widelink[MAX_PATH];
869
870 CoInitialize(0);
871
872 hres = CoCreateInstance( &CLSID_ShellLink,
873 NULL,
874 CLSCTX_INPROC_SERVER,
875 &IID_IShellLinkA,
876 (LPVOID )&psl);
877 if(SUCCEEDED(hres)) {
878
879 hres = IShellLinkA_QueryInterface(psl, &IID_IPersistFile,
880 (LPVOID *)&pPf);
881 if(FAILED(hres)) {
882 /* bombed */
883 ERR("failed QueryInterface for IPersistFile %08lx\n", hres);
884 goto fail;
885 }
886
887 /* Set the document path or pidl */
888 if (uFlags & SHARD_PIDL) {
889 hres = IShellLinkA_SetIDList(psl, (LPCITEMIDLIST) pv);
890 } else {
891 hres = IShellLinkA_SetPath(psl, (LPCSTR) pv);
892 }
893 if(FAILED(hres)) {
894 /* bombed */
895 ERR("failed Set{IDList|Path} %08lx\n", hres);
896 goto fail;
897 }
898
899 lstrcpyA(desc, "Shortcut to ");
900 lstrcatA(desc, doc_name);
901 hres = IShellLinkA_SetDescription(psl, desc);
902 if(FAILED(hres)) {
903 /* bombed */
904 ERR("failed SetDescription %08lx\n", hres);
905 goto fail;
906 }
907
908 MultiByteToWideChar(CP_ACP, 0, new_lnk_filepath, -1,
909 widelink, MAX_PATH);
910 /* create the short cut */
911 hres = IPersistFile_Save(pPf, widelink, TRUE);
912 if(FAILED(hres)) {
913 /* bombed */
914 ERR("failed IPersistFile::Save %08lx\n", hres);
915 IPersistFile_Release(pPf);
916 IShellLinkA_Release(psl);
917 goto fail;
918 }
919 hres = IPersistFile_SaveCompleted(pPf, widelink);
920 IPersistFile_Release(pPf);
921 IShellLinkA_Release(psl);
922 TRACE("shortcut %s has been created, result=%08lx\n",
923 new_lnk_filepath, hres);
924 }
925 else {
926 ERR("CoCreateInstance failed, hres=%08lx\n", hres);
927 }
928 }
929
930 fail:
931 CoUninitialize();
932
933 /* all done */
934 RegCloseKey(HCUbasekey);
935 return 0;
936}
937
938/*************************************************************************
939 * SHCreateShellFolderViewEx [SHELL32.174]
940 *
941 * NOTES
942 * see IShellFolder::CreateViewObject
943 */
944HRESULT WINAPI SHCreateShellFolderViewEx(
945 LPCSHELLFOLDERVIEWINFO psvcbi, /* [in] shelltemplate struct */
946 LPSHELLVIEW* ppv) /* [out] IShellView pointer */
947{
948 IShellView * psf;
949 HRESULT hRes;
950
951 TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=0x%08lx\n",
952 psvcbi->pshf, psvcbi->pidlFolder, psvcbi->lpfnCallback,
953 psvcbi->uViewMode, psvcbi->dwUser);
954
955 psf = IShellView_Constructor(psvcbi->pshf);
956
957 if (!psf)
958 return E_OUTOFMEMORY;
959
960 IShellView_AddRef(psf);
961 hRes = IShellView_QueryInterface(psf, &IID_IShellView, (LPVOID *)ppv);
962 IShellView_Release(psf);
963
964 return hRes;
965}
966/*************************************************************************
967 * SHWinHelp [SHELL32.127]
968 *
969 */
970HRESULT WINAPI SHWinHelp (DWORD v, DWORD w, DWORD x, DWORD z)
971{ FIXME("0x%08lx 0x%08lx 0x%08lx 0x%08lx stub\n",v,w,x,z);
972 return 0;
973}
974/*************************************************************************
975 * SHRunControlPanel [SHELL32.161]
976 *
977 */
978HRESULT WINAPI SHRunControlPanel (DWORD x, DWORD z)
979{ FIXME("0x%08lx 0x%08lx stub\n",x,z);
980 return 0;
981}
982/*************************************************************************
983 * ShellExecuteEx [SHELL32.291]
984 *
985 */
986BOOL WINAPI ShellExecuteExAW (LPVOID sei)
987{ if (SHELL_OsIsUnicode())
988 return ShellExecuteExW (sei);
989 return ShellExecuteExA (sei);
990}
991/*************************************************************************
992 * ShellExecuteExA [SHELL32.292]
993 *
994 * placeholder in the commandline:
995 * %1 file
996 * %2 printer
997 * %3 driver
998 * %4 port
999 * %I adress of a global item ID (explorer switch /idlist)
1000 * %L ??? path/url/current file ???
1001 * %S ???
1002 * %* all following parameters (see batfile)
1003 */
1004BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
1005{ CHAR szApplicationName[MAX_PATH],szCommandline[MAX_PATH],szPidl[20];
1006 LPSTR pos;
1007 int gap, len;
1008 STARTUPINFOA startup;
1009 PROCESS_INFORMATION info;
1010
1011 WARN("mask=0x%08lx hwnd=0x%04x verb=%s file=%s parm=%s dir=%s show=0x%08x class=%s incomplete\n",
1012 sei->fMask, sei->hwnd, sei->lpVerb, sei->lpFile,
1013 sei->lpParameters, sei->lpDirectory, sei->nShow,
1014 (sei->fMask & SEE_MASK_CLASSNAME) ? sei->lpClass : "not used");
1015
1016 ZeroMemory(szApplicationName,MAX_PATH);
1017 if (sei->lpFile)
1018 strcpy(szApplicationName, sei->lpFile);
1019
1020 ZeroMemory(szCommandline,MAX_PATH);
1021 if (sei->lpParameters)
1022 strcpy(szCommandline, sei->lpParameters);
1023
1024 if (sei->fMask & (SEE_MASK_CLASSKEY | SEE_MASK_INVOKEIDLIST | SEE_MASK_ICON | SEE_MASK_HOTKEY |
1025 SEE_MASK_CONNECTNETDRV | SEE_MASK_FLAG_DDEWAIT |
1026 SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI | SEE_MASK_UNICODE |
1027 SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR ))
1028 {
1029 FIXME("flags ignored: 0x%08lx\n", sei->fMask);
1030 }
1031
1032 /* launch a document by fileclass like 'Wordpad.Document.1' */
1033 if (sei->fMask & SEE_MASK_CLASSNAME)
1034 {
1035 /* FIXME: szCommandline should not be of a fixed size. Plus MAX_PATH is way too short! */
1036 /* the commandline contains 'c:\Path\wordpad.exe "%1"' */
1037 HCR_GetExecuteCommand(sei->lpClass, (sei->lpVerb) ? sei->lpVerb : "open", szCommandline, sizeof(szCommandline));
1038 /* fixme: get the extension of lpFile, check if it fits to the lpClass */
1039 TRACE("SEE_MASK_CLASSNAME->'%s'\n", szCommandline);
1040 }
1041
1042 /* process the IDList */
1043 if ( (sei->fMask & SEE_MASK_INVOKEIDLIST) == SEE_MASK_INVOKEIDLIST) /*0x0c*/
1044 {
1045 SHGetPathFromIDListA (sei->lpIDList,szApplicationName);
1046 TRACE("-- idlist=%p (%s)\n", sei->lpIDList, szApplicationName);
1047 }
1048 else
1049 {
1050 if (sei->fMask & SEE_MASK_IDLIST )
1051 {
1052 pos = strstr(szCommandline, "%I");
1053 if (pos)
1054 {
1055 LPVOID pv;
1056 HGLOBAL hmem = SHAllocShared ( sei->lpIDList, ILGetSize(sei->lpIDList), 0);
1057 pv = SHLockShared(hmem,0);
1058 sprintf(szPidl,":%p",pv );
1059 SHUnlockShared(pv);
1060
1061 gap = strlen(szPidl);
1062 len = strlen(pos)-2;
1063 memmove(pos+gap,pos+2,len);
1064 memcpy(pos,szPidl,gap);
1065
1066 }
1067 }
1068 }
1069
1070 TRACE("execute:'%s','%s'\n",szApplicationName, szCommandline);
1071
1072 strcat(szApplicationName, " ");
1073 strcat(szApplicationName, szCommandline);
1074
1075 ZeroMemory(&startup,sizeof(STARTUPINFOA));
1076 startup.cb = sizeof(STARTUPINFOA);
1077
1078 if (! CreateProcessA(NULL, szApplicationName,
1079 NULL, NULL, FALSE, 0,
1080 NULL, NULL, &startup, &info))
1081 {
1082 sei->hInstApp = GetLastError();
1083 return FALSE;
1084 }
1085
1086 sei->hInstApp = 33;
1087
1088 /* Give 30 seconds to the app to come up */
1089 if ( WaitForInputIdle ( info.hProcess, 30000 ) == 0xFFFFFFFF )
1090 ERR("WaitForInputIdle failed: Error %ld\n", GetLastError() );
1091
1092 if(sei->fMask & SEE_MASK_NOCLOSEPROCESS)
1093 sei->hProcess = info.hProcess;
1094 else
1095 CloseHandle( info.hProcess );
1096 CloseHandle( info.hThread );
1097 return TRUE;
1098}
1099/*************************************************************************
1100 * ShellExecuteExW [SHELL32.293]
1101 *
1102 */
1103BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
1104{ SHELLEXECUTEINFOA seiA;
1105 DWORD ret;
1106
1107 TRACE("%p\n", sei);
1108
1109 memcpy(&seiA, sei, sizeof(SHELLEXECUTEINFOA));
1110
1111 if (sei->lpVerb)
1112 seiA.lpVerb = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpVerb);
1113
1114 if (sei->lpFile)
1115 seiA.lpFile = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpFile);
1116
1117 if (sei->lpParameters)
1118 seiA.lpParameters = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpParameters);
1119
1120 if (sei->lpDirectory)
1121 seiA.lpDirectory = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpDirectory);
1122
1123 if ((sei->fMask & SEE_MASK_CLASSNAME) && sei->lpClass)
1124 seiA.lpClass = HEAP_strdupWtoA( GetProcessHeap(), 0, sei->lpClass);
1125 else
1126 seiA.lpClass = NULL;
1127
1128 ret = ShellExecuteExA(&seiA);
1129
1130 if (seiA.lpVerb) HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpVerb );
1131 if (seiA.lpFile) HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpFile );
1132 if (seiA.lpParameters) HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpParameters );
1133 if (seiA.lpDirectory) HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpDirectory );
1134 if (seiA.lpClass) HeapFree( GetProcessHeap(), 0, (LPSTR) seiA.lpClass );
1135
1136 return ret;
1137}
1138
1139static LPUNKNOWN SHELL32_IExplorerInterface=0;
1140/*************************************************************************
1141 * SHSetInstanceExplorer [SHELL32.176]
1142 *
1143 * NOTES
1144 * Sets the interface
1145 */
1146HRESULT WINAPI SHSetInstanceExplorer (LPUNKNOWN lpUnknown)
1147{ TRACE("%p\n", lpUnknown);
1148 SHELL32_IExplorerInterface = lpUnknown;
1149 return (HRESULT) lpUnknown;
1150}
1151/*************************************************************************
1152 * SHGetInstanceExplorer [SHELL32.@]
1153 *
1154 * NOTES
1155 * gets the interface pointer of the explorer and a reference
1156 */
1157HRESULT WINAPI SHGetInstanceExplorer (LPUNKNOWN * lpUnknown)
1158{ TRACE("%p\n", lpUnknown);
1159
1160 *lpUnknown = SHELL32_IExplorerInterface;
1161
1162 if (!SHELL32_IExplorerInterface)
1163 return E_FAIL;
1164
1165 IUnknown_AddRef(SHELL32_IExplorerInterface);
1166 return NOERROR;
1167}
1168/*************************************************************************
1169 * SHFreeUnusedLibraries [SHELL32.123]
1170 *
1171 * NOTES
1172 * exported by name
1173 */
1174void WINAPI SHFreeUnusedLibraries (void)
1175{
1176 FIXME("stub\n");
1177}
1178/*************************************************************************
1179 * DAD_SetDragImage [SHELL32.136]
1180 *
1181 * NOTES
1182 * exported by name
1183 */
1184BOOL WINAPI DAD_SetDragImage(
1185 HIMAGELIST himlTrack,
1186 LPPOINT lppt)
1187{
1188 FIXME("%p %p stub\n",himlTrack, lppt);
1189 return 0;
1190}
1191/*************************************************************************
1192 * DAD_ShowDragImage [SHELL32.137]
1193 *
1194 * NOTES
1195 * exported by name
1196 */
1197BOOL WINAPI DAD_ShowDragImage(BOOL bShow)
1198{
1199 FIXME("0x%08x stub\n",bShow);
1200 return 0;
1201}
1202/*************************************************************************
1203 * ReadCabinetState [SHELL32.651] NT 4.0
1204 *
1205 */
1206HRESULT WINAPI ReadCabinetState(DWORD u, DWORD v)
1207{ FIXME("0x%04lx 0x%04lx stub\n",u,v);
1208 return 0;
1209}
1210/*************************************************************************
1211 * WriteCabinetState [SHELL32.652] NT 4.0
1212 *
1213 */
1214HRESULT WINAPI WriteCabinetState(DWORD u)
1215{ FIXME("0x%04lx stub\n",u);
1216 return 0;
1217}
1218/*************************************************************************
1219 * FileIconInit [SHELL32.660]
1220 *
1221 */
1222BOOL WINAPI FileIconInit(BOOL bFullInit)
1223{ FIXME("(%s)\n", bFullInit ? "true" : "false");
1224 return 0;
1225}
1226/*************************************************************************
1227 * IsUserAdmin [SHELL32.680] NT 4.0
1228 *
1229 */
1230HRESULT WINAPI IsUserAdmin(void)
1231{ FIXME("stub\n");
1232 return TRUE;
1233}
1234
1235/*************************************************************************
1236 * SHAllocShared [SHELL32.520]
1237 *
1238 * NOTES
1239 * parameter1 is return value from HeapAlloc
1240 * parameter2 is equal to the size allocated with HeapAlloc
1241 * parameter3 is return value from GetCurrentProcessId
1242 *
1243 * the return value is posted as lParam with 0x402 (WM_USER+2) to somewhere
1244 * WM_USER+2 could be the undocumented CWM_SETPATH
1245 * the allocated memory contains a pidl
1246 */
1247HGLOBAL WINAPI SHAllocShared(LPVOID psrc, DWORD size, DWORD procID)
1248{ HGLOBAL hmem;
1249 LPVOID pmem;
1250
1251 TRACE("ptr=%p size=0x%04lx procID=0x%04lx\n",psrc,size,procID);
1252 hmem = GlobalAlloc(GMEM_FIXED, size);
1253 if (!hmem)
1254 return 0;
1255
1256 pmem = GlobalLock (hmem);
1257
1258 if (! pmem)
1259 return 0;
1260
1261 memcpy (pmem, psrc, size);
1262 GlobalUnlock(hmem);
1263 return hmem;
1264}
1265/*************************************************************************
1266 * SHLockShared [SHELL32.521]
1267 *
1268 * NOTES
1269 * parameter1 is return value from SHAllocShared
1270 * parameter2 is return value from GetCurrentProcessId
1271 * the receiver of (WM_USER+2) trys to lock the HANDLE (?)
1272 * the returnvalue seems to be a memoryadress
1273 */
1274LPVOID WINAPI SHLockShared(HANDLE hmem, DWORD procID)
1275{ TRACE("handle=0x%04x procID=0x%04lx\n",hmem,procID);
1276 return GlobalLock(hmem);
1277}
1278/*************************************************************************
1279 * SHUnlockShared [SHELL32.522]
1280 *
1281 * NOTES
1282 * parameter1 is return value from SHLockShared
1283 */
1284BOOL WINAPI SHUnlockShared(LPVOID pv)
1285{
1286 TRACE("%p\n",pv);
1287 return GlobalUnlock((HANDLE)pv);
1288}
1289/*************************************************************************
1290 * SHFreeShared [SHELL32.523]
1291 *
1292 * NOTES
1293 * parameter1 is return value from SHAllocShared
1294 * parameter2 is return value from GetCurrentProcessId
1295 */
1296BOOL WINAPI SHFreeShared(
1297 HANDLE hMem,
1298 DWORD pid)
1299{
1300 TRACE("handle=0x%04x 0x%04lx\n",hMem,pid);
1301 return GlobalFree(hMem);
1302}
1303
1304/*************************************************************************
1305 * SetAppStartingCursor [SHELL32.99]
1306 */
1307HRESULT WINAPI SetAppStartingCursor(HWND u, DWORD v)
1308{ FIXME("hwnd=0x%04x 0x%04lx stub\n",u,v );
1309 return 0;
1310}
1311/*************************************************************************
1312 * SHLoadOLE [SHELL32.151]
1313 *
1314 */
1315HRESULT WINAPI SHLoadOLE(DWORD u)
1316{ FIXME("0x%04lx stub\n",u);
1317 return S_OK;
1318}
1319/*************************************************************************
1320 * DriveType [SHELL32.64]
1321 *
1322 */
1323HRESULT WINAPI DriveType(DWORD u)
1324{ FIXME("0x%04lx stub\n",u);
1325 return 0;
1326}
1327/*************************************************************************
1328 * SHAbortInvokeCommand [SHELL32.198]
1329 *
1330 */
1331HRESULT WINAPI SHAbortInvokeCommand(void)
1332{ FIXME("stub\n");
1333 return 1;
1334}
1335/*************************************************************************
1336 * SHOutOfMemoryMessageBox [SHELL32.126]
1337 *
1338 */
1339int WINAPI SHOutOfMemoryMessageBox(
1340 HWND hwndOwner,
1341 LPCSTR lpCaption,
1342 UINT uType)
1343{
1344 FIXME("0x%04x %s 0x%08x stub\n",hwndOwner, lpCaption, uType);
1345 return 0;
1346}
1347/*************************************************************************
1348 * SHFlushClipboard [SHELL32.121]
1349 *
1350 */
1351HRESULT WINAPI SHFlushClipboard(void)
1352{ FIXME("stub\n");
1353 return 1;
1354}
1355
1356/*************************************************************************
1357 * SHWaitForFileToOpen [SHELL32.97]
1358 *
1359 */
1360BOOL WINAPI SHWaitForFileToOpen(
1361 LPCITEMIDLIST pidl,
1362 DWORD dwFlags,
1363 DWORD dwTimeout)
1364{
1365 FIXME("%p 0x%08lx 0x%08lx stub\n", pidl, dwFlags, dwTimeout);
1366 return 0;
1367}
1368
1369/************************************************************************
1370 * @ [SHELL32.654]
1371 *
1372 * NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState)
1373 * second one could be a size (0x0c). The size is the same as the structure saved to
1374 * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
1375 * I'm (js) guessing: this one is just ReadCabinetState ;-)
1376 */
1377HRESULT WINAPI shell32_654 (DWORD x, DWORD y)
1378{ FIXME("0x%08lx 0x%08lx stub\n",x,y);
1379 return 0;
1380}
1381
1382/************************************************************************
1383 * RLBuildListOfPaths [SHELL32.146]
1384 *
1385 * NOTES
1386 * builds a DPA
1387 */
1388DWORD WINAPI RLBuildListOfPaths (void)
1389{ FIXME("stub\n");
1390 return 0;
1391}
1392/************************************************************************
1393 * SHValidateUNC [SHELL32.173]
1394 *
1395 */
1396HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
1397{
1398 FIXME("0x%08lx 0x%08lx 0x%08lx stub\n",x,y,z);
1399 return 0;
1400}
1401
1402/************************************************************************
1403 * DoEnvironmentSubstA [SHELL32.@]
1404 *
1405 */
1406HRESULT WINAPI DoEnvironmentSubstA(LPSTR x, LPSTR y)
1407{
1408 FIXME("(%s, %s) stub\n", debugstr_a(x), debugstr_a(y));
1409 return 0;
1410}
1411
1412/************************************************************************
1413 * DoEnvironmentSubstW [SHELL32.@]
1414 *
1415 */
1416HRESULT WINAPI DoEnvironmentSubstW(LPWSTR x, LPWSTR y)
1417{
1418 FIXME("(%s, %s): stub\n", debugstr_w(x), debugstr_w(y));
1419 return 0;
1420}
1421
1422/************************************************************************
1423 * DoEnvironmentSubst [SHELL32.53]
1424 *
1425 */
1426HRESULT WINAPI DoEnvironmentSubstAW(LPVOID x, LPVOID y)
1427{
1428 if (SHELL_OsIsUnicode())
1429 return DoEnvironmentSubstW(x, y);
1430 return DoEnvironmentSubstA(x, y);
1431}
1432
1433/*************************************************************************
1434 * @ [SHELL32.243]
1435 *
1436 * Win98+ by-ordinal routine. In Win98 this routine returns zero and
1437 * does nothing else. Possibly this does something in NT or SHELL32 5.0?
1438 *
1439 */
1440
1441BOOL WINAPI shell32_243(DWORD a, DWORD b)
1442{
1443 return FALSE;
1444}
1445
1446/*************************************************************************
1447 * @ [SHELL32.714]
1448 */
1449DWORD WINAPI SHELL32_714(LPVOID x)
1450{
1451 FIXME("(%s)stub\n", debugstr_w(x));
1452 return 0;
1453}
1454
1455/*************************************************************************
1456 * SHAddFromPropSheetExtArray [SHELL32.167]
1457 */
1458DWORD WINAPI SHAddFromPropSheetExtArray(DWORD a, DWORD b, DWORD c)
1459{
1460 FIXME("(%08lx,%08lx,%08lx)stub\n", a, b, c);
1461 return 0;
1462}
1463
1464/*************************************************************************
1465 * SHCreatePropSheetExtArray [SHELL32.168]
1466 */
1467DWORD WINAPI SHCreatePropSheetExtArray(DWORD a, LPCSTR b, DWORD c)
1468{
1469 FIXME("(%08lx,%s,%08lx)stub\n", a, debugstr_a(b), c);
1470 return 0;
1471}
1472
1473/*************************************************************************
1474 * SHReplaceFromPropSheetExtArray [SHELL32.170]
1475 */
1476DWORD WINAPI SHReplaceFromPropSheetExtArray(DWORD a, DWORD b, DWORD c, DWORD d)
1477{
1478 FIXME("(%08lx,%08lx,%08lx,%08lx)stub\n", a, b, c, d);
1479 return 0;
1480}
1481
1482/*************************************************************************
1483 * SHDestroyPropSheetExtArray [SHELL32.169]
1484 */
1485DWORD WINAPI SHDestroyPropSheetExtArray(DWORD a)
1486{
1487 FIXME("(%08lx)stub\n", a);
1488 return 0;
1489}
1490
1491/*************************************************************************
1492* CIDLData_CreateFromIDArray[SHELL32.83]
1493*
1494* Create IDataObject from PIDLs??
1495*/
1496HRESULT WINAPI CIDLData_CreateFromIDArray(
1497 LPCITEMIDLIST pidlFolder,
1498 DWORD cpidlFiles,
1499 LPCITEMIDLIST *lppidlFiles,
1500 LPDATAOBJECT *ppdataObject)
1501{
1502 INT i;
1503 HWND hwnd = 0; /*FIXME: who should be hwnd of owner? set to desktop */
1504 BOOL boldpidl;
1505
1506#ifndef __WIN32OS2__
1507 if (TRACE_ON(shell)) {
1508 TRACE("(%p, %ld, %p, %p)\n", pidlFolder, cpidlFiles,
1509 lppidlFiles, ppdataObject);
1510 boldpidl = TRACE_ON(pidl);
1511 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_shell, FALSE);
1512 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_pidl, TRUE);
1513 pdump (pidlFolder);
1514 for (i=0; i<cpidlFiles; i++){
1515 pdump (lppidlFiles[i]);
1516 }
1517 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_shell, TRUE);
1518 __SET_DEBUGGING(__DBCL_TRACE, __wine_dbch_pidl, boldpidl);
1519 }
1520#endif
1521
1522 *ppdataObject = IDataObject_Constructor( hwnd, pidlFolder,
1523 lppidlFiles, cpidlFiles);
1524 if (*ppdataObject) return S_OK;
1525 return E_OUTOFMEMORY;
1526}
Note: See TracBrowser for help on using the repository browser.