shell.c 19.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
 * 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
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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
#include "winreg.h"
37
#include "wownt32.h"
38
#include "shellapi.h"
39 40
#include "winuser.h"
#include "wingdi.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
41
#include "shlobj.h"
42
#include "shlwapi.h"
43 44

#include "wine/winbase16.h"
45
#include "wine/winuser16.h"
46

47
#include "wine/debug.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
48

49
WINE_DEFAULT_DEBUG_CHANNEL(shell);
50

51 52 53
extern HINSTANCE WINAPI WOWShellExecute(HWND hWnd, LPCSTR lpOperation,LPCSTR lpFile,
                                        LPCSTR lpParameters,LPCSTR lpDirectory,
                                        INT iShowCmd, void *callback);
Alexandre Julliard's avatar
Alexandre Julliard committed
54

55 56 57
#define HINSTANCE_32(h16)	((HINSTANCE)(ULONG_PTR)(h16))
#define HINSTANCE_16(h32)	(LOWORD(h32))

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

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

69
static HWND	SHELL_hWnd = 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
70
static HHOOK	SHELL_hHook = 0;
71 72 73
static UINT	uMsgWndCreated = 0;
static UINT	uMsgWndDestroyed = 0;
static UINT	uMsgShellActivate = 0;
74

75 76 77 78 79 80 81 82 83 84 85
static HICON convert_icon_to_32( HICON16 icon16 )
{
    CURSORICONINFO *info = GlobalLock16( icon16 );
    void *and_bits = info + 1;
    void *xor_bits = (BYTE *)and_bits + info->nHeight * 2 * ((info->nWidth + 15) / 16);
    HICON ret = CreateIcon( 0, info->nWidth, info->nHeight, info->bPlanes, info->bBitsPerPixel,
                            and_bits, xor_bits );
    GlobalUnlock16( icon16 );
    return ret;
}

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
static HICON16 convert_icon_to_16( HINSTANCE16 inst, HICON icon )
{
    static HICON16 (WINAPI *pCreateIcon16)(HINSTANCE16,INT16,INT16,BYTE,BYTE,LPCVOID,LPCVOID);
    ICONINFO info;
    BITMAP bm;
    UINT and_size, xor_size;
    void *xor_bits = NULL, *and_bits;
    HICON16 handle = 0;

    if (!pCreateIcon16 &&
        !(pCreateIcon16 = (void *)GetProcAddress( GetModuleHandleA("user.exe16"), "CreateIcon16" )))
        return 0;

    if (!(GetIconInfo( icon, &info ))) return 0;
    GetObjectW( info.hbmMask, sizeof(bm), &bm );
    and_size = bm.bmHeight * bm.bmWidthBytes;
    if (!(and_bits = HeapAlloc( GetProcessHeap(), 0, and_size ))) goto done;
    GetBitmapBits( info.hbmMask, and_size, and_bits );
    if (info.hbmColor)
    {
        GetObjectW( info.hbmColor, sizeof(bm), &bm );
        xor_size = bm.bmHeight * bm.bmWidthBytes;
        if (!(xor_bits = HeapAlloc( GetProcessHeap(), 0, xor_size ))) goto done;
        GetBitmapBits( info.hbmColor, xor_size, xor_bits );
    }
    else
    {
        bm.bmHeight /= 2;
        xor_bits = (char *)and_bits + and_size / 2;
    }
    handle = pCreateIcon16( inst, bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel,
                            and_bits, xor_bits );
done:
    HeapFree( GetProcessHeap(), 0, and_bits );
    if (info.hbmColor)
    {
        HeapFree( GetProcessHeap(), 0, xor_bits );
        DeleteObject( info.hbmColor );
    }
    DeleteObject( info.hbmMask );
    DestroyIcon( icon );
    return handle;
}

130
/***********************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
131
 * DllEntryPoint [SHELL.101]
132 133 134 135
 *
 * 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
136 137 138
 * RETURNS
 *  Success: TRUE. Initialization completed successfully.
 *  Failure: FALSE.
139 140 141 142 143 144
 */
BOOL WINAPI SHELL_DllEntryPoint(DWORD Reason, HINSTANCE16 hInst,
				WORD ds, WORD HeapSize, DWORD res1, WORD res2)
{
    return TRUE;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
145

Kai Morich's avatar
Kai Morich committed
146
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
147
 *				DragAcceptFiles		[SHELL.9]
Kai Morich's avatar
Kai Morich committed
148 149 150
 */
void WINAPI DragAcceptFiles16(HWND16 hWnd, BOOL16 b)
{
151
  DragAcceptFiles(HWND_32(hWnd), b);
Alexandre Julliard's avatar
Alexandre Julliard committed
152 153
}

Kai Morich's avatar
Kai Morich committed
154
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
155
 *				DragQueryFile		[SHELL.11]
Kai Morich's avatar
Kai Morich committed
156
 */
157 158 159 160 161
UINT16 WINAPI DragQueryFile16(
	HDROP16 hDrop,
	WORD wFile,
	LPSTR lpszFile,
	WORD wLength)
Kai Morich's avatar
Kai Morich committed
162
{
163 164
 	LPSTR lpDrop;
	UINT i = 0;
165 166
	LPDROPFILESTRUCT16 lpDropFileStruct = (LPDROPFILESTRUCT16) GlobalLock16(hDrop);

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

169
	if(!lpDropFileStruct) goto end;
170

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

173 174 175
	while (i++ < wFile)
	{
	  while (*lpDrop++); /* skip filename */
176
	  if (!*lpDrop)
177
	  {
Alexandre Julliard's avatar
Alexandre Julliard committed
178
	    i = (wFile == 0xFFFF) ? i : 0;
179 180 181
	    goto end;
	  }
	}
182

183
	i = strlen(lpDrop);
184
	if (!lpszFile ) goto end;   /* needed buffer size */
185
	lstrcpynA (lpszFile, lpDrop, wLength);
186 187 188
end:
	GlobalUnlock16(hDrop);
	return i;
Kai Morich's avatar
Kai Morich committed
189 190 191
}

/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
192
 *				DragFinish		[SHELL.12]
Kai Morich's avatar
Kai Morich committed
193 194
 */
void WINAPI DragFinish16(HDROP16 h)
195 196
{
    TRACE("\n");
197
    GlobalFree16(h);
Alexandre Julliard's avatar
Alexandre Julliard committed
198 199 200
}


Kai Morich's avatar
Kai Morich committed
201
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
202
 *				DragQueryPoint		[SHELL.13]
Kai Morich's avatar
Kai Morich committed
203 204 205
 */
BOOL16 WINAPI DragQueryPoint16(HDROP16 hDrop, POINT16 *p)
{
206
  LPDROPFILESTRUCT16 lpDropFileStruct;
Kai Morich's avatar
Kai Morich committed
207
  BOOL16           bRet;
208
  TRACE("\n");
Kai Morich's avatar
Kai Morich committed
209
  lpDropFileStruct = (LPDROPFILESTRUCT16) GlobalLock16(hDrop);
210

Kai Morich's avatar
Kai Morich committed
211 212
  memcpy(p,&lpDropFileStruct->ptMousePos,sizeof(POINT16));
  bRet = lpDropFileStruct->fInNonClientArea;
213

Kai Morich's avatar
Kai Morich committed
214 215
  GlobalUnlock16(hDrop);
  return bRet;
Alexandre Julliard's avatar
Alexandre Julliard committed
216 217
}

Alexandre Julliard's avatar
Alexandre Julliard committed
218
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
219
 *             FindExecutable   (SHELL.21)
Alexandre Julliard's avatar
Alexandre Julliard committed
220
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
221 222
HINSTANCE16 WINAPI FindExecutable16( LPCSTR lpFile, LPCSTR lpDirectory,
                                     LPSTR lpResult )
223
{ return HINSTANCE_16(FindExecutableA( lpFile, lpDirectory, lpResult ));
Alexandre Julliard's avatar
Alexandre Julliard committed
224 225
}

Alexandre Julliard's avatar
Alexandre Julliard committed
226
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
227
 *             AboutDlgProc   (SHELL.33)
Alexandre Julliard's avatar
Alexandre Julliard committed
228
 */
229
BOOL16 WINAPI AboutDlgProc16( HWND16 hWnd, UINT16 msg, WPARAM16 wParam,
Alexandre Julliard's avatar
Alexandre Julliard committed
230
                               LPARAM lParam )
231 232 233
{
    FIXME( "stub\n" );
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
234 235
}

Alexandre Julliard's avatar
Alexandre Julliard committed
236

Alexandre Julliard's avatar
Alexandre Julliard committed
237
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
238
 *             ShellAbout   (SHELL.22)
Alexandre Julliard's avatar
Alexandre Julliard committed
239
 */
240 241 242 243 244 245
BOOL16 WINAPI ShellAbout16( HWND16 hWnd, LPCSTR szApp, LPCSTR szOtherStuff, HICON16 icon16 )
{
    HICON icon = convert_icon_to_32( icon16 );
    BOOL ret = ShellAboutA( HWND_32(hWnd), szApp, szOtherStuff, icon );
    DestroyIcon( icon );
    return ret;
Alexandre Julliard's avatar
Alexandre Julliard committed
246 247
}

Alexandre Julliard's avatar
Alexandre Julliard committed
248 249 250 251 252
/*************************************************************************
 *			InternalExtractIcon		[SHELL.39]
 *
 * This abortion is called directly by Progman
 */
253
HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance,
254
                                     LPCSTR lpszExeFileName, UINT16 nIconIndex, WORD n )
255 256 257 258
{
    HGLOBAL16 hRet = 0;
    HICON16 *RetPtr = NULL;

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

262
	if (!n)
263
	  return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
264

265
	hRet = GlobalAlloc16(GMEM_FIXED | GMEM_ZEROINIT, sizeof(*RetPtr) * n);
266
        RetPtr = GlobalLock16(hRet);
Alexandre Julliard's avatar
Alexandre Julliard committed
267

268 269
	if (nIconIndex == (UINT16)-1)  /* get number of icons */
	{
270
	  RetPtr[0] = PrivateExtractIconsA(lpszExeFileName, 0, 0, 0, NULL, NULL, 0, LR_DEFAULTCOLOR);
271 272 273 274 275 276 277
	}
	else
	{
	  UINT ret;
	  HICON *icons;

	  icons = HeapAlloc(GetProcessHeap(), 0, n * sizeof(*icons));
278
	  ret = PrivateExtractIconsA(lpszExeFileName, nIconIndex,
279 280 281 282
	                             GetSystemMetrics(SM_CXICON),
	                             GetSystemMetrics(SM_CYICON),
	                             icons, NULL, n, LR_DEFAULTCOLOR);
	  if ((ret != 0xffffffff) && ret)
283 284
	  {
	    int i;
285
	    for (i = 0; i < n; i++) RetPtr[i] = convert_icon_to_16(hInstance, icons[i]);
286
	  }
287 288 289 290 291 292
	  else
	  {
	    GlobalFree16(hRet);
	    hRet = 0;
	  }
	  HeapFree(GetProcessHeap(), 0, icons);
293
	}
294
	return hRet;
Alexandre Julliard's avatar
Alexandre Julliard committed
295 296
}

Alexandre Julliard's avatar
Alexandre Julliard committed
297
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
298
 *             ExtractIcon   (SHELL.34)
Alexandre Julliard's avatar
Alexandre Julliard committed
299
 */
Alexandre Julliard's avatar
Alexandre Julliard committed
300
HICON16 WINAPI ExtractIcon16( HINSTANCE16 hInstance, LPCSTR lpszExeFileName,
Alexandre Julliard's avatar
Alexandre Julliard committed
301
	UINT16 nIconIndex )
302
{   TRACE("\n");
303
    return convert_icon_to_16( hInstance, ExtractIconA(NULL, lpszExeFileName, nIconIndex) );
Alexandre Julliard's avatar
Alexandre Julliard committed
304 305
}

306
/*************************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
307
 *             ExtractIconEx   (SHELL.40)
308
 */
309
UINT16 WINAPI ExtractIconEx16(
310 311 312
	LPCSTR lpszFile, INT16 nIconIndex, HICON16 *phiconLarge,
	HICON16 *phiconSmall, UINT16 nIcons
) {
313
    HICON	*ilarge,*ismall;
314
    int		i, ret;
315 316

    if (phiconLarge)
317
    	ilarge = HeapAlloc(GetProcessHeap(),0,nIcons*sizeof(HICON));
318 319 320
    else
    	ilarge = NULL;
    if (phiconSmall)
321
    	ismall = HeapAlloc(GetProcessHeap(),0,nIcons*sizeof(HICON));
322 323
    else
    	ismall = NULL;
324
    ret = ExtractIconExA(lpszFile,nIconIndex,ilarge,ismall,nIcons);
325
    if (ilarge) {
326 327
	for (i=0;i<ret;i++)
	    phiconLarge[i] = convert_icon_to_16(0, ilarge[i]);
328 329 330
	HeapFree(GetProcessHeap(),0,ilarge);
    }
    if (ismall) {
331 332
	for (i=0;i<ret;i++)
	    phiconSmall[i] = convert_icon_to_16(0, ismall[i]);
333 334 335 336
	HeapFree(GetProcessHeap(),0,ismall);
    }
    return ret;
}
Alexandre Julliard's avatar
Alexandre Julliard committed
337

338 339
/*************************************************************************
 *				ExtractAssociatedIcon	[SHELL.36]
340
 *
341 342 343
 * Return icon for given file (either from file itself or from associated
 * executable) and patch parameters if needed.
 */
344
HICON16 WINAPI ExtractAssociatedIcon16(HINSTANCE16 hInst, LPSTR lpIconPath, LPWORD lpiIcon)
345
{
346
    return convert_icon_to_16( hInst, ExtractAssociatedIconA(NULL, lpIconPath, lpiIcon) );
Alexandre Julliard's avatar
Alexandre Julliard committed
347 348 349
}

/*************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
350 351 352
 *				FindEnvironmentString	[SHELL.38]
 *
 * Returns a pointer into the DOS environment... Ugh.
Alexandre Julliard's avatar
Alexandre Julliard committed
353
 */
354
static LPSTR SHELL_FindString(LPSTR lpEnv, LPCSTR entry)
Alexandre Julliard's avatar
Alexandre Julliard committed
355 356
{ UINT16 l;

357
  TRACE("\n");
Alexandre Julliard's avatar
Alexandre Julliard committed
358

359
  l = strlen(entry);
Alexandre Julliard's avatar
Alexandre Julliard committed
360
  for( ; *lpEnv ; lpEnv+=strlen(lpEnv)+1 )
361
  { if( strncasecmp(lpEnv, entry, l) )
Alexandre Julliard's avatar
Alexandre Julliard committed
362
      continue;
Alexandre Julliard's avatar
Alexandre Julliard committed
363 364 365 366 367 368
	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
369 370
}

371 372
/**********************************************************************/

373
SEGPTR WINAPI FindEnvironmentString16(LPCSTR str)
Alexandre Julliard's avatar
Alexandre Julliard committed
374 375
{ SEGPTR  spEnv;
  LPSTR lpEnv,lpString;
376
  TRACE("\n");
377

378
  spEnv = GetDOSEnvironment16();
Alexandre Julliard's avatar
Alexandre Julliard committed
379

380
  lpEnv = MapSL(spEnv);
381
  lpString = (spEnv)?SHELL_FindString(lpEnv, str):NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
382

Alexandre Julliard's avatar
Alexandre Julliard committed
383 384
    if( lpString )		/*  offset should be small enough */
	return spEnv + (lpString - lpEnv);
385
    return 0;
Alexandre Julliard's avatar
Alexandre Julliard committed
386 387 388 389 390 391
}

/*************************************************************************
 *              		DoEnvironmentSubst      [SHELL.37]
 *
 * Replace %KEYWORD% in the str with the value of variable KEYWORD
392 393 394
 * from "DOS" environment. If it is not found the %KEYWORD% is left
 * intact. If the buffer is too small, str is not modified.
 *
395 396
 * PARAMS
 *  str        [I] '\0' terminated string with %keyword%.
397
 *             [O] '\0' terminated string with %keyword% substituted.
398
 *  length     [I] size of str.
399
 *
400 401
 * RETURNS
 *  str length in the LOWORD and 1 in HIWORD if subst was successful.
Alexandre Julliard's avatar
Alexandre Julliard committed
402
 */
403
DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length)
Alexandre Julliard's avatar
Alexandre Julliard committed
404
{
405
  LPSTR   lpEnv = MapSL(GetDOSEnvironment16());
Alexandre Julliard's avatar
Alexandre Julliard committed
406
  LPSTR   lpstr = str;
407 408 409 410 411 412 413
  LPSTR   lpend;
  LPSTR   lpBuffer = HeapAlloc( GetProcessHeap(), 0, length);
  WORD    bufCnt = 0;
  WORD    envKeyLen;
  LPSTR   lpKey;
  WORD    retStatus = 0;
  WORD    retLength = length;
Alexandre Julliard's avatar
Alexandre Julliard committed
414

415
  CharToOemA(str,str);
Alexandre Julliard's avatar
Alexandre Julliard committed
416

417
  TRACE("accept %s\n", str);
Alexandre Julliard's avatar
Alexandre Julliard committed
418

419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
  while( *lpstr && bufCnt <= length - 1 ) {
     if ( *lpstr != '%' ) {
        lpBuffer[bufCnt++] = *lpstr++;
        continue;
     }

     for( lpend = lpstr + 1; *lpend && *lpend != '%'; lpend++) /**/;

     envKeyLen = lpend - lpstr - 1;
     if( *lpend != '%' || envKeyLen == 0)
        goto err; /* "%\0" or "%%" found; back off and whine */

     *lpend = '\0';
     lpKey = SHELL_FindString(lpEnv, lpstr+1);
     *lpend = '%';
     if( lpKey ) {
         int l = strlen(lpKey);

         if( bufCnt + l > length - 1 )
                goto err;

        memcpy(lpBuffer + bufCnt, lpKey, l);
        bufCnt += l;
     } else { /* Keyword not found; Leave the %KEYWORD% intact */
        if( bufCnt + envKeyLen + 2 > length - 1 )
            goto err;

         memcpy(lpBuffer + bufCnt, lpstr, envKeyLen + 2);
        bufCnt += envKeyLen + 2;
     }

     lpstr = lpend + 1;
  }

  if (!*lpstr && bufCnt <= length - 1) {
      memcpy(str,lpBuffer, bufCnt);
      str[bufCnt] = '\0';
      retLength = bufCnt + 1;
      retStatus = 1;
  }

  err:
  if (!retStatus)
      WARN("-- Env subst aborted - string too short or invalid input\n");
463
  TRACE("-- return %s\n", str);
Alexandre Julliard's avatar
Alexandre Julliard committed
464

465
  OemToCharA(str,str);
Alexandre Julliard's avatar
Alexandre Julliard committed
466
  HeapFree( GetProcessHeap(), 0, lpBuffer);
Alexandre Julliard's avatar
Alexandre Julliard committed
467

468
  return (DWORD)MAKELONG(retLength, retStatus);
Alexandre Julliard's avatar
Alexandre Julliard committed
469
}
Alexandre Julliard's avatar
Alexandre Julliard committed
470 471

/*************************************************************************
472 473 474
 *				SHELL_HookProc
 *
 * 32-bit version of the system-wide WH_SHELL hook.
Alexandre Julliard's avatar
Alexandre Julliard committed
475
 */
476
static LRESULT WINAPI SHELL_HookProc(INT code, WPARAM wParam, LPARAM lParam)
Alexandre Julliard's avatar
Alexandre Julliard committed
477
{
478
    TRACE("%i, %lx, %08lx\n", code, wParam, lParam );
479 480

    if (SHELL_hWnd)
Alexandre Julliard's avatar
Alexandre Julliard committed
481 482 483
    {
        switch( code )
        {
484 485 486 487 488 489 490 491 492
        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
493 494
        }
    }
495 496 497 498 499 500 501 502 503 504
    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
505 506 507
}

/*************************************************************************
Alexandre Julliard's avatar
Alexandre Julliard committed
508
 *				RegisterShellHook	[SHELL.102]
Alexandre Julliard's avatar
Alexandre Julliard committed
509
 */
510
BOOL WINAPI RegisterShellHook16(HWND16 hWnd, UINT16 uAction)
511
{
512
    TRACE("%04x [%u]\n", hWnd, uAction );
Alexandre Julliard's avatar
Alexandre Julliard committed
513 514

    switch( uAction )
515
    {
516 517
    case 2:  /* register hWnd as a shell window */
        if( !SHELL_hHook )
518
        {
519 520
            SHELL_hHook = SetWindowsHookExA( WH_SHELL, SHELL_HookProc,
                                             GetModuleHandleA("shell32.dll"), 0 );
521
            if ( SHELL_hHook )
522
            {
523 524 525
                uMsgWndCreated = RegisterWindowMessageA( lpstrMsgWndCreated );
                uMsgWndDestroyed = RegisterWindowMessageA( lpstrMsgWndDestroyed );
                uMsgShellActivate = RegisterWindowMessageA( lpstrMsgShellActivate );
526 527
            }
            else
528
                WARN("-- unable to install ShellHookProc()!\n");
529 530 531
        }

        if ( SHELL_hHook )
532
            return ((SHELL_hWnd = HWND_32(hWnd)) != 0);
533 534 535
        break;

    default:
536
        WARN("-- unknown code %i\n", uAction );
537
        SHELL_hWnd = 0; /* just in case */
Alexandre Julliard's avatar
Alexandre Julliard committed
538 539
    }
    return FALSE;
Alexandre Julliard's avatar
Alexandre Julliard committed
540
}
541 542 543


/***********************************************************************
Patrik Stridvall's avatar
Patrik Stridvall committed
544
 *           DriveType   (SHELL.262)
545 546 547 548 549 550 551 552 553 554 555 556
 */
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;
557 558
    case DRIVE_NO_ROOT_DIR:
        ret = DRIVE_UNKNOWN;
559 560 561 562
        break;
    }
    return ret;
}
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 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625


/* 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
Austin English's avatar
Austin English committed
626
 *    mask out the high 16 bit.  This (not so much incidentally) hopefully fixes
627 628 629 630 631 632 633
 *    Aldus FH4)
 */
DWORD WINAPI RegQueryValue16( HKEY hkey, LPCSTR name, LPSTR data, LPDWORD count
)
{
    fix_win16_hkey( &hkey );
    if (count) *count &= 0xffff;
634
    return RegQueryValueA( hkey, name, data, (LONG*) count );
635 636 637 638 639 640 641 642 643 644
}

/******************************************************************************
 *           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 );
}
645 646 647 648

/*************************************************************************
 *           SHELL_Execute16 [Internal]
 */
649
static UINT_PTR SHELL_Execute16(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
650
			    const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
651
{
652 653 654
    UINT ret;
    char sCmd[MAX_PATH];
    WideCharToMultiByte(CP_ACP, 0, lpCmd, -1, sCmd, MAX_PATH, NULL, NULL);
655 656
    ret = WinExec16(sCmd, (UINT16)psei->nShow);
    psei_out->hInstApp = HINSTANCE_32(ret);
657
    return ret;
658 659 660 661 662 663 664 665 666
}

/*************************************************************************
 *                              ShellExecute            [SHELL.20]
 */
HINSTANCE16 WINAPI ShellExecute16( HWND16 hWnd, LPCSTR lpOperation,
                                   LPCSTR lpFile, LPCSTR lpParameters,
                                   LPCSTR lpDirectory, INT16 iShowCmd )
{
667 668
    return HINSTANCE_16( WOWShellExecute( HWND_32(hWnd), lpOperation, lpFile, lpParameters,
                                          lpDirectory, iShowCmd, SHELL_Execute16 ));
669
}
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694


/*************************************************************************
 * RunDLL_CallEntry16
 *
 * Only exported from shell32 on Windows, probably imported
 * from shell through the 16/32 thunks.
 */
void WINAPI RunDLL_CallEntry16( DWORD proc, HWND hwnd, HINSTANCE inst, LPCSTR cmdline, INT cmdshow )
{
    WORD args[5];
    SEGPTR cmdline_seg;

    TRACE( "proc %x hwnd %p inst %p cmdline %s cmdshow %d\n",
           proc, hwnd, inst, debugstr_a(cmdline), cmdshow );

    cmdline_seg = MapLS( cmdline );
    args[4] = HWND_16(hwnd);
    args[3] = MapHModuleLS(inst);
    args[2] = SELECTOROF(cmdline_seg);
    args[1] = OFFSETOF(cmdline_seg);
    args[0] = cmdshow;
    WOWCallback16Ex( proc, WCB16_PASCAL, sizeof(args), args, NULL );
    UnMapLS( cmdline_seg );
}