CreateMutexA
関数シグネチャ
// KERNEL32.dll (ANSI / -A)
#include <windows.h>
HANDLE CreateMutexA(
SECURITY_ATTRIBUTES* lpMutexAttributes, // optional
BOOL bInitialOwner,
LPCSTR lpName // optional
);パラメーター
| 名前 | 型 | 方向 | 説明 |
|---|---|---|---|
| lpMutexAttributes | SECURITY_ATTRIBUTES* | inoptional | SECURITY_ATTRIBUTES 構造体へのポインターです。このパラメーターが NULL の場合、ハンドルは子プロセスに継承されません。 構造体の lpSecurityDescriptor メンバーは、新しい mutex のセキュリティ記述子を指定します。lpMutexAttributes が NULL の場合、mutex には既定のセキュリティ記述子が割り当てられます。mutex の既定のセキュリティ記述子に含まれる ACL は、作成者のプライマリトークンまたは偽装トークンから取得されます。詳細については、同期オブジェクトのセキュリティとアクセス権を参照してください。 |
| bInitialOwner | BOOL | in | この値が TRUE であり、かつ呼び出し元が mutex を作成した場合、呼び出し元のスレッドが mutex オブジェクトの初期所有権を取得します。それ以外の場合、呼び出し元のスレッドは所有権を取得しません。呼び出し元が mutex を作成したかどうかを判定するには、「戻り値」のセクションを参照してください。 |
| lpName | LPCSTR | inoptional | mutex オブジェクトの名前です。名前は MAX_PATH 文字までに制限されます。名前の比較では大文字と小文字が区別されます。 lpName が既存の名前付き mutex オブジェクトの名前と一致する場合、この関数は MUTEX_ALL_ACCESS アクセス権を要求します。この場合、bInitialOwner パラメーターは無視されます。これは作成プロセスによって既に設定されているためです。lpMutexAttributes パラメーターが NULL でない場合、それはハンドルを継承できるかどうかを決定しますが、そのセキュリティ記述子メンバーは無視されます。 lpName が NULL の場合、mutex オブジェクトは名前なしで作成されます。 lpName が既存の event、semaphore、待機可能タイマー、ジョブ、またはファイルマッピングオブジェクトの名前と一致する場合、関数は失敗し、 GetLastError 関数は ERROR_INVALID_HANDLE を返します。これは、これらのオブジェクトが同じ名前空間を共有しているために発生します。 名前には "Global" または "Local" プレフィックスを付けて、グローバル名前空間またはセッション名前空間にオブジェクトを明示的に作成できます。名前の残りの部分には、円記号 (\) を除く任意の文字を含めることができます。詳細については、 カーネルオブジェクトの名前空間を参照してください。ファストユーザー切り替えは、ターミナルサービスのセッションを使用して実装されています。アプリケーションが複数のユーザーをサポートできるように、カーネルオブジェクト名はターミナルサービスのガイドラインに従う必要があります。 オブジェクトはプライベート名前空間に作成できます。詳細については、オブジェクトの名前空間を参照してください。 |
戻り値の型: HANDLE
公式ドキュメント
名前付きまたは名前なしの mutex オブジェクトを作成または開きます。(ANSI)
戻り値
関数が成功した場合、戻り値は新しく作成された mutex オブジェクトへのハンドルです。
関数が失敗した場合、戻り値は NULL です。拡張エラー情報を取得するには、GetLastError を呼び出してください。
mutex が名前付き mutex であり、この関数呼び出しの前にオブジェクトが既に存在していた場合、戻り値は既存のオブジェクトへのハンドルとなり、GetLastError 関数は ERROR_ALREADY_EXISTS を返します。
解説(Remarks)
CreateMutex が返すハンドルは MUTEX_ALL_ACCESS アクセス権を持ち、呼び出し元にアクセスが許可されている限り、mutex オブジェクトへのハンドルを必要とする任意の関数で使用できます。サービスから、または別のユーザーを偽装しているスレッドから mutex を作成する場合は、作成時に mutex へセキュリティ記述子を適用するか、作成プロセスの既定の DACL を変更してその既定のセキュリティ記述子を変更することができます。詳細については、 同期オブジェクトのセキュリティとアクセス権を参照してください。
名前付き mutex を使用してアプリケーションを単一インスタンスに制限する場合、悪意のあるユーザーがこの mutex を先に作成して、アプリケーションの起動を妨げる可能性があります。この状況を防ぐには、ランダムな名前の mutex を作成し、その名前を認可されたユーザーのみが取得できるように保存します。あるいは、この目的でファイルを使用することもできます。アプリケーションをユーザーごとに 1 インスタンスに制限するには、ユーザーのプロファイルディレクトリにロックされたファイルを作成します。
呼び出しプロセスの任意のスレッドは、いずれかの 待機関数の呼び出しで mutex オブジェクトのハンドルを指定できます。単一オブジェクトの待機関数は、指定したオブジェクトの状態がシグナル状態になると制御を返します。複数オブジェクトの待機関数は、指定したオブジェクトのいずれか 1 つがシグナル状態になったとき、またはすべてがシグナル状態になったときに制御を返すよう指示できます。待機関数が制御を返すと、待機していたスレッドは解放され、実行を継続します。
mutex オブジェクトの状態は、どのスレッドにも所有されていないときにシグナル状態になります。作成スレッドは bInitialOwner フラグを使用して mutex の即時所有権を要求できます。そうでない場合、スレッドは所有権を要求するためにいずれかの待機関数を使用する必要があります。mutex の状態がシグナル状態になると、待機中のスレッドの 1 つに所有権が付与され、mutex の状態は非シグナル状態に変わり、待機関数が制御を返します。任意の時点で mutex を所有できるスレッドは 1 つだけです。所有スレッドは ReleaseMutex 関数を使用して所有権を解放します。
mutex を所有するスレッドは、実行をブロックすることなく、繰り返しの待機関数呼び出しで同じ mutex を指定できます。通常、同じ mutex を繰り返し待機することはありませんが、この仕組みにより、スレッドが既に所有している mutex を待機している間にデッドロックに陥ることを防ぎます。ただし、所有権を解放するには、mutex が待機を満たした回数と同じ回数だけ ReleaseMutex を呼び出す必要があります。
2 つ以上のプロセスが CreateMutex を呼び出して同じ名前付き mutex を作成できます。最初のプロセスが実際に mutex を作成し、十分なアクセス権を持つ後続のプロセスは、既存の mutex へのハンドルを単に開きます。これにより、複数のプロセスが同じ mutex のハンドルを取得でき、作成プロセスが最初に起動されることを保証する責任からユーザーを解放します。この手法を使用する場合は、bInitialOwner フラグを FALSE に設定する必要があります。そうしないと、どのプロセスが初期所有権を持つかを確実に判断するのが困難になる可能性があります。
複数のプロセスが同じ mutex オブジェクトのハンドルを持つことができ、プロセス間同期にそのオブジェクトを使用できます。次のオブジェクト共有メカニズムが利用できます。
- CreateProcess 関数によって作成された子プロセスは、 CreateMutex の lpMutexAttributes パラメーターが継承を有効にしていた場合、mutex オブジェクトへのハンドルを継承できます。このメカニズムは名前付きおよび名前なしの両方の mutex で機能します。
- プロセスは、DuplicateHandle 関数の呼び出しで mutex オブジェクトのハンドルを指定して、別のプロセスで使用できる複製ハンドルを作成できます。このメカニズムは名前付きおよび名前なしの両方の mutex で機能します。
- プロセスは、[OpenMutex](./nf-synchapi-openmutexw.md) または CreateMutex の呼び出しで名前付き mutex を指定して、mutex オブジェクトへのハンドルを取得できます。
例
CreateMutex の例については、mutex オブジェクトの使用を参照してください。
synchapi.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI 版または Unicode 版を自動的に選択するエイリアスとして CreateMutex を定義しています。エンコーディング中立のエイリアスの使用を、エンコーディング中立でないコードと混在させると、コンパイルエラーや実行時エラーを引き起こす不一致につながる可能性があります。詳細については、関数プロトタイプの規則を参照してください。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
各言語での呼び出し定義
// KERNEL32.dll (ANSI / -A)
#include <windows.h>
HANDLE CreateMutexA(
SECURITY_ATTRIBUTES* lpMutexAttributes, // optional
BOOL bInitialOwner,
LPCSTR lpName // optional
);[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern IntPtr CreateMutexA(
IntPtr lpMutexAttributes, // SECURITY_ATTRIBUTES* optional
bool bInitialOwner, // BOOL
[MarshalAs(UnmanagedType.LPStr)] string lpName // LPCSTR optional
);<DllImport("KERNEL32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function CreateMutexA(
lpMutexAttributes As IntPtr, ' SECURITY_ATTRIBUTES* optional
bInitialOwner As Boolean, ' BOOL
<MarshalAs(UnmanagedType.LPStr)> lpName As String ' LPCSTR optional
) As IntPtr
End Function' lpMutexAttributes : SECURITY_ATTRIBUTES* optional
' bInitialOwner : BOOL
' lpName : LPCSTR optional
Declare PtrSafe Function CreateMutexA Lib "kernel32" ( _
ByVal lpMutexAttributes As LongPtr, _
ByVal bInitialOwner As Long, _
ByVal lpName As String) As LongPtr
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。import ctypes
from ctypes import wintypes
CreateMutexA = ctypes.windll.kernel32.CreateMutexA
CreateMutexA.restype = ctypes.c_void_p
CreateMutexA.argtypes = [
ctypes.c_void_p, # lpMutexAttributes : SECURITY_ATTRIBUTES* optional
wintypes.BOOL, # bInitialOwner : BOOL
wintypes.LPCSTR, # lpName : LPCSTR optional
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))require 'fiddle'
require 'fiddle/import'
lib = Fiddle.dlopen('KERNEL32.dll')
CreateMutexA = Fiddle::Function.new(
lib['CreateMutexA'],
[
Fiddle::TYPE_VOIDP, # lpMutexAttributes : SECURITY_ATTRIBUTES* optional
Fiddle::TYPE_INT, # bInitialOwner : BOOL
Fiddle::TYPE_VOIDP, # lpName : LPCSTR optional
],
Fiddle::TYPE_VOIDP)#[link(name = "kernel32")]
extern "system" {
fn CreateMutexA(
lpMutexAttributes: *mut SECURITY_ATTRIBUTES, // SECURITY_ATTRIBUTES* optional
bInitialOwner: i32, // BOOL
lpName: *const u8 // LPCSTR optional
) -> *mut core::ffi::c_void;
}
// crates: windows-sys provides ready-made bindings for this API.$sig = @"
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern IntPtr CreateMutexA(IntPtr lpMutexAttributes, bool bInitialOwner, [MarshalAs(UnmanagedType.LPStr)] string lpName);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_CreateMutexA' -Namespace Win32 -PassThru
# $api::CreateMutexA(lpMutexAttributes, bInitialOwner, lpName)#uselib "KERNEL32.dll"
#func global CreateMutexA "CreateMutexA" sptr, sptr, sptr
; CreateMutexA varptr(lpMutexAttributes), bInitialOwner, lpName ; 戻り値は stat
; lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "sptr"
; bInitialOwner : BOOL -> "sptr"
; lpName : LPCSTR optional -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。#uselib "KERNEL32.dll" #cfunc global CreateMutexA "CreateMutexA" var, int, str ; res = CreateMutexA(lpMutexAttributes, bInitialOwner, lpName) ; lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "var" ; bInitialOwner : BOOL -> "int" ; lpName : LPCSTR optional -> "str" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。#uselib "KERNEL32.dll" #cfunc global CreateMutexA "CreateMutexA" sptr, int, str ; res = CreateMutexA(varptr(lpMutexAttributes), bInitialOwner, lpName) ; lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "sptr" ; bInitialOwner : BOOL -> "int" ; lpName : LPCSTR optional -> "str" ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。
; HANDLE CreateMutexA(SECURITY_ATTRIBUTES* lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName) #uselib "KERNEL32.dll" #cfunc global CreateMutexA "CreateMutexA" var, int, str ; res = CreateMutexA(lpMutexAttributes, bInitialOwner, lpName) ; lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "var" ; bInitialOwner : BOOL -> "int" ; lpName : LPCSTR optional -> "str" ; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。; HANDLE CreateMutexA(SECURITY_ATTRIBUTES* lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName) #uselib "KERNEL32.dll" #cfunc global CreateMutexA "CreateMutexA" intptr, int, str ; res = CreateMutexA(varptr(lpMutexAttributes), bInitialOwner, lpName) ; lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "intptr" ; bInitialOwner : BOOL -> "int" ; lpName : LPCSTR optional -> "str" ; ※出力/バッファ引数はポインタ方式(token=intptr / 呼び出しは varptr(変数))。
import (
"golang.org/x/sys/windows"
"unsafe"
)
var (
kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
procCreateMutexA = kernel32.NewProc("CreateMutexA")
)
// lpMutexAttributes (SECURITY_ATTRIBUTES* optional), bInitialOwner (BOOL), lpName (LPCSTR optional)
r1, _, err := procCreateMutexA.Call(
uintptr(lpMutexAttributes),
uintptr(bInitialOwner),
uintptr(unsafe.Pointer(windows.BytePtrFromString(lpName))),
)
_ = err // syscall.Errno (valid when the call sets last-error)
_ = r1 // HANDLEfunction CreateMutexA(
lpMutexAttributes: Pointer; // SECURITY_ATTRIBUTES* optional
bInitialOwner: BOOL; // BOOL
lpName: PAnsiChar // LPCSTR optional
): THandle; stdcall;
external 'KERNEL32.dll' name 'CreateMutexA';result := DllCall("KERNEL32\CreateMutexA"
, "Ptr", lpMutexAttributes ; SECURITY_ATTRIBUTES* optional
, "Int", bInitialOwner ; BOOL
, "AStr", lpName ; LPCSTR optional
, "Ptr") ; return: HANDLE●CreateMutexA(lpMutexAttributes, bInitialOwner, lpName) = DLL("KERNEL32.dll", "void* CreateMutexA(void*, bool, char*)")
# 呼び出し: CreateMutexA(lpMutexAttributes, bInitialOwner, lpName)
# lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "void*"
# bInitialOwner : BOOL -> "bool"
# lpName : LPCSTR optional -> "char*"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。const std = @import("std");
extern "kernel32" fn CreateMutexA(
lpMutexAttributes: [*c]SECURITY_ATTRIBUTES, // SECURITY_ATTRIBUTES* optional
bInitialOwner: i32, // BOOL
lpName: [*c]const u8 // LPCSTR optional
) callconv(std.os.windows.WINAPI) ?*anyopaque;proc CreateMutexA(
lpMutexAttributes: ptr SECURITY_ATTRIBUTES, # SECURITY_ATTRIBUTES* optional
bInitialOwner: int32, # BOOL
lpName: cstring # LPCSTR optional
): pointer {.importc: "CreateMutexA", stdcall, dynlib: "KERNEL32.dll".}pragma(lib, "kernel32");
extern(Windows)
void* CreateMutexA(
SECURITY_ATTRIBUTES* lpMutexAttributes, // SECURITY_ATTRIBUTES* optional
int bInitialOwner, // BOOL
const(char)* lpName // LPCSTR optional
);ccall((:CreateMutexA, "KERNEL32.dll"), stdcall, Ptr{Cvoid},
(Ptr{SECURITY_ATTRIBUTES}, Int32, Cstring),
lpMutexAttributes, bInitialOwner, lpName)
# lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> Ptr{SECURITY_ATTRIBUTES}
# bInitialOwner : BOOL -> Int32
# lpName : LPCSTR optional -> Cstring
# stdcall は 32bit のみ意味を持つ(x64 では無視)。local ffi = require("ffi")
ffi.cdef[[
void* CreateMutexA(
void* lpMutexAttributes,
int32_t bInitialOwner,
const char* lpName);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.CreateMutexA(lpMutexAttributes, bInitialOwner, lpName)
-- lpMutexAttributes : SECURITY_ATTRIBUTES* optional
-- bInitialOwner : BOOL
-- lpName : LPCSTR optional
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const CreateMutexA = lib.func('__stdcall', 'CreateMutexA', 'void *', ['void *', 'int32_t', 'str']);
// CreateMutexA(lpMutexAttributes, bInitialOwner, lpName)
// lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> 'void *'
// bInitialOwner : BOOL -> 'int32_t'
// lpName : LPCSTR optional -> 'str'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。const lib = Deno.dlopen("KERNEL32.dll", {
CreateMutexA: { parameters: ["pointer", "i32", "buffer"], result: "pointer" },
});
// lib.symbols.CreateMutexA(lpMutexAttributes, bInitialOwner, lpName)
// lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> "pointer"
// bInitialOwner : BOOL -> "i32"
// lpName : LPCSTR optional -> "buffer"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。<?php
$ffi = FFI::cdef(<<<C
void* CreateMutexA(
void* lpMutexAttributes,
int32_t bInitialOwner,
const char* lpName);
C, "KERNEL32.dll");
// $ffi->CreateMutexA(lpMutexAttributes, bInitialOwner, lpName);
// lpMutexAttributes : SECURITY_ATTRIBUTES* optional
// bInitialOwner : BOOL
// lpName : LPCSTR optional
// 構造体/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 Kernel32 extends StdCallLibrary {
Kernel32 INSTANCE = Native.load("kernel32", Kernel32.class, W32APIOptions.ASCII_OPTIONS);
Pointer CreateMutexA(
Pointer lpMutexAttributes, // SECURITY_ATTRIBUTES* optional
boolean bInitialOwner, // BOOL
String lpName // LPCSTR optional
);
}@[Link("kernel32")]
lib LibKERNEL32
fun CreateMutexA = CreateMutexA(
lpMutexAttributes : SECURITY_ATTRIBUTES*, # SECURITY_ATTRIBUTES* optional
bInitialOwner : Int32, # BOOL
lpName : UInt8* # LPCSTR optional
) : Void*
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。import 'dart:ffi';
import 'package:ffi/ffi.dart';
typedef CreateMutexANative = Pointer<Void> Function(Pointer<Void>, Int32, Pointer<Utf8>);
typedef CreateMutexADart = Pointer<Void> Function(Pointer<Void>, int, Pointer<Utf8>);
final CreateMutexA = DynamicLibrary.open('KERNEL32.dll')
.lookupFunction<CreateMutexANative, CreateMutexADart>('CreateMutexA');
// lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> Pointer<Void>
// bInitialOwner : BOOL -> Int32
// lpName : LPCSTR optional -> Pointer<Utf8>
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。{$mode objfpc}{$H+}
function CreateMutexA(
lpMutexAttributes: Pointer; // SECURITY_ATTRIBUTES* optional
bInitialOwner: BOOL; // BOOL
lpName: PAnsiChar // LPCSTR optional
): THandle; stdcall;
external 'KERNEL32.dll' name 'CreateMutexA';import Foreign
import Foreign.C.Types
import Foreign.C.String
foreign import stdcall safe "CreateMutexA"
c_CreateMutexA :: Ptr () -> CInt -> CString -> IO (Ptr ())
-- lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> Ptr ()
-- bInitialOwner : BOOL -> CInt
-- lpName : LPCSTR optional -> CString
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。open Ctypes
open Foreign
let createmutexa =
foreign "CreateMutexA"
((ptr void) @-> int32_t @-> string @-> returning (ptr void))
(* lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> (ptr void) *)
(* bInitialOwner : BOOL -> int32_t *)
(* lpName : LPCSTR optional -> string *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)
(cffi:defcfun ("CreateMutexA" create-mutex-a :convention :stdcall) :pointer
(lp-mutex-attributes :pointer) ; SECURITY_ATTRIBUTES* optional
(b-initial-owner :int32) ; BOOL
(lp-name :string)) ; LPCSTR optional
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。use Win32::API;
my $CreateMutexA = Win32::API::More->new('KERNEL32',
'HANDLE CreateMutexA(LPVOID lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)');
# my $ret = $CreateMutexA->Call($lpMutexAttributes, $bInitialOwner, $lpName);
# lpMutexAttributes : SECURITY_ATTRIBUTES* optional -> LPVOID
# bInitialOwner : BOOL -> BOOL
# lpName : LPCSTR optional -> LPCSTR
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。関連項目
- f CreateMutexW (Unicode版) — 名前付きまたは無名のミューテックスを作成する(Unicode版)。
- f CreateMutexExA — アクセス権とフラグを指定してミューテックスを作成する(ANSI版)。
- f CloseHandle — オープンされたオブジェクトハンドルを閉じる。
- f CreateProcessA — 新しいプロセスとそのプライマリスレッドを作成する(ANSI版)。
- f DuplicateHandle — オブジェクトハンドルの複製を作成する。
- f ReleaseMutex — ミューテックスの所有権を解放する。