CreateProcessAsUserA
関数シグネチャ
// ADVAPI32.dll (ANSI / -A)
#include <windows.h>
BOOL CreateProcessAsUserA(
HANDLE hToken, // optional
LPCSTR lpApplicationName, // optional
LPSTR lpCommandLine, // optional
SECURITY_ATTRIBUTES* lpProcessAttributes, // optional
SECURITY_ATTRIBUTES* lpThreadAttributes, // optional
BOOL bInheritHandles,
PROCESS_CREATION_FLAGS dwCreationFlags,
void* lpEnvironment, // optional
LPCSTR lpCurrentDirectory, // optional
STARTUPINFOA* lpStartupInfo,
PROCESS_INFORMATION* lpProcessInformation
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| hToken | HANDLE | inoptional | ユーザーを表すプライマリトークンへのハンドル。このハンドルには TOKEN_QUERY、TOKEN_DUPLICATE、TOKEN_ASSIGN_PRIMARY のアクセス権が必要です。詳細については、 Access Rights for Access-Token Objects を参照してください。トークンが表すユーザーは、lpApplicationName または lpCommandLine パラメーターで指定されるアプリケーションに対する読み取りおよび実行アクセス権を持っている必要があります。 指定したユーザーを表すプライマリトークンを取得するには、 LogonUser 関数を呼び出します。あるいは、 DuplicateTokenEx 関数を呼び出して、偽装トークンをプライマリトークンに変換することもできます。これにより、クライアントを偽装しているサーバーアプリケーションが、クライアントのセキュリティコンテキストを持つプロセスを作成できます。 hToken が呼び出し元のプライマリトークンの制限されたバージョンである場合、SE_ASSIGNPRIMARYTOKEN_NAME 特権は不要です。必要な特権がまだ有効になっていない場合、 CreateProcessAsUser は呼び出しの間それらを有効にします。詳細については、 Running with Special Privileges を参照してください。 ターミナルサービス: プロセスは、トークンで指定されたセッションで実行されます。既定では、これは LogonUser を呼び出したのと同じセッションです。セッションを変更するには、 SetTokenInformation 関数を使用します。 |
| lpApplicationName | LPCSTR | inoptional | 実行するモジュールの名前。このモジュールは Windows ベースのアプリケーションにできます。適切なサブシステムがローカルコンピューターで利用可能であれば、他の種類のモジュール(たとえば MS-DOS や OS/2)にすることもできます。 文字列には、実行するモジュールのフルパスとファイル名を指定するか、部分的な名前を指定できます。部分的な名前の場合、関数は現在のドライブと現在のディレクトリを使用して指定を補完します。この関数は検索パスを使用しません。このパラメーターにはファイル名の拡張子を含める必要があります。既定の拡張子は想定されません。 lpApplicationName パラメーターには NULL を指定できます。その場合、モジュール名は lpCommandLine 文字列内の最初の空白区切りのトークンである必要があります。スペースを含む長いファイル名を使用する場合は、引用符付きの文字列を使用してファイル名の終わりと引数の始まりを示してください。そうしないと、ファイル名が曖昧になります。たとえば、文字列 "c:\program files\sub dir\program name" を考えてみます。この文字列はいくつかの方法で解釈できます。システムは次の順序で解釈を試みます。 c:\program.exe c:\program files\sub.exe c:\program files\sub dir\program.exe c:\program files\sub dir\program name.exe 実行可能モジュールが 16 ビットアプリケーションの場合、lpApplicationName は NULL にし、lpCommandLine が指す文字列で実行可能モジュールとその引数を指定する必要があります。既定では、 CreateProcessAsUser によって作成されるすべての 16 ビット Windows ベースのアプリケーションは、個別の VDM で実行されます( CreateProcess の CREATE_SEPARATE_WOW_VDM に相当)。 |
| lpCommandLine | LPSTR | inoutoptional | 実行するコマンドライン。この文字列の最大長は 32K 文字です。lpApplicationName が NULL の場合、lpCommandLine のモジュール名部分は MAX_PATH 文字に制限されます。 この関数の Unicode バージョン CreateProcessAsUserW は、この文字列の内容を変更することがあります。したがって、このパラメーターは読み取り専用メモリ(const 変数やリテラル文字列など)へのポインターにすることはできません。このパラメーターが定数文字列の場合、関数がアクセス違反を引き起こす可能性があります。 lpCommandLine パラメーターには NULL を指定できます。その場合、関数は lpApplicationName が指す文字列をコマンドラインとして使用します。 lpApplicationName と lpCommandLine の両方が非 NULL の場合、lpApplicationName は実行するモジュールを指定し、lpCommandLine はコマンドラインを指定します。新しいプロセスは GetCommandLine を使用してコマンドライン全体を取得できます。C で記述されたコンソールプロセスは、argc および argv 引数を使用してコマンドラインを解析できます。argv[0] はモジュール名であるため、C プログラマーは通常、モジュール名をコマンドラインの最初のトークンとして繰り返します。 lpApplicationName が NULL の場合、コマンドラインの最初の空白区切りのトークンがモジュール名を指定します。スペースを含む長いファイル名を使用する場合は、引用符付きの文字列を使用してファイル名の終わりと引数の始まりを示してください(lpApplicationName パラメーターの説明を参照)。ファイル名に拡張子が含まれていない場合は、.exe が付加されます。したがって、ファイル名の拡張子が .com の場合、このパラメーターには .com 拡張子を含める必要があります。ファイル名がピリオド(.)で終わり拡張子がない場合、またはファイル名にパスが含まれている場合は、.exe は付加されません。ファイル名にディレクトリパスが含まれていない場合、システムは次の順序で実行可能ファイルを検索します。
|
| lpProcessAttributes | SECURITY_ATTRIBUTES* | inoptional | 新しいプロセスオブジェクトのセキュリティ記述子を指定し、返されるプロセスへのハンドルを子プロセスが継承できるかどうかを決定する SECURITY_ATTRIBUTES 構造体へのポインター。lpProcessAttributes が NULL または lpSecurityDescriptor が NULL の場合、プロセスには既定のセキュリティ記述子が割り当てられ、ハンドルは継承できません。既定のセキュリティ記述子は、hToken パラメーターで参照されるユーザーのものです。このセキュリティ記述子は呼び出し元にアクセスを許可しない場合があり、その場合、プロセスは実行後に再び開くことができません。プロセスハンドルは有効であり、引き続き完全なアクセス権を持ちます。 |
| lpThreadAttributes | SECURITY_ATTRIBUTES* | inoptional | 新しいスレッドのセキュリティ記述子を指定し、返されるハンドルを子プロセスが継承できるかどうかを決定する SECURITY_ATTRIBUTES 構造体へのポインター。lpThreadAttributes が NULL または lpSecurityDescriptor が NULL の場合、スレッドには既定のセキュリティ記述子が割り当てられ、ハンドルは継承できません。既定のセキュリティ記述子は、hToken パラメーターで参照されるユーザーのものです。このセキュリティ記述子は呼び出し元にアクセスを許可しない場合があります。 |
| bInheritHandles | BOOL | in | このパラメーターが TRUE の場合、呼び出し元プロセス内の継承可能な各ハンドルは新しいプロセスに継承されます。パラメーターが FALSE の場合、ハンドルは継承されません。継承されたハンドルは、元のハンドルと同じ値とアクセス権を持つことに注意してください。 継承可能なハンドルに関する追加の説明については、「解説」を参照してください。 ターミナルサービス: セッションをまたいでハンドルを継承することはできません。さらに、このパラメーターが TRUE の場合、呼び出し元と同じセッションでプロセスを作成する必要があります。 Protected Process Light (PPL) プロセス: PPL プロセスが非 PPL プロセスを作成する場合、非 PPL プロセスから PPL プロセスへの PROCESS_DUP_HANDLE は許可されないため、汎用ハンドルの継承はブロックされます。Process Security and Access Rights を参照してください。 |
| dwCreationFlags | PROCESS_CREATION_FLAGS | in | 優先順位クラスとプロセスの作成を制御するフラグ。値の一覧については、 Process Creation Flags を参照してください。 このパラメーターは、プロセスの優先順位クラスも制御します。これは、プロセスのスレッドのスケジューリング優先順位を決定するために使用されます。値の一覧については、 GetPriorityClass を参照してください。優先順位クラスフラグが何も指定されていない場合、作成元プロセスの優先順位クラスが IDLE_PRIORITY_CLASS または BELOW_NORMAL_PRIORITY_CLASS でない限り、優先順位クラスは既定で NORMAL_PRIORITY_CLASS になります。その場合、子プロセスは呼び出し元プロセスの既定の優先順位クラスを受け取ります。 dwCreationFlags パラメーターの値が 0 の場合:
|
| lpEnvironment | void* | inoptional | 新しいプロセスの 環境ブロック へのポインター。このパラメーターが NULL の場合、新しいプロセスは呼び出し元プロセスの環境を使用します。 環境ブロックは、null で終わる文字列の null 終端ブロックで構成されます。各文字列は次の形式です。 name=value\0 等号は区切り文字として使用されるため、環境変数の名前に使用してはなりません。 環境ブロックには、Unicode 文字または ANSI 文字のいずれかを含めることができます。lpEnvironment が指す環境ブロックに Unicode 文字が含まれている場合は、dwCreationFlags に CREATE_UNICODE_ENVIRONMENT が含まれていることを確認してください。 この関数の ANSI バージョン CreateProcessAsUserA は、プロセスの環境ブロックの合計サイズが 32,767 文字を超えると失敗します。 ANSI 環境ブロックは 2 つのゼロバイトで終端されることに注意してください。1 つは最後の文字列用、もう 1 つはブロックを終端するためのものです。Unicode 環境ブロックは 4 つのゼロバイトで終端されます。2 つは最後の文字列用、もう 2 つはブロックを終端するためのものです。 Windows Server 2003 および Windows XP: ユーザー環境変数とシステム環境変数を合わせたサイズが 8192 バイトを超える場合、CreateProcessAsUser によって作成されたプロセスは、親プロセスから関数に渡された環境ブロックでは実行されなくなります。代わりに、子プロセスは CreateEnvironmentBlock 関数によって返された環境ブロックで実行されます。 指定したユーザーの環境ブロックのコピーを取得するには、 CreateEnvironmentBlock 関数を使用します。 |
| lpCurrentDirectory | LPCSTR | inoptional | プロセスの現在のディレクトリへのフルパス。この文字列には UNC パスを指定することもできます。 このパラメーターが NULL の場合、新しいプロセスは呼び出し元プロセスと同じ現在のドライブおよびディレクトリを持ちます。(この機能は、主にアプリケーションを起動して初期のドライブと作業ディレクトリを指定する必要があるシェル向けに提供されています。) |
| lpStartupInfo | STARTUPINFOA* | in | STARTUPINFO または STARTUPINFOEX 構造体へのポインター。 ユーザーは、指定されたウィンドウステーションとデスクトップの両方に対する完全なアクセス権を持っている必要があります。プロセスを対話的にする場合は、winsta0\default を指定します。lpDesktop メンバーが NULL の場合、新しいプロセスは親プロセスのデスクトップとウィンドウステーションを継承します。 このメンバーが空の文字列 "" の場合、新しいプロセスは Process Connection to a Window Station で説明されているルールを使用してウィンドウステーションに接続します。 拡張属性を設定するには、STARTUPINFOEX 構造体を使用し、dwCreationFlags パラメーターに EXTENDED_STARTUPINFO_PRESENT を指定します。 STARTUPINFO または STARTUPINFOEX 内のハンドルは、不要になったら CloseHandle で閉じる必要があります。 重要 呼び出し元は、STARTUPINFO 内の標準ハンドルフィールドに有効なハンドル値が含まれていることを保証する責任があります。これらのフィールドは、dwFlags メンバーが STARTF_USESTDHANDLES を指定している場合でも、検証されずにそのまま子プロセスにコピーされます。不正な値は、子プロセスの誤動作やクラッシュを引き起こす可能性があります。無効なハンドルを検出するには、Application Verifier ランタイム検証ツールを使用してください。
|
| lpProcessInformation | PROCESS_INFORMATION* | out | 新しいプロセスに関する識別情報を受け取る PROCESS_INFORMATION 構造体へのポインター。 PROCESS_INFORMATION 内のハンドルは、不要になったら CloseHandle で閉じる必要があります。 |
戻り値の型: BOOL
公式ドキュメント
新しいプロセスとそのプライマリスレッドを作成します。新しいプロセスは、指定されたトークンが表すユーザーのセキュリティコンテキストで実行されます。(ANSI)
戻り値
関数が成功すると、戻り値は 0 以外になります。
関数が失敗すると、戻り値は 0 になります。拡張エラー情報を取得するには、 GetLastError を呼び出します。
関数は、プロセスの初期化が完了する前に戻ることに注意してください。必要な DLL が見つからない、または初期化に失敗した場合、プロセスは終了します。プロセスの終了ステータスを取得するには、GetExitCodeProcess を呼び出します。
解説(Remarks)
CreateProcessAsUser は、TOKEN_DUPLICATE および TOKEN_IMPERSONATE のアクセス権で呼び出し元プロセスのプライマリトークンを開くことができる必要があります。
既定では、 CreateProcessAsUser は、表示されずユーザー入力を受け取れないデスクトップを持つ非対話的なウィンドウステーション上に新しいプロセスを作成します。新しいプロセスとのユーザー対話を有効にするには、 STARTUPINFO 構造体の lpDesktop メンバーに、既定の対話的なウィンドウステーションとデスクトップの名前 "winsta0\default" を指定する必要があります。さらに、 CreateProcessAsUser を呼び出す前に、既定の対話的なウィンドウステーションと既定のデスクトップの両方の随意アクセス制御リスト (DACL) を変更する必要があります。ウィンドウステーションとデスクトップの DACL は、hToken パラメーターが表すユーザーまたはログオンセッションにアクセスを許可する必要があります。
CreateProcessAsUser は、指定したユーザーのプロファイルを HKEY_USERS レジストリキーに読み込みません。したがって、HKEY_CURRENT_USER レジストリキー内の情報にアクセスするには、 CreateProcessAsUser を呼び出す前に、 LoadUserProfile 関数を使用してユーザーのプロファイル情報を HKEY_USERS に読み込む必要があります。新しいプロセスが終了した後は、必ず UnloadUserProfile を呼び出してください。
lpEnvironment パラメーターが NULL の場合、新しいプロセスは呼び出し元プロセスの環境を継承します。 CreateProcessAsUser は、hToken が表すユーザーに固有の環境変数を含めるように環境ブロックを自動的に変更することはありません。たとえば、lpEnvironment が NULL の場合、USERNAME および USERDOMAIN 変数は呼び出し元プロセスから継承されます。新しいプロセスの環境ブロックを準備し、それを lpEnvironment に指定するのは呼び出し元の責任です。
CreateProcessWithLogonW および CreateProcessWithTokenW 関数は CreateProcessAsUser に似ていますが、呼び出し元がユーザーを認証してトークンを取得するために LogonUser 関数を呼び出す必要がない点が異なります。
CreateProcessAsUser を使用すると、呼び出し元または対象ユーザーのセキュリティコンテキストで、指定したディレクトリと実行可能イメージにアクセスできます。既定では、 CreateProcessAsUser は呼び出し元のセキュリティコンテキストでディレクトリと実行可能イメージにアクセスします。この場合、呼び出し元がディレクトリと実行可能イメージへのアクセス権を持っていないと、関数は失敗します。対象ユーザーのセキュリティコンテキストを使用してディレクトリと実行可能イメージにアクセスするには、 CreateProcessAsUser を呼び出す前に、 ImpersonateLoggedOnUser 関数の呼び出しで hToken を指定します。
プロセスにはプロセス識別子が割り当てられます。この識別子はプロセスが終了するまで有効です。これを使用してプロセスを識別したり、 OpenProcess 関数でプロセスへのハンドルを開くために指定したりできます。プロセス内の最初のスレッドにもスレッド識別子が割り当てられます。これを OpenThread 関数で指定して、スレッドへのハンドルを開くことができます。この識別子はスレッドが終了するまで有効であり、システム内でスレッドを一意に識別するために使用できます。これらの識別子は PROCESS_INFORMATION 構造体で返されます。
呼び出し元スレッドは、 WaitForInputIdle 関数を使用して、新しいプロセスが初期化を完了し、保留中の入力がない状態でユーザー入力を待機するまで待つことができます。 CreateProcessAsUser は新しいプロセスの初期化完了を待たずに戻るため、これは親プロセスと子プロセス間の同期に役立ちます。たとえば、作成元プロセスは、新しいプロセスに関連付けられたウィンドウを見つけようとする前に WaitForInputIdle を使用します。
プロセスをシャットダウンする推奨される方法は、 ExitProcess 関数を使用することです。この関数は、プロセスにアタッチされているすべての DLL に終了が近づいていることの通知を送信するためです。他のプロセスシャットダウン手段では、アタッチされた DLL に通知されません。スレッドが ExitProcess を呼び出すと、プロセスの他のスレッドは、追加のコード(アタッチされた DLL のスレッド終了コードを含む)を実行する機会なく終了することに注意してください。詳細については、 Terminating a Process を参照してください。
既定では、bInheritHandles パラメーターの値として TRUE を渡すと、すべての継承可能なハンドルが新しいプロセスに継承されます。 これは、複数のスレッドから同時にプロセスを作成しつつ、各プロセスに異なるハンドルを継承させたいアプリケーションにとっては問題になることがあります。 アプリケーションは、 UpdateProcThreadAttributeList 関数を PROC_THREAD_ATTRIBUTE_HANDLE_LIST パラメーターとともに使用して、特定のプロセスに継承させるハンドルのリストを指定できます。
セキュリティに関する解説
lpApplicationName パラメーターには NULL を指定できますが、その場合、実行可能ファイル名は lpCommandLine 内の最初の空白区切りの文字列である必要があります。実行可能ファイル名またはパス名にスペースが含まれている場合、関数がスペースを解析する方法のために、別の実行可能ファイルが実行されるリスクがあります。次の例は危険です。"MyApp.exe" の代わりに "Program.exe" が存在すれば、関数はそれを実行しようとするためです。 LPTSTR szCmdline[] = _tcsdup(TEXT("C:\\Program Files\\MyApp"));
CreateProcessAsUser(hToken, NULL, szCmdline, /*...*/ );
悪意のあるユーザーがシステム上に "Program.exe" という名前のアプリケーションを作成した場合、Program Files ディレクトリを使用して CreateProcessAsUser を誤って呼び出すプログラムは、意図したアプリケーションの代わりにこのアプリケーションを実行します。
この問題を回避するには、lpApplicationName に NULL を渡さないでください。lpApplicationName に NULL を渡す場合は、以下の例に示すように、lpCommandLine 内の実行可能ファイルのパスを引用符で囲んでください。
LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\""));
CreateProcessAsUser(hToken, NULL, szCmdline, /*...*/);
PowerShell: CreateProcessAsUser 関数を使用して PowerShell バージョン 2.0 のコマンドレットを実装する場合、コマンドレットはファンインおよびファンアウトのリモートセッションの両方で正しく動作します。ただし、特定のセキュリティシナリオのため、CreateProcessAsUser で実装されたコマンドレットは、PowerShell バージョン 3.0 ではファンインのリモートセッションでのみ正しく動作します。ファンアウトのリモートセッションは、クライアントのセキュリティ特権が不十分なため失敗します。PowerShell バージョン 3.0 でファンインとファンアウトの両方のリモートセッションで動作するコマンドレットを実装するには、CreateProcess 関数を使用します。
例
例については、 Starting an Interactive Client Process を参照してください。
processthreadsapi.h ヘッダーは、CreateProcessAsUser を、UNICODE プリプロセッサ定数の定義に基づいてこの関数の ANSI バージョンまたは Unicode バージョンを自動的に選択するエイリアスとして定義します。エンコーディング中立のエイリアスの使用を、エンコーディング中立でないコードと混在させると、コンパイルエラーまたはランタイムエラーを引き起こす不一致につながる可能性があります。詳細については、Conventions for Function Prototypes を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// ADVAPI32.dll (ANSI / -A)
#include <windows.h>
BOOL CreateProcessAsUserA(
HANDLE hToken, // optional
LPCSTR lpApplicationName, // optional
LPSTR lpCommandLine, // optional
SECURITY_ATTRIBUTES* lpProcessAttributes, // optional
SECURITY_ATTRIBUTES* lpThreadAttributes, // optional
BOOL bInheritHandles,
PROCESS_CREATION_FLAGS dwCreationFlags,
void* lpEnvironment, // optional
LPCSTR lpCurrentDirectory, // optional
STARTUPINFOA* lpStartupInfo,
PROCESS_INFORMATION* lpProcessInformation
);[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("ADVAPI32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern bool CreateProcessAsUserA(
IntPtr hToken, // HANDLE optional
[MarshalAs(UnmanagedType.LPStr)] string lpApplicationName, // LPCSTR optional
[MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpCommandLine, // LPSTR optional, in/out
IntPtr lpProcessAttributes, // SECURITY_ATTRIBUTES* optional
IntPtr lpThreadAttributes, // SECURITY_ATTRIBUTES* optional
bool bInheritHandles, // BOOL
uint dwCreationFlags, // PROCESS_CREATION_FLAGS
IntPtr lpEnvironment, // void* optional
[MarshalAs(UnmanagedType.LPStr)] string lpCurrentDirectory, // LPCSTR optional
IntPtr lpStartupInfo, // STARTUPINFOA*
IntPtr lpProcessInformation // PROCESS_INFORMATION* out
);<DllImport("ADVAPI32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function CreateProcessAsUserA(
hToken As IntPtr, ' HANDLE optional
<MarshalAs(UnmanagedType.LPStr)> lpApplicationName As String, ' LPCSTR optional
<MarshalAs(UnmanagedType.LPStr)> lpCommandLine As System.Text.StringBuilder, ' LPSTR optional, in/out
lpProcessAttributes As IntPtr, ' SECURITY_ATTRIBUTES* optional
lpThreadAttributes As IntPtr, ' SECURITY_ATTRIBUTES* optional
bInheritHandles As Boolean, ' BOOL
dwCreationFlags As UInteger, ' PROCESS_CREATION_FLAGS
lpEnvironment As IntPtr, ' void* optional
<MarshalAs(UnmanagedType.LPStr)> lpCurrentDirectory As String, ' LPCSTR optional
lpStartupInfo As IntPtr, ' STARTUPINFOA*
lpProcessInformation As IntPtr ' PROCESS_INFORMATION* out
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function' hToken : HANDLE optional
' lpApplicationName : LPCSTR optional
' lpCommandLine : LPSTR optional, in/out
' lpProcessAttributes : SECURITY_ATTRIBUTES* optional
' lpThreadAttributes : SECURITY_ATTRIBUTES* optional
' bInheritHandles : BOOL
' dwCreationFlags : PROCESS_CREATION_FLAGS
' lpEnvironment : void* optional
' lpCurrentDirectory : LPCSTR optional
' lpStartupInfo : STARTUPINFOA*
' lpProcessInformation : PROCESS_INFORMATION* out
Declare PtrSafe Function CreateProcessAsUserA Lib "advapi32" ( _
ByVal hToken As LongPtr, _
ByVal lpApplicationName As String, _
ByVal lpCommandLine As String, _
ByVal lpProcessAttributes As LongPtr, _
ByVal lpThreadAttributes As LongPtr, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As LongPtr, _
ByVal lpCurrentDirectory As String, _
ByVal lpStartupInfo As LongPtr, _
ByVal lpProcessInformation As LongPtr) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
CreateProcessAsUserA = ctypes.windll.advapi32.CreateProcessAsUserA
CreateProcessAsUserA.restype = wintypes.BOOL
CreateProcessAsUserA.argtypes = [
wintypes.HANDLE, # hToken : HANDLE optional
wintypes.LPCSTR, # lpApplicationName : LPCSTR optional
wintypes.LPSTR, # lpCommandLine : LPSTR optional, in/out
ctypes.c_void_p, # lpProcessAttributes : SECURITY_ATTRIBUTES* optional
ctypes.c_void_p, # lpThreadAttributes : SECURITY_ATTRIBUTES* optional
wintypes.BOOL, # bInheritHandles : BOOL
wintypes.DWORD, # dwCreationFlags : PROCESS_CREATION_FLAGS
ctypes.POINTER(None), # lpEnvironment : void* optional
wintypes.LPCSTR, # lpCurrentDirectory : LPCSTR optional
ctypes.c_void_p, # lpStartupInfo : STARTUPINFOA*
ctypes.c_void_p, # lpProcessInformation : PROCESS_INFORMATION* out
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('ADVAPI32.dll')
CreateProcessAsUserA = Fiddle::Function.new(
lib['CreateProcessAsUserA'],
[
Fiddle::TYPE_VOIDP, # hToken : HANDLE optional
Fiddle::TYPE_VOIDP, # lpApplicationName : LPCSTR optional
Fiddle::TYPE_VOIDP, # lpCommandLine : LPSTR optional, in/out
Fiddle::TYPE_VOIDP, # lpProcessAttributes : SECURITY_ATTRIBUTES* optional
Fiddle::TYPE_VOIDP, # lpThreadAttributes : SECURITY_ATTRIBUTES* optional
Fiddle::TYPE_INT, # bInheritHandles : BOOL
-Fiddle::TYPE_INT, # dwCreationFlags : PROCESS_CREATION_FLAGS
Fiddle::TYPE_VOIDP, # lpEnvironment : void* optional
Fiddle::TYPE_VOIDP, # lpCurrentDirectory : LPCSTR optional
Fiddle::TYPE_VOIDP, # lpStartupInfo : STARTUPINFOA*
Fiddle::TYPE_VOIDP, # lpProcessInformation : PROCESS_INFORMATION* out
],
Fiddle::TYPE_INT)#[link(name = "advapi32")]
extern "system" {
fn CreateProcessAsUserA(
hToken: *mut core::ffi::c_void, // HANDLE optional
lpApplicationName: *const u8, // LPCSTR optional
lpCommandLine: *mut u8, // LPSTR optional, in/out
lpProcessAttributes: *mut SECURITY_ATTRIBUTES, // SECURITY_ATTRIBUTES* optional
lpThreadAttributes: *mut SECURITY_ATTRIBUTES, // SECURITY_ATTRIBUTES* optional
bInheritHandles: i32, // BOOL
dwCreationFlags: u32, // PROCESS_CREATION_FLAGS
lpEnvironment: *mut (), // void* optional
lpCurrentDirectory: *const u8, // LPCSTR optional
lpStartupInfo: *mut STARTUPINFOA, // STARTUPINFOA*
lpProcessInformation: *mut PROCESS_INFORMATION // PROCESS_INFORMATION* out
) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("ADVAPI32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool CreateProcessAsUserA(IntPtr hToken, [MarshalAs(UnmanagedType.LPStr)] string lpApplicationName, [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, [MarshalAs(UnmanagedType.LPStr)] string lpCurrentDirectory, IntPtr lpStartupInfo, IntPtr lpProcessInformation);
"@
$api = Add-Type -MemberDefinition $sig -Name 'ADVAPI32_CreateProcessAsUserA' -Namespace Win32 -PassThru
# $api::CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)#uselib "ADVAPI32.dll"
#func global CreateProcessAsUserA "CreateProcessAsUserA" sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr, sptr
; CreateProcessAsUserA hToken, lpApplicationName, varptr(lpCommandLine), varptr(lpProcessAttributes), varptr(lpThreadAttributes), bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, varptr(lpStartupInfo), varptr(lpProcessInformation) ; 戻り値は stat
; hToken : HANDLE optional -> "sptr"
; lpApplicationName : LPCSTR optional -> "sptr"
; lpCommandLine : LPSTR optional, in/out -> "sptr"
; lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "sptr"
; lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "sptr"
; bInheritHandles : BOOL -> "sptr"
; dwCreationFlags : PROCESS_CREATION_FLAGS -> "sptr"
; lpEnvironment : void* optional -> "sptr"
; lpCurrentDirectory : LPCSTR optional -> "sptr"
; lpStartupInfo : STARTUPINFOA* -> "sptr"
; lpProcessInformation : PROCESS_INFORMATION* out -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "ADVAPI32.dll" #cfunc global CreateProcessAsUserA "CreateProcessAsUserA" sptr, str, var, var, var, int, int, sptr, str, var, var ; res = CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) ; hToken : HANDLE optional -> "sptr" ; lpApplicationName : LPCSTR optional -> "str" ; lpCommandLine : LPSTR optional, in/out -> "var" ; lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "var" ; lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "var" ; bInheritHandles : BOOL -> "int" ; dwCreationFlags : PROCESS_CREATION_FLAGS -> "int" ; lpEnvironment : void* optional -> "sptr" ; lpCurrentDirectory : LPCSTR optional -> "str" ; lpStartupInfo : STARTUPINFOA* -> "var" ; lpProcessInformation : PROCESS_INFORMATION* out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "ADVAPI32.dll" #cfunc global CreateProcessAsUserA "CreateProcessAsUserA" sptr, str, sptr, sptr, sptr, int, int, sptr, str, sptr, sptr ; res = CreateProcessAsUserA(hToken, lpApplicationName, varptr(lpCommandLine), varptr(lpProcessAttributes), varptr(lpThreadAttributes), bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, varptr(lpStartupInfo), varptr(lpProcessInformation)) ; hToken : HANDLE optional -> "sptr" ; lpApplicationName : LPCSTR optional -> "str" ; lpCommandLine : LPSTR optional, in/out -> "sptr" ; lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "sptr" ; lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "sptr" ; bInheritHandles : BOOL -> "int" ; dwCreationFlags : PROCESS_CREATION_FLAGS -> "int" ; lpEnvironment : void* optional -> "sptr" ; lpCurrentDirectory : LPCSTR optional -> "str" ; lpStartupInfo : STARTUPINFOA* -> "sptr" ; lpProcessInformation : PROCESS_INFORMATION* out -> "sptr" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; BOOL CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, SECURITY_ATTRIBUTES* lpProcessAttributes, SECURITY_ATTRIBUTES* lpThreadAttributes, BOOL bInheritHandles, PROCESS_CREATION_FLAGS dwCreationFlags, void* lpEnvironment, LPCSTR lpCurrentDirectory, STARTUPINFOA* lpStartupInfo, PROCESS_INFORMATION* lpProcessInformation) #uselib "ADVAPI32.dll" #cfunc global CreateProcessAsUserA "CreateProcessAsUserA" intptr, str, var, var, var, int, int, intptr, str, var, var ; res = CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) ; hToken : HANDLE optional -> "intptr" ; lpApplicationName : LPCSTR optional -> "str" ; lpCommandLine : LPSTR optional, in/out -> "var" ; lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "var" ; lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "var" ; bInheritHandles : BOOL -> "int" ; dwCreationFlags : PROCESS_CREATION_FLAGS -> "int" ; lpEnvironment : void* optional -> "intptr" ; lpCurrentDirectory : LPCSTR optional -> "str" ; lpStartupInfo : STARTUPINFOA* -> "var" ; lpProcessInformation : PROCESS_INFORMATION* out -> "var" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; BOOL CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, SECURITY_ATTRIBUTES* lpProcessAttributes, SECURITY_ATTRIBUTES* lpThreadAttributes, BOOL bInheritHandles, PROCESS_CREATION_FLAGS dwCreationFlags, void* lpEnvironment, LPCSTR lpCurrentDirectory, STARTUPINFOA* lpStartupInfo, PROCESS_INFORMATION* lpProcessInformation) #uselib "ADVAPI32.dll" #cfunc global CreateProcessAsUserA "CreateProcessAsUserA" intptr, str, intptr, intptr, intptr, int, int, intptr, str, intptr, intptr ; res = CreateProcessAsUserA(hToken, lpApplicationName, varptr(lpCommandLine), varptr(lpProcessAttributes), varptr(lpThreadAttributes), bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, varptr(lpStartupInfo), varptr(lpProcessInformation)) ; hToken : HANDLE optional -> "intptr" ; lpApplicationName : LPCSTR optional -> "str" ; lpCommandLine : LPSTR optional, in/out -> "intptr" ; lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "intptr" ; lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "intptr" ; bInheritHandles : BOOL -> "int" ; dwCreationFlags : PROCESS_CREATION_FLAGS -> "int" ; lpEnvironment : void* optional -> "intptr" ; lpCurrentDirectory : LPCSTR optional -> "str" ; lpStartupInfo : STARTUPINFOA* -> "intptr" ; lpProcessInformation : PROCESS_INFORMATION* out -> "intptr" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
advapi32 = windows.NewLazySystemDLL("ADVAPI32.dll")
procCreateProcessAsUserA = advapi32.NewProc("CreateProcessAsUserA")
)
// hToken (HANDLE optional), lpApplicationName (LPCSTR optional), lpCommandLine (LPSTR optional, in/out), lpProcessAttributes (SECURITY_ATTRIBUTES* optional), lpThreadAttributes (SECURITY_ATTRIBUTES* optional), bInheritHandles (BOOL), dwCreationFlags (PROCESS_CREATION_FLAGS), lpEnvironment (void* optional), lpCurrentDirectory (LPCSTR optional), lpStartupInfo (STARTUPINFOA*), lpProcessInformation (PROCESS_INFORMATION* out)
r1, _, err := procCreateProcessAsUserA.Call(
uintptr(hToken),
uintptr(unsafe.Pointer(windows.BytePtrFromString(lpApplicationName))),
uintptr(lpCommandLine),
uintptr(lpProcessAttributes),
uintptr(lpThreadAttributes),
uintptr(bInheritHandles),
uintptr(dwCreationFlags),
uintptr(lpEnvironment),
uintptr(unsafe.Pointer(windows.BytePtrFromString(lpCurrentDirectory))),
uintptr(lpStartupInfo),
uintptr(lpProcessInformation),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // BOOLfunction CreateProcessAsUserA(
hToken: THandle; // HANDLE optional
lpApplicationName: PAnsiChar; // LPCSTR optional
lpCommandLine: PAnsiChar; // LPSTR optional, in/out
lpProcessAttributes: Pointer; // SECURITY_ATTRIBUTES* optional
lpThreadAttributes: Pointer; // SECURITY_ATTRIBUTES* optional
bInheritHandles: BOOL; // BOOL
dwCreationFlags: DWORD; // PROCESS_CREATION_FLAGS
lpEnvironment: Pointer; // void* optional
lpCurrentDirectory: PAnsiChar; // LPCSTR optional
lpStartupInfo: Pointer; // STARTUPINFOA*
lpProcessInformation: Pointer // PROCESS_INFORMATION* out
): BOOL; stdcall;
external 'ADVAPI32.dll' name 'CreateProcessAsUserA';result := DllCall("ADVAPI32\CreateProcessAsUserA"
, "Ptr", hToken ; HANDLE optional
, "AStr", lpApplicationName ; LPCSTR optional
, "Ptr", lpCommandLine ; LPSTR optional, in/out
, "Ptr", lpProcessAttributes ; SECURITY_ATTRIBUTES* optional
, "Ptr", lpThreadAttributes ; SECURITY_ATTRIBUTES* optional
, "Int", bInheritHandles ; BOOL
, "UInt", dwCreationFlags ; PROCESS_CREATION_FLAGS
, "Ptr", lpEnvironment ; void* optional
, "AStr", lpCurrentDirectory ; LPCSTR optional
, "Ptr", lpStartupInfo ; STARTUPINFOA*
, "Ptr", lpProcessInformation ; PROCESS_INFORMATION* out
, "Int") ; return: BOOL●CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation) = DLL("ADVAPI32.dll", "bool CreateProcessAsUserA(void*, char*, char*, void*, void*, bool, dword, void*, char*, void*, void*)")
# 呼び出し: CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
# hToken : HANDLE optional -> "void*"
# lpApplicationName : LPCSTR optional -> "char*"
# lpCommandLine : LPSTR optional, in/out -> "char*"
# lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "void*"
# lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "void*"
# bInheritHandles : BOOL -> "bool"
# dwCreationFlags : PROCESS_CREATION_FLAGS -> "dword"
# lpEnvironment : void* optional -> "void*"
# lpCurrentDirectory : LPCSTR optional -> "char*"
# lpStartupInfo : STARTUPINFOA* -> "void*"
# lpProcessInformation : PROCESS_INFORMATION* out -> "void*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "advapi32" fn CreateProcessAsUserA(
hToken: ?*anyopaque, // HANDLE optional
lpApplicationName: [*c]const u8, // LPCSTR optional
lpCommandLine: [*c]u8, // LPSTR optional, in/out
lpProcessAttributes: [*c]SECURITY_ATTRIBUTES, // SECURITY_ATTRIBUTES* optional
lpThreadAttributes: [*c]SECURITY_ATTRIBUTES, // SECURITY_ATTRIBUTES* optional
bInheritHandles: i32, // BOOL
dwCreationFlags: u32, // PROCESS_CREATION_FLAGS
lpEnvironment: ?*anyopaque, // void* optional
lpCurrentDirectory: [*c]const u8, // LPCSTR optional
lpStartupInfo: [*c]STARTUPINFOA, // STARTUPINFOA*
lpProcessInformation: [*c]PROCESS_INFORMATION // PROCESS_INFORMATION* out
) callconv(std.os.windows.WINAPI) i32;proc CreateProcessAsUserA(
hToken: pointer, # HANDLE optional
lpApplicationName: cstring, # LPCSTR optional
lpCommandLine: ptr char, # LPSTR optional, in/out
lpProcessAttributes: ptr SECURITY_ATTRIBUTES, # SECURITY_ATTRIBUTES* optional
lpThreadAttributes: ptr SECURITY_ATTRIBUTES, # SECURITY_ATTRIBUTES* optional
bInheritHandles: int32, # BOOL
dwCreationFlags: uint32, # PROCESS_CREATION_FLAGS
lpEnvironment: pointer, # void* optional
lpCurrentDirectory: cstring, # LPCSTR optional
lpStartupInfo: ptr STARTUPINFOA, # STARTUPINFOA*
lpProcessInformation: ptr PROCESS_INFORMATION # PROCESS_INFORMATION* out
): int32 {.importc: "CreateProcessAsUserA", stdcall, dynlib: "ADVAPI32.dll".}pragma(lib, "advapi32");
extern(Windows)
int CreateProcessAsUserA(
void* hToken, // HANDLE optional
const(char)* lpApplicationName, // LPCSTR optional
char* lpCommandLine, // LPSTR optional, in/out
SECURITY_ATTRIBUTES* lpProcessAttributes, // SECURITY_ATTRIBUTES* optional
SECURITY_ATTRIBUTES* lpThreadAttributes, // SECURITY_ATTRIBUTES* optional
int bInheritHandles, // BOOL
uint dwCreationFlags, // PROCESS_CREATION_FLAGS
void* lpEnvironment, // void* optional
const(char)* lpCurrentDirectory, // LPCSTR optional
STARTUPINFOA* lpStartupInfo, // STARTUPINFOA*
PROCESS_INFORMATION* lpProcessInformation // PROCESS_INFORMATION* out
);ccall((:CreateProcessAsUserA, "ADVAPI32.dll"), stdcall, Int32,
(Ptr{Cvoid}, Cstring, Ptr{UInt8}, Ptr{SECURITY_ATTRIBUTES}, Ptr{SECURITY_ATTRIBUTES}, Int32, UInt32, Ptr{Cvoid}, Cstring, Ptr{STARTUPINFOA}, Ptr{PROCESS_INFORMATION}),
hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
# hToken : HANDLE optional -> Ptr{Cvoid}
# lpApplicationName : LPCSTR optional -> Cstring
# lpCommandLine : LPSTR optional, in/out -> Ptr{UInt8}
# lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> Ptr{SECURITY_ATTRIBUTES}
# lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> Ptr{SECURITY_ATTRIBUTES}
# bInheritHandles : BOOL -> Int32
# dwCreationFlags : PROCESS_CREATION_FLAGS -> UInt32
# lpEnvironment : void* optional -> Ptr{Cvoid}
# lpCurrentDirectory : LPCSTR optional -> Cstring
# lpStartupInfo : STARTUPINFOA* -> Ptr{STARTUPINFOA}
# lpProcessInformation : PROCESS_INFORMATION* out -> Ptr{PROCESS_INFORMATION}
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
int32_t CreateProcessAsUserA(
void* hToken,
const char* lpApplicationName,
char* lpCommandLine,
void* lpProcessAttributes,
void* lpThreadAttributes,
int32_t bInheritHandles,
uint32_t dwCreationFlags,
void* lpEnvironment,
const char* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation);
]]
local advapi32 = ffi.load("advapi32")
-- advapi32.CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
-- hToken : HANDLE optional
-- lpApplicationName : LPCSTR optional
-- lpCommandLine : LPSTR optional, in/out
-- lpProcessAttributes : SECURITY_ATTRIBUTES* optional
-- lpThreadAttributes : SECURITY_ATTRIBUTES* optional
-- bInheritHandles : BOOL
-- dwCreationFlags : PROCESS_CREATION_FLAGS
-- lpEnvironment : void* optional
-- lpCurrentDirectory : LPCSTR optional
-- lpStartupInfo : STARTUPINFOA*
-- lpProcessInformation : PROCESS_INFORMATION* out
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('ADVAPI32.dll');
const CreateProcessAsUserA = lib.func('__stdcall', 'CreateProcessAsUserA', 'int32_t', ['void *', 'str', 'char *', 'void *', 'void *', 'int32_t', 'uint32_t', 'void *', 'str', 'void *', 'void *']);
// CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
// hToken : HANDLE optional -> 'void *'
// lpApplicationName : LPCSTR optional -> 'str'
// lpCommandLine : LPSTR optional, in/out -> 'char *'
// lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> 'void *'
// lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> 'void *'
// bInheritHandles : BOOL -> 'int32_t'
// dwCreationFlags : PROCESS_CREATION_FLAGS -> 'uint32_t'
// lpEnvironment : void* optional -> 'void *'
// lpCurrentDirectory : LPCSTR optional -> 'str'
// lpStartupInfo : STARTUPINFOA* -> 'void *'
// lpProcessInformation : PROCESS_INFORMATION* out -> 'void *'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("ADVAPI32.dll", {
CreateProcessAsUserA: { parameters: ["pointer", "buffer", "buffer", "pointer", "pointer", "i32", "u32", "pointer", "buffer", "pointer", "pointer"], result: "i32" },
});
// lib.symbols.CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation)
// hToken : HANDLE optional -> "pointer"
// lpApplicationName : LPCSTR optional -> "buffer"
// lpCommandLine : LPSTR optional, in/out -> "buffer"
// lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> "pointer"
// lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> "pointer"
// bInheritHandles : BOOL -> "i32"
// dwCreationFlags : PROCESS_CREATION_FLAGS -> "u32"
// lpEnvironment : void* optional -> "pointer"
// lpCurrentDirectory : LPCSTR optional -> "buffer"
// lpStartupInfo : STARTUPINFOA* -> "pointer"
// lpProcessInformation : PROCESS_INFORMATION* out -> "pointer"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
int32_t CreateProcessAsUserA(
void* hToken,
const char* lpApplicationName,
char* lpCommandLine,
void* lpProcessAttributes,
void* lpThreadAttributes,
int32_t bInheritHandles,
uint32_t dwCreationFlags,
void* lpEnvironment,
const char* lpCurrentDirectory,
void* lpStartupInfo,
void* lpProcessInformation);
C, "ADVAPI32.dll");
// $ffi->CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
// hToken : HANDLE optional
// lpApplicationName : LPCSTR optional
// lpCommandLine : LPSTR optional, in/out
// lpProcessAttributes : SECURITY_ATTRIBUTES* optional
// lpThreadAttributes : SECURITY_ATTRIBUTES* optional
// bInheritHandles : BOOL
// dwCreationFlags : PROCESS_CREATION_FLAGS
// lpEnvironment : void* optional
// lpCurrentDirectory : LPCSTR optional
// lpStartupInfo : STARTUPINFOA*
// lpProcessInformation : PROCESS_INFORMATION* out
// 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
// WINAPI(stdcall): x64 では呼出規約が統一されるため問題なし。x86 では __stdcall 対応のラッパが必要な場合あり。import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public interface Advapi32 extends StdCallLibrary {
Advapi32 INSTANCE = Native.load("advapi32", Advapi32.class, W32APIOptions.ASCII_OPTIONS);
boolean CreateProcessAsUserA(
Pointer hToken, // HANDLE optional
String lpApplicationName, // LPCSTR optional
byte[] lpCommandLine, // LPSTR optional, in/out
Pointer lpProcessAttributes, // SECURITY_ATTRIBUTES* optional
Pointer lpThreadAttributes, // SECURITY_ATTRIBUTES* optional
boolean bInheritHandles, // BOOL
int dwCreationFlags, // PROCESS_CREATION_FLAGS
Pointer lpEnvironment, // void* optional
String lpCurrentDirectory, // LPCSTR optional
Pointer lpStartupInfo, // STARTUPINFOA*
Pointer lpProcessInformation // PROCESS_INFORMATION* out
);
}@[Link("advapi32")]
lib LibADVAPI32
fun CreateProcessAsUserA = CreateProcessAsUserA(
hToken : Void*, # HANDLE optional
lpApplicationName : UInt8*, # LPCSTR optional
lpCommandLine : UInt8*, # LPSTR optional, in/out
lpProcessAttributes : SECURITY_ATTRIBUTES*, # SECURITY_ATTRIBUTES* optional
lpThreadAttributes : SECURITY_ATTRIBUTES*, # SECURITY_ATTRIBUTES* optional
bInheritHandles : Int32, # BOOL
dwCreationFlags : UInt32, # PROCESS_CREATION_FLAGS
lpEnvironment : Void*, # void* optional
lpCurrentDirectory : UInt8*, # LPCSTR optional
lpStartupInfo : STARTUPINFOA*, # STARTUPINFOA*
lpProcessInformation : PROCESS_INFORMATION* # PROCESS_INFORMATION* out
) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef CreateProcessAsUserANative = Int32 Function(Pointer<Void>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Void>, Pointer<Void>, Int32, Uint32, Pointer<Void>, Pointer<Utf8>, Pointer<Void>, Pointer<Void>);
typedef CreateProcessAsUserADart = int Function(Pointer<Void>, Pointer<Utf8>, Pointer<Utf8>, Pointer<Void>, Pointer<Void>, int, int, Pointer<Void>, Pointer<Utf8>, Pointer<Void>, Pointer<Void>);
final CreateProcessAsUserA = DynamicLibrary.open('ADVAPI32.dll')
.lookupFunction<CreateProcessAsUserANative, CreateProcessAsUserADart>('CreateProcessAsUserA');
// hToken : HANDLE optional -> Pointer<Void>
// lpApplicationName : LPCSTR optional -> Pointer<Utf8>
// lpCommandLine : LPSTR optional, in/out -> Pointer<Utf8>
// lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> Pointer<Void>
// lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> Pointer<Void>
// bInheritHandles : BOOL -> Int32
// dwCreationFlags : PROCESS_CREATION_FLAGS -> Uint32
// lpEnvironment : void* optional -> Pointer<Void>
// lpCurrentDirectory : LPCSTR optional -> Pointer<Utf8>
// lpStartupInfo : STARTUPINFOA* -> Pointer<Void>
// lpProcessInformation : PROCESS_INFORMATION* out -> Pointer<Void>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function CreateProcessAsUserA(
hToken: THandle; // HANDLE optional
lpApplicationName: PAnsiChar; // LPCSTR optional
lpCommandLine: PAnsiChar; // LPSTR optional, in/out
lpProcessAttributes: Pointer; // SECURITY_ATTRIBUTES* optional
lpThreadAttributes: Pointer; // SECURITY_ATTRIBUTES* optional
bInheritHandles: BOOL; // BOOL
dwCreationFlags: DWORD; // PROCESS_CREATION_FLAGS
lpEnvironment: Pointer; // void* optional
lpCurrentDirectory: PAnsiChar; // LPCSTR optional
lpStartupInfo: Pointer; // STARTUPINFOA*
lpProcessInformation: Pointer // PROCESS_INFORMATION* out
): BOOL; stdcall;
external 'ADVAPI32.dll' name 'CreateProcessAsUserA';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "CreateProcessAsUserA"
c_CreateProcessAsUserA :: Ptr () -> CString -> CString -> Ptr () -> Ptr () -> CInt -> Word32 -> Ptr () -> CString -> Ptr () -> Ptr () -> IO CInt
-- hToken : HANDLE optional -> Ptr ()
-- lpApplicationName : LPCSTR optional -> CString
-- lpCommandLine : LPSTR optional, in/out -> CString
-- lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> Ptr ()
-- lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> Ptr ()
-- bInheritHandles : BOOL -> CInt
-- dwCreationFlags : PROCESS_CREATION_FLAGS -> Word32
-- lpEnvironment : void* optional -> Ptr ()
-- lpCurrentDirectory : LPCSTR optional -> CString
-- lpStartupInfo : STARTUPINFOA* -> Ptr ()
-- lpProcessInformation : PROCESS_INFORMATION* out -> Ptr ()
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let createprocessasusera =
foreign "CreateProcessAsUserA"
((ptr void) @-> string @-> string @-> (ptr void) @-> (ptr void) @-> int32_t @-> uint32_t @-> (ptr void) @-> string @-> (ptr void) @-> (ptr void) @-> returning int32_t)
(* hToken : HANDLE optional -> (ptr void) *)
(* lpApplicationName : LPCSTR optional -> string *)
(* lpCommandLine : LPSTR optional, in/out -> string *)
(* lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> (ptr void) *)
(* lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> (ptr void) *)
(* bInheritHandles : BOOL -> int32_t *)
(* dwCreationFlags : PROCESS_CREATION_FLAGS -> uint32_t *)
(* lpEnvironment : void* optional -> (ptr void) *)
(* lpCurrentDirectory : LPCSTR optional -> string *)
(* lpStartupInfo : STARTUPINFOA* -> (ptr void) *)
(* lpProcessInformation : PROCESS_INFORMATION* out -> (ptr void) *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library advapi32 (t "ADVAPI32.dll"))
(cffi:use-foreign-library advapi32)
(cffi:defcfun ("CreateProcessAsUserA" create-process-as-user-a :convention :stdcall) :int32
(h-token :pointer) ; HANDLE optional
(lp-application-name :string) ; LPCSTR optional
(lp-command-line :pointer) ; LPSTR optional, in/out
(lp-process-attributes :pointer) ; SECURITY_ATTRIBUTES* optional
(lp-thread-attributes :pointer) ; SECURITY_ATTRIBUTES* optional
(b-inherit-handles :int32) ; BOOL
(dw-creation-flags :uint32) ; PROCESS_CREATION_FLAGS
(lp-environment :pointer) ; void* optional
(lp-current-directory :string) ; LPCSTR optional
(lp-startup-info :pointer) ; STARTUPINFOA*
(lp-process-information :pointer)) ; PROCESS_INFORMATION* out
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $CreateProcessAsUserA = Win32::API::More->new('ADVAPI32',
'BOOL CreateProcessAsUserA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPVOID lpProcessAttributes, LPVOID lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPVOID lpStartupInfo, LPVOID lpProcessInformation)');
# my $ret = $CreateProcessAsUserA->Call($hToken, $lpApplicationName, $lpCommandLine, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, $lpStartupInfo, $lpProcessInformation);
# hToken : HANDLE optional -> HANDLE
# lpApplicationName : LPCSTR optional -> LPCSTR
# lpCommandLine : LPSTR optional, in/out -> LPSTR
# lpProcessAttributes : SECURITY_ATTRIBUTES* optional -> LPVOID
# lpThreadAttributes : SECURITY_ATTRIBUTES* optional -> LPVOID
# bInheritHandles : BOOL -> BOOL
# dwCreationFlags : PROCESS_CREATION_FLAGS -> DWORD
# lpEnvironment : void* optional -> LPVOID
# lpCurrentDirectory : LPCSTR optional -> LPCSTR
# lpStartupInfo : STARTUPINFOA* -> LPVOID
# lpProcessInformation : PROCESS_INFORMATION* out -> LPVOID
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f CreateProcessAsUserW (Unicode版) — 指定ユーザートークンのセキュリティ環境で新規プロセスを作成する(Unicode版)。
- f CloseHandle — オープンされたオブジェクトハンドルを閉じる。
- f CreateEnvironmentBlock — 指定ユーザートークンに基づく環境ブロックを作成する。
- f CreateProcessA — 新しいプロセスとそのプライマリスレッドを作成する(ANSI版)。
- f CreateProcessWithLogonW — 指定のユーザー資格情報でログオンして新しいプロセスを作成する。
- f ExitProcess — 現在のプロセスを指定終了コードで終了する。
- f GetExitCodeProcess — 指定プロセスの終了コードを取得する。
- f ImpersonateLoggedOnUser — 指定したログオンユーザーのトークンで偽装する。
- f LoadUserProfileA — 指定ユーザーのプロファイルを読み込む(ANSI版)。
- f SHCreateProcessAsUserW — 指定ユーザーの資格情報でプロセスを作成し起動する。
- s STARTUPINFOEXA
- f SetErrorMode — 重大エラー時のシステム既定処理を制御するエラーモードを設定する。
- f WaitForInputIdle — プロセスが入力待ちのアイドル状態になるまで待機する。