shell.c 17.9 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2
/*
 * 				Shell Library Functions
Alexandre Julliard's avatar
Alexandre Julliard committed
3
 *
4
 * Copyright 1998 Marcus Meissner
5
 * Copyright 2000 Juergen Schmied
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * Copyright 2002 Eric Pouech
 *
 * 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"
24
#include "wine/port.h"
25

26
#include <stdarg.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
27 28
#include <stdlib.h>
#include <string.h>
29 30 31
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
32
#include <ctype.h>
33

34
#include "windef.h"
35
#include "winbase.h"
36 37
#include "winerror.h"
#include "winreg.h"
38
#include "wownt32.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
39
#include "dlgs.h"
40
#include "shellapi.h"
41 42
#include "winuser.h"
#include "wingdi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
43
#include "shlobj.h"
44
#include "shlwapi.h"
45
#include "ddeml.h"
46 47 48 49 50

#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "shell32_main.h"

51
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
52

53 54
WINE_DEFAULT_DEBUG_CHANNEL(shell);
WINE_DECLARE_DEBUG_CHANNEL(exec);
55

Alexandre Julliard's avatar
Alexandre Julliard committed
56

57 58 59 60 61 62 63
typedef struct {     /* structure for dropped files */
 WORD     wSize;
 POINT16  ptMousePos;
 BOOL16   fInNonClientArea;
 /* memory block with filenames follows */
} DROPFILESTRUCT16, *LPDROPFILESTRUCT16;

Alexandre Julliard's avatar
Alexandre Julliard committed
64 65 66 67
static const char*	lpstrMsgWndCreated = "OTHERWINDOWCREATED";
static const char*	lpstrMsgWndDestroyed = "OTHERWINDOWDESTROYED";
static const char*	lpstrMsgShellActivate = "ACTIVATESHELLWINDOW";

68
static HWND	SHELL_hWnd = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
69
static HHOOK	SHELL_hHook = 0;
70 71 72
static UINT	uMsgWndCreated = 0;
static UINT	uMsgWndDestroyed = 0;
static UINT	uMsgShellActivate = 0;
73 74 75 76 77
HINSTANCE16	SHELL_hInstance = 0;
HINSTANCE SHELL_hInstance32;
static int SHELL_Attach = 0;

/***********************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
78
 * DllEntryPoint [SHELL.101]
79 80 81 82
 *
 * Initialization code for shell.dll. Automatically loads the
 * 32-bit shell32.dll to allow thunking up to 32-bit code.
 *
Jon Griffiths's avatar
Jon Griffiths committed
83 84 85
 * RETURNS
 *  Success: TRUE. Initialization completed successfully.
 *  Failure: FALSE.
86 87 88 89
 */
BOOL WINAPI SHELL_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst,
				WORD ds, WORD HeapSize, DWORD res1, WORD res2)
{
90 91
    TRACE("(%08lx, %04x, %04x, %04x, %08lx, %04x)\n",
          Reason, hInst, ds, HeapSize, res1, res2);
92 93 94 95

    switch(Reason)
    {
    case DLL_PROCESS_ATTACH:
96
	if (SHELL_Attach++) break;
97 98 99 100 101
	SHELL_hInstance = hInst;
	if(!SHELL_hInstance32)
	{
	    if(!(SHELL_hInstance32 = LoadLibraryA("shell32.dll")))
	    {
102
		ERR("Could not load sibling shell32.dll\n");
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
		return FALSE;
	    }
	}
	break;

    case DLL_PROCESS_DETACH:
	if(!--SHELL_Attach)
	{
	    SHELL_hInstance = 0;
	    if(SHELL_hInstance32)
		FreeLibrary(SHELL_hInstance32);
	}
	break;
    }
    return TRUE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
119

Kai Morich's avatar
Kai Morich committed
120
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
121
 *				DragAcceptFiles		[SHELL.9]
Kai Morich's avatar
Kai Morich committed
122 123 124
 */
void WINAPI DragAcceptFiles16(HWND16 hWnd, BOOL16 b)
{
125
  DragAcceptFiles(HWND_32(hWnd), b);
Alexandre Julliard's avatar
Alexandre Julliard committed
126 127
}

Kai Morich's avatar
Kai Morich committed
128
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
129
 *				DragQueryFile		[SHELL.11]
Kai Morich's avatar
Kai Morich committed
130
 */
131 132 133 134 135
UINT16 WINAPI DragQueryFile16(
	HDROP16 hDrop,
	WORD wFile,
	LPSTR lpszFile,
	WORD wLength)
Kai Morich's avatar
Kai Morich committed
136
{
137 138
 	LPSTR lpDrop;
	UINT i = 0;
139 140
	LPDROPFILESTRUCT16 lpDropFileStruct = (LPDROPFILESTRUCT16) GlobalLock16(hDrop);

141
	TRACE("(%04x, %x, %p, %u)\n", hDrop,wFile,lpszFile,wLength);
142

143
	if(!lpDropFileStruct) goto end;
144

145
	lpDrop = (LPSTR) lpDropFileStruct + lpDropFileStruct->wSize;
Kai Morich's avatar
Kai Morich committed
146

147 148 149
	while (i++ < wFile)
	{
	  while (*lpDrop++); /* skip filename */
150
	  if (!*lpDrop)
151
	  {
Alexandre Julliard's avatar
Alexandre Julliard committed
152
	    i = (wFile == 0xFFFF) ? i : 0;
153 154 155
	    goto end;
	  }
	}
156

157
	i = strlen(lpDrop);
158 159 160 161 162 163 164
	i++;
	if (!lpszFile ) goto end;   /* needed buffer size */
	i = (wLength > i) ? i : wLength;
	lstrcpynA (lpszFile,  lpDrop,  i);
end:
	GlobalUnlock16(hDrop);
	return i;
Kai Morich's avatar
Kai Morich committed
165 166 167
}

/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
168
 *				DragFinish		[SHELL.12]
Kai Morich's avatar
Kai Morich committed
169 170
 */
void WINAPI DragFinish16(HDROP16 h)
171 172
{
    TRACE("\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
173
    GlobalFree16((HGLOBAL16)h);
Alexandre Julliard's avatar
Alexandre Julliard committed
174 175 176
}


Kai Morich's avatar
Kai Morich committed
177
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
178
 *				DragQueryPoint		[SHELL.13]
Kai Morich's avatar
Kai Morich committed
179 180 181
 */
BOOL16 WINAPI DragQueryPoint16(HDROP16 hDrop, POINT16 *p)
{
182
  LPDROPFILESTRUCT16 lpDropFileStruct;
Kai Morich's avatar
Kai Morich committed
183
  BOOL16           bRet;
184
  TRACE("\n");
Kai Morich's avatar
Kai Morich committed
185
  lpDropFileStruct = (LPDROPFILESTRUCT16) GlobalLock16(hDrop);
186

Kai Morich's avatar
Kai Morich committed
187 188
  memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT16));
  bRet = lpDropFileStruct->fInNonClientArea;
189

Kai Morich's avatar
Kai Morich committed
190 191
  GlobalUnlock16(hDrop);
  return bRet;
Alexandre Julliard's avatar
Alexandre Julliard committed
192 193
}

Alexandre Julliard's avatar
Alexandre Julliard committed
194
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
195
 *             FindExecutable   (SHELL.21)
Alexandre Julliard's avatar
Alexandre Julliard committed
196
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
197 198
HINSTANCE16 WINAPI FindExecutable16( LPCSTR lpFile, LPCSTR lpDirectory,
                                     LPSTR lpResult )
199
{ return HINSTANCE_16(FindExecutableA( lpFile, lpDirectory, lpResult ));
Alexandre Julliard's avatar
Alexandre Julliard committed
200 201
}

Alexandre Julliard's avatar
Alexandre Julliard committed
202
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
203
 *             AboutDlgProc   (SHELL.33)
Alexandre Julliard's avatar
Alexandre Julliard committed
204
 */
205
BOOL16 WINAPI AboutDlgProc16( HWND16 hWnd, UINT16 msg, WPARAM16 wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
206
                               LPARAM lParam )
207
{ return (BOOL16)AboutDlgProc( HWND_32(hWnd), msg, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
208 209
}

Alexandre Julliard's avatar
Alexandre Julliard committed
210

Alexandre Julliard's avatar
Alexandre Julliard committed
211
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
212
 *             ShellAbout   (SHELL.22)
Alexandre Julliard's avatar
Alexandre Julliard committed
213
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
214 215
BOOL16 WINAPI ShellAbout16( HWND16 hWnd, LPCSTR szApp, LPCSTR szOtherStuff,
                            HICON16 hIcon )
216
{ return ShellAboutA( HWND_32(hWnd), szApp, szOtherStuff, HICON_32(hIcon) );
Alexandre Julliard's avatar
Alexandre Julliard committed
217 218
}

Alexandre Julliard's avatar
Alexandre Julliard committed
219 220 221 222 223
/*************************************************************************
 *			InternalExtractIcon		[SHELL.39]
 *
 * This abortion is called directly by Progman
 */
224
HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
225
                                     LPCSTR lpszExeFileName, UINT16 nIconIndex, WORD n )
226 227 228 229 230
{
    HGLOBAL16 hRet = 0;
    HICON16 *RetPtr = NULL;
    OFSTRUCT ofs;

231
	TRACE("(%04x,file %s,start %d,extract %d\n",
Alexandre Julliard's avatar
Alexandre Julliard committed
232 233
		       hInstance, lpszExeFileName, nIconIndex, n);

234
	if (!n)
235
	  return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
236

237
	hRet = GlobalAlloc16(GMEM_FIXED | GMEM_ZEROINIT, sizeof(*RetPtr) * n);
238
	RetPtr = (HICON16*)GlobalLock16(hRet);
Alexandre Julliard's avatar
Alexandre Julliard committed
239

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
	if (nIconIndex == (UINT16)-1)  /* get number of icons */
	{
	  RetPtr[0] = PrivateExtractIconsA(ofs.szPathName, 0, 0, 0, NULL, NULL, 0, LR_DEFAULTCOLOR);
	}
	else
	{
	  UINT ret;
	  HICON *icons;

	  icons = HeapAlloc(GetProcessHeap(), 0, n * sizeof(*icons));
	  ret = PrivateExtractIconsA(ofs.szPathName, nIconIndex,
	                             GetSystemMetrics(SM_CXICON),
	                             GetSystemMetrics(SM_CYICON),
	                             icons, NULL, n, LR_DEFAULTCOLOR);
	  if ((ret != 0xffffffff) && ret)
255 256
	  {
	    int i;
257
	    for (i = 0; i < n; i++) RetPtr[i] = HICON_16(icons[i]);
258
	  }
259 260 261 262 263 264
	  else
	  {
	    GlobalFree16(hRet);
	    hRet = 0;
	  }
	  HeapFree(GetProcessHeap(), 0, icons);
265
	}
266
	return hRet;
Alexandre Julliard's avatar
Alexandre Julliard committed
267 268
}

Alexandre Julliard's avatar
Alexandre Julliard committed
269
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
270
 *             ExtractIcon   (SHELL.34)
Alexandre Julliard's avatar
Alexandre Julliard committed
271
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
272
HICON16 WINAPI ExtractIcon16( HINSTANCE16 hInstance, LPCSTR lpszExeFileName,
Alexandre Julliard's avatar
Alexandre Julliard committed
273
	UINT16 nIconIndex )
274
{   TRACE("\n");
275
    return HICON_16(ExtractIconA(HINSTANCE_32(hInstance), lpszExeFileName, nIconIndex));
Alexandre Julliard's avatar
Alexandre Julliard committed
276 277
}

278
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
279
 *             ExtractIconEx   (SHELL.40)
280 281 282 283 284
 */
HICON16 WINAPI ExtractIconEx16(
	LPCSTR lpszFile, INT16 nIconIndex, HICON16 *phiconLarge,
	HICON16 *phiconSmall, UINT16 nIcons
) {
285
    HICON	*ilarge,*ismall;
286 287 288 289
    UINT16	ret;
    int		i;

    if (phiconLarge)
290
    	ilarge = (HICON*)HeapAlloc(GetProcessHeap(),0,nIcons*sizeof(HICON));
291 292 293
    else
    	ilarge = NULL;
    if (phiconSmall)
294
    	ismall = (HICON*)HeapAlloc(GetProcessHeap(),0,nIcons*sizeof(HICON));
295 296
    else
    	ismall = NULL;
297
    ret = HICON_16(ExtractIconExA(lpszFile,nIconIndex,ilarge,ismall,nIcons));
298 299
    if (ilarge) {
    	for (i=0;i<nIcons;i++)
300
	    phiconLarge[i]=HICON_16(ilarge[i]);
301 302 303 304
	HeapFree(GetProcessHeap(),0,ilarge);
    }
    if (ismall) {
    	for (i=0;i<nIcons;i++)
305
	    phiconSmall[i]=HICON_16(ismall[i]);
306 307 308 309
	HeapFree(GetProcessHeap(),0,ismall);
    }
    return ret;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
310

311 312
/*************************************************************************
 *				ExtractAssociatedIcon	[SHELL.36]
313
 *
314 315 316
 * Return icon for given file (either from file itself or from associated
 * executable) and patch parameters if needed.
 */
317
HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst, LPSTR lpIconPath, LPWORD lpiIcon)
318 319 320
{
    return HICON_16(ExtractAssociatedIconA(HINSTANCE_32(hInst), lpIconPath,
		    lpiIcon));
Alexandre Julliard's avatar
Alexandre Julliard committed
321 322 323
}

/*************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
324 325 326
 *				FindEnvironmentString	[SHELL.38]
 *
 * Returns a pointer into the DOS environment... Ugh.
Alexandre Julliard's avatar
Alexandre Julliard committed
327
 */
328
static LPSTR SHELL_FindString(LPSTR lpEnv, LPCSTR entry)
Alexandre Julliard's avatar
Alexandre Julliard committed
329 330
{ UINT16 l;

331
  TRACE("\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
332

333
  l = strlen(entry);
Alexandre Julliard's avatar
Alexandre Julliard committed
334
  for( ; *lpEnv ; lpEnv+=strlen(lpEnv)+1 )
335
  { if( strncasecmp(lpEnv, entry, l) )
Alexandre Julliard's avatar
Alexandre Julliard committed
336
      continue;
Alexandre Julliard's avatar
Alexandre Julliard committed
337 338 339 340 341 342
	if( !*(lpEnv+l) )
	    return (lpEnv + l); 		/* empty entry */
	else if ( *(lpEnv+l)== '=' )
	    return (lpEnv + l + 1);
    }
    return NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
343 344
}

345 346
/**********************************************************************/

347
SEGPTR WINAPI FindEnvironmentString16(LPSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
348 349
{ SEGPTR  spEnv;
  LPSTR lpEnv,lpString;
350
  TRACE("\n");
351

352
  spEnv = GetDOSEnvironment16();
Alexandre Julliard's avatar
Alexandre Julliard committed
353

354
  lpEnv = MapSL(spEnv);
355
  lpString = (spEnv)?SHELL_FindString(lpEnv, str):NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
356

Alexandre Julliard's avatar
Alexandre Julliard committed
357 358 359
    if( lpString )		/*  offset should be small enough */
	return spEnv + (lpString - lpEnv);
    return (SEGPTR)NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
360 361 362 363 364 365 366 367
}

/*************************************************************************
 *              		DoEnvironmentSubst      [SHELL.37]
 *
 * Replace %KEYWORD% in the str with the value of variable KEYWORD
 * from "DOS" environment.
 */
368
DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length)
Alexandre Julliard's avatar
Alexandre Julliard committed
369
{
370
  LPSTR   lpEnv = MapSL(GetDOSEnvironment16());
Alexandre Julliard's avatar
Alexandre Julliard committed
371
  LPSTR   lpBuffer = (LPSTR)HeapAlloc( GetProcessHeap(), 0, length);
Alexandre Julliard's avatar
Alexandre Julliard committed
372 373 374
  LPSTR   lpstr = str;
  LPSTR   lpbstr = lpBuffer;

375
  CharToOemA(str,str);
Alexandre Julliard's avatar
Alexandre Julliard committed
376

377
  TRACE("accept %s\n", str);
Alexandre Julliard's avatar
Alexandre Julliard committed
378 379 380 381 382 383 384 385 386 387 388

  while( *lpstr && lpbstr - lpBuffer < length )
   {
     LPSTR lpend = lpstr;

     if( *lpstr == '%' )
       {
	  do { lpend++; } while( *lpend && *lpend != '%' );
	  if( *lpend == '%' && lpend - lpstr > 1 )	/* found key */
	    {
	       LPSTR lpKey;
389
	      *lpend = '\0';
Alexandre Julliard's avatar
Alexandre Julliard committed
390 391 392 393 394 395 396
	       lpKey = SHELL_FindString(lpEnv, lpstr+1);
	       if( lpKey )				/* found key value */
		 {
		   int l = strlen(lpKey);

		   if( l > length - (lpbstr - lpBuffer) - 1 )
		     {
397
           WARN("-- Env subst aborted - string too short\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
398 399 400 401 402 403 404 405 406 407 408 409 410
		      *lpend = '%';
		       break;
		     }
		   strcpy(lpbstr, lpKey);
		   lpbstr += l;
		 }
	       else break;
	      *lpend = '%';
	       lpstr = lpend + 1;
	    }
	  else break;					/* back off and whine */

	  continue;
411
       }
Alexandre Julliard's avatar
Alexandre Julliard committed
412 413 414 415 416 417 418 419 420 421 422 423 424

     *lpbstr++ = *lpstr++;
   }

 *lpbstr = '\0';
  if( lpstr - str == strlen(str) )
    {
      strncpy(str, lpBuffer, length);
      length = 1;
    }
  else
      length = 0;

425
  TRACE("-- return %s\n", str);
Alexandre Julliard's avatar
Alexandre Julliard committed
426

427
  OemToCharA(str,str);
Alexandre Julliard's avatar
Alexandre Julliard committed
428
  HeapFree( GetProcessHeap(), 0, lpBuffer);
Alexandre Julliard's avatar
Alexandre Julliard committed
429 430 431 432 433

  /*  Return str length in the LOWORD
   *  and 1 in HIWORD if subst was successful.
   */
 return (DWORD)MAKELONG(strlen(str), length);
Alexandre Julliard's avatar
Alexandre Julliard committed
434
}
Alexandre Julliard's avatar
Alexandre Julliard committed
435 436

/*************************************************************************
437 438 439
 *				SHELL_HookProc
 *
 * 32-bit version of the system-wide WH_SHELL hook.
Alexandre Julliard's avatar
Alexandre Julliard committed
440
 */
441
static LRESULT WINAPI SHELL_HookProc(INT code, WPARAM wParam, LPARAM lParam)
Alexandre Julliard's avatar
Alexandre Julliard committed
442
{
443 444 445
    TRACE("%i, %x, %08lx\n", code, wParam, lParam );

    if (SHELL_hWnd)
Alexandre Julliard's avatar
Alexandre Julliard committed
446 447 448
    {
        switch( code )
        {
449 450 451 452 453 454 455 456 457
        case HSHELL_WINDOWCREATED:
            PostMessageA( SHELL_hWnd, uMsgWndCreated, wParam, 0 );
            break;
        case HSHELL_WINDOWDESTROYED:
            PostMessageA( SHELL_hWnd, uMsgWndDestroyed, wParam, 0 );
            break;
        case HSHELL_ACTIVATESHELLWINDOW:
            PostMessageA( SHELL_hWnd, uMsgShellActivate, wParam, 0 );
            break;
Alexandre Julliard's avatar
Alexandre Julliard committed
458 459
        }
    }
460 461 462 463 464 465 466 467 468 469
    return CallNextHookEx( SHELL_hHook, code, wParam, lParam );
}

/*************************************************************************
 *				ShellHookProc		[SHELL.103]
 * System-wide WH_SHELL hook.
 */
LRESULT WINAPI ShellHookProc16(INT16 code, WPARAM16 wParam, LPARAM lParam)
{
    return SHELL_HookProc( code, wParam, lParam );
Alexandre Julliard's avatar
Alexandre Julliard committed
470 471 472
}

/*************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
473
 *				RegisterShellHook	[SHELL.102]
Alexandre Julliard's avatar
Alexandre Julliard committed
474
 */
475
BOOL WINAPI RegisterShellHook16(HWND16 hWnd, UINT16 uAction)
476
{
477
    TRACE("%04x [%u]\n", hWnd, uAction );
Alexandre Julliard's avatar
Alexandre Julliard committed
478 479

    switch( uAction )
480
    {
481 482
    case 2:  /* register hWnd as a shell window */
        if( !SHELL_hHook )
483
        {
484 485
            SHELL_hHook = SetWindowsHookExA( WH_SHELL, SHELL_HookProc,
                                             GetModuleHandleA("shell32.dll"), 0 );
486
            if ( SHELL_hHook )
487
            {
488 489 490
                uMsgWndCreated = RegisterWindowMessageA( lpstrMsgWndCreated );
                uMsgWndDestroyed = RegisterWindowMessageA( lpstrMsgWndDestroyed );
                uMsgShellActivate = RegisterWindowMessageA( lpstrMsgShellActivate );
491 492
            }
            else
493
                WARN("-- unable to install ShellHookProc()!\n");
494 495 496
        }

        if ( SHELL_hHook )
497
            return ((SHELL_hWnd = HWND_32(hWnd)) != 0);
498 499 500
        break;

    default:
501
        WARN("-- unknown code %i\n", uAction );
502
        SHELL_hWnd = 0; /* just in case */
Alexandre Julliard's avatar
Alexandre Julliard committed
503 504
    }
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
505
}
506 507 508


/***********************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
509
 *           DriveType   (SHELL.262)
510 511 512 513 514 515 516 517 518 519 520 521
 */
UINT16 WINAPI DriveType16( UINT16 drive )
{
    UINT ret;
    char path[] = "A:\\";
    path[0] += drive;
    ret = GetDriveTypeA(path);
    switch(ret)  /* some values are not supported in Win16 */
    {
    case DRIVE_CDROM:
        ret = DRIVE_REMOTE;
        break;
522 523
    case DRIVE_NO_ROOT_DIR:
        ret = DRIVE_UNKNOWN;
524 525 526 527
        break;
    }
    return ret;
}
528 529 530 531 532 533 534 535 536 537 538 539 540 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 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609


/* 0 and 1 are valid rootkeys in win16 shell.dll and are used by
 * some programs. Do not remove those cases. -MM
 */
static inline void fix_win16_hkey( HKEY *hkey )
{
    if (*hkey == 0 || *hkey == (HKEY)1) *hkey = HKEY_CLASSES_ROOT;
}

/******************************************************************************
 *           RegOpenKey   [SHELL.1]
 */
DWORD WINAPI RegOpenKey16( HKEY hkey, LPCSTR name, PHKEY retkey )
{
    fix_win16_hkey( &hkey );
    return RegOpenKeyA( hkey, name, retkey );
}

/******************************************************************************
 *           RegCreateKey   [SHELL.2]
 */
DWORD WINAPI RegCreateKey16( HKEY hkey, LPCSTR name, PHKEY retkey )
{
    fix_win16_hkey( &hkey );
    return RegCreateKeyA( hkey, name, retkey );
}

/******************************************************************************
 *           RegCloseKey   [SHELL.3]
 */
DWORD WINAPI RegCloseKey16( HKEY hkey )
{
    fix_win16_hkey( &hkey );
    return RegCloseKey( hkey );
}

/******************************************************************************
 *           RegDeleteKey   [SHELL.4]
 */
DWORD WINAPI RegDeleteKey16( HKEY hkey, LPCSTR name )
{
    fix_win16_hkey( &hkey );
    return RegDeleteKeyA( hkey, name );
}

/******************************************************************************
 *           RegSetValue   [SHELL.5]
 */
DWORD WINAPI RegSetValue16( HKEY hkey, LPCSTR name, DWORD type, LPCSTR data, DWORD count )
{
    fix_win16_hkey( &hkey );
    return RegSetValueA( hkey, name, type, data, count );
}

/******************************************************************************
 *           RegQueryValue   [SHELL.6]
 *
 * NOTES
 *    Is this HACK still applicable?
 *
 * HACK
 *    The 16bit RegQueryValue doesn't handle selectorblocks anyway, so we just
 *    mask out the high 16 bit.  This (not so much incidently) hopefully fixes
 *    Aldus FH4)
 */
DWORD WINAPI RegQueryValue16( HKEY hkey, LPCSTR name, LPSTR data, LPDWORD count
)
{
    fix_win16_hkey( &hkey );
    if (count) *count &= 0xffff;
    return RegQueryValueA( hkey, name, data, count );
}

/******************************************************************************
 *           RegEnumKey   [SHELL.7]
 */
DWORD WINAPI RegEnumKey16( HKEY hkey, DWORD index, LPSTR name, DWORD name_len )
{
    fix_win16_hkey( &hkey );
    return RegEnumKeyA( hkey, index, name, name_len );
}
610 611 612 613

/*************************************************************************
 *           SHELL_Execute16 [Internal]
 */
614
static UINT SHELL_Execute16(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
615
			    LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
616
{
617 618 619
    UINT ret;
    char sCmd[MAX_PATH];
    WideCharToMultiByte(CP_ACP, 0, lpCmd, -1, sCmd, MAX_PATH, NULL, NULL);
620 621
    ret = WinExec16(sCmd, (UINT16)psei->nShow);
    psei_out->hInstApp = HINSTANCE_32(ret);
622
    return ret;
623 624 625 626 627 628 629 630 631
}

/*************************************************************************
 *                              ShellExecute            [SHELL.20]
 */
HINSTANCE16 WINAPI ShellExecute16( HWND16 hWnd, LPCSTR lpOperation,
                                   LPCSTR lpFile, LPCSTR lpParameters,
                                   LPCSTR lpDirectory, INT16 iShowCmd )
{
632 633
    SHELLEXECUTEINFOW seiW;
    WCHAR *wVerb = NULL, *wFile = NULL, *wParameters = NULL, *wDirectory = NULL;
634 635
    HANDLE hProcess = 0;

636 637 638 639
    seiW.lpVerb = lpOperation ? __SHCloneStrAtoW(&wVerb, lpOperation) : NULL;
    seiW.lpFile = lpFile ? __SHCloneStrAtoW(&wFile, lpFile) : NULL;
    seiW.lpParameters = lpParameters ? __SHCloneStrAtoW(&wParameters, lpParameters) : NULL;
    seiW.lpDirectory = lpDirectory ? __SHCloneStrAtoW(&wDirectory, lpDirectory) : NULL;
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658

    seiW.cbSize = sizeof(seiW);
    seiW.fMask = 0;
    seiW.hwnd = HWND_32(hWnd);
    seiW.nShow = iShowCmd;
    seiW.lpIDList = 0;
    seiW.lpClass = 0;
    seiW.hkeyClass = 0;
    seiW.dwHotKey = 0;
    seiW.hProcess = hProcess;

    ShellExecuteExW32 (&seiW, SHELL_Execute16);

    if (wVerb) SHFree(wVerb);
    if (wFile) SHFree(wFile);
    if (wParameters) SHFree(wParameters);
    if (wDirectory) SHFree(wDirectory);

    return HINSTANCE_16(seiW.hInstApp);
659
}