shellord.c 44 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1
/*
2 3
 * The parameters of many functions changes between different OS versions
 * (NT uses Unicode strings, 95 uses ASCII strings)
4
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
5
 * Copyright 1997 Marcus Meissner
Alexandre Julliard's avatar
Alexandre Julliard committed
6
 *           1998 Jrgen Schmied
7 8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Alexandre Julliard's avatar
Alexandre Julliard committed
21
 */
22 23
#include "config.h"

Alexandre Julliard's avatar
Alexandre Julliard committed
24
#include <string.h>
25
#include <stdarg.h>
26
#include <stdio.h>
27 28 29

#define COBJMACROS

Alexandre Julliard's avatar
Alexandre Julliard committed
30
#include "winerror.h"
31 32
#include "windef.h"
#include "winbase.h"
33
#include "winreg.h"
34
#include "wine/debug.h"
35
#include "winnls.h"
36

37
#include "shellapi.h"
38
#include "objbase.h"
39
#include "shlguid.h"
40 41
#include "wingdi.h"
#include "winuser.h"
42
#include "shlobj.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
43
#include "shell32_main.h"
44
#include "undocshell.h"
45
#include "pidl.h"
46
#include "shlwapi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
47
#include "commdlg.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
48

49 50
WINE_DEFAULT_DEBUG_CHANNEL(shell);
WINE_DECLARE_DEBUG_CHANNEL(pidl);
51

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
/* FIXME: !!! move CREATEMRULIST and flags to header file !!! */
/*        !!! it is in both here and comctl32undoc.c      !!! */
typedef struct tagCREATEMRULIST
{
    DWORD  cbSize;        /* size of struct */
    DWORD  nMaxItems;     /* max no. of items in list */
    DWORD  dwFlags;       /* see below */
    HKEY   hKey;          /* root reg. key under which list is saved */
    LPCSTR lpszSubKey;    /* reg. subkey */
    PROC   lpfnCompare;   /* item compare proc */
} CREATEMRULISTA, *LPCREATEMRULISTA;

/* dwFlags */
#define MRUF_STRING_LIST  0 /* list will contain strings */
#define MRUF_BINARY_LIST  1 /* list will contain binary data */
#define MRUF_DELAYED_SAVE 2 /* only save list order to reg. is FreeMRUList */

extern HANDLE WINAPI CreateMRUListA(LPCREATEMRULISTA lpcml);
extern DWORD  WINAPI FreeMRUList(HANDLE hMRUList);
extern INT    WINAPI AddMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData);
extern INT    WINAPI FindMRUData(HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum);
extern INT    WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer, DWORD nBufferSize);

75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

/* Get a function pointer from a DLL handle */
#define GET_FUNC(func, module, name, fail) \
  do { \
    if (!func) { \
      if (!SHELL32_h##module && !(SHELL32_h##module = LoadLibraryA(#module ".dll"))) return fail; \
      func = (void*)GetProcAddress(SHELL32_h##module, name); \
      if (!func) return fail; \
    } \
  } while (0)

/* Function pointers for GET_FUNC macro */
static HMODULE SHELL32_hshlwapi=NULL;
static HANDLE (WINAPI *pSHAllocShared)(LPCVOID,DWORD,DWORD);
static LPVOID (WINAPI *pSHLockShared)(HANDLE,DWORD);
static BOOL   (WINAPI *pSHUnlockShared)(LPVOID);
static BOOL   (WINAPI *pSHFreeShared)(HANDLE,DWORD);


Alexandre Julliard's avatar
Alexandre Julliard committed
94
/*************************************************************************
95
 * ParseFieldA					[internal]
Alexandre Julliard's avatar
Alexandre Julliard committed
96
 *
97
 * copies a field from a ',' delimited string
98
 *
99
 * first field is nField = 1
Alexandre Julliard's avatar
Alexandre Julliard committed
100
 */
101 102 103 104
DWORD WINAPI ParseFieldA(
	LPCSTR src,
	DWORD nField,
	LPSTR dst,
105
	DWORD len)
106
{
107
	WARN("(%s,0x%08lx,%p,%ld) semi-stub.\n",debugstr_a(src),nField,dst,len);
108 109 110 111

	if (!src || !src[0] || !dst || !len)
	  return 0;

112 113 114 115 116
	/* skip n fields delimited by ',' */
	while (nField > 1)
	{
	  if (*src=='\0') return FALSE;
	  if (*(src++)==',') nField--;
117 118
	}

119 120
	/* copy part till the next ',' to dst */
	while ( *src!='\0' && *src!=',' && (len--)>0 ) *(dst++)=*(src++);
121

122
	/* finalize the string */
123
	*dst=0x0;
124

125
	return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
126 127 128
}

/*************************************************************************
129 130
 * ParseFieldW			[internal]
 *
131
 * copies a field from a ',' delimited string
132
 *
133
 * first field is nField = 1
Alexandre Julliard's avatar
Alexandre Julliard committed
134
 */
135
DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len)
136
{
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
	WARN("(%s,0x%08lx,%p,%ld) semi-stub.\n", debugstr_w(src), nField, dst, len);

	if (!src || !src[0] || !dst || !len)
	  return 0;

	/* skip n fields delimited by ',' */
	while (nField > 1)
	{
	  if (*src == 0x0) return FALSE;
	  if (*src++ == ',') nField--;
	}

	/* copy part till the next ',' to dst */
	while ( *src != 0x0 && *src != ',' && (len--)>0 ) *(dst++) = *(src++);

	/* finalize the string */
	*dst = 0x0;

	return TRUE;
156 157 158
}

/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
159
 * ParseField			[SHELL32.58]
160
 */
161
DWORD WINAPI ParseFieldAW(LPCVOID src, DWORD nField, LPVOID dst, DWORD len)
162
{
163
	if (SHELL_OsIsUnicode())
164 165
	  return ParseFieldW(src, nField, dst, len);
	return ParseFieldA(src, nField, dst, len);
Alexandre Julliard's avatar
Alexandre Julliard committed
166 167 168
}

/*************************************************************************
169
 * GetFileNameFromBrowse			[SHELL32.63]
170
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
171
 */
172 173 174 175 176 177 178 179 180
BOOL WINAPI GetFileNameFromBrowse(
	HWND hwndOwner,
	LPSTR lpstrFile,
	DWORD nMaxFile,
	LPCSTR lpstrInitialDir,
	LPCSTR lpstrDefExt,
	LPCSTR lpstrFilter,
	LPCSTR lpstrTitle)
{
Alexandre Julliard's avatar
Alexandre Julliard committed
181 182 183 184 185
    HMODULE hmodule;
    FARPROC pGetOpenFileNameA;
    OPENFILENAMEA ofn;
    BOOL ret;

186
    TRACE("%p, %s, %ld, %s, %s, %s, %s)\n",
187 188 189
	  hwndOwner, lpstrFile, nMaxFile, lpstrInitialDir, lpstrDefExt,
	  lpstrFilter, lpstrTitle);

Alexandre Julliard's avatar
Alexandre Julliard committed
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
    hmodule = LoadLibraryA("comdlg32.dll");
    if(!hmodule) return FALSE;
    pGetOpenFileNameA = GetProcAddress(hmodule, "GetOpenFileNameA");
    if(!pGetOpenFileNameA)
    {
	FreeLibrary(hmodule);
	return FALSE;
    }

    memset(&ofn, 0, sizeof(ofn));

    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = hwndOwner;
    ofn.lpstrFilter = lpstrFilter;
    ofn.lpstrFile = lpstrFile;
    ofn.nMaxFile = nMaxFile;
    ofn.lpstrInitialDir = lpstrInitialDir;
    ofn.lpstrTitle = lpstrTitle;
    ofn.lpstrDefExt = lpstrDefExt;
    ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
    ret = pGetOpenFileNameA(&ofn);
211

Alexandre Julliard's avatar
Alexandre Julliard committed
212 213
    FreeLibrary(hmodule);
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
214 215 216
}

/*************************************************************************
217 218
 * SHGetSetSettings				[SHELL32.68]
 */
219
VOID WINAPI SHGetSetSettings(LPSHELLSTATE lpss, DWORD dwMask, BOOL bSet)
220
{
221 222 223 224 225 226 227 228
  if(bSet)
  {
    FIXME("%p 0x%08lx TRUE\n", lpss, dwMask);
  }
  else
  {
    SHGetSettings((LPSHELLFLAGSTATE)lpss,dwMask);
  }
229 230 231 232
}

/*************************************************************************
 * SHGetSettings				[SHELL32.@]
233
 *
234 235 236
 * NOTES
 *  the registry path are for win98 (tested)
 *  and possibly are the same in nt40
237
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
238
 */
239
VOID WINAPI SHGetSettings(LPSHELLFLAGSTATE lpsfs, DWORD dwMask)
240 241 242 243 244
{
	HKEY	hKey;
	DWORD	dwData;
	DWORD	dwDataSize = sizeof (DWORD);

245
	TRACE("(%p 0x%08lx)\n",lpsfs,dwMask);
246

247
	if (RegCreateKeyExA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced",
248 249
				 0, 0, 0, KEY_ALL_ACCESS, 0, &hKey, 0))
	  return;
250

251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284
	if ( (SSF_SHOWEXTENSIONS & dwMask) && !RegQueryValueExA(hKey, "HideFileExt", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	  lpsfs->fShowExtensions  = ((dwData == 0) ?  0 : 1);

	if ( (SSF_SHOWINFOTIP & dwMask) && !RegQueryValueExA(hKey, "ShowInfoTip", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	  lpsfs->fShowInfoTip  = ((dwData == 0) ?  0 : 1);

	if ( (SSF_DONTPRETTYPATH & dwMask) && !RegQueryValueExA(hKey, "DontPrettyPath", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	  lpsfs->fDontPrettyPath  = ((dwData == 0) ?  0 : 1);

	if ( (SSF_HIDEICONS & dwMask) && !RegQueryValueExA(hKey, "HideIcons", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	  lpsfs->fHideIcons  = ((dwData == 0) ?  0 : 1);

	if ( (SSF_MAPNETDRVBUTTON & dwMask) && !RegQueryValueExA(hKey, "MapNetDrvBtn", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	  lpsfs->fMapNetDrvBtn  = ((dwData == 0) ?  0 : 1);

	if ( (SSF_SHOWATTRIBCOL & dwMask) && !RegQueryValueExA(hKey, "ShowAttribCol", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	  lpsfs->fShowAttribCol  = ((dwData == 0) ?  0 : 1);

	if (((SSF_SHOWALLOBJECTS | SSF_SHOWSYSFILES) & dwMask) && !RegQueryValueExA(hKey, "Hidden", 0, 0, (LPBYTE)&dwData, &dwDataSize))
	{ if (dwData == 0)
	  { if (SSF_SHOWALLOBJECTS & dwMask)	lpsfs->fShowAllObjects  = 0;
	    if (SSF_SHOWSYSFILES & dwMask)	lpsfs->fShowSysFiles  = 0;
	  }
	  else if (dwData == 1)
	  { if (SSF_SHOWALLOBJECTS & dwMask)	lpsfs->fShowAllObjects  = 1;
	    if (SSF_SHOWSYSFILES & dwMask)	lpsfs->fShowSysFiles  = 0;
	  }
	  else if (dwData == 2)
	  { if (SSF_SHOWALLOBJECTS & dwMask)	lpsfs->fShowAllObjects  = 0;
	    if (SSF_SHOWSYSFILES & dwMask)	lpsfs->fShowSysFiles  = 1;
	  }
	}
	RegCloseKey (hKey);

285
	TRACE("-- 0x%04x\n", *(WORD*)lpsfs);
Alexandre Julliard's avatar
Alexandre Julliard committed
286 287
}

Alexandre Julliard's avatar
Alexandre Julliard committed
288
/*************************************************************************
289
 * SHShellFolderView_Message			[SHELL32.73]
Alexandre Julliard's avatar
Alexandre Julliard committed
290
 *
Jon Griffiths's avatar
Jon Griffiths committed
291 292 293 294 295 296 297 298 299
 * Send a message to an explorer cabinet window.
 *
 * PARAMS
 *  hwndCabinet [I] The window containing the shellview to communicate with
 *  dwMessage   [I] The SFVM message to send
 *  dwParam     [I] Message parameter
 *
 * RETURNS
 *  fixme.
Alexandre Julliard's avatar
Alexandre Julliard committed
300
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
301 302
 * NOTES
 *  Message SFVM_REARRANGE = 1
Jon Griffiths's avatar
Jon Griffiths committed
303
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
304
 *    This message gets sent when a column gets clicked to instruct the
Jon Griffiths's avatar
Jon Griffiths committed
305
 *    shell view to re-sort the item list. dwParam identifies the column
Alexandre Julliard's avatar
Alexandre Julliard committed
306 307
 *    that was clicked.
 */
308
LRESULT WINAPI SHShellFolderView_Message(
309
	HWND hwndCabinet,
310 311
	UINT uMessage,
	LPARAM lParam)
312
{
313
	FIXME("%p %08x %08lx stub\n",hwndCabinet, uMessage, lParam);
314
	return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
315 316
}

Alexandre Julliard's avatar
Alexandre Julliard committed
317
/*************************************************************************
318
 * RegisterShellHook				[SHELL32.181]
Alexandre Julliard's avatar
Alexandre Julliard committed
319
 *
Jon Griffiths's avatar
Jon Griffiths committed
320 321
 * Register a shell hook.
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
322
 * PARAMS
Jon Griffiths's avatar
Jon Griffiths committed
323 324
 *      hwnd   [I]  Window handle
 *      dwType [I]  Type of hook.
325
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
326
 * NOTES
Jon Griffiths's avatar
Jon Griffiths committed
327
 *     Exported by ordinal
Alexandre Julliard's avatar
Alexandre Julliard committed
328
 */
329 330 331 332
BOOL WINAPI RegisterShellHook(
	HWND hWnd,
	DWORD dwType)
{
333
	FIXME("(%p,0x%08lx):stub.\n",hWnd, dwType);
334
	return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
335
}
Jon Griffiths's avatar
Jon Griffiths committed
336

337
/*************************************************************************
338
 * ShellMessageBoxW				[SHELL32.182]
339
 *
Jon Griffiths's avatar
Jon Griffiths committed
340
 * See ShellMessageBoxA.
341
 */
342 343 344 345 346 347 348 349
int WINAPIV ShellMessageBoxW(
	HINSTANCE hInstance,
	HWND hWnd,
	LPCWSTR lpText,
	LPCWSTR lpCaption,
	UINT uType,
	...)
{
350 351
	WCHAR	szText[100],szTitle[100];
	LPCWSTR pszText = szText, pszTitle = szTitle, pszTemp;
352
	va_list args;
353 354
	int	ret;

355 356 357 358 359 360 361
	va_start(args, uType);
	/* wvsprintfA(buf,fmt, args); */

	TRACE("(%08lx,%08lx,%p,%p,%08x)\n",
	(DWORD)hInstance,(DWORD)hWnd,lpText,lpCaption,uType);

	if (!HIWORD(lpCaption))
362
	  LoadStringW(hInstance, (DWORD)lpCaption, szTitle, sizeof(szTitle)/sizeof(szTitle[0]));
363
	else
364
	  pszTitle = lpCaption;
365

366
	if (!HIWORD(lpText))
367
	  LoadStringW(hInstance, (DWORD)lpText, szText, sizeof(szText)/sizeof(szText[0]));
368
	else
369
	  pszText = lpText;
370

371
	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
372
		       pszText, 0, 0, (LPWSTR)&pszTemp, 0, &args);
Patrik Stridvall's avatar
Patrik Stridvall committed
373 374 375

	va_end(args);

376 377 378
	ret = MessageBoxW(hWnd,pszTemp,pszTitle,uType);
	LocalFree((HLOCAL)pszTemp);
	return ret;
379
}
Alexandre Julliard's avatar
Alexandre Julliard committed
380

Alexandre Julliard's avatar
Alexandre Julliard committed
381
/*************************************************************************
382
 * ShellMessageBoxA				[SHELL32.183]
Jon Griffiths's avatar
Jon Griffiths committed
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
 *
 * Format and output an error message.
 *
 * PARAMS
 *  hInstance [I] Instance handle of message creator
 *  hWnd      [I] Window handle of message creator
 *  lpText    [I] Resource Id of title or LPSTR
 *  lpCaption [I] Resource Id of title or LPSTR
 *  uType     [I] Type of error message
 *
 * RETURNS
 *  A return value from MessageBoxA().
 *
 * NOTES
 *     Exported by ordinal
Alexandre Julliard's avatar
Alexandre Julliard committed
398
 */
399 400 401 402 403 404 405 406
int WINAPIV ShellMessageBoxA(
	HINSTANCE hInstance,
	HWND hWnd,
	LPCSTR lpText,
	LPCSTR lpCaption,
	UINT uType,
	...)
{
407 408
	char	szText[100],szTitle[100];
	LPCSTR  pszText = szText, pszTitle = szTitle, pszTemp;
409
	va_list args;
410 411
	int	ret;

412 413 414 415 416 417 418
	va_start(args, uType);
	/* wvsprintfA(buf,fmt, args); */

	TRACE("(%08lx,%08lx,%p,%p,%08x)\n",
	(DWORD)hInstance,(DWORD)hWnd,lpText,lpCaption,uType);

	if (!HIWORD(lpCaption))
419
	  LoadStringA(hInstance, (DWORD)lpCaption, szTitle, sizeof(szTitle));
420
	else
421
	  pszTitle = lpCaption;
422

423
	if (!HIWORD(lpText))
424
	  LoadStringA(hInstance, (DWORD)lpText, szText, sizeof(szText));
425
	else
426
	  pszText = lpText;
427

428
	FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
429
		       pszText, 0, 0, (LPSTR)&pszTemp, 0, &args);
Patrik Stridvall's avatar
Patrik Stridvall committed
430 431 432

	va_end(args);

433 434 435
	ret = MessageBoxA(hWnd,pszTemp,pszTitle,uType);
	LocalFree((HLOCAL)pszTemp);
	return ret;
436 437
}

Alexandre Julliard's avatar
Alexandre Julliard committed
438
/*************************************************************************
439
 * SHRegisterDragDrop				[SHELL32.86]
Alexandre Julliard's avatar
Alexandre Julliard committed
440 441
 *
 * NOTES
Alexandre Julliard's avatar
Alexandre Julliard committed
442
 *     exported by ordinal
Alexandre Julliard's avatar
Alexandre Julliard committed
443
 */
444 445 446
HRESULT WINAPI SHRegisterDragDrop(
	HWND hWnd,
	LPDROPTARGET pDropTarget)
447
{
448
	FIXME("(%p,%p):stub.\n", hWnd, pDropTarget);
449
	return RegisterDragDrop(hWnd, pDropTarget);
Alexandre Julliard's avatar
Alexandre Julliard committed
450 451 452
}

/*************************************************************************
453
 * SHRevokeDragDrop				[SHELL32.87]
Alexandre Julliard's avatar
Alexandre Julliard committed
454 455
 *
 * NOTES
Alexandre Julliard's avatar
Alexandre Julliard committed
456
 *     exported by ordinal
Alexandre Julliard's avatar
Alexandre Julliard committed
457
 */
458 459
HRESULT WINAPI SHRevokeDragDrop(HWND hWnd)
{
460
    FIXME("(%p):stub.\n",hWnd);
461
    return RevokeDragDrop(hWnd);
Alexandre Julliard's avatar
Alexandre Julliard committed
462 463
}

Eric Kohl's avatar
Eric Kohl committed
464 465 466 467 468 469
/*************************************************************************
 * SHDoDragDrop					[SHELL32.88]
 *
 * NOTES
 *     exported by ordinal
 */
470 471 472 473 474 475
HRESULT WINAPI SHDoDragDrop(
	HWND hWnd,
	LPDATAOBJECT lpDataObject,
	LPDROPSOURCE lpDropSource,
	DWORD dwOKEffect,
	LPDWORD pdwEffect)
Alexandre Julliard's avatar
Alexandre Julliard committed
476
{
477
    FIXME("(%p %p %p 0x%08lx %p):stub.\n",
478
    hWnd, lpDataObject, lpDropSource, dwOKEffect, pdwEffect);
479
	return DoDragDrop(lpDataObject, lpDropSource, dwOKEffect, pdwEffect);
Alexandre Julliard's avatar
Alexandre Julliard committed
480 481 482
}

/*************************************************************************
483
 * ArrangeWindows				[SHELL32.184]
484
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
485
 */
486 487 488 489 490 491
WORD WINAPI ArrangeWindows(
	HWND hwndParent,
	DWORD dwReserved,
	LPCRECT lpRect,
	WORD cKids,
	CONST HWND * lpKids)
Alexandre Julliard's avatar
Alexandre Julliard committed
492
{
493
    FIXME("(%p 0x%08lx %p 0x%04x %p):stub.\n",
494
	   hwndParent, dwReserved, lpRect, cKids, lpKids);
Alexandre Julliard's avatar
Alexandre Julliard committed
495 496 497
    return 0;
}

Alexandre Julliard's avatar
Alexandre Julliard committed
498
/*************************************************************************
499
 * SignalFileOpen				[SHELL32.103]
Alexandre Julliard's avatar
Alexandre Julliard committed
500 501 502 503 504 505 506
 *
 * NOTES
 *     exported by ordinal
 */
DWORD WINAPI
SignalFileOpen (DWORD dwParam1)
{
507
    FIXME("(0x%08lx):stub.\n", dwParam1);
Alexandre Julliard's avatar
Alexandre Julliard committed
508

Alexandre Julliard's avatar
Alexandre Julliard committed
509 510 511
    return 0;
}

512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
/*************************************************************************
 * SHADD_get_policy - helper function for SHAddToRecentDocs
 *
 * PARAMETERS
 *   policy    [IN]  policy name (null termed string) to find
 *   type      [OUT] ptr to DWORD to receive type
 *   buffer    [OUT] ptr to area to hold data retrieved
 *   len       [IN/OUT] ptr to DWORD holding size of buffer and getting
 *                      length filled
 *
 * RETURNS
 *   result of the SHQueryValueEx call
 */
static INT SHADD_get_policy(LPSTR policy, LPDWORD type, LPVOID buffer, LPDWORD len)
{
    HKEY Policy_basekey;
    INT ret;

530
    /* Get the key for the policies location in the registry
531 532 533 534 535 536 537 538
     */
    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
		      "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
		      0, KEY_READ, &Policy_basekey)) {

	if (RegOpenKeyExA(HKEY_CURRENT_USER,
			  "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer",
			  0, KEY_READ, &Policy_basekey)) {
539 540
	    TRACE("No Explorer Policies location exists. Policy wanted=%s\n",
		  policy);
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
	    *len = 0;
	    return ERROR_FILE_NOT_FOUND;
	}
    }

    /* Retrieve the data if it exists
     */
    ret = SHQueryValueExA(Policy_basekey, policy, 0, type, buffer, len);
    RegCloseKey(Policy_basekey);
    return ret;
}


/*************************************************************************
 * SHADD_compare_mru - helper function for SHAddToRecentDocs
 *
 * PARAMETERS
 *   data1     [IN] data being looked for
 *   data2     [IN] data in MRU
 *   cbdata    [IN] length from FindMRUData call (not used)
 *
 * RETURNS
 *   position within MRU list that data was added.
 */
static INT CALLBACK SHADD_compare_mru(LPCVOID data1, LPCVOID data2, DWORD cbData)
{
    return lstrcmpiA(data1, data2);
}

/*************************************************************************
 * SHADD_create_add_mru_data - helper function for SHAddToRecentDocs
 *
 * PARAMETERS
 *   mruhandle    [IN] handle for created MRU list
 *   doc_name     [IN] null termed pure doc name
 *   new_lnk_name [IN] null termed path and file name for .lnk file
577
 *   buffer       [IN/OUT] 2048 byte area to construct MRU data
578 579 580 581 582 583 584 585 586 587
 *   len          [OUT] ptr to int to receive space used in buffer
 *
 * RETURNS
 *   position within MRU list that data was added.
 */
static INT SHADD_create_add_mru_data(HANDLE mruhandle, LPSTR doc_name, LPSTR new_lnk_name,
                                     LPSTR buffer, INT *len)
{
    LPSTR ptr;
    INT wlen;
588

589 590 591 592
    /*FIXME: Document:
     *  RecentDocs MRU data structure seems to be:
     *    +0h   document file name w/ terminating 0h
     *    +nh   short int w/ size of remaining
593
     *    +n+2h 02h 30h, or 01h 30h, or 00h 30h  -  unknown
594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
     *    +n+4h 10 bytes zeros  -   unknown
     *    +n+eh shortcut file name w/ terminating 0h
     *    +n+e+nh 3 zero bytes  -  unknown
     */

    /* Create the MRU data structure for "RecentDocs"
	 */
    ptr = buffer;
    lstrcpyA(ptr, doc_name);
    ptr += (lstrlenA(buffer) + 1);
    wlen= lstrlenA(new_lnk_name) + 1 + 12;
    *((short int*)ptr) = wlen;
    ptr += 2;   /* step past the length */
    *(ptr++) = 0x30;  /* unknown reason */
    *(ptr++) = 0;     /* unknown, but can be 0x00, 0x01, 0x02 */
    memset(ptr, 0, 10);
    ptr += 10;
    lstrcpyA(ptr, new_lnk_name);
    ptr += (lstrlenA(new_lnk_name) + 1);
    memset(ptr, 0, 3);
    ptr += 3;
    *len = ptr - buffer;

617
    /* Add the new entry into the MRU list
618
     */
619
    return AddMRUData(mruhandle, (LPCVOID)buffer, *len);
620 621
}

Alexandre Julliard's avatar
Alexandre Julliard committed
622
/*************************************************************************
623
 * SHAddToRecentDocs				[SHELL32.@]
Alexandre Julliard's avatar
Alexandre Julliard committed
624
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
625 626 627 628
 * PARAMETERS
 *   uFlags  [IN] SHARD_PATH or SHARD_PIDL
 *   pv      [IN] string or pidl, NULL clears the list
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
629 630 631
 * NOTES
 *     exported by name
 */
632
void WINAPI SHAddToRecentDocs (UINT uFlags,LPCVOID pv)
633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
{
/* If list is a string list lpfnCompare has the following prototype
 * int CALLBACK MRUCompareString(LPCSTR s1, LPCSTR s2)
 * for binary lists the prototype is
 * int CALLBACK MRUCompareBinary(LPCVOID data1, LPCVOID data2, DWORD cbData)
 * where cbData is the no. of bytes to compare.
 * Need to check what return value means identical - 0?
 */


    UINT olderrormode;
    HKEY HCUbasekey;
    CHAR doc_name[MAX_PATH];
    CHAR link_dir[MAX_PATH];
    CHAR new_lnk_filepath[MAX_PATH];
    CHAR new_lnk_name[MAX_PATH];
    IMalloc *ppM;
    LPITEMIDLIST pidl;
    HWND hwnd = 0;       /* FIXME:  get real window handle */
    INT ret;
    DWORD data[64], datalen, type;

    /*FIXME: Document:
     *  RecentDocs MRU data structure seems to be:
     *    +0h   document file name w/ terminating 0h
     *    +nh   short int w/ size of remaining
659
     *    +n+2h 02h 30h, or 01h 30h, or 00h 30h  -  unknown
660 661 662 663 664 665 666 667 668 669 670
     *    +n+4h 10 bytes zeros  -   unknown
     *    +n+eh shortcut file name w/ terminating 0h
     *    +n+e+nh 3 zero bytes  -  unknown
     */

    /* See if we need to do anything.
     */
    datalen = 64;
    ret=SHADD_get_policy( "NoRecentDocsHistory", &type, &data, &datalen);
    if ((ret > 0) && (ret != ERROR_FILE_NOT_FOUND)) {
	ERR("Error %d getting policy \"NoRecentDocsHistory\"\n", ret);
671
	return;
672 673
    }
    if (ret == ERROR_SUCCESS) {
674
	if (!( (type == REG_DWORD) ||
675
	       ((type == REG_BINARY) && (datalen == 4)) )) {
676
	    ERR("Error policy data for \"NoRecentDocsHistory\" not formatted correctly, type=%ld, len=%ld\n",
677
		type, datalen);
678
	    return;
Alexandre Julliard's avatar
Alexandre Julliard committed
679
	}
680 681 682 683

	TRACE("policy value for NoRecentDocsHistory = %08lx\n", data[0]);
	/* now test the actual policy value */
	if ( data[0] != 0)
684
	    return;
685 686 687 688 689 690 691 692
    }

    /* Open key to where the necessary info is
     */
    /* FIXME: This should be done during DLL PROCESS_ATTACH (or THREAD_ATTACH)
     *        and the close should be done during the _DETACH. The resulting
     *        key is stored in the DLL global data.
     */
693 694 695 696
    if (RegCreateKeyExA(HKEY_CURRENT_USER,
			"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer",
			0, 0, 0, KEY_READ, 0, &HCUbasekey, 0)) {
	ERR("Failed to create 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer'\n");
697
	return;
698
    }
699 700 701 702

    /* Get path to user's "Recent" directory
     */
    if(SUCCEEDED(SHGetMalloc(&ppM))) {
703
	if (SUCCEEDED(SHGetSpecialFolderLocation(hwnd, CSIDL_RECENT,
704 705 706 707
						 &pidl))) {
	    SHGetPathFromIDListA(pidl, link_dir);
	    IMalloc_Free(ppM, pidl);
	}
708 709 710 711 712
	else {
	    /* serious issues */
	    link_dir[0] = 0;
	    ERR("serious issues 1\n");
	}
713 714 715 716 717
	IMalloc_Release(ppM);
    }
    else {
	/* serious issues */
	link_dir[0] = 0;
718
	ERR("serious issues 2\n");
719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746
    }
    TRACE("Users Recent dir %s\n", link_dir);

    /* If no input, then go clear the lists */
    if (!pv) {
	/* clear user's Recent dir
	 */

	/* FIXME: delete all files in "link_dir"
	 *
	 * while( more files ) {
	 *    lstrcpyA(old_lnk_name, link_dir);
	 *    PathAppendA(old_lnk_name, filenam);
	 *    DeleteFileA(old_lnk_name);
	 * }
	 */
	FIXME("should delete all files in %s\\ \n", link_dir);

	/* clear MRU list
	 */
	/* MS Bug ?? v4.72.3612.1700 of shell32 does the delete against
	 *  HKEY_LOCAL_MACHINE version of ...CurrentVersion\Explorer
	 *  and naturally it fails w/ rc=2. It should do it against
	 *  HKEY_CURRENT_USER which is where it is stored, and where
	 *  the MRU routines expect it!!!!
	 */
	RegDeleteKeyA(HCUbasekey, "RecentDocs");
	RegCloseKey(HCUbasekey);
747
	return;
748 749 750 751 752
    }

    /* Have data to add, the jobs to be done:
     *   1. Add document to MRU list in registry "HKCU\Software\
     *      Microsoft\Windows\CurrentVersion\Explorer\RecentDocs".
753
     *   2. Add shortcut to document in the user's Recent directory
754 755 756 757 758 759 760 761 762 763
     *      (CSIDL_RECENT).
     *   3. Add shortcut to Start menu's Documents submenu.
     */

    /* Get the pure document name from the input
     */
    if (uFlags & SHARD_PIDL) {
	SHGetPathFromIDListA((LPCITEMIDLIST) pv, doc_name);
    }
    else {
Eric Pouech's avatar
Eric Pouech committed
764
	lstrcpyA(doc_name, (LPCSTR) pv);
765 766
    }
    TRACE("full document name %s\n", doc_name);
767
    PathStripPathA(doc_name);
768 769 770 771 772
    TRACE("stripped document name %s\n", doc_name);


    /* ***  JOB 1: Update registry for ...\Explorer\RecentDocs list  *** */

773 774
    {  /* on input needs:
	*      doc_name    -  pure file-spec, no path
775 776 777 778 779
	*      link_dir    -  path to the user's Recent directory
	*      HCUbasekey  -  key of ...Windows\CurrentVersion\Explorer" node
	* creates:
	*      new_lnk_name-  pure file-spec, no path for new .lnk file
	*      new_lnk_filepath
780
	*                  -  path and file name of new .lnk file
781
	*/
782
	CREATEMRULISTA mymru;
783 784 785 786 787 788 789 790 791
	HANDLE mruhandle;
	INT len, pos, bufused, err;
	INT i;
	DWORD attr;
	CHAR buffer[2048];
	CHAR *ptr;
	CHAR old_lnk_name[MAX_PATH];
	short int slen;

792
	mymru.cbSize = sizeof(CREATEMRULISTA);
793 794 795 796 797
	mymru.nMaxItems = 15;
	mymru.dwFlags = MRUF_BINARY_LIST | MRUF_DELAYED_SAVE;
	mymru.hKey = HCUbasekey;
	mymru.lpszSubKey = "RecentDocs";
	mymru.lpfnCompare = &SHADD_compare_mru;
798
	mruhandle = CreateMRUListA(&mymru);
799 800 801 802
	if (!mruhandle) {
	    /* MRU failed */
	    ERR("MRU processing failed, handle zero\n");
	    RegCloseKey(HCUbasekey);
803
	    return;
804 805
	}
	len = lstrlenA(doc_name);
806
	pos = FindMRUData(mruhandle, doc_name, len, 0);
807

808 809
	/* Now get the MRU entry that will be replaced
	 * and delete the .lnk file for it
810
	 */
811 812
	if ((bufused = EnumMRUListA(mruhandle, (pos == -1) ? 14 : pos,
                                    buffer, 2048)) != -1) {
813 814 815 816 817 818 819 820 821 822 823 824 825
	    ptr = buffer;
	    ptr += (lstrlenA(buffer) + 1);
	    slen = *((short int*)ptr);
	    ptr += 2;  /* skip the length area */
	    if (bufused >= slen + (ptr-buffer)) {
		/* buffer size looks good */
		ptr += 12; /* get to string */
		len = bufused - (ptr-buffer);  /* get length of buf remaining */
		if ((lstrlenA(ptr) > 0) && (lstrlenA(ptr) <= len-1)) {
		    /* appears to be good string */
		    lstrcpyA(old_lnk_name, link_dir);
		    PathAppendA(old_lnk_name, ptr);
		    if (!DeleteFileA(old_lnk_name)) {
826
			if ((attr = GetFileAttributesA(old_lnk_name)) == INVALID_FILE_ATTRIBUTES) {
827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854
			    if ((err = GetLastError()) != ERROR_FILE_NOT_FOUND) {
				ERR("Delete for %s failed, err=%d, attr=%08lx\n",
				    old_lnk_name, err, attr);
			    }
			    else {
				TRACE("old .lnk file %s did not exist\n",
				      old_lnk_name);
			    }
			}
			else {
			    ERR("Delete for %s failed, attr=%08lx\n",
				old_lnk_name, attr);
			}
		    }
		    else {
			TRACE("deleted old .lnk file %s\n", old_lnk_name);
		    }
		}
	    }
	}

	/* Create usable .lnk file name for the "Recent" directory
	 */
	wsprintfA(new_lnk_name, "%s.lnk", doc_name);
	lstrcpyA(new_lnk_filepath, link_dir);
	PathAppendA(new_lnk_filepath, new_lnk_name);
	i = 1;
	olderrormode = SetErrorMode(SEM_FAILCRITICALERRORS);
855
	while (GetFileAttributesA(new_lnk_filepath) != INVALID_FILE_ATTRIBUTES) {
856 857 858 859
	    i++;
	    wsprintfA(new_lnk_name, "%s (%u).lnk", doc_name, i);
	    lstrcpyA(new_lnk_filepath, link_dir);
	    PathAppendA(new_lnk_filepath, new_lnk_name);
Alexandre Julliard's avatar
Alexandre Julliard committed
860
	}
861 862 863 864 865 866 867
	SetErrorMode(olderrormode);
	TRACE("new shortcut will be %s\n", new_lnk_filepath);

	/* Now add the new MRU entry and data
	 */
	pos = SHADD_create_add_mru_data(mruhandle, doc_name, new_lnk_name,
					buffer, &len);
868
	FreeMRUList(mruhandle);
869 870 871 872 873
	TRACE("Updated MRU list, new doc is position %d\n", pos);
    }

    /* ***  JOB 2: Create shortcut in user's "Recent" directory  *** */

874
    {  /* on input needs:
875 876
	*      doc_name    -  pure file-spec, no path
	*      new_lnk_filepath
877
	*                  -  path and file name of new .lnk file
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895
 	*      uFlags[in]  -  flags on call to SHAddToRecentDocs
	*      pv[in]      -  document path/pidl on call to SHAddToRecentDocs
	*/
	IShellLinkA *psl = NULL;
	IPersistFile *pPf = NULL;
	HRESULT hres;
	CHAR desc[MAX_PATH];
	WCHAR widelink[MAX_PATH];

	CoInitialize(0);

	hres = CoCreateInstance( &CLSID_ShellLink,
				 NULL,
				 CLSCTX_INPROC_SERVER,
				 &IID_IShellLinkA,
				 (LPVOID )&psl);
	if(SUCCEEDED(hres)) {

896
	    hres = IShellLinkA_QueryInterface(psl, &IID_IPersistFile,
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
					     (LPVOID *)&pPf);
	    if(FAILED(hres)) {
		/* bombed */
		ERR("failed QueryInterface for IPersistFile %08lx\n", hres);
		goto fail;
	    }

	    /* Set the document path or pidl */
	    if (uFlags & SHARD_PIDL) {
		hres = IShellLinkA_SetIDList(psl, (LPCITEMIDLIST) pv);
	    } else {
		hres = IShellLinkA_SetPath(psl, (LPCSTR) pv);
	    }
	    if(FAILED(hres)) {
		/* bombed */
		ERR("failed Set{IDList|Path} %08lx\n", hres);
		goto fail;
	    }

	    lstrcpyA(desc, "Shortcut to ");
	    lstrcatA(desc, doc_name);
	    hres = IShellLinkA_SetDescription(psl, desc);
	    if(FAILED(hres)) {
		/* bombed */
		ERR("failed SetDescription %08lx\n", hres);
		goto fail;
	    }

925
	    MultiByteToWideChar(CP_ACP, 0, new_lnk_filepath, -1,
926 927 928 929 930 931 932 933 934 935 936 937 938
				widelink, MAX_PATH);
	    /* create the short cut */
	    hres = IPersistFile_Save(pPf, widelink, TRUE);
	    if(FAILED(hres)) {
		/* bombed */
		ERR("failed IPersistFile::Save %08lx\n", hres);
		IPersistFile_Release(pPf);
		IShellLinkA_Release(psl);
		goto fail;
	    }
	    hres = IPersistFile_SaveCompleted(pPf, widelink);
	    IPersistFile_Release(pPf);
	    IShellLinkA_Release(psl);
939
	    TRACE("shortcut %s has been created, result=%08lx\n",
940 941 942 943 944 945 946 947 948 949 950 951
		  new_lnk_filepath, hres);
	}
	else {
	    ERR("CoCreateInstance failed, hres=%08lx\n", hres);
	}
    }

 fail:
    CoUninitialize();

    /* all done */
    RegCloseKey(HCUbasekey);
952
    return;
Alexandre Julliard's avatar
Alexandre Julliard committed
953
}
954

Alexandre Julliard's avatar
Alexandre Julliard committed
955
/*************************************************************************
956
 * SHCreateShellFolderViewEx			[SHELL32.174]
Alexandre Julliard's avatar
Alexandre Julliard committed
957
 *
Alexandre Julliard's avatar
Alexandre Julliard committed
958 959
 * NOTES
 *  see IShellFolder::CreateViewObject
Alexandre Julliard's avatar
Alexandre Julliard committed
960
 */
961
HRESULT WINAPI SHCreateShellFolderViewEx(
962 963
	LPCSFV psvcbi,    /* [in] shelltemplate struct */
	IShellView **ppv) /* [out] IShellView pointer */
964 965 966
{
	IShellView * psf;
	HRESULT hRes;
967

968
	TRACE("sf=%p pidl=%p cb=%p mode=0x%08x parm=%p\n",
969
	  psvcbi->pshf, psvcbi->pidl, psvcbi->pfnCallback,
970
	  psvcbi->fvm, psvcbi->psvOuter);
971

972
	psf = IShellView_Constructor(psvcbi->pshf);
973

974 975 976 977 978 979 980 981
	if (!psf)
	  return E_OUTOFMEMORY;

	IShellView_AddRef(psf);
	hRes = IShellView_QueryInterface(psf, &IID_IShellView, (LPVOID *)ppv);
	IShellView_Release(psf);

	return hRes;
Alexandre Julliard's avatar
Alexandre Julliard committed
982
}
Alexandre Julliard's avatar
Alexandre Julliard committed
983
/*************************************************************************
984
 *  SHWinHelp					[SHELL32.127]
Alexandre Julliard's avatar
Alexandre Julliard committed
985 986 987
 *
 */
HRESULT WINAPI SHWinHelp (DWORD v, DWORD w, DWORD x, DWORD z)
988
{	FIXME("0x%08lx 0x%08lx 0x%08lx 0x%08lx stub\n",v,w,x,z);
Alexandre Julliard's avatar
Alexandre Julliard committed
989 990 991
	return 0;
}
/*************************************************************************
Eric Kohl's avatar
Eric Kohl committed
992
 *  SHRunControlPanel [SHELL32.161]
Alexandre Julliard's avatar
Alexandre Julliard committed
993 994
 *
 */
Eric Kohl's avatar
Eric Kohl committed
995
HRESULT WINAPI SHRunControlPanel (DWORD x, DWORD z)
996
{	FIXME("0x%08lx 0x%08lx stub\n",x,z);
Alexandre Julliard's avatar
Alexandre Julliard committed
997 998
	return 0;
}
999

1000
static LPUNKNOWN SHELL32_IExplorerInterface=0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1001
/*************************************************************************
1002
 * SHSetInstanceExplorer			[SHELL32.176]
Alexandre Julliard's avatar
Alexandre Julliard committed
1003
 *
1004 1005
 * NOTES
 *  Sets the interface
Alexandre Julliard's avatar
Alexandre Julliard committed
1006
 */
1007
HRESULT WINAPI SHSetInstanceExplorer (LPUNKNOWN lpUnknown)
1008
{	TRACE("%p\n", lpUnknown);
1009 1010
	SHELL32_IExplorerInterface = lpUnknown;
	return (HRESULT) lpUnknown;
Alexandre Julliard's avatar
Alexandre Julliard committed
1011 1012
}
/*************************************************************************
1013
 * SHGetInstanceExplorer			[SHELL32.@]
Alexandre Julliard's avatar
Alexandre Julliard committed
1014 1015
 *
 * NOTES
1016
 *  gets the interface pointer of the explorer and a reference
Alexandre Julliard's avatar
Alexandre Julliard committed
1017
 */
1018
HRESULT WINAPI SHGetInstanceExplorer (LPUNKNOWN * lpUnknown)
1019
{	TRACE("%p\n", lpUnknown);
1020 1021 1022 1023 1024 1025

	*lpUnknown = SHELL32_IExplorerInterface;

	if (!SHELL32_IExplorerInterface)
	  return E_FAIL;

1026
	IUnknown_AddRef(SHELL32_IExplorerInterface);
1027
	return NOERROR;
Alexandre Julliard's avatar
Alexandre Julliard committed
1028 1029
}
/*************************************************************************
1030
 * SHFreeUnusedLibraries			[SHELL32.123]
Alexandre Julliard's avatar
Alexandre Julliard committed
1031 1032 1033 1034
 *
 * NOTES
 *  exported by name
 */
1035 1036 1037
void WINAPI SHFreeUnusedLibraries (void)
{
	FIXME("stub\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
1038
}
1039 1040 1041 1042
/*************************************************************************
 * DAD_AutoScroll				[SHELL32.129]
 *
 */
1043
BOOL WINAPI DAD_AutoScroll(HWND hwnd, AUTO_SCROLL_DATA *samples, LPPOINT pt)
1044
{
1045
    FIXME("hwnd = %p %p %p\n",hwnd,samples,pt);
1046 1047 1048 1049 1050 1051 1052 1053
    return 0;
}
/*************************************************************************
 * DAD_DragEnter				[SHELL32.130]
 *
 */
BOOL WINAPI DAD_DragEnter(HWND hwnd)
{
1054
    FIXME("hwnd = %p\n",hwnd);
1055 1056 1057 1058 1059 1060 1061 1062
    return FALSE;
}
/*************************************************************************
 * DAD_DragEnterEx				[SHELL32.131]
 *
 */
BOOL WINAPI DAD_DragEnterEx(HWND hwnd, POINT p)
{
1063
    FIXME("hwnd = %p (%ld,%ld)\n",hwnd,p.x,p.y);
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075
    return FALSE;
}
/*************************************************************************
 * DAD_DragMove				[SHELL32.134]
 *
 */
BOOL WINAPI DAD_DragMove(POINT p)
{
    FIXME("(%ld,%ld)\n",p.x,p.y);
    return FALSE;
}
/*************************************************************************
1076
 * DAD_DragLeave				[SHELL32.132]
1077 1078 1079 1080 1081 1082 1083
 *
 */
BOOL WINAPI DAD_DragLeave(VOID)
{
    FIXME("\n");
    return FALSE;
}
1084 1085 1086 1087 1088 1089
/*************************************************************************
 * DAD_SetDragImage				[SHELL32.136]
 *
 * NOTES
 *  exported by name
 */
1090 1091 1092 1093 1094
BOOL WINAPI DAD_SetDragImage(
	HIMAGELIST himlTrack,
	LPPOINT lppt)
{
	FIXME("%p %p stub\n",himlTrack, lppt);
1095 1096
  return 0;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
1097
/*************************************************************************
1098
 * DAD_ShowDragImage				[SHELL32.137]
Alexandre Julliard's avatar
Alexandre Julliard committed
1099 1100 1101 1102
 *
 * NOTES
 *  exported by name
 */
1103 1104 1105 1106
BOOL WINAPI DAD_ShowDragImage(BOOL bShow)
{
	FIXME("0x%08x stub\n",bShow);
	return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
1107
}
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119

static const WCHAR szwCabLocation[] = {
  'S','o','f','t','w','a','r','e','\\',
  'M','i','c','r','o','s','o','f','t','\\',
  'W','i','n','d','o','w','s','\\',
  'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
  'E','x','p','l','o','r','e','r','\\',
  'C','a','b','i','n','e','t','S','t','a','t','e',0
};

static const WCHAR szwSettings[] = { 'S','e','t','t','i','n','g','s',0 };

1120
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1121
 * ReadCabinetState				[SHELL32.651] NT 4.0
1122 1123
 *
 */
1124 1125 1126 1127 1128 1129 1130
BOOL WINAPI ReadCabinetState(CABINETSTATE *cs, int length)
{
	HKEY hkey = 0;
	DWORD type, r;

	TRACE("%p %d \n",cs,length);

1131
	if( (cs == NULL) || (length < (int)sizeof(*cs))  )
1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
		return FALSE;

	r = RegOpenKeyW( HKEY_CURRENT_USER, szwCabLocation, &hkey );
	if( r == ERROR_SUCCESS )
	{
		type = REG_BINARY;
		r = RegQueryValueExW( hkey, szwSettings, 
			NULL, &type, (LPBYTE)cs, (LPDWORD)&length );
		RegCloseKey( hkey );
			
	}

	/* if we can't read from the registry, create default values */
1145
	if ( (r != ERROR_SUCCESS) || (cs->cLength < sizeof(*cs)) ||
1146 1147 1148
		(cs->cLength != length) )
	{
		ERR("Initializing shell cabinet settings\n");
1149 1150
		memset(cs, 0, sizeof(*cs));
		cs->cLength          = sizeof(*cs);
1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
		cs->nVersion         = 2;
		cs->fFullPathTitle   = FALSE;
		cs->fSaveLocalView   = TRUE;
		cs->fNotShell        = FALSE;
		cs->fSimpleDefault   = TRUE;
		cs->fDontShowDescBar = FALSE;
		cs->fNewWindowMode   = FALSE;
		cs->fShowCompColor   = FALSE;
		cs->fDontPrettyNames = FALSE;
		cs->fAdminsCreateCommonGroups = TRUE;
		cs->fMenuEnumFilter  = 96;
	}
	
	return TRUE;
1165
}
1166

1167
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1168
 * WriteCabinetState				[SHELL32.652] NT 4.0
1169 1170
 *
 */
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191
BOOL WINAPI WriteCabinetState(CABINETSTATE *cs)
{
	DWORD r;
	HKEY hkey = 0;

	TRACE("%p\n",cs);

	if( cs == NULL )
		return FALSE;

	r = RegCreateKeyExW( HKEY_CURRENT_USER, szwCabLocation, 0,
		 NULL, 0, KEY_ALL_ACCESS, NULL, &hkey, NULL);
	if( r == ERROR_SUCCESS )
	{
		r = RegSetValueExW( hkey, szwSettings, 0, 
			REG_BINARY, (LPBYTE) cs, cs->cLength);

		RegCloseKey( hkey );
	}

	return (r==ERROR_SUCCESS);
1192
}
1193

1194
/*************************************************************************
1195
 * FileIconInit 				[SHELL32.660]
1196 1197
 *
 */
1198
BOOL WINAPI FileIconInit(BOOL bFullInit)
1199
{	FIXME("(%s)\n", bFullInit ? "true" : "false");
1200 1201
	return 0;
}
1202
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1203
 * IsUserAdmin					[SHELL32.680] NT 4.0
1204 1205
 *
 */
1206
HRESULT WINAPI IsUserAdmin(void)
1207
{	FIXME("stub\n");
1208
	return TRUE;
Alexandre Julliard's avatar
Alexandre Julliard committed
1209
}
1210

1211
/*************************************************************************
1212
 * SHAllocShared				[SHELL32.520]
1213
 *
1214
 * See shlwapi.SHAllocShared
1215
 */
1216 1217 1218 1219
HANDLE WINAPI SHAllocShared(LPVOID lpvData, DWORD dwSize, DWORD dwProcId)
{
    GET_FUNC(pSHAllocShared, shlwapi, (char*)7, NULL);
    return pSHAllocShared(lpvData, dwSize, dwProcId);
1220
}
1221

1222
/*************************************************************************
1223
 * SHLockShared					[SHELL32.521]
1224
 *
1225
 * See shlwapi.SHLockShared
1226
 */
1227 1228 1229 1230
LPVOID WINAPI SHLockShared(HANDLE hShared, DWORD dwProcId)
{
    GET_FUNC(pSHLockShared, shlwapi, (char*)8, NULL);
    return pSHLockShared(hShared, dwProcId);
1231
}
1232

1233
/*************************************************************************
1234
 * SHUnlockShared				[SHELL32.522]
1235
 *
1236
 * See shlwapi.SHUnlockShared
1237
 */
1238
BOOL WINAPI SHUnlockShared(LPVOID lpView)
1239
{
1240 1241
    GET_FUNC(pSHUnlockShared, shlwapi, (char*)9, FALSE);
    return pSHUnlockShared(lpView);
1242
}
1243

1244
/*************************************************************************
1245
 * SHFreeShared					[SHELL32.523]
1246
 *
1247
 * See shlwapi.SHFreeShared
1248
 */
1249
BOOL WINAPI SHFreeShared(HANDLE hShared, DWORD dwProcId)
1250
{
1251 1252
    GET_FUNC(pSHFreeShared, shlwapi, (char*)10, FALSE);
    return pSHFreeShared(hShared, dwProcId);
1253 1254 1255
}

/*************************************************************************
1256
 * SetAppStartingCursor				[SHELL32.99]
Eric Kohl's avatar
Eric Kohl committed
1257
 */
1258
HRESULT WINAPI SetAppStartingCursor(HWND u, DWORD v)
1259
{	FIXME("hwnd=%p 0x%04lx stub\n",u,v );
1260 1261 1262
	return 0;
}
/*************************************************************************
1263
 * SHLoadOLE					[SHELL32.151]
1264 1265
 *
 */
1266 1267
HRESULT WINAPI SHLoadOLE(LPARAM lParam)
{	FIXME("0x%04lx stub\n",lParam);
1268 1269 1270
	return S_OK;
}
/*************************************************************************
1271
 * DriveType					[SHELL32.64]
1272 1273
 *
 */
1274
HRESULT WINAPI DriveType(DWORD u)
1275
{	FIXME("0x%04lx stub\n",u);
1276 1277 1278
	return 0;
}
/*************************************************************************
1279
 * SHAbortInvokeCommand				[SHELL32.198]
1280 1281
 *
 */
1282
HRESULT WINAPI SHAbortInvokeCommand(void)
1283
{	FIXME("stub\n");
1284 1285 1286
	return 1;
}
/*************************************************************************
1287
 * SHOutOfMemoryMessageBox			[SHELL32.126]
1288 1289
 *
 */
1290 1291 1292 1293 1294
int WINAPI SHOutOfMemoryMessageBox(
	HWND hwndOwner,
	LPCSTR lpCaption,
	UINT uType)
{
1295
	FIXME("%p %s 0x%08x stub\n",hwndOwner, lpCaption, uType);
Eric Kohl's avatar
Eric Kohl committed
1296 1297
	return 0;
}
1298
/*************************************************************************
1299
 * SHFlushClipboard				[SHELL32.121]
1300 1301
 *
 */
1302
HRESULT WINAPI SHFlushClipboard(void)
1303
{	FIXME("stub\n");
1304 1305
	return 1;
}
1306

1307
/*************************************************************************
1308
 * SHWaitForFileToOpen				[SHELL32.97]
1309 1310
 *
 */
1311
BOOL WINAPI SHWaitForFileToOpen(
1312
	LPCITEMIDLIST pidl,
1313 1314 1315 1316
	DWORD dwFlags,
	DWORD dwTimeout)
{
	FIXME("%p 0x%08lx 0x%08lx stub\n", pidl, dwFlags, dwTimeout);
1317 1318
	return 0;
}
Juergen Schmied's avatar
Juergen Schmied committed
1319

1320
/************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1321
 *	@				[SHELL32.654]
1322
 *
1323 1324 1325 1326
 * NOTES: first parameter seems to be a pointer (same as passed to WriteCabinetState)
 * second one could be a size (0x0c). The size is the same as the structure saved to
 * HCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
 * I'm (js) guessing: this one is just ReadCabinetState ;-)
1327
 */
1328 1329 1330 1331
HRESULT WINAPI shell32_654 (CABINETSTATE *cs, int length)
{
	TRACE("%p %d\n",cs,length);
	return ReadCabinetState(cs,length);
Juergen Schmied's avatar
Juergen Schmied committed
1332
}
1333 1334 1335 1336 1337 1338 1339

/************************************************************************
 *	RLBuildListOfPaths			[SHELL32.146]
 *
 * NOTES
 *   builds a DPA
 */
1340
DWORD WINAPI RLBuildListOfPaths (void)
1341
{	FIXME("stub\n");
1342 1343
	return 0;
}
1344 1345 1346 1347
/************************************************************************
 *	SHValidateUNC				[SHELL32.173]
 *
 */
1348
HRESULT WINAPI SHValidateUNC (DWORD x, DWORD y, DWORD z)
1349 1350 1351 1352 1353 1354
{
	FIXME("0x%08lx 0x%08lx 0x%08lx stub\n",x,y,z);
	return 0;
}

/************************************************************************
1355
 *	DoEnvironmentSubstA			[SHELL32.@]
1356 1357 1358 1359
 *
 */
HRESULT WINAPI DoEnvironmentSubstA(LPSTR x, LPSTR y)
{
1360
	FIXME("(%s, %s) stub\n", debugstr_a(x), debugstr_a(y));
1361 1362
	return 0;
}
1363

1364
/************************************************************************
1365
 *	DoEnvironmentSubstW			[SHELL32.@]
1366 1367
 *
 */
1368 1369
HRESULT WINAPI DoEnvironmentSubstW(LPWSTR x, LPWSTR y)
{
1370
	FIXME("(%s, %s): stub\n", debugstr_w(x), debugstr_w(y));
1371 1372 1373
	return 0;
}

1374 1375 1376 1377
/************************************************************************
 *	DoEnvironmentSubst			[SHELL32.53]
 *
 */
1378 1379
HRESULT WINAPI DoEnvironmentSubstAW(LPVOID x, LPVOID y)
{
1380
	if (SHELL_OsIsUnicode())
1381 1382 1383
	  return DoEnvironmentSubstW(x, y);
	return DoEnvironmentSubstA(x, y);
}
1384

1385
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1386
 *      @                             [SHELL32.243]
1387
 *
1388 1389 1390 1391 1392
 * Win98+ by-ordinal routine.  In Win98 this routine returns zero and
 * does nothing else.  Possibly this does something in NT or SHELL32 5.0?
 *
 */

1393 1394 1395
BOOL WINAPI shell32_243(DWORD a, DWORD b)
{
  return FALSE;
1396
}
1397

1398
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1399
 *      @	[SHELL32.714]
1400 1401 1402 1403 1404 1405
 */
DWORD WINAPI SHELL32_714(LPVOID x)
{
 	FIXME("(%s)stub\n", debugstr_w(x));
	return 0;
}
1406 1407

/*************************************************************************
1408
 *      SHAddFromPropSheetExtArray	[SHELL32.167]
1409 1410 1411 1412 1413 1414 1415 1416
 */
DWORD WINAPI SHAddFromPropSheetExtArray(DWORD a, DWORD b, DWORD c)
{
 	FIXME("(%08lx,%08lx,%08lx)stub\n", a, b, c);
	return 0;
}

/*************************************************************************
1417
 *      SHCreatePropSheetExtArray	[SHELL32.168]
1418 1419 1420 1421 1422 1423 1424 1425
 */
DWORD WINAPI SHCreatePropSheetExtArray(DWORD a, LPCSTR b, DWORD c)
{
 	FIXME("(%08lx,%s,%08lx)stub\n", a, debugstr_a(b), c);
	return 0;
}

/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
1426
 *      SHReplaceFromPropSheetExtArray	[SHELL32.170]
1427 1428 1429 1430 1431 1432 1433 1434
 */
DWORD WINAPI SHReplaceFromPropSheetExtArray(DWORD a, DWORD b, DWORD c, DWORD d)
{
 	FIXME("(%08lx,%08lx,%08lx,%08lx)stub\n", a, b, c, d);
	return 0;
}

/*************************************************************************
1435
 *      SHDestroyPropSheetExtArray	[SHELL32.169]
1436 1437 1438 1439 1440 1441
 */
DWORD WINAPI SHDestroyPropSheetExtArray(DWORD a)
{
 	FIXME("(%08lx)stub\n", a);
	return 0;
}
1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453

/*************************************************************************
 *      CIDLData_CreateFromIDArray	[SHELL32.83]
 *
 *  Create IDataObject from PIDLs??
 */
HRESULT WINAPI CIDLData_CreateFromIDArray(
	LPCITEMIDLIST pidlFolder,
	DWORD cpidlFiles,
	LPCITEMIDLIST *lppidlFiles,
	LPDATAOBJECT *ppdataObject)
{
1454
    UINT i;
1455
    HWND hwnd = 0;   /*FIXME: who should be hwnd of owner? set to desktop */
1456 1457 1458 1459

    TRACE("(%p, %ld, %p, %p)\n", pidlFolder, cpidlFiles, lppidlFiles, ppdataObject);
    if (TRACE_ON(pidl))
    {
1460
	pdump (pidlFolder);
1461
	for (i=0; i<cpidlFiles; i++) pdump (lppidlFiles[i]);
1462 1463 1464 1465 1466 1467
    }
    *ppdataObject = IDataObject_Constructor( hwnd, pidlFolder,
					     lppidlFiles, cpidlFiles);
    if (*ppdataObject) return S_OK;
    return E_OUTOFMEMORY;
}
1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493

/*************************************************************************
 * SHCreateStdEnumFmtEtc			[SHELL32.74]
 *
 * NOTES
 *
 */
HRESULT WINAPI SHCreateStdEnumFmtEtc(
	DWORD cFormats,
	const FORMATETC *lpFormats,
	LPENUMFORMATETC *ppenumFormatetc)
{
	IEnumFORMATETC *pef;
	HRESULT hRes;
	TRACE("cf=%ld fe=%p pef=%p\n", cFormats, lpFormats, ppenumFormatetc);

	pef = IEnumFORMATETC_Constructor(cFormats, lpFormats);
	if (!pef)
	  return E_OUTOFMEMORY;

	IEnumFORMATETC_AddRef(pef);
	hRes = IEnumFORMATETC_QueryInterface(pef, &IID_IEnumFORMATETC, (LPVOID*)ppenumFormatetc);
	IEnumFORMATETC_Release(pef);

	return hRes;
}
1494 1495 1496


/*************************************************************************
1497
 *		SHELL32_256 (SHELL32.256)
1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
 */
HRESULT WINAPI SHELL32_256(LPDWORD lpdw0, LPDWORD lpdw1)
{
    HRESULT ret = S_OK;

    FIXME("stub %p 0x%08lx %p\n", lpdw0, lpdw0 ? *lpdw0 : 0, lpdw1);

    if (!lpdw0 || *lpdw0 != 0x10)
        ret = E_INVALIDARG;
    else
    {
1509
        LPVOID lpdata = 0;/*LocalAlloc(LMEM_ZEROINIT, 0x4E4);*/
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520

	if (!lpdata)
            ret = E_OUTOFMEMORY;
	else
	{
            /* Initialize and return unknown lpdata structure */
	}
    }

    return ret;
}
1521

1522 1523 1524
/*************************************************************************
 *		SHFindFiles (SHELL32.90)
 */
1525 1526 1527 1528 1529
BOOL WINAPI SHFindFiles( LPCITEMIDLIST pidlFolder, LPCITEMIDLIST pidlSaveFile )
{
    FIXME("%p %p\n", pidlFolder, pidlSaveFile );
    return FALSE;
}
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548

/*************************************************************************
 *		SHUpdateImageW (SHELL32.192)
 *
 * Notifies the shell that an icon in the system image list has been changed.
 *
 * PARAMS
 *  pszHashItem [I] Path to file that contains the icon.
 *  iIndex      [I] Zero-based index of the icon in the file.
 *  uFlags      [I] Flags determining the icon attributes. See notes.
 *  iImageIndex [I] Index of the icon in the system image list.
 *
 * NOTES
 *  uFlags can be one or more of the following flags:
 *  GIL_NOTFILENAME - pszHashItem is not a file name.
 *  GIL_SIMULATEDOC - Create a document icon using the specified icon.
 */
void WINAPI SHUpdateImageW(LPCWSTR pszHashItem, int iIndex, UINT uFlags, int iImageIndex)
{
1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634
    FIXME("%s, %d, 0x%x, %d - stub\n", debugstr_w(pszHashItem), iIndex, uFlags, iImageIndex);
}

VOID WINAPI SHUpdateImageA(LPCSTR pszHashItem, INT iIndex, UINT uFlags, INT iImageIndex)
{
    FIXME("%s, %d, 0x%x, %d - stub\n", debugstr_a(pszHashItem), iIndex, uFlags, iImageIndex);
}

INT WINAPI SHHandleUpdateImage(LPCITEMIDLIST pidlExtra)
{
    FIXME("%p - stub\n", pidlExtra);

    return -1;
}

BOOL WINAPI SHObjectProperties(HWND hwnd, DWORD dwType, LPCWSTR szObject, LPCWSTR szPage)
{
    FIXME("%p, 0x%08lx, %s, %s - stub\n", hwnd, dwType, debugstr_w(szObject), debugstr_w(szPage));

    return TRUE;
}

BOOL WINAPI SHGetNewLinkInfoA(LPCSTR pszLinkTo, LPCSTR pszDir, LPSTR pszName, BOOL *pfMustCopy,
                              UINT uFlags)
{
    FIXME("%s, %s, %p, %p, 0x%08x - stub\n", debugstr_a(pszLinkTo), debugstr_a(pszDir),
          pszName, pfMustCopy, uFlags);

    return FALSE;
}

BOOL WINAPI SHGetNewLinkInfoW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName, BOOL *pfMustCopy,
                              UINT uFlags)
{
    FIXME("%s, %s, %p, %p, 0x%08x - stub\n", debugstr_w(pszLinkTo), debugstr_w(pszDir),
          pszName, pfMustCopy, uFlags);

    return FALSE;
}

HRESULT WINAPI SHStartNetConnectionDialog(HWND hwnd, LPCSTR pszRemoteName, DWORD dwType)
{
    FIXME("%p, %s, 0x%08lx - stub\n", hwnd, debugstr_a(pszRemoteName), dwType);

    return S_OK;
}

HRESULT WINAPI SHEmptyRecycleBinA(HWND hwnd, LPCSTR pszRootPath, DWORD dwFlags)
{
    FIXME("%p, %s, 0x%08lx - stub\n", hwnd, debugstr_a(pszRootPath), dwFlags);

    return S_OK;
}

HRESULT WINAPI SHEmptyRecycleBinW(HWND hwnd, LPCWSTR pszRootPath, DWORD dwFlags)
{
    FIXME("%p, %s, 0x%08lx - stub\n", hwnd, debugstr_w(pszRootPath), dwFlags);

    return S_OK;
}

DWORD WINAPI SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
{
    FIXME("%p, 0x%08x, 0x%08x, 0x%08x - stub\n", hwnd, drive, fmtID, options);

    return SHFMT_NOFORMAT;
}

HRESULT WINAPI SHQueryRecycleBinA(LPCSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo)
{
    FIXME("%s, %p - stub\n", debugstr_a(pszRootPath), pSHQueryRBInfo);

    pSHQueryRBInfo->i64Size = 0;
    pSHQueryRBInfo->i64NumItems = 0;

    return S_OK;
}

HRESULT WINAPI SHQueryRecycleBinW(LPCWSTR pszRootPath, LPSHQUERYRBINFO pSHQueryRBInfo)
{
    FIXME("%s, %p - stub\n", debugstr_w(pszRootPath), pSHQueryRBInfo);

    pSHQueryRBInfo->i64Size = 0;
    pSHQueryRBInfo->i64NumItems = 0;

    return S_OK;
1635
}