Пример #1
0
 public static extern bool CreateProcessWithTokenW(
     IntPtr hToken,
     uint dwLogonFlags,
     IntPtr lpApplicationName,
     IntPtr lpCommandLine,
     uint dwCreationFlags,
     IntPtr lpEnvironment,
     IntPtr lpCurrentDirectory,
     IntPtr lpStartupInfo,
     out NativeStructs.PROCESS_INFORMATION lpProcessInfo);
Пример #2
0
        public static int ExecRequireNonAdmin(IWin32Window parent, string exePath, string args, out IntPtr hProcess)
        {
            int    nError      = NativeConstants.ERROR_SUCCESS;
            string commandLine = "\"" + exePath + "\"" + (args == null ? "" : (" " + args));

            string dir;

            try {
                dir = Path.GetDirectoryName(exePath);
            }

            catch (Exception) {
                dir = null;
            }

            IntPtr hWndShell          = IntPtr.Zero;
            IntPtr hShellProcess      = IntPtr.Zero;
            IntPtr hShellProcessToken = IntPtr.Zero;
            IntPtr hTokenCopy         = IntPtr.Zero;
            IntPtr bstrExePath        = IntPtr.Zero;
            IntPtr bstrCommandLine    = IntPtr.Zero;
            IntPtr bstrDir            = IntPtr.Zero;
            var    procInfo           = new NativeStructs.PROCESS_INFORMATION();

            try {
                hWndShell = SafeNativeMethods.FindWindowW("Progman", null);
                if (hWndShell == IntPtr.Zero)
                {
                    NativeMethods.ThrowOnWin32Error("FindWindowW() returned NULL");
                }

                uint dwPID;
                uint dwThreadId = SafeNativeMethods.GetWindowThreadProcessId(hWndShell, out dwPID);
                if (0 == dwPID)
                {
                    NativeMethods.ThrowOnWin32Error("GetWindowThreadProcessId returned 0", NativeErrors.ERROR_FILE_NOT_FOUND);
                }

                hShellProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_QUERY_INFORMATION, false, dwPID);
                if (IntPtr.Zero == hShellProcess)
                {
                    NativeMethods.ThrowOnWin32Error("OpenProcess() returned NULL");
                }

                bool optResult = NativeMethods.OpenProcessToken(
                    hShellProcess,
                    NativeConstants.TOKEN_ASSIGN_PRIMARY | NativeConstants.TOKEN_DUPLICATE | NativeConstants.TOKEN_QUERY,
                    out hShellProcessToken);

                if (!optResult)
                {
                    NativeMethods.ThrowOnWin32Error("OpenProcessToken() returned FALSE");
                }

                bool dteResult = NativeMethods.DuplicateTokenEx(
                    hShellProcessToken,
                    NativeConstants.MAXIMUM_ALLOWED,
                    IntPtr.Zero,
                    NativeConstants.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
                    NativeConstants.TOKEN_TYPE.TokenPrimary,
                    out hTokenCopy);

                if (!dteResult)
                {
                    NativeMethods.ThrowOnWin32Error("DuplicateTokenEx() returned FALSE");
                }

                bstrExePath     = Marshal.StringToBSTR(exePath);
                bstrCommandLine = Marshal.StringToBSTR(commandLine);
                bstrDir         = Marshal.StringToBSTR(dir);

                bool cpwtResult = NativeMethods.CreateProcessWithTokenW(
                    hTokenCopy,
                    0,
                    bstrExePath,
                    bstrCommandLine,
                    0,
                    IntPtr.Zero,
                    bstrDir,
                    IntPtr.Zero,
                    out procInfo);

                if (cpwtResult)
                {
                    hProcess          = procInfo.hProcess;
                    procInfo.hProcess = IntPtr.Zero;
                    nError            = NativeConstants.ERROR_SUCCESS;
                }
                else
                {
                    hProcess = IntPtr.Zero;
                    nError   = Marshal.GetLastWin32Error();
                }
            }

            catch (Win32Exception ex) {
                nError   = ex.ErrorCode;
                hProcess = IntPtr.Zero;
            }

            finally {
                if (bstrExePath != IntPtr.Zero)
                {
                    Marshal.FreeBSTR(bstrExePath);
                    bstrExePath = IntPtr.Zero;
                }

                if (bstrCommandLine != IntPtr.Zero)
                {
                    Marshal.FreeBSTR(bstrCommandLine);
                    bstrCommandLine = IntPtr.Zero;
                }

                if (bstrDir != IntPtr.Zero)
                {
                    Marshal.FreeBSTR(bstrDir);
                    bstrDir = IntPtr.Zero;
                }

                if (hShellProcess != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(hShellProcess);
                    hShellProcess = IntPtr.Zero;
                }

                if (hShellProcessToken != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(hShellProcessToken);
                    hShellProcessToken = IntPtr.Zero;
                }

                if (hTokenCopy != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(hTokenCopy);
                    hTokenCopy = IntPtr.Zero;
                }

                if (procInfo.hThread != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(procInfo.hThread);
                    procInfo.hThread = IntPtr.Zero;
                }

                if (procInfo.hProcess != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(procInfo.hProcess);
                    procInfo.hProcess = IntPtr.Zero;
                }
            }

            return(nError);
        }
Пример #3
0
		public static int ExecRequireNonAdmin(IWin32Window parent, string exePath, string args, out IntPtr hProcess) {
			int nError = NativeConstants.ERROR_SUCCESS;
			string commandLine = "\"" + exePath + "\"" + (args == null ? "" : (" " + args));

			string dir;

			try {
				dir = Path.GetDirectoryName(exePath);
			}

			catch (Exception) {
				dir = null;
			}

			IntPtr hWndShell = IntPtr.Zero;
			IntPtr hShellProcess = IntPtr.Zero;
			IntPtr hShellProcessToken = IntPtr.Zero;
			IntPtr hTokenCopy = IntPtr.Zero;
			IntPtr bstrExePath = IntPtr.Zero;
			IntPtr bstrCommandLine = IntPtr.Zero;
			IntPtr bstrDir = IntPtr.Zero;
			var procInfo = new NativeStructs.PROCESS_INFORMATION();

			try {
				hWndShell = SafeNativeMethods.FindWindowW("Progman", null);
				if (hWndShell == IntPtr.Zero) {
					NativeMethods.ThrowOnWin32Error("FindWindowW() returned NULL");
				}

				uint dwPID;
				uint dwThreadId = SafeNativeMethods.GetWindowThreadProcessId(hWndShell, out dwPID);
				if (0 == dwPID) {
					NativeMethods.ThrowOnWin32Error("GetWindowThreadProcessId returned 0", NativeErrors.ERROR_FILE_NOT_FOUND);
				}

				hShellProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_QUERY_INFORMATION, false, dwPID);
				if (IntPtr.Zero == hShellProcess) {
					NativeMethods.ThrowOnWin32Error("OpenProcess() returned NULL");
				}

				bool optResult = NativeMethods.OpenProcessToken(
					hShellProcess,
					NativeConstants.TOKEN_ASSIGN_PRIMARY | NativeConstants.TOKEN_DUPLICATE | NativeConstants.TOKEN_QUERY,
					out hShellProcessToken);

				if (!optResult) {
					NativeMethods.ThrowOnWin32Error("OpenProcessToken() returned FALSE");
				}

				bool dteResult = NativeMethods.DuplicateTokenEx(
					hShellProcessToken,
					NativeConstants.MAXIMUM_ALLOWED,
					IntPtr.Zero,
					NativeConstants.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
					NativeConstants.TOKEN_TYPE.TokenPrimary,
					out hTokenCopy);

				if (!dteResult) {
					NativeMethods.ThrowOnWin32Error("DuplicateTokenEx() returned FALSE");
				}

				bstrExePath = Marshal.StringToBSTR(exePath);
				bstrCommandLine = Marshal.StringToBSTR(commandLine);
				bstrDir = Marshal.StringToBSTR(dir);

				bool cpwtResult = NativeMethods.CreateProcessWithTokenW(
					hTokenCopy,
					0,
					bstrExePath,
					bstrCommandLine,
					0,
					IntPtr.Zero,
					bstrDir,
					IntPtr.Zero,
					out procInfo);

				if (cpwtResult) {
					hProcess = procInfo.hProcess;
					procInfo.hProcess = IntPtr.Zero;
					nError = NativeConstants.ERROR_SUCCESS;
				}
				else {
					hProcess = IntPtr.Zero;
					nError = Marshal.GetLastWin32Error();
				}
			}

			catch (Win32Exception ex) {
				nError = ex.ErrorCode;
				hProcess = IntPtr.Zero;
			}

			finally {
				if (bstrExePath != IntPtr.Zero) {
					Marshal.FreeBSTR(bstrExePath);
					bstrExePath = IntPtr.Zero;
				}

				if (bstrCommandLine != IntPtr.Zero) {
					Marshal.FreeBSTR(bstrCommandLine);
					bstrCommandLine = IntPtr.Zero;
				}

				if (bstrDir != IntPtr.Zero) {
					Marshal.FreeBSTR(bstrDir);
					bstrDir = IntPtr.Zero;
				}

				if (hShellProcess != IntPtr.Zero) {
					SafeNativeMethods.CloseHandle(hShellProcess);
					hShellProcess = IntPtr.Zero;
				}

				if (hShellProcessToken != IntPtr.Zero) {
					SafeNativeMethods.CloseHandle(hShellProcessToken);
					hShellProcessToken = IntPtr.Zero;
				}

				if (hTokenCopy != IntPtr.Zero) {
					SafeNativeMethods.CloseHandle(hTokenCopy);
					hTokenCopy = IntPtr.Zero;
				}

				if (procInfo.hThread != IntPtr.Zero) {
					SafeNativeMethods.CloseHandle(procInfo.hThread);
					procInfo.hThread = IntPtr.Zero;
				}

				if (procInfo.hProcess != IntPtr.Zero) {
					SafeNativeMethods.CloseHandle(procInfo.hProcess);
					procInfo.hProcess = IntPtr.Zero;
				}
			}

			return nError;
		}