Fungsi CreateProcessWithTokenW (winbase.h)
Membuat proses baru dan utas utamanya. Proses baru berjalan dalam konteks keamanan token yang ditentukan. Ini dapat secara opsional memuat profil pengguna untuk pengguna yang ditentukan.
Proses yang memanggil CreateProcessWithTokenW harus memiliki hak istimewa SE_IMPERSONATE_NAME. Jika fungsi ini gagal dengan ERROR_PRIVILEGE_NOT_HELD (1314), gunakan fungsi CreateProcessAsUser atau CreateProcessWithLogonW sebagai gantinya. Biasanya, proses yang memanggil
CreateProcessAsUser harus memiliki hak istimewa SE_INCREASE_QUOTA_NAME dan mungkin memerlukan hak istimewa SE_ASSIGNPRIMARYTOKEN_NAME jika token tidak dapat ditetapkan. CreateProcessWithLogonW tidak memerlukan hak istimewa khusus, tetapi akun pengguna yang ditentukan harus diizinkan untuk masuk secara interaktif. Umumnya, yang terbaik adalah menggunakan CreateProcessWithLogonW untuk membuat proses dengan kredensial alternatif.
Sintaks
BOOL CreateProcessWithTokenW(
[in] HANDLE hToken,
[in] DWORD dwLogonFlags,
[in, optional] LPCWSTR lpApplicationName,
[in, out, optional] LPWSTR lpCommandLine,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCWSTR lpCurrentDirectory,
[in] LPSTARTUPINFOW lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);
Parameter
[in] hToken
Handel ke token utama yang mewakili pengguna. Handel harus memiliki hak akses TOKEN_QUERY, TOKEN_DUPLICATE, dan TOKEN_ASSIGN_PRIMARY. Untuk informasi selengkapnya, lihat Hak Akses untuk Objek Access-Token. Pengguna yang diwakili oleh token harus telah membaca dan menjalankan akses ke aplikasi yang ditentukan oleh lpApplicationName atau parameter lpCommandLine .
Untuk mendapatkan token utama yang mewakili pengguna yang ditentukan, panggil fungsi LogonUser . Atau, Anda dapat memanggil fungsi DuplicateTokenEx untuk mengonversi token peniruan menjadi token utama. Ini memungkinkan aplikasi server yang meniru klien untuk membuat proses yang memiliki konteks keamanan klien.
Layanan Terminal: Proses penelepon selalu berjalan di sesi pemanggil, bukan dalam sesi yang ditentukan dalam token. Untuk menjalankan proses dalam sesi yang ditentukan dalam token, gunakan fungsi CreateProcessAsUser.
[in] dwLogonFlags
Opsi masuk. Parameter ini bisa nol atau salah satu nilai berikut.
[in, optional] lpApplicationName
Nama modul yang akan dijalankan. Modul ini bisa menjadi aplikasi berbasis Windows. Ini bisa menjadi beberapa jenis modul lain (misalnya, MS-DOS atau OS/2) jika subsistem yang sesuai tersedia di komputer lokal.
String dapat menentukan jalur lengkap dan nama file modul yang akan dijalankan atau dapat menentukan nama parsial. Dalam kasus nama parsial, fungsi menggunakan drive saat ini dan direktori saat ini untuk menyelesaikan spesifikasi. Fungsi tidak akan menggunakan jalur pencarian. Parameter ini harus menyertakan ekstensi nama file; tidak ada ekstensi default yang diasumsikan.
Parameter lpApplicationName dapat berupa NULL. Dalam hal ini, nama modul harus menjadi token pertama yang dibatasi spasi putih dalam string lpCommandLine . Jika Anda menggunakan nama file panjang yang berisi spasi, gunakan string yang dikutip untuk menunjukkan di mana nama file berakhir dan argumen dimulai; jika tidak, nama file ambigu. Misalnya, pertimbangkan string "c:\program files\sub dir\program name". String ini dapat ditafsirkan dalam sejumlah cara. Sistem mencoba menafsirkan kemungkinan dalam urutan berikut:
c:\program.exec:\program files\sub.exec:\program files\sub dir\program.exec:\program files\sub dir\program name.exe Jika modul yang dapat dieksekusi adalah aplikasi 16-bit, lpApplicationName harus NULL, dan string yang ditunjukkan oleh lpCommandLine harus menentukan modul yang dapat dieksekusi serta argumennya.
[in, out, optional] lpCommandLine
Baris perintah yang akan dijalankan.
Panjang maksimum string ini adalah 1024 karakter. Jika lpApplicationName adalah NULL, bagian nama modul dari lpCommandLine terbatas pada MAX_PATH karakter.
Fungsi ini dapat mengubah konten string ini. Oleh karena itu, parameter ini tidak dapat menjadi penunjuk ke memori baca-saja (seperti variabel const atau string literal). Jika parameter ini adalah string konstanta, fungsi dapat menyebabkan pelanggaran akses.
Parameter lpCommandLine dapat berupa NULL. Dalam hal ini, fungsi menggunakan string yang diacu oleh lpApplicationName sebagai baris perintah.
Jika lpApplicationName dan lpCommandLine non-NULL, *lpApplicationName menentukan modul yang akan dijalankan, dan *lpCommandLine menentukan baris perintah. Proses baru dapat menggunakan GetCommandLine untuk mengambil seluruh baris perintah. Proses konsol yang ditulis dalam C dapat menggunakan argumen argc dan argv untuk mengurai baris perintah. Karena argv[0] adalah nama modul, programmer C umumnya mengulangi nama modul sebagai token pertama di baris perintah.
Jika lpApplicationName adalah NULL, token spasi putih pertama dari baris perintah menentukan nama modul. Jika Anda menggunakan nama file panjang yang berisi spasi, gunakan string yang dikutip untuk menunjukkan di mana nama file berakhir dan argumen dimulai (lihat penjelasan untuk parameter lpApplicationName ). Jika nama file tidak berisi ekstensi, .exe ditambahkan. Oleh karena itu, jika ekstensi nama file .com, parameter ini harus menyertakan ekstensi .com. Jika nama file berakhiran titik (.) tanpa ekstensi, atau jika nama file berisi jalur, .exe tidak ditambahkan. Jika nama file tidak berisi jalur direktori, sistem akan mencari file yang dapat dieksekusi dalam urutan berikut:
- Direktori tempat aplikasi dimuat.
- Direktori saat ini untuk proses induk.
- Direktori sistem Windows 32-bit. Gunakan fungsi GetSystemDirectory untuk mendapatkan jalur direktori ini.
- Direktori sistem Windows 16-bit. Tidak ada fungsi yang mendapatkan jalur direktori ini, tetapi dicari.
- Direktori Windows. Gunakan fungsi GetWindowsDirectory untuk mendapatkan jalur direktori ini.
- Direktori yang tercantum dalam variabel lingkungan PATH. Perhatikan bahwa fungsi ini tidak mencari jalur per aplikasi yang ditentukan oleh kunci registri Jalur Aplikasi . Untuk menyertakan jalur per aplikasi ini dalam urutan pencarian, gunakan fungsi ShellExecute .
[in] dwCreationFlags
Bendera yang mengontrol cara proses dibuat. Bendera CREATE_DEFAULT_ERROR_MODE, CREATE_NEW_CONSOLE, dan CREATE_NEW_PROCESS_GROUP diaktifkan secara default. Untuk daftar nilai, lihat Bendera Pembuatan Proses.
Parameter ini juga mengontrol kelas prioritas proses baru, yang digunakan untuk menentukan prioritas penjadwalan utas proses. Untuk daftar nilai, lihat GetPriorityClass. Jika tidak ada bendera kelas prioritas yang ditentukan, kelas prioritas default ke NORMAL_PRIORITY_CLASS kecuali kelas prioritas proses pembuatan IDLE_PRIORITY_CLASS atau BELOW_NORMAL_PRIORITY_CLASS. Dalam hal ini, proses anak menerima kelas prioritas default dari proses panggilan.
Jika parameter dwCreationFlags memiliki nilai 0:
- Proses ini mendapatkan mode kesalahan default, membuat konsol baru dan membuat grup proses baru.
- Blok lingkungan untuk proses baru diasumsikan berisi karakter ANSI (lihat parameter lpEnvironment untuk informasi tambahan).
- Aplikasi berbasis Windows 16-bit berjalan di komputer Virtual DOS bersama (VDM).
[in, optional] lpEnvironment
Pointer ke blok lingkungan untuk proses baru. Jika parameter ini NULL, proses baru menggunakan lingkungan yang dibuat dari profil pengguna yang ditentukan oleh lpUsername.
Blok lingkungan terdiri dari blok string null-terminated null-terminated. Setiap string dalam bentuk berikut:
Nama=Nilai
Karena tanda sama dengan (=) digunakan sebagai pemisah, tanda tersebut tidak boleh digunakan dalam nama variabel lingkungan.
Blok lingkungan dapat berisi karakter Unicode atau ANSI. Jika blok lingkungan yang diarahkan oleh lpEnvironment berisi karakter Unicode, pastikan bahwa dwCreationFlags menyertakan CREATE_UNICODE_ENVIRONMENT.
Blok lingkungan ANSI dihentikan oleh dua byte nol: satu untuk string terakhir, satu lagi untuk mengakhiri blok. Blok lingkungan Unicode dihentikan oleh empat byte nol: dua untuk string terakhir dan dua lagi untuk mengakhiri blok.
Untuk mengambil salinan blok lingkungan untuk pengguna tertentu, gunakan fungsi CreateEnvironmentBlock .
[in, optional] lpCurrentDirectory
Jalur lengkap ke direktori saat ini untuk proses tersebut. String juga dapat menentukan jalur UNC.
Jika parameter ini NULL, proses baru akan memiliki drive dan direktori saat ini yang sama dengan proses pemanggilan. (Fitur ini disediakan terutama untuk shell yang perlu memulai aplikasi dan menentukan drive awal dan direktori kerjanya.)
[in] lpStartupInfo
Penunjuk ke struktur STARTUPINFO atau STARTUPINFOEX .
Jika anggota lpDesktop adalah NULL atau string kosong, proses baru mewarisi stasiun desktop dan jendela dari proses induknya. Fungsi menambahkan izin untuk akun pengguna yang ditentukan ke stasiun jendela dan desktop yang diwariskan. Jika tidak, jika anggota ini menentukan desktop, aplikasi bertanggung jawab untuk menambahkan izin untuk akun pengguna yang ditentukan ke stasiun jendela dan desktop yang ditentukan, bahkan untuk WinSta0\Default.
Handel di STARTUPINFO atau STARTUPINFOEX harus ditutup dengan CloseHandle ketika tidak lagi diperlukan.
[out] lpProcessInformation
Penunjuk ke struktur PROCESS_INFORMATION yang menerima informasi identifikasi untuk proses baru, termasuk handel ke proses.
Handel di PROCESS_INFORMATION harus ditutup dengan fungsi CloseHandle saat tidak lagi diperlukan.
Mengembalikan nilai
Jika fungsi berhasil, nilai yang dikembalikan bukan nol.
Jika fungsi gagal, nilai yang dikembalikan adalah nol. Untuk mendapatkan informasi kesalahan yang diperluas, hubungi GetLastError.
Perhatikan bahwa fungsi kembali sebelum proses selesai diinisialisasi. Jika DLL yang diperlukan tidak dapat ditemukan atau gagal diinisialisasi, proses dihentikan. Untuk mendapatkan status penghentian proses, panggil GetExitCodeProcess.
Keterangan
Secara default, CreateProcessWithTokenW tidak memuat profil pengguna yang ditentukan ke dalam kunci registri HKEY_USERS . Ini berarti bahwa akses ke informasi dalam kunci registri HKEY_CURRENT_USER mungkin tidak menghasilkan hasil yang konsisten dengan masuk interaktif normal. Anda bertanggung jawab untuk memuat sarang registri pengguna ke HKEY_USERS dengan menggunakan LOGON_WITH_PROFILE, atau dengan memanggil fungsi LoadUserProfile sebelum memanggil fungsi ini.
Jika parameter lpEnvironment adalah NULL, proses baru menggunakan blok lingkungan yang dibuat dari profil pengguna yang ditentukan oleh lpUserName. Jika variabel HOMEDRIVE dan HOMEPATH tidak diatur, CreateProcessWithTokenW memodifikasi blok lingkungan untuk menggunakan drive dan jalur direktori kerja pengguna.
Saat dibuat, proses baru dan handel utas menerima hak akses penuh (PROCESS_ALL_ACCESS dan THREAD_ALL_ACCESS). Untuk salah satu handel, jika deskriptor keamanan tidak disediakan, handel dapat digunakan dalam fungsi apa pun yang memerlukan handel objek dari jenis tersebut. Ketika deskriptor keamanan disediakan, pemeriksaan akses dilakukan pada semua penggunaan handel berikutnya sebelum akses diberikan. Jika akses ditolak, proses permintaan tidak dapat menggunakan handel untuk mendapatkan akses ke proses atau utas.
Untuk mengambil token keamanan, teruskan handel proses dalam struktur PROCESS_INFORMATION ke fungsi OpenProcessToken .
Proses ini diberi pengidentifikasi proses. Pengidentifikasi valid sampai proses berakhir. Ini dapat digunakan untuk mengidentifikasi proses, atau ditentukan dalam fungsi OpenProcess untuk membuka handel ke proses. Utas awal dalam proses juga diberi pengidentifikasi utas. Ini dapat ditentukan dalam fungsi OpenThread untuk membuka handel ke utas. Pengidentifikasi valid sampai utas berakhir dan dapat digunakan untuk mengidentifikasi utas secara unik dalam sistem. Pengidentifikasi ini dikembalikan dalam PROCESS_INFORMATION.
Utas panggilan dapat menggunakan fungsi WaitForInputIdle untuk menunggu sampai proses baru selesai inisialisasinya dan menunggu input pengguna tanpa input tertunda. Ini dapat berguna untuk sinkronisasi antara proses induk dan anak, karena CreateProcessWithTokenW kembali tanpa menunggu proses baru selesai inisialisasinya. Misalnya, proses pembuatan akan menggunakan WaitForInputIdle sebelum mencoba menemukan jendela yang terkait dengan proses baru.
Cara yang disukai untuk mematikan proses adalah dengan menggunakan fungsi ExitProcess , karena fungsi ini mengirimkan pemberitahuan tentang penghentian mendekati ke semua DLL yang terpasang pada proses. Cara lain untuk mematikan proses tidak memberi tahu DLL yang terlampir. Perhatikan bahwa ketika utas memanggil ExitProcess, utas proses lainnya dihentikan tanpa kesempatan untuk menjalankan kode tambahan apa pun (termasuk kode penghentian utas DLL yang dilampirkan). Untuk informasi selengkapnya, lihat Mengakhiri Proses.
Untuk mengkompilasi aplikasi yang menggunakan fungsi ini, tentukan _WIN32_WINNT sebagai 0x0500 atau yang lebih baru. Untuk informasi selengkapnya, lihat Menggunakan Header Windows.
Keterangan Keamanan
Parameter lpApplicationName dapat berupa NULL, dalam hal ini nama yang dapat dieksekusi harus berupa string yang dibatasi spasi putih pertama di lpCommandLine. Jika nama yang dapat dieksekusi atau jalur memiliki ruang di dalamnya, ada risiko bahwa executable yang berbeda dapat dijalankan karena cara fungsi mengurai spasi. Contoh berikut berbahaya karena fungsi akan mencoba menjalankan "Program.exe", jika ada, alih-alih "MyApp.exe". LPTSTR szCmdline = L"C:\\Program Files\\MyApp";
CreateProcessWithTokenW(/*...*/, szCmdline, /*...*/);
Jika pengguna jahat membuat aplikasi yang disebut "Program.exe" pada sistem, program apa pun yang salah memanggil CreateProcessWithTokenW menggunakan direktori Program Files akan menjalankan aplikasi ini alih-alih aplikasi yang dimaksudkan.
Untuk menghindari masalah ini, jangan lewati NULL untuk lpApplicationName. Jika Anda melewati NULL untuk lpApplicationName, gunakan tanda kutip di sekitar jalur yang dapat dieksekusi di lpCommandLine, seperti yang ditunjukkan pada contoh di bawah ini.
LPTSTR szCmdline = L"\"C:\\Program Files\\MyApp\"";
CreateProcessWithTokenW(/*...*/, szCmdline, /*...*/);
Persyaratan
Persyaratan | Nilai |
---|---|
Klien minimum yang didukung | Windows Vista [hanya aplikasi desktop] |
Server minimum yang didukung | Windows Server 2003 [hanya aplikasi desktop] |
Target Platform | Windows |
Header | winbase.h (termasuk Windows.h) |
Pustaka | Advapi32.lib |
DLL | Advapi32.dll |