Advertisement
bejiitas_wrath

Windows XP Taskmanager source.

May 4th, 2024
929
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 43.34 KB | None | 0 0
  1. /*++
  2.  
  3. Copyright (c) 1992  Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     taskman.c
  8.  
  9. Abstract:
  10.  
  11.     This file contains the source for the windows Task Manager.
  12.     Taskman basically is a dialog box, which enumerates active windows
  13.     keep in the user window manager, then sets active focus to the selected
  14.     dialog box element(ie active window).
  15.  
  16. --*/
  17.  
  18. #define UNICODE
  19.  
  20. #include "taskman.h"
  21. #include <port1632.h>
  22. #include <shellapi.h>
  23. #include <shlapip.h>
  24.  
  25. //LATER find correct define for NT
  26. #if !defined(NTWIN) && !defined(DOSWIN32) && !defined(WIN16)
  27. #define NTWIN   1
  28. #endif
  29.  
  30. #define ARRAYSIZE(x)    (sizeof(x)/sizeof(x[0]))
  31.  
  32. #define MAXPATHFIELD 260
  33.  
  34. #define INIT_MAX_FILES 4
  35. #define FILES_KEY  L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager\\Recent File List"
  36. #define MAXFILES_ENTRY L"Max Files"
  37. #define FILE_ENTRY L"File%lu"
  38.  
  39. #define WM_CONTENTSCHANGED (WM_USER+5)
  40.  
  41. TCHAR szPathField[MAXPATHFIELD];
  42. TCHAR szDirField[MAXPATHFIELD];
  43. TCHAR szTitle[MAXPATHFIELD];
  44. TCHAR szMessage[MAXMSGBOXLEN];
  45.  
  46. TCHAR szUserHomeDir[MAXPATHFIELD];
  47. TCHAR szWindowsDirectory[MAXPATHFIELD];
  48.  
  49. TCHAR szOOMExitMsg[64] = TEXT("Close an application and try again."); // 64
  50. TCHAR szOOMExitTitle[32] = TEXT("Extremely Low on Memory"); // 32
  51.  
  52. TCHAR szNoRun[] = TEXT("NoRun");
  53. // registry key for groups
  54.  
  55. HANDLE hInst;
  56.  
  57. BOOL bChangedDefaultButton;
  58.  
  59. INT_PTR APIENTRY TaskmanDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
  60.  
  61. WORD APIENTRY ExecProgram(LPTSTR lpszPath,LPTSTR lpDir,LPTSTR lpTitle);
  62. void APIENTRY SaveRecentFileList (HWND, LPTSTR);
  63.  
  64. VOID GetPathInfo(PTSTR szPath,PTSTR *pszFileName,PTSTR *pszExt,WORD *pich,BOOL *pfUnc);
  65. VOID GetFilenameFromPath(PTSTR szPath, PTSTR szFilename);
  66. VOID GetDirectoryFromPath(PTSTR szFilePath, PTSTR szDir);
  67. BOOL IsUserAdmin();
  68. BOOL OKToExec();
  69. BOOL TestTokenForAdmin(HANDLE Token);
  70. VOID SetDefButton(HWND hwndDlg, INT  idButton);
  71.  
  72. WINUSERAPI VOID SwitchToThisWindow(HWND, BOOL);
  73. INT MyMessageBox(HWND hWnd,WORD idTitle,WORD idMessage,PWSTR psz,WORD wStyle);
  74.  
  75. INT MyX = 0;
  76. INT MyY = 0;
  77. INT dxTaskman;
  78. INT dyTaskman;
  79. INT dxScreen;
  80. INT dyScreen;
  81.  
  82. HWND ghwndDialog;
  83. BOOL fExecOK = TRUE;
  84. BOOL fMsgBox = FALSE;
  85.  
  86.  
  87. PVOID Alloc(
  88.     DWORD   Bytes)
  89. {
  90.     HANDLE  hMem;
  91.     PVOID   Buffer;
  92.  
  93.     hMem = LocalAlloc(LMEM_MOVEABLE, Bytes + sizeof(hMem));
  94.  
  95.     if (hMem == NULL) {
  96.         return(NULL);
  97.     }
  98.  
  99.     Buffer = LocalLock(hMem);
  100.     if (Buffer == NULL) {
  101.         LocalFree(hMem);
  102.         return(NULL);
  103.     }
  104.  
  105.     *((PHANDLE)Buffer) = hMem;
  106.  
  107.     return (PVOID)(((PHANDLE)Buffer)+1);
  108. }
  109.  
  110.  
  111. BOOL Free(
  112.     PVOID   Buffer)
  113. {
  114.     HANDLE  hMem;
  115.  
  116.     hMem = *(((PHANDLE)Buffer) - 1);
  117.  
  118.     LocalUnlock(hMem);
  119.  
  120.     return(LocalFree(hMem) == NULL);
  121. }
  122.  
  123.  
  124. VOID
  125. HideWindow(HWND hwnd)
  126. {
  127.    if (!fMsgBox) {
  128.  
  129.       if (fExecOK) {
  130.          SetDlgItemText(ghwndDialog, IDD_PATH, TEXT(""));
  131.       }
  132.  
  133.       // redundant?  why do they do the reverse twice for show below?
  134.       ShowWindow(ghwndDialog, SW_HIDE);
  135.  
  136.       SetWindowPos(ghwndDialog, HWND_NOTOPMOST, 0, 0, 0, 0,
  137.          SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
  138.    }
  139.  
  140.    // Erase dark border from depressed pushbuttons
  141.    SendMessage(GetDlgItem(hwnd, IDCANCEL), // IDCANCEL
  142.       BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0));
  143.    SendMessage(GetDlgItem(hwnd, IDD_TERMINATE),
  144.       BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0));
  145.    SendMessage(GetDlgItem(hwnd, IDD_CASCADE),
  146.       BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0));
  147.    SendMessage(GetDlgItem(hwnd, IDD_TILE),
  148.       BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0));
  149.    SendMessage(GetDlgItem(hwnd, IDD_ARRANGEICONS),
  150.       BM_SETSTYLE, BS_PUSHBUTTON, MAKELPARAM(TRUE, 0));
  151. }
  152.  
  153. /*
  154.  * We call HideTasklist() when we want to remove the tasklist window
  155.  * from the screen but not select another window (ie. when we're about
  156.  * to select another app.  We call ShowWindow(SW_HIDE) directly when
  157.  * we're doing something like tiling or cascading so a window other than
  158.  * the tasklist will become the foreground window.
  159.  */
  160. VOID HideTasklist(VOID)
  161. {
  162.     if (fExecOK) {
  163.        SetDlgItemText(ghwndDialog, IDD_PATH, TEXT(""));
  164.     }
  165.  
  166.     SetWindowPos(ghwndDialog, HWND_TOP, 0, 0, 0, 0, SWP_HIDEWINDOW |
  167.             SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
  168.  
  169. }
  170.  
  171.  
  172. VOID ShowTasklist(
  173.    POINT pt)
  174. {
  175.     /*
  176.      * Retract the drop down listbox.
  177.      */
  178.  
  179.      if (fExecOK) {
  180.         SendDlgItemMessage(ghwndDialog, IDD_PATH,
  181.                            CB_SHOWDROPDOWN,0,0);
  182.      }
  183.  
  184.     SetWindowPos(ghwndDialog, HWND_TOPMOST, pt.x, pt.y, 0, 0,
  185.        SWP_NOSIZE | SWP_NOACTIVATE );
  186.     SetForegroundWindow(ghwndDialog);
  187.  
  188.     ShowWindow(ghwndDialog, SW_NORMAL);
  189. }
  190.  
  191.  
  192. /*** ActivateSelectedWindow --         Calls user, to set active window, selected
  193.  *                                                                 by the user.
  194.  *
  195.  *
  196.  * ActivateSelectedWindow(HWND hwndLB)
  197.  *
  198.  * ENTRY -         HWND hwndLB - handle to window, which is to become the active
  199.  *                                                  window, with focus.
  200.  * EXIT  -
  201.  * SYNOPSIS -  This function takes the hwnd passed into it, calls user
  202.  *                                to set active focus to that window.
  203.  * WARNINGS -
  204.  * EFFECTS  -
  205.  *
  206.  */
  207.  
  208. VOID ActivateSelectedWindow(
  209.     HWND hwndLB)
  210. {
  211.    INT nIndex;
  212.    HWND hwndT;
  213.    HWND hwndLastActive;
  214.    DWORD lTemp;
  215.  
  216.     /*
  217.      * Get the hwnd of the item which was selected.
  218.      */
  219.     nIndex = (int)SendMessage(hwndLB, LB_GETCURSEL, 0, 0);
  220.     hwndT = (HWND)SendMessage(hwndLB, LB_GETITEMDATA, nIndex, 0);
  221.  
  222.     if (!IsWindow(hwndT)) {
  223.         /*
  224.          * We gotta make sure the window is valid before doing stuff with it.
  225.          * An app may terminate itself in the background rendering these
  226.          * window handles invalid.
  227.          */
  228.         goto Beep;
  229.     }
  230.  
  231.     /*
  232.      * Switch to that task.
  233.      * HACK! Activate the window in the hwndLastActive field of the WndStruct.
  234.      */
  235.     hwndLastActive = GetLastActivePopup(hwndT);
  236.  
  237.     if (!IsWindow(hwndLastActive)) {
  238.         goto Beep;
  239.     }
  240.  
  241.     /*
  242.      * But only if it isn't disabled.
  243.      */
  244.     lTemp = GetWindowLong(hwndLastActive, GWL_STYLE);
  245.     if (!(lTemp & WS_DISABLED)) {
  246.         /*
  247.          * HACK!! Use SwitchToThisWindow() to bring dialog parents as well.
  248.          */
  249.         SwitchToThisWindow(hwndLastActive, TRUE);
  250.  
  251.     } else {
  252. Beep:
  253.         MessageBeep(0);
  254.     }
  255. }
  256.  
  257. #ifdef NTWIN
  258. /*** DoEndTask --
  259.  *
  260.  * void DoEndTask( HWND hwnd )
  261.  */
  262. VOID DoEndTask(
  263.    HWND hwnd )
  264. {
  265.    TCHAR szMsgBoxText[MAXMSGBOXLEN];
  266.    TCHAR szTempField[MAXTASKNAMELEN];
  267.    INT nch;
  268.  
  269.  
  270.    if (!EndTask(hwnd, FALSE, FALSE)) {
  271.       /* App does not want to close, ask user if
  272.        * he wants to blow it away
  273.        */
  274.  
  275.        InternalGetWindowText(hwnd, (LPTSTR)szTempField, MAXTASKNAMELEN);
  276.  
  277.        /* Load the message box string, it is very long (greater than 255 chars
  278.         * which is why we load it in two pieces
  279.         */
  280.         nch = LoadString(NULL, IDS_MSGBOXSTR1, szMsgBoxText, MAXMSGBOXLEN);
  281.         LoadString(NULL, IDS_MSGBOXSTR2, &szMsgBoxText[nch], MAXMSGBOXLEN-nch);
  282.  
  283.         if( MessageBox( NULL, szMsgBoxText, szTempField,
  284.                 MB_SETFOREGROUND | MB_SYSTEMMODAL | MB_YESNO ) == IDYES) {
  285.             EndTask(hwnd, FALSE, TRUE);
  286.         }
  287.     }
  288. }
  289.  
  290.  
  291. /*** CallEndTask --                 A separate thread to instigate EndTask
  292.  *
  293.  * CallEndTask( HWND hwnd );
  294.  *
  295.  * ENTRY -      HWND hwnd - window handle for the task to be killed
  296.  * EXIT  -
  297.  * SYNOPSIS -  This function calls EndTask on the given window to kill the
  298.  *              task that owns that window.
  299.  *
  300.  * WARNINGS -
  301.  * EFFECTS  -   Kills the task that owns hwnd.
  302.  *
  303.  */
  304.  
  305. DWORD CallEndTask(
  306.     HWND hwnd)
  307. {
  308.     DoEndTask(hwnd);
  309.  
  310.     ExitThread(0);
  311.     return 0; /* placate compiler */
  312. }
  313. #endif
  314.  
  315.  
  316. /*** TaskmanDlgProc --         Dialog Procedure for Taskman Window
  317.  *
  318.  *
  319.  *
  320.  * TaskmanDlgProc(HWND hDlg, WORD wMSG, DWORD wParam, LPARAM lParam)
  321.  *
  322.  * ENTRY -         HWND hhDlg                 - handle to dialog box.
  323.  *                        WORD wMsg                  - message to be acted upon.
  324.  *                        DWORD wParam        - value specific to wMsg.
  325.  *                        LPARAM lParam                - value specific to wMsg.
  326.  *
  327.  * EXIT  -           True if success, False if not.
  328.  * SYNOPSIS -  Dialog box message processing function.
  329.  *
  330.  * WARNINGS -
  331.  * EFFECTS  -
  332.  *
  333.  */
  334.  
  335. INT_PTR TaskmanDlgProc(
  336.     HWND hwnd,
  337.     UINT wMsg,
  338.     WPARAM wParam,
  339.     LPARAM lParam)
  340. {
  341.     int nIndex;
  342.     RECT rc;
  343.     HWND hwndLB;
  344.     HWND hwndNext;
  345.     TCHAR szTempField[MAXTASKNAMELEN];
  346.     POINT pt;
  347.     HKEY  hKey;
  348.     DWORD dwDisp;
  349.     DWORD dwDataType, dwMaxFiles=INIT_MAX_FILES, dwMaxFilesSize, dwCount;
  350.     TCHAR szFileEntry[20];
  351.     TCHAR szFullPath[MAXPATHFIELD];
  352. #ifndef NTWIN
  353.     LONG lTemp;
  354. #endif
  355.  
  356.     hwndLB = GetDlgItem(hwnd, IDD_TASKLISTBOX);
  357.  
  358.     switch (wMsg) {
  359.  
  360.     case WM_INITDIALOG:
  361.         /*
  362.          * call private api to mark task man as a system app. This causes
  363.          * it to be killed after all other non-system apps during shutdown.
  364.          */
  365. //      MarkProcess(MP_SYSTEMAPP);
  366.         GetWindowRect(hwnd, &rc);
  367.         dxTaskman = rc.right - rc.left;
  368.         dyTaskman = rc.bottom - rc.top;
  369.         dxScreen = GetSystemMetrics(SM_CXSCREEN);
  370.         dyScreen = GetSystemMetrics(SM_CYSCREEN);
  371.  
  372.         pt.x = (dxScreen - dxTaskman) / 2;
  373.         pt.y = (dyScreen - dyTaskman) / 2;
  374.  
  375.         SetWindowPos(hwnd, HWND_NOTOPMOST, pt.x, pt.y, 0, 0,
  376.            SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
  377.  
  378.         SendDlgItemMessage(hwnd, IDD_PATH, EM_LIMITTEXT, MAXPATHFIELD-4, 0L);
  379.         szPathField[0] = TEXT('\0');
  380.  
  381.         bChangedDefaultButton = FALSE;
  382.  
  383.         return FALSE;
  384.  
  385.     case WM_SHOWWINDOW:
  386.         /*
  387.          * If we're being shown fill in the listbox.  We do this here
  388.          * rather than in WM_ACTIVATE process so we can do it while the
  389.          * dialog is still invisible.
  390.          */
  391.         if (wParam != 0) {
  392.             DWORD pidTaskMan = GetCurrentProcessId();
  393.  
  394.             /*
  395.              * First delete any previous entries.
  396.              */
  397.             while ((int)SendMessage(hwndLB, LB_DELETESTRING, 0, 0) != LB_ERR);
  398.  
  399.             /*
  400.              * Search the window list for enabled top level windows.
  401.              */
  402.             hwndNext = GetWindow(hwnd, GW_HWNDFIRST);
  403.             while (hwndNext) {
  404.  
  405.                 /*
  406.                  * Only add non-owned, visible, non-Taskman, Top Level Windows.
  407.                  */
  408.                 if ((hwndNext != hwnd) && (IsWindowVisible(hwndNext)) &&
  409.                         (!GetWindow(hwndNext, GW_OWNER))) {
  410.                     DWORD pidNext;
  411.                     GetWindowThreadProcessId(hwndNext, &pidNext);
  412.                     if (pidNext != pidTaskMan) {
  413.                         if (InternalGetWindowText(hwndNext, (LPTSTR)szTempField,
  414.                                 MAXTASKNAMELEN)) {
  415.                             nIndex = (int)SendMessage(hwndLB, LB_ADDSTRING, 0,
  416.                                     (DWORD_PTR)(LPTSTR)szTempField);
  417.                             SendMessage(hwndLB, LB_SETITEMDATA, nIndex,
  418.                                     (DWORD_PTR)hwndNext);
  419.                         }
  420.                     }
  421.                 }
  422.  
  423.                 hwndNext = GetWindow(hwndNext, GW_HWNDNEXT);
  424.             }
  425.             SendMessage(hwndLB, LB_SETCURSEL, 0, 0);
  426.  
  427.             //
  428.             // Set the default button to "Switch To"
  429.             //
  430.  
  431.             SetDefButton(hwnd,IDD_SWITCH);
  432.  
  433.             //
  434.             // Load the combobox with the recently used files.
  435.             //
  436.  
  437.             if (GetDlgItem(hwnd, IDD_PATH)) {
  438.  
  439.                 //
  440.                 // FIrst empty the combo box from the last time.
  441.                 //
  442.  
  443.                 SendDlgItemMessage (hwnd, IDD_PATH,
  444.                                     CB_RESETCONTENT, 0, 0);
  445.  
  446.  
  447.                 //
  448.                 // Load the combobox with recently used files from the registry.
  449.                 //
  450.                 // Query the max number of files first.
  451.                 //
  452.  
  453.                 if (RegCreateKeyEx (HKEY_CURRENT_USER, FILES_KEY, 0, 0,
  454.                                     REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
  455.                                     NULL, &hKey, &dwDisp) == ERROR_SUCCESS) {
  456.  
  457.                     if (dwDisp == REG_OPENED_EXISTING_KEY) {
  458.  
  459.                         //
  460.                         //  Query the max number of entries
  461.                         //
  462.  
  463.                         dwMaxFilesSize = sizeof (DWORD);
  464.  
  465.                         if (RegQueryValueEx (hKey, MAXFILES_ENTRY, NULL, &dwDataType,
  466.                                        (LPBYTE)&dwMaxFiles, &dwMaxFilesSize) == ERROR_SUCCESS) {
  467.  
  468.                             //
  469.                             //  Now Query each entry and add it to the list box.
  470.                             //
  471.  
  472.                             for (dwCount=0; dwCount < dwMaxFiles; dwCount++) {
  473.  
  474.                                 wsprintf (szFileEntry, FILE_ENTRY, dwCount);
  475.                                 dwMaxFilesSize = MAXPATHFIELD+1;
  476.  
  477.                                 if (RegQueryValueEx (hKey, szFileEntry, NULL, &dwDataType,
  478.                                                  (LPBYTE) szFullPath, &dwMaxFilesSize) == ERROR_SUCCESS) {
  479.  
  480.                                     //
  481.                                     // Found an entry.  Add it to the combo box.
  482.                                     //
  483.  
  484.                                     SendDlgItemMessage (hwnd, IDD_PATH,
  485.                                                         CB_ADDSTRING, 0,
  486.                                                         (LPARAM)szFullPath);
  487.  
  488.                                 } else {
  489.                                     break;
  490.                                 }
  491.                             }
  492.                         }
  493.                     } else {
  494.                         //
  495.                         // We are working with a new key, so we need to
  496.                         // set the default number of files.
  497.                         //
  498.  
  499.                         RegSetValueEx (hKey, MAXFILES_ENTRY, 0, REG_DWORD,
  500.                                        (CONST BYTE *) &dwMaxFiles, sizeof (DWORD));
  501.                     }
  502.  
  503.                     //
  504.                     //  Close the registry key
  505.                     //
  506.  
  507.                     RegCloseKey (hKey);
  508.  
  509.                 }
  510.             }
  511.  
  512.             //
  513.             // Disable the Run button and set the focus to the
  514.             // listbox.
  515.             //
  516.  
  517.             EnableWindow(GetDlgItem(hwnd, IDD_RUN), FALSE);
  518.             SetFocus(hwndLB);
  519.         }
  520.         break;
  521.  
  522.     case WM_ACTIVATE:
  523.         /*
  524.          * If we're being deactivated clear the listbox so we
  525.          * can fill it in afresh when we're re-activated.
  526.          */
  527.         if (wParam == 0) {
  528.             /*
  529.              * If we're not already invisible, hide ourself.
  530.              */
  531.             if (IsWindowVisible(hwnd)) {
  532.                 HideWindow(hwnd);
  533.             }
  534.         }
  535.  
  536.         if (!bChangedDefaultButton) {
  537.            SetDefButton(hwnd,IDD_SWITCH);
  538.         }
  539.  
  540.         break;
  541.  
  542.     case WM_ACTIVATEAPP:
  543.         if (wParam)
  544.             return FALSE;
  545.  
  546.         /*
  547.          * If we are not visible when we get this message it is because
  548.          * we are already in the process of terminating.  If we don't
  549.          * ignore this we get into a weird race condition and the frame
  550.          * of the window being activated doesn't get fully drawn.  (BG)
  551.          */
  552.         if (IsWindowVisible(hwnd)) {
  553.             HideWindow(hwnd);
  554.         }
  555.         break;
  556.  
  557. #ifdef JAPAN // bug fix
  558.     //
  559.     // Do nothing. Let the progman main thread do the work.
  560.     //
  561. #else // not JAPAN
  562.     case WM_WININICHANGE:
  563.         //
  564.         // Check if the user's environment variables have changed, if so
  565.         // regenerate the environment, so that new apps started from
  566.         // taskman will have the latest environment.
  567.         //
  568.         if (lParam && (!lstrcmpi((LPTSTR)lParam, (LPTSTR) TEXT("Environment")))) {
  569.             PVOID pEnv;
  570.  
  571.             RegenerateUserEnvironment(&pEnv, TRUE);
  572.             break;
  573.         }
  574.         else {
  575.             return FALSE;
  576.         }
  577. #endif // JAPAN
  578.  
  579.     case WM_CONTENTSCHANGED:
  580.        if (fExecOK) {
  581.           if (GetDlgItemText(hwnd, IDD_PATH, (LPTSTR)szPathField, MAXPATHFIELD)) {
  582.              EnableWindow(GetDlgItem(hwnd, IDD_RUN), TRUE);
  583.              if (!bChangedDefaultButton) {
  584.                 SetDefButton(hwnd,IDD_RUN);
  585.                 bChangedDefaultButton = TRUE;
  586.              }
  587.           } else {
  588.              EnableWindow(GetDlgItem(hwnd, IDD_RUN), FALSE);
  589.              if (bChangedDefaultButton) {
  590.                 SetDefButton(hwnd,IDD_SWITCH);
  591.                 bChangedDefaultButton = FALSE;
  592.              }
  593.           }
  594.        }
  595.  
  596.        break;
  597.  
  598.  
  599.     case WM_COMMAND:
  600.         switch(LOWORD(wParam)) {
  601.  
  602.         case IDD_TASKLISTBOX:
  603.  
  604.             switch(HIWORD(wParam)) {
  605.  
  606.             case LBN_DBLCLK:
  607.                 HideTasklist();
  608.                 ActivateSelectedWindow(hwndLB);
  609.                 break;
  610.  
  611.             default:
  612.                 return FALSE;
  613.             }
  614.             break;
  615.  
  616.         case IDD_PATH:
  617.            PostMessage (hwnd, WM_CONTENTSCHANGED, 0, 0);
  618.            break;
  619.  
  620.  
  621.         case IDOK:
  622.            if (!bChangedDefaultButton) {
  623.               goto Switchem;
  624.            }
  625.  
  626.         case IDD_RUN:
  627.            if (fExecOK) {
  628.               TCHAR szFilename[MAXPATHFIELD+4];
  629.               WORD ret;
  630.  
  631.               GetDlgItemText(hwnd, IDD_PATH, szPathField, MAXPATHFIELD);
  632.               DoEnvironmentSubst(szPathField, MAXPATHFIELD);
  633.               GetDirectoryFromPath(szPathField, szDirField);
  634.               if (*szDirField) {
  635.                   // Convert path into a .\foo.exe style thing.
  636.                   lstrcpy(szFilename, L".\\");
  637.                   // Tag the filename and params on to the end of the dot slash.
  638.                   GetFilenameFromPath(szPathField, szFilename+2);
  639.                   if (*(szFilename+2) == L'"' ) {
  640.                       SheRemoveQuotes(szFilename+2);
  641.                       CheckEscapes(szFilename, ARRAYSIZE(szFilename));
  642.                   }
  643.               }
  644.               else {
  645.                   GetFilenameFromPath(szPathField, szFilename);
  646.               }
  647.  
  648.               ret = ExecProgram(szFilename, szDirField, szFilename);
  649.  
  650.               if (ret) {
  651.                  fMsgBox = TRUE;
  652.                  MyMessageBox( hwnd, IDS_EXECERRTITLE, ret, szPathField,
  653.                     MB_SYSTEMMODAL | MB_OK | MB_ICONEXCLAMATION );
  654.                  fMsgBox = FALSE;
  655.  
  656.                  SetFocus(GetDlgItem(hwnd, IDD_PATH));
  657.               } else {
  658.                  GetDlgItemText(hwnd, IDD_PATH, szPathField, MAXPATHFIELD);
  659.                  SaveRecentFileList (hwnd, szPathField);
  660.                  HideWindow(hwnd);
  661.               }
  662.  
  663.            }
  664.            break;
  665.  
  666. Switchem:
  667.  
  668.         case IDD_SWITCH:
  669.             HideTasklist();
  670.             ActivateSelectedWindow(hwndLB);
  671.             break;
  672.  
  673.         case IDCANCEL:
  674.            HideWindow(hwnd);
  675.            break;
  676.  
  677.         case IDD_TERMINATE:
  678.             /*
  679.              * Get the hwnd of the item which was selected.
  680.              */
  681.             nIndex = (int)SendMessage(hwndLB, LB_GETCURSEL, 0, 0);
  682.             hwndNext = (HWND)SendMessage(hwndLB, LB_GETITEMDATA, nIndex, 0);
  683.  
  684.             if (!IsWindow(hwndNext)) {
  685.                 HideWindow(hwnd);
  686.                 MessageBeep(0);
  687.                 break;
  688.             }
  689.  
  690. #ifndef NTWIN   /* Since NTWIN uses WM_ENDSESSION to kill the app,
  691.                  * It is OK to kill it when it is disabled
  692.                  */
  693.             /*
  694.              * Test if the toplevel window is disabled. If it is
  695.              * diabled, we don't want to send a WM_CLOSE message to
  696.              * the parent. This is because the app could have a dialog
  697.              * box up and it's not expecting a CLOSE message...
  698.              * Nasty rips can happen... Instead, active the window so
  699.              * that the user can dismis any dialog box or fix whatever
  700.              * is causing the top level window to be disabled...
  701.              */
  702.             lTemp = GetWindowLong(hwndNext, GWL_STYLE);
  703.             if (lTemp & WS_DISABLED) {
  704.                 HideTasklist();
  705.                 MessageBeep(0);
  706.                 ActivateSelectedWindow(hwndLB);
  707.  
  708.             } else
  709. #endif
  710.             {
  711.                 /* Always activate the window first.  This prevents
  712.                  * apps from going to Beep mode.  Failing to do this
  713.                  * can cause re-entrancy problems in the app if we
  714.                  * do this again before activating the app.
  715.                  *
  716.                  * However, don't do this if it is a old app task.
  717.                  */
  718.  
  719. #ifdef WIN16    /* if NTWIN, then always do this, as is no winoldapp */
  720.                 if (!IsWinoldapTask(GetTaskFromHwnd(hwndNext)))
  721. #endif
  722.                 HideWindow(hwnd);
  723.                 ActivateSelectedWindow(hwndLB);
  724. #ifdef NTWIN
  725.                 {
  726.                     DWORD idt;
  727.                     HANDLE hThread;
  728.  
  729.                     hThread = CreateThread(NULL, 0,
  730.                              (LPTHREAD_START_ROUTINE)CallEndTask,
  731.                              (LPVOID)hwndNext, 0,
  732.                              &idt);
  733.  
  734.                     if (hThread == NULL) {
  735.                         /*
  736.                          * Can not create thread, just call EndTask
  737.                          * syncronously
  738.                          */
  739.                         DoEndTask( hwndNext );
  740.                     } else {
  741.                         CloseHandle(hThread);
  742.                     }
  743.                 }
  744. #else
  745.                 EndTask(hwndNext, FALSE, FALSE);
  746. #endif
  747.             }
  748.  
  749.             break;
  750.  
  751.         case IDD_TILE:
  752.         case IDD_CASCADE:
  753.             {
  754.                 HWND hwndDesktop;
  755.  
  756.                 HideWindow(hwnd);
  757.  
  758.                 hwndDesktop = GetDesktopWindow();
  759.  
  760.                 if (wParam == IDD_CASCADE) {
  761.                     CascadeChildWindows(hwndDesktop, 0);
  762.  
  763.                 } else {
  764.                     /*
  765.                      * If shift is down, tile vertically, else horizontally.
  766.                      */
  767.                     TileChildWindows(hwndDesktop, ((GetKeyState(VK_SHIFT) &
  768.                             0x8000) ? MDITILE_HORIZONTAL : MDITILE_VERTICAL));
  769.                 }
  770.                 break;
  771.             }
  772.  
  773.         case IDD_ARRANGEICONS:
  774.             /*
  775.              * Let's restore the saved bits before ArrangeIcons
  776.              * FIX for Bug #4884; --SANKAR-- 10-02-89
  777.              */
  778.             HideWindow(hwnd);
  779.             ArrangeIconicWindows(GetDesktopWindow());
  780.             break;
  781.         }
  782.  
  783.         break;
  784.  
  785.  
  786.     case WM_CLOSE:
  787.         /*
  788.          * If wParam != 0, this is a shutdown request, so exit.
  789.          */
  790.         if (wParam != 0)
  791.             ExitProcess(0);
  792.         return FALSE;
  793.         break;
  794.  
  795.     case WM_HOTKEY:
  796.         if (wParam == 1) {
  797.             pt.x = (dxScreen - dxTaskman) / 2;
  798.             pt.y = (dyScreen - dyTaskman) / 2;
  799.             ShowTasklist(pt);
  800.         }
  801.         break;
  802.  
  803.     case WM_LOGOFF:
  804.         PostQuitMessage(0);
  805.         break;
  806.  
  807.     default:
  808.         return FALSE;
  809.     }
  810.  
  811.     return TRUE;
  812.  
  813.     lParam;
  814. }
  815.  
  816. //*************************************************************
  817. //
  818. //  SetDefButton()
  819. //
  820. //  Purpose:    Sets the default button
  821. //
  822. //  Parameters: HWND hDlg     - Window handle of dialog box
  823. //              INT  idButton - ID of button
  824. //
  825. //  Return:     void
  826. //
  827. //*************************************************************
  828.  
  829. VOID SetDefButton(HWND hwndDlg, INT  idButton)
  830. {
  831.     LRESULT lr;
  832.  
  833.     if (HIWORD(lr = SendMessage(hwndDlg, DM_GETDEFID, 0, 0)) == DC_HASDEFID)
  834.     {
  835.         HWND hwndOldDefButton = GetDlgItem(hwndDlg, LOWORD(lr));
  836.  
  837.         SendMessage (hwndOldDefButton,
  838.                      BM_SETSTYLE,
  839.                      MAKEWPARAM(BS_PUSHBUTTON, 0),
  840.                      MAKELPARAM(TRUE, 0));
  841.     }
  842.  
  843.     SendMessage( hwndDlg, DM_SETDEFID, idButton, 0L );
  844.     SendMessage( GetDlgItem(hwndDlg, idButton),
  845.                  BM_SETSTYLE,
  846.                  MAKEWPARAM( BS_DEFPUSHBUTTON, 0 ),
  847.                  MAKELPARAM( TRUE, 0 ));
  848.  
  849. }
  850.  
  851.  
  852. /*** SaveRecentFileList --    Save the list of recently used files
  853.  *
  854.  * void APIENTRY SaveRecentFileList (HWND hwnd, LPTSTR szCurrentFile);
  855.  *
  856.  *
  857.  *
  858.  * ENTRY - HWND   hwnd            - handle to dialog box.
  859.  *         LPTSTR szCurrentFile   - pointer to selected filename
  860.  *
  861.  * EXIT  -
  862.  * SYNOPSIS -
  863.  *
  864.  * WARNINGS -
  865.  * EFFECTS  -
  866.  *
  867.  */
  868.  
  869.  
  870. void APIENTRY SaveRecentFileList (HWND hwnd, LPTSTR szCurrentFile)
  871. {
  872.     HKEY  hKey;
  873.     DWORD dwDisp;
  874.     DWORD dwDataType, dwMaxFiles=INIT_MAX_FILES, dwMaxFilesSize, dwCount;
  875.     TCHAR szFileEntry[20];
  876.     DWORD dwEnd=0;
  877.     DWORD dwFileNum=0;
  878.     DWORD dwDup;
  879.     static TCHAR szRecentFilePath[MAXPATHFIELD+1];
  880.  
  881.     //
  882.     // Open registry key
  883.     //
  884.  
  885.     if ( RegCreateKeyEx (HKEY_CURRENT_USER, FILES_KEY, 0, 0,
  886.                              REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE,
  887.                              NULL, &hKey, &dwDisp) != ERROR_SUCCESS) {
  888.         return;
  889.     }
  890.  
  891.  
  892.     //
  893.     // Query the max number of files to save first.
  894.     //
  895.  
  896.     dwMaxFilesSize = sizeof (DWORD);
  897.  
  898.     RegQueryValueEx (hKey, MAXFILES_ENTRY, NULL, &dwDataType,
  899.                     (LPBYTE)&dwMaxFiles, &dwMaxFilesSize);
  900.  
  901.     //
  902.     // If the user request 0 entries, then exit now.
  903.     //
  904.     if (dwMaxFiles == 0) {
  905.         RegCloseKey (hKey);
  906.         return;
  907.     }
  908.  
  909.     //
  910.     // Find out how many items are in the list box.
  911.     //
  912.  
  913.     dwEnd = (DWORD)SendDlgItemMessage (hwnd, IDD_PATH, CB_GETCOUNT, 0, 0);
  914.  
  915.     //
  916.     // If the max number of items we want to save is less than the
  917.     // number of entries, then change the ending point.
  918.     //
  919.  
  920.     if (dwMaxFiles < dwEnd) {
  921.         dwEnd = dwMaxFiles;
  922.     }
  923.  
  924.     //
  925.     // Add the first entry (the current file)
  926.     //
  927.  
  928.     wsprintf (szFileEntry, FILE_ENTRY, dwFileNum++);
  929.     dwMaxFilesSize = MAXPATHFIELD+1;
  930.  
  931.     RegSetValueEx (hKey, szFileEntry, 0, REG_SZ, (CONST BYTE *)szCurrentFile,
  932.                    sizeof (TCHAR) * (lstrlen (szCurrentFile)+1));
  933.  
  934.  
  935.     //
  936.     // Check for a duplicate string.
  937.     //
  938.  
  939.     dwDup = (DWORD)SendDlgItemMessage (hwnd, IDD_PATH, CB_FINDSTRING,
  940.                                 (WPARAM) -1, (LPARAM) szCurrentFile);
  941.  
  942.     //
  943.     // If we already have dwMaxFiles in the list and we don't have any
  944.     // duplicates, then we only want to save dwMaxFiles - 1 entries
  945.     // (drop the last entry).
  946.     //
  947.     //
  948.  
  949.     if ( (dwEnd == dwMaxFiles) && (dwDup == CB_ERR) ) {
  950.         dwEnd--;
  951.     }
  952.  
  953.     //
  954.     // Now loop through the remaining entries
  955.     //
  956.  
  957.     for (dwCount=0; dwCount < dwEnd; dwCount++) {
  958.  
  959.         //
  960.         // Check to see if we are at the duplicate entry.  If
  961.         // so skip on to the next item.
  962.         //
  963.  
  964.         if ((dwDup != CB_ERR) && (dwCount == dwDup)) {
  965.             continue;
  966.         }
  967.  
  968.         //
  969.         // Get an entry out of the listbox.
  970.         //
  971.  
  972.         SendDlgItemMessage (hwnd, IDD_PATH, CB_GETLBTEXT, (WPARAM) dwCount,
  973.                             (LPARAM) szRecentFilePath);
  974.  
  975.         //
  976.         // If we get a NULL string, break out of the loop.
  977.         //
  978.  
  979.         if (!(*szRecentFilePath) || !szRecentFilePath) {
  980.             break;
  981.         }
  982.  
  983.         //
  984.         // Build the entry name
  985.         //
  986.  
  987.         wsprintf (szFileEntry, FILE_ENTRY, dwFileNum);
  988.         dwMaxFilesSize = MAXPATHFIELD+1;
  989.  
  990.         //
  991.         // Save the entry
  992.         //
  993.  
  994.         RegSetValueEx (hKey, szFileEntry, 0, REG_SZ,(CONST BYTE *) szRecentFilePath,
  995.                        sizeof (TCHAR) * (lstrlen (szRecentFilePath)+1));
  996.  
  997.         //
  998.         // Increment our current file number
  999.         //
  1000.  
  1001.         dwFileNum++;
  1002.     }
  1003.  
  1004.     //
  1005.     // Close the key
  1006.     //
  1007.  
  1008.     RegCloseKey (hKey);
  1009.  
  1010. }
  1011.  
  1012.  
  1013.  
  1014. /*** Main --         Program entry point (was WinMain).
  1015.  *
  1016.  *
  1017.  *
  1018.  * Main(int argc, char *argv[], char *envp[])
  1019.  *
  1020.  * ENTRY -         int argc                - argument count.
  1021.  *                        char *argv[]        - argument list.
  1022.  *                        char *envp[]        - environment.
  1023.  *
  1024.  * EXIT  -           TRUE if success, FALSE if not.
  1025.  * SYNOPSIS -  Parses command line, for position to place dialog box, if no
  1026.  *                                position (came from ctl/esc) then center on screen.
  1027.  *                                Also make sure only one instance of taskman.
  1028.  *
  1029.  * WARNINGS -
  1030.  * EFFECTS  -
  1031.  */
  1032.  
  1033. INT __cdecl main(
  1034.    INT argc,
  1035.    CHAR *argv[],
  1036.    CHAR *envp[])
  1037. {
  1038.    MSG msg;
  1039.  
  1040.    /*
  1041.     * First set the priority of taskman so it is higher than foreground apps
  1042.     * that spin in loops - this way it'll always come up when you hit
  1043.     * ctrl-esc.
  1044.     */
  1045.    hInst = GetModuleHandle(NULL);
  1046.  
  1047.    SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
  1048.  
  1049.    {
  1050.        //
  1051.        // Set the working set size to 200k.
  1052.        //
  1053.  
  1054.        QUOTA_LIMITS QuotaLimits;
  1055.        NTSTATUS status;
  1056.  
  1057.        status = NtQueryInformationProcess( NtCurrentProcess(),
  1058.                                            ProcessQuotaLimits,
  1059.                                            &QuotaLimits,
  1060.                                            sizeof(QUOTA_LIMITS),
  1061.                                            NULL );
  1062.        if (NT_SUCCESS(status)) {
  1063.            QuotaLimits.MinimumWorkingSetSize = 300 * 1024;
  1064.            QuotaLimits.MaximumWorkingSetSize = 372 * 1024;
  1065.  
  1066.            NtSetInformationProcess( NtCurrentProcess(),
  1067.                                     ProcessQuotaLimits,
  1068.                                     &QuotaLimits,
  1069.                                     sizeof(QUOTA_LIMITS) );
  1070.        }
  1071.    }
  1072.  
  1073.    /*
  1074.     * Taskman will work in the windows directory, and switch to the
  1075.     * original directory (home directory) before execing programs.
  1076.     * This is to prevent weird popups if a UNC original directory is
  1077.     * disconnected.
  1078.     */
  1079.  
  1080.    GetCurrentDirectory(MAXPATHFIELD, szUserHomeDir);
  1081.    GetWindowsDirectory(szWindowsDirectory, MAXPATHFIELD);
  1082.    SetCurrentDirectory(szWindowsDirectory);
  1083.  
  1084.    fExecOK = OKToExec();
  1085.    if (!IsUserAdmin() && !fExecOK) {
  1086.       ghwndDialog = CreateDialog(hInst, MAKEINTRESOURCE(WMPTASKMANDLG), NULL,
  1087.          TaskmanDlgProc);
  1088.    } else {
  1089.       ghwndDialog = CreateDialog(hInst, MAKEINTRESOURCE(PWRTASKMANDLG), NULL,
  1090.          TaskmanDlgProc);
  1091.    }
  1092.  
  1093.    if (ghwndDialog == NULL)
  1094.        return 0;
  1095.  
  1096.    LoadString(hInst, IDS_OOMEXITTITLE, szOOMExitTitle, 32);
  1097.    LoadString(hInst, IDS_OOMEXITMSG, szOOMExitMsg, 64);
  1098.  
  1099.    if (!RegisterHotKey(ghwndDialog, 1, MOD_CONTROL, VK_ESCAPE) ||
  1100.            !RegisterTasklist(ghwndDialog)) {
  1101.        goto exit;
  1102.    }
  1103.  
  1104.    while (GetMessage(&msg, (HWND)NULL, (UINT)0, (UINT)0)) {
  1105.        if (!IsDialogMessage(ghwndDialog, &msg)) {
  1106.           if ((msg.message == WM_SYSCOMMAND) && (msg.wParam == SC_TASKLIST)) {
  1107.              POINT pt;
  1108.  
  1109.              GetCursorPos(&pt);
  1110.              pt.x = max(pt.x - (dyTaskman / 2), 0);
  1111.              pt.x = min(pt.x, dxScreen - dxTaskman);
  1112.              pt.y = max(pt.y - (GetSystemMetrics(SM_CYCAPTION) * 2), 0);
  1113.              pt.y = min(pt.y, dyScreen - dyTaskman);
  1114.  
  1115.              ShowTasklist(pt);
  1116.           } else {
  1117.  
  1118.               //
  1119.               //  We need to have a regular message loop in order
  1120.               //  to handle the DDE messages generated by spawning
  1121.               //  an application via an association.
  1122.               //
  1123.  
  1124.               TranslateMessage (&msg);
  1125.               DispatchMessage (&msg);
  1126.           }
  1127.  
  1128.        }
  1129.    }
  1130.  
  1131. exit:
  1132.     DestroyWindow(ghwndDialog);
  1133.     return 0;
  1134.  
  1135.     argc;
  1136.     argv;
  1137.     envp;
  1138. }
  1139.  
  1140.  
  1141. WORD APIENTRY
  1142. ExecProgram(
  1143.     LPTSTR lpszPath,
  1144.     LPTSTR lpDir,
  1145.     LPTSTR lpTitle
  1146.     )
  1147. {
  1148.   WORD      ret;
  1149.   HCURSOR   hCursor;
  1150.   LPTSTR     lpP;
  1151.   TCHAR cSeparator;
  1152.   TCHAR lpReservedFormat[] = TEXT("dde.%d,hotkey.%d");
  1153.   TCHAR lpReserved[100];  // used for DDE request of icons from console apps
  1154.                          // add for passing the hotkey associated with an item.
  1155.   HANDLE hProcess;
  1156.  
  1157.   ret = 0;
  1158.  
  1159.   /*
  1160.    * Set the current directory to the user's home directory if possible.
  1161.    */
  1162.   SetCurrentDirectory(szUserHomeDir);
  1163.  
  1164.   hCursor = SetCursor(LoadCursor(NULL, IDC_WAIT));
  1165.  
  1166.   /* Don't mess with the mouse state; unless we're on a mouseless system.
  1167.    */
  1168.   if (!GetSystemMetrics(SM_MOUSEPRESENT))
  1169.       ShowCursor(TRUE);
  1170.  
  1171.   /* skip leading spaces
  1172.    */
  1173.   while (*lpszPath == TEXT(' '))
  1174.       lpszPath++;
  1175.  
  1176.   /* skip past path
  1177.    */
  1178.   lpP = lpszPath;
  1179.   if (*lpszPath == TEXT('"')) {
  1180.      cSeparator = TEXT('"');
  1181.      lpP++;
  1182.   }
  1183.   else {
  1184.      cSeparator = TEXT(' ');
  1185.   }
  1186.  
  1187.   for (; *lpP && *lpP != cSeparator; lpP = CharNext(lpP))
  1188.       ;
  1189.   if (*lpP == TEXT('"')) {
  1190.      lpP++;
  1191.   }
  1192.  
  1193.   /* if stuff on end, separate it
  1194.    */
  1195.   if (*lpP)
  1196.       *lpP++ = 0;
  1197.  
  1198.  
  1199.   /* Try to exec 'szCommandLine'. */
  1200.  
  1201.   /*changed order, since wPendINstance is a 32b HANDLE, and ret is WORD*/
  1202.     if (!lpP)
  1203.         lpP = TEXT("");
  1204.  
  1205.     wsprintf(lpReserved, lpReservedFormat, 0, 0);
  1206.  
  1207.     ret = (WORD)RealShellExecute(ghwndDialog, NULL, lpszPath, lpP,
  1208.                             lpDir, NULL, lpTitle, lpReserved,
  1209.                             (WORD)SW_SHOWNORMAL, &hProcess);
  1210.  
  1211.   /*BUG BUG these are DOS exec function return codes, no map yet to NT return codes!*/
  1212.   switch (ret) {
  1213.       case 0:
  1214.       case SE_ERR_OOM:    // 8
  1215.           ret = IDS_NOMEMORYMSG;
  1216.           break;
  1217.  
  1218.       case SE_ERR_FNF:    // 2
  1219.           ret = IDS_FILENOTFOUNDMSG;
  1220.           break;
  1221.  
  1222.       case SE_ERR_PNF:    // 3
  1223.           ret = IDS_BADPATHMSG;
  1224.           break;
  1225.  
  1226.       case 4:
  1227.           ret = IDS_MANYOPENFILESMSG;
  1228.           break;
  1229.  
  1230.       case 5:
  1231.           ret = IDS_ACCESSDENIED;
  1232.           break;
  1233.  
  1234.       case 10:
  1235.           ret = IDS_NEWWINDOWSMSG;
  1236.           break;
  1237.  
  1238.       case 12:
  1239.           ret = IDS_OS2APPMSG;
  1240.           break;
  1241.  
  1242.       case 15:
  1243.           /* KERNEL has already put up a messagebox for this one. */
  1244.           ret = 0;
  1245.           break;
  1246.  
  1247.       case 16:
  1248.           ret = IDS_MULTIPLEDSMSG;
  1249.           break;
  1250.  
  1251.       case 18:
  1252.           ret = IDS_PMODEONLYMSG;
  1253.           break;
  1254.  
  1255.       case 19:
  1256.           ret = IDS_COMPRESSEDEXE;
  1257.           break;
  1258.  
  1259.       case 20:
  1260.           ret = IDS_INVALIDDLL;
  1261.           break;
  1262.  
  1263.       case SE_ERR_SHARE:
  1264.           ret = IDS_SHAREERROR;
  1265.           break;
  1266.  
  1267.       case SE_ERR_ASSOCINCOMPLETE:
  1268.           ret = IDS_ASSOCINCOMPLETE;
  1269.           break;
  1270.  
  1271.       case SE_ERR_DDETIMEOUT:
  1272.       case SE_ERR_DDEFAIL:
  1273.       case SE_ERR_DDEBUSY:
  1274.           ret = IDS_DDEFAIL;
  1275.           break;
  1276.  
  1277.       case SE_ERR_NOASSOC:
  1278.           ret = IDS_NOASSOCMSG;
  1279.           break;
  1280.  
  1281.       default:
  1282.           ret = 0;
  1283.           break;
  1284.   }
  1285.  
  1286.   if (!GetSystemMetrics(SM_MOUSEPRESENT)) {
  1287.       /*
  1288.        * We want to turn the mouse off here on mouseless systems, but
  1289.        * the mouse will already have been turned off by USER if the
  1290.        * app has GP'd so make sure everything's kosher.
  1291.        */
  1292.       if (ShowCursor(FALSE) != -1)
  1293.           ShowCursor(TRUE);
  1294.   }
  1295.  
  1296.   SetCursor(hCursor);
  1297.  
  1298.   /*
  1299.    * Reset the working directory to the windows directory.
  1300.    */
  1301.   SetCurrentDirectory(szWindowsDirectory);
  1302.  
  1303.   return(ret);
  1304. }
  1305.  
  1306.  
  1307. VOID
  1308. GetDirectoryFromPath(
  1309.    PTSTR szFilePath,
  1310.    PTSTR szDir)
  1311. {
  1312.    PTSTR pFileName;
  1313.    PTSTR pExt;
  1314.    WORD ich;
  1315.    BOOL fUnc;
  1316.  
  1317.    *szDir = TEXT('\0');
  1318.  
  1319.    /* Get info about file path. */
  1320.    GetPathInfo(szFilePath, &pFileName, &pExt, &ich, &fUnc);
  1321.  
  1322.    /* UNC paths don't (conceptually to Progman) have a directory component. */
  1323.    if (fUnc)
  1324.       return;
  1325.  
  1326.    /* Does it have a directory component ? */
  1327.    if (pFileName != szFilePath) { // Yep.
  1328.       /* copy path to temp. */
  1329.       if (*szFilePath == TEXT('"')) {
  1330.          szFilePath++;
  1331.       }
  1332.       lstrcpy(szDir, szFilePath);
  1333.       /* check path style. */
  1334.       if (ich <= 3 && *(szDir+1) == TEXT(':')) {
  1335.          /*
  1336.           * The path is "c:\foo.c" or "c:foo.c" style.
  1337.           * Don't remove the last slash/colon, just the filename.
  1338.           */
  1339.          szDir[pFileName-szFilePath] = TEXT('\0');
  1340.       }
  1341.  
  1342.       else if (ich == 1) {
  1343.          /*
  1344.           * something like "\foo.c"
  1345.           * Don't remove the last slash/colon, just the filename.
  1346.           */
  1347.           szDir[pFileName-szFilePath] = TEXT('\0');
  1348.        }
  1349.        else {
  1350.           /*
  1351.            * The filepath is a full normal path.
  1352.            * Could be something like "..\foo.c" or ".\foo.c" though.
  1353.            * Stomp on the last slash to get just the path.
  1354.            */
  1355.            szDir[pFileName-szFilePath-1] = TEXT('\0');
  1356.        }
  1357.     }
  1358.  
  1359.     /* else just a filename with no path. */
  1360. }
  1361.  
  1362. VOID
  1363. GetFilenameFromPath(
  1364.    PTSTR szPath,
  1365.    PTSTR szFilename)
  1366. {
  1367.    DWORD dummy;
  1368.    PTSTR pFileName;
  1369.    BOOL fUNC;
  1370.  
  1371.    GetPathInfo(szPath, &pFileName, (PTSTR*) &dummy, (WORD*) &dummy,
  1372.       &fUNC);
  1373.  
  1374.    /* If it's a UNC then the 'filename' part is the whole thing. */
  1375.    if (fUNC || (szPath == pFileName))
  1376.       lstrcpy(szFilename, szPath);
  1377.    else {
  1378.       if (*szPath == TEXT('"')) {
  1379.          *szFilename++ = TEXT('"');
  1380.       }
  1381.       lstrcpy(szFilename, pFileName);
  1382.    }
  1383. }
  1384.  
  1385.  
  1386. VOID
  1387. GetPathInfo(
  1388.    PTSTR szPath,
  1389.    PTSTR *pszFileName,
  1390.    PTSTR *pszExt,
  1391.    WORD *pich,
  1392.    BOOL *pfUnc)
  1393. {
  1394.    TCHAR *pch;          // Temp variable.
  1395.    WORD ich = 0;       // Temp.
  1396.    BOOL InQuotes;
  1397.  
  1398.    *pszExt = NULL;         // If no extension, return NULL.
  1399.    *pszFileName = szPath;  // If no seperate filename component, return path.
  1400.    *pich = 0;
  1401.    *pfUnc = FALSE;         // Default to not UNC style.
  1402.  
  1403.    //
  1404.    // Check if path is in quotes.
  1405.    //
  1406.    if (InQuotes = (*szPath == TEXT('"'))) {
  1407.       szPath++;
  1408.    }
  1409.  
  1410.    // Check for UNC style paths.
  1411.    if (*szPath == TEXT('\\') && *(szPath+1) == TEXT('\\'))
  1412.       *pfUnc = TRUE;
  1413.  
  1414.    // Search forward to find the last backslash or colon in the path.
  1415.    // While we're at it, look for the last dot.
  1416.    for (pch = szPath; *pch; pch = CharNext(pch)) {
  1417.  
  1418.       if ((*pch == TEXT(' ')) && (!InQuotes)) {
  1419.          // Found a space - stop here.
  1420.          break;
  1421.       }
  1422.       if (*pch == TEXT('"')) {
  1423.          // Found a the second quote - stop here.
  1424.          pch++;
  1425.          break;
  1426.       }
  1427.       if (*pch == TEXT('\\') || *pch == TEXT(':')) {
  1428.          // Found it, record ptr to it and it's index.
  1429.          *pszFileName = pch+1;
  1430.          *pich = ich + (WORD)1;
  1431.       }
  1432.       if (*pch == TEXT('.')) {
  1433.          // Found a dot.
  1434.          *pszExt = pch;
  1435.       }
  1436.       ich++;
  1437.    }
  1438.  
  1439.    /* Check that the last dot is part of the last filename. */
  1440.    if (*pszExt < *pszFileName)
  1441.       *pszExt = NULL;
  1442. }
  1443.  
  1444.  
  1445. BOOL
  1446. IsUserAdmin()
  1447. {
  1448.     BOOL UserIsAdmin = FALSE;
  1449.     HANDLE Token;
  1450.     PSID    AdminAliasSid = NULL;
  1451.     SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  1452.  
  1453.     //
  1454.     // Get the token of the current process.
  1455.     //
  1456.  
  1457.     if (!OpenProcessToken(
  1458.           GetCurrentProcess(),
  1459.           TOKEN_QUERY,
  1460.           &Token) ) {
  1461.        return(FALSE);
  1462.     }
  1463.  
  1464.     UserIsAdmin = TestTokenForAdmin(Token);
  1465.  
  1466.  
  1467.     CloseHandle(Token);
  1468.  
  1469.     return(UserIsAdmin);
  1470. }
  1471.  
  1472. BOOL
  1473. TestTokenForAdmin(
  1474.    HANDLE Token
  1475.    )
  1476. {
  1477.    NTSTATUS    Status;
  1478.    DWORD       InfoLength;
  1479.    PTOKEN_GROUPS TokenGroupList;
  1480.    DWORD       GroupIndex;
  1481.    PSID        AdminSid;
  1482.    BOOL        FoundAdmin;
  1483.    SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;
  1484.  
  1485.    //
  1486.    // Get a list of groups in the token
  1487.    //
  1488.  
  1489.    Status = NtQueryInformationToken(
  1490.       Token,                    // Handle
  1491.       TokenGroups,              // TokenInformationClass
  1492.       NULL,                     // TokenInformation
  1493.       0,                        // TokenInformationLength
  1494.       &InfoLength               // ReturnLength
  1495.    );
  1496.  
  1497.    if ((Status != STATUS_SUCCESS) && (Status != STATUS_BUFFER_TOO_SMALL)) {
  1498.       return(FALSE);
  1499.    }
  1500.  
  1501.    TokenGroupList = Alloc(InfoLength);
  1502.  
  1503.    if (TokenGroupList == NULL) {
  1504.       return(FALSE);
  1505.    }
  1506.  
  1507.    Status = NtQueryInformationToken(
  1508.       Token,                    // Handle
  1509.       TokenGroups,              // TokenInformationClass
  1510.       TokenGroupList,           // TokenInformation
  1511.       InfoLength,               // TokenInformationLength
  1512.       &InfoLength               // ReturnLength
  1513.    );
  1514.  
  1515.    if (!NT_SUCCESS(Status)) {
  1516.       LocalFree(TokenGroupList);
  1517.       return(FALSE);
  1518.    }
  1519.  
  1520.    //
  1521.    // Create the admin sid
  1522.    //
  1523.    Status = RtlAllocateAndInitializeSid(
  1524.       &SystemSidAuthority, 2,
  1525.       SECURITY_BUILTIN_DOMAIN_RID,
  1526.       DOMAIN_ALIAS_RID_ADMINS,
  1527.       0, 0, 0, 0, 0, 0,
  1528.       &AdminSid);
  1529.  
  1530.    if (!NT_SUCCESS(Status)) {
  1531.       Free(TokenGroupList);
  1532.       return(FALSE);
  1533.    }
  1534.  
  1535.    //
  1536.    // Search group list for admin alias
  1537.    //
  1538.    FoundAdmin = FALSE;
  1539.  
  1540.    for (GroupIndex=0; GroupIndex < TokenGroupList->GroupCount; GroupIndex++ ) {
  1541.       if (RtlEqualSid(TokenGroupList->Groups[GroupIndex].Sid, AdminSid)) {
  1542.          FoundAdmin = TRUE;
  1543.          break;
  1544.       }
  1545.    }
  1546.  
  1547.    //
  1548.    // Tidy up
  1549.    //
  1550.  
  1551.    RtlFreeSid(AdminSid);
  1552.    Free(TokenGroupList);
  1553.  
  1554.    return(FoundAdmin);
  1555. }
  1556.  
  1557. BOOL
  1558. OKToExec()
  1559. {
  1560.    TCHAR szRestrict[]        = TEXT("Restrictions");
  1561.    TCHAR szProgramManager[]  = TEXT("Software\\Microsoft\\Windows NT\\CurrentVersion\\Program Manager");
  1562.    HKEY hkeyProgramManager  = NULL;  // progman.ini key
  1563.    HKEY hkeyPMRestrict      = NULL;
  1564.    DWORD cbData, dwType;
  1565.    BOOL fNoRun = FALSE;
  1566.  
  1567.   /*
  1568.    * Create/Open the registry keys corresponding to progman.ini sections.
  1569.    */
  1570.   if (!RegCreateKeyEx(HKEY_CURRENT_USER, szProgramManager, 0, szProgramManager, 0,
  1571.                          KEY_READ | KEY_WRITE, NULL, &hkeyProgramManager, NULL)) {
  1572.  
  1573.       RegCreateKeyEx(hkeyProgramManager, szRestrict, 0, szProgramManager, 0,
  1574.                          KEY_READ, NULL, &hkeyPMRestrict, NULL);
  1575.  
  1576.   } else {
  1577.     return(FALSE);
  1578.   }
  1579.  
  1580.   if (hkeyPMRestrict) {
  1581.       cbData = sizeof(fNoRun);
  1582.       RegQueryValueEx(hkeyPMRestrict, szNoRun, 0, &dwType, (LPBYTE)&fNoRun,
  1583.          &cbData);
  1584.   }
  1585.  
  1586.   if (hkeyPMRestrict) {
  1587.       RegCloseKey(hkeyPMRestrict);
  1588.       hkeyPMRestrict = NULL;
  1589.   }
  1590.  
  1591.   RegCloseKey(hkeyProgramManager);
  1592.  
  1593.   return(!fNoRun);
  1594.  
  1595. }
  1596.  
  1597. INT
  1598. MyMessageBox(
  1599.    HWND hWnd,
  1600.    WORD idTitle,
  1601.    WORD idMessage,
  1602.    PWSTR psz,
  1603.    WORD wStyle)
  1604. {
  1605.     WCHAR    szTempField[MAXMSGBOXLEN];
  1606.     INT     iMsgResult;
  1607.  
  1608.     if (!LoadString(hInst, idTitle, szTitle, ARRAYSIZE(szTitle))){
  1609.         goto MessageBoxOOM;
  1610.     }
  1611.     if (idMessage < 32){
  1612.         if (!LoadString(hInst, IDS_UNKNOWNMSG, szTempField, ARRAYSIZE(szTempField))){
  1613.             goto MessageBoxOOM;
  1614.         }
  1615.         wsprintf(szMessage, szTempField, idMessage);
  1616.     }
  1617.     else{
  1618.         if (!LoadString(hInst, idMessage, szTempField, ARRAYSIZE(szTempField)))
  1619.             goto MessageBoxOOM;
  1620.  
  1621.         if (psz) {
  1622.             wsprintf(szMessage, szTempField, (LPTSTR)psz);
  1623.         }
  1624.         else
  1625.             lstrcpy(szMessage, szTempField);
  1626.     }
  1627.  
  1628.     iMsgResult = MessageBox(hWnd, szMessage, szTitle, wStyle );
  1629.  
  1630.     if (iMsgResult == -1){
  1631.  
  1632. MessageBoxOOM:
  1633.         MessageBox(hWnd, szOOMExitMsg, szOOMExitTitle, MB_SYSTEMMODAL | MB_ICONHAND | MB_OK);
  1634.     }
  1635.  
  1636.     return(iMsgResult);
  1637. }
  1638.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement