shlexec.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 3k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "shprv.h"
  2. #define IMECOMPAT_USEALTSTKFORSHLEXEC   0x00008000      // ;Internal
  3. #define ALT_STACK 0x5000
  4. typedef struct tagSHLEXECPARAM {
  5.     HWND hwnd;
  6.     LPSTR lpsz[4];
  7.     int wShowCmd;
  8. } SHLEXECPARAM, *PSHLEXECPARAM, FAR *LPSHLEXECPARAM;
  9. typedef DWORD (WINAPI *LPFNIMMGETAPPCOMPATFLAGS)(DWORD);
  10. HANDLE WINAPI ShellExecute32( HWND hwnd, LPSTR lpszOp, LPSTR lpszFile, LPSTR lpszParams, LPSTR lpszDir, int wShowCmd);
  11. /*--------------------------------------------------------------------------
  12.  *
  13.  * ShellExecute
  14.  *
  15.  * ShellExecute of SHELL32.DLL eats lots of stack under 16 bit applciation.
  16.  * Because ATOK9 does not have enough stack, we need to prepare altanative 
  17.  * stack to call WIn32 ShellExecute.
  18.  *
  19.  * GACF_INCREASE does not work for ATOK9, because its _DATA is too big and
  20.  * there is no rool to increase Stack.
  21.  *
  22.  *------------------------------------------------------------------------*/
  23. HANDLE WINAPI ShellExecute( HWND hwnd, LPCSTR lpszOp, LPCSTR lpszFile, LPCSTR lpszParams, LPCSTR lpszDir, int wShowCmd)
  24. {
  25.     UINT os[4];
  26.     UINT uLen = 0;
  27.     int i;
  28.     HANDLE hIMM;
  29.     static HANDLE hRet;
  30.     static LPSHLEXECPARAM lpsep;
  31.     static LPFNIMMGETAPPCOMPATFLAGS lpfnImmGetAppCompatFlag = NULL;
  32.     if (!lpfnImmGetAppCompatFlag)
  33.     {
  34.         if (hIMM = GetModuleHandle("IMM"))
  35.             lpfnImmGetAppCompatFlag = (LPFNIMMGETAPPCOMPATFLAGS)GetProcAddress(hIMM,MAKEINTRESOURCE(146));
  36.     }
  37.     if (!lpfnImmGetAppCompatFlag ||
  38.         !((*lpfnImmGetAppCompatFlag)(0) & IMECOMPAT_USEALTSTKFORSHLEXEC))
  39.         return ShellExecute32(hwnd, (LPSTR)lpszOp, (LPSTR)lpszFile, 
  40.                               (LPSTR)lpszParams, (LPSTR)lpszDir, wShowCmd);
  41.     for (i = 0; i < 4; i ++)
  42.         os[i] = 0xFFFF;
  43.     if (lpszOp )
  44.     {
  45.         os[0] = 0;
  46.         uLen += (lstrlen(lpszOp) + 5);
  47.         uLen &= 0xFFFC;
  48.     }
  49.     if (lpszFile )
  50.     {
  51.         os[1] = uLen;
  52.         uLen += (lstrlen(lpszFile) + 5);
  53.         uLen &= 0xFFFC;
  54.     }
  55.     if (lpszParams )
  56.     {
  57.         os[2] = uLen;
  58.         uLen += (lstrlen(lpszParams) + 5);
  59.         uLen &= 0xFFFC;
  60.     }
  61.     if (lpszDir )
  62.     {
  63.         os[3] = uLen;
  64.         uLen += (lstrlen(lpszDir) + 5);
  65.         uLen &= 0xFFFC;
  66.     }
  67.     if (lpsep = MAKELP(GlobalAlloc(GPTR, ALT_STACK + uLen + sizeof(SHLEXECPARAM)),0))
  68.     {
  69.         LPSTR lpTemp;
  70.         (LPSTR)lpsep += ALT_STACK;
  71.         lpTemp = (LPSTR)lpsep + sizeof(SHLEXECPARAM);
  72.         for (i = 0; i < 4; i ++)
  73.         {
  74.             if (os[i] != 0xFFFF)
  75.                 lpsep->lpsz[i] = (LPSTR)(lpTemp + os[i]);
  76.             else
  77.                 lpsep->lpsz[i] = NULL;
  78.         }
  79.         lpsep->hwnd = hwnd;
  80.         lpsep->wShowCmd = wShowCmd;
  81.         if (lpsep->lpsz[0])
  82.             lstrcpy(lpsep->lpsz[0], lpszOp);
  83.         if (lpsep->lpsz[1])
  84.             lstrcpy(lpsep->lpsz[1], lpszFile);
  85.         if (lpsep->lpsz[2])
  86.             lstrcpy(lpsep->lpsz[2], lpszParams);
  87.         if (lpsep->lpsz[3])
  88.             lstrcpy(lpsep->lpsz[3], lpszDir);
  89.         SwitchStackTo(SELECTOROF(lpsep), ALT_STACK - 1, 0);
  90.         hRet =  ShellExecute32(lpsep->hwnd, lpsep->lpsz[0], lpsep->lpsz[1], 
  91.                                lpsep->lpsz[2], lpsep->lpsz[3], lpsep->wShowCmd);
  92.         SwitchStackBack();
  93.         GlobalFree(SELECTOROF(lpsep));
  94.     }
  95.     return hRet;
  96. }