Win32 API 日本語リファレンス
ホームStorage.FileSystem › GetVolumePathNameA

GetVolumePathNameA

関数
ファイルパスが属するボリュームのマウントパスを取得する(ANSI版)。
DLLKERNEL32.dll文字セットANSI (-A)呼出規約winapiSetLastErrorあり対応OSWindows XP 以降

シグネチャ

// KERNEL32.dll  (ANSI / -A)
#include <windows.h>

BOOL GetVolumePathNameA(
    LPCSTR lpszFileName,
    LPSTR lpszVolumePathName,
    DWORD cchBufferLength
);

パラメーター

名前方向説明
lpszFileNameLPCSTRin

入力パス文字列へのポインターです。絶対パスと相対パスのいずれのファイル名・ディレクトリ名(たとえば "..")もこのパスに指定できます。

ボリューム修飾子を伴わない相対ディレクトリ名またはファイル名を指定した場合、 GetVolumePathName はブート ボリュームのドライブ文字を返します。

このパラメーターが空文字列 "" の場合、関数は失敗しますが、最終エラーは ERROR_SUCCESS に設定されます。

lpszVolumePathNameLPSTRout入力パスのボリューム マウント ポイントを受け取る文字列へのポインターです。
cchBufferLengthDWORDin出力バッファーの長さ(TCHAR 単位)です。

戻り値の型: BOOL

公式ドキュメント

指定したパスがマウントされているボリュームのマウント ポイントを取得します。(GetVolumePathNameA)

戻り値

関数が成功した場合、戻り値は 0 以外の値になります。

関数が失敗した場合、戻り値は 0 になります。拡張エラー情報を取得するには、 GetLastError を呼び出します。

解説(Remarks)

指定したパスが渡されると、GetVolumePathName はボリューム マウント ポイントへのパスを返します。これは、指定したパスの終端が存在するボリュームのルートを返すことを意味します。

たとえば、ボリューム D が C:\Mnt\Ddrive にマウントされ、 ボリューム E が "C:\Mnt\Ddrive\Mnt\Edrive" にマウントされているとします。さらに、 パスが "E:\Dir\Subdir\MyFile" のファイルがあるとします。このとき "C:\Mnt\Ddrive\Mnt\Edrive\Dir\Subdir\MyFile" を GetVolumePathName に渡すと、パス "C:\Mnt\Ddrive\Mnt\Edrive" が返されます。

ボリューム修飾子を伴わない相対ディレクトリまたはファイルが渡された場合、関数はブート ボリュームのドライブ文字を返します。 有効なボリューム修飾子を伴わずに無効なファイル名またはディレクトリ名が指定された場合も、ブート ボリュームのドライブ文字が返されます。 有効なボリューム指定子が与えられ、そのボリュームが存在するものの、無効なファイル名またはディレクトリ名が指定された場合、関数は成功し、 そのボリューム名が返されます。例については、このトピックの「Examples」セクションを参照してください。

有効な Win32 名前空間パスを指定する必要があります。NT 名前空間パス(たとえば "\DosDevices\H:" や "\Device\HardDiskVolume6")を指定した場合、関数はその NT 名前空間パスのドライブ文字ではなく、 ブート ボリュームのドライブ文字を返します。

パス名と名前空間の詳細については、 Naming Files, Paths, and Namespaces を参照してください。

ローカル パスとリモート パスの両方を指定できます。ローカル パスを指定した場合、 GetVolumePathName はボリュームを表す最長のプレフィックスをプレフィックスとするフル パスを返します。

ネットワーク共有を指定した場合、GetVolumePathNameGetDriveTypeDRIVE_REMOTE を返す最短のパスを返します。これは、そのパスが、現在のユーザーがアクセスできる、 存在するリモート ドライブとして検証されることを意味します。

末尾の円記号(バックスラッシュ)を返さない特定の特殊なケースがあります。これは、出力バッファーの長さが 1 文字だけ足りない場合に発生します。 たとえば、lpszFileName が C: で、lpszVolumePathName が 4 文字の長さの場合、 返される値は "C:" になります。一方、 lpszVolumePathName が 3 文字の長さの場合、返される値は "C:" になります。より安全ですが低速な方法として、戻りバッファーのサイズを設定するには、 GetFullPathName 関数を呼び出し、 バッファー サイズが GetFullPathName が返すフル パスと少なくとも同じサイズになるようにします。 出力バッファーが 1 文字を超えて短い場合、関数は失敗してエラーを返します。

Windows 8 および Windows Server 2012 では、この関数は次のテクノロジでサポートされています。

テクノロジ サポート
Server Message Block (SMB) 3.0 プロトコル いいえ
SMB 3.0 Transparent Failover (TFO) いいえ
SMB 3.0 with Scale-out File Shares (SO) いいえ
Cluster Shared Volume File System (CsvFS) はい
Resilient File System (ReFS) はい

SMB はボリューム管理関数をサポートしません。

末尾のパス要素

無効な末尾のパス要素は無視されます。リモート パスの場合、次のいずれかの条件が真であると、 (末尾の要素だけでなく)パス全体が無効と見なされます。

ジャンクション ポイントとマウントされたフォルダー

指定したパスがジャンクション ポイントを経由する場合、 GetVolumePathName はそのジャンクション ポイントが参照するボリュームを返します。 たとえば、W:\AdirC:\Adir を指すジャンクション ポイントである場合、 W:\Adir\Afile に対して GetVolumePathName を呼び出すと "C:\" が返されます。 指定したパスが複数のジャンクション ポイントを経由する場合、チェーン全体がたどられ、 GetVolumePathName はチェーン内の最後のジャンクション ポイントが参照するボリュームを返します。

マウントされたフォルダーまたはジャンクション ポイントへのリモート パスが指定された場合、そのパスはリモート パスとして解析され、 マウントされたフォルダーまたはジャンクション ポイントは無視されます。たとえば、 C:\Dir_CD:\Dir_D にリンクされ、リモート コンピューター上で C:X: にマップされている場合、リモート コンピューター上で X:\Dir_C を指定して GetVolumePathName を呼び出すと X:</code> が返されます。

次の一連の例では、U: はリモート コンピューター \\YourComputer\C$ にマップされており、Q はローカル ドライブです。

指定したパス 関数が返す値
\\YourComputer\C$\Windows \\YourComputer\C$\
\\?\UNC\YourComputer\C$\Windows \\?\UNC\YourComputer\C$\
Q:\Windows Q:\
\\?\Q:\Windows \\?\Q:\
\\.\Q:\Windows \\.\Q:\
\\?\UNC\W:\Windows 指定したリモート パスが無効であったため、エラー 123 で FALSE になります。 W$ 共有が存在しないか、ユーザー アクセスが許可されていません。
C:\COM2(存在する場合) \\.\COM2\
C:\COM3(存在しない) 存在しない COM デバイスが指定されたため、エラー 123 で FALSE になります。
次の一連の例では、パスに無効な末尾のパス要素が含まれています。
指定したパス 関数が返す値
G:\invalid(無効なパス) G:\
\\.\I:\aaa\invalid(無効なパス) \\.\I:\
\\YourComputer\C$\invalid(無効な末尾のパス要素) \\YourComputer\C$\
出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)

各言語での呼び出し定義

// KERNEL32.dll  (ANSI / -A)
#include <windows.h>

BOOL GetVolumePathNameA(
    LPCSTR lpszFileName,
    LPSTR lpszVolumePathName,
    DWORD cchBufferLength
);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern bool GetVolumePathNameA(
    [MarshalAs(UnmanagedType.LPStr)] string lpszFileName,   // LPCSTR
    [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpszVolumePathName,   // LPSTR out
    uint cchBufferLength   // DWORD
);
<DllImport("KERNEL32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)>
Public Shared Function GetVolumePathNameA(
    <MarshalAs(UnmanagedType.LPStr)> lpszFileName As String,   ' LPCSTR
    <MarshalAs(UnmanagedType.LPStr)> lpszVolumePathName As System.Text.StringBuilder,   ' LPSTR out
    cchBufferLength As UInteger   ' DWORD
) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
' lpszFileName : LPCSTR
' lpszVolumePathName : LPSTR out
' cchBufferLength : DWORD
Declare PtrSafe Function GetVolumePathNameA Lib "kernel32" ( _
    ByVal lpszFileName As String, _
    ByVal lpszVolumePathName As String, _
    ByVal cchBufferLength As Long) As Long
' VBA7前提(PtrSafe)。32bit Office では LongPtr→Long。Integer=16bit / Long=32bit / LongLong=64bit。
import ctypes
from ctypes import wintypes

GetVolumePathNameA = ctypes.windll.kernel32.GetVolumePathNameA
GetVolumePathNameA.restype = wintypes.BOOL
GetVolumePathNameA.argtypes = [
    wintypes.LPCSTR,  # lpszFileName : LPCSTR
    wintypes.LPSTR,  # lpszVolumePathName : LPSTR out
    wintypes.DWORD,  # cchBufferLength : DWORD
]
# GetLastError: use ctypes.GetLastError() (or ctypes.WinDLL(use_last_error=True))
require 'fiddle'
require 'fiddle/import'

lib = Fiddle.dlopen('KERNEL32.dll')
GetVolumePathNameA = Fiddle::Function.new(
  lib['GetVolumePathNameA'],
  [
    Fiddle::TYPE_VOIDP,  # lpszFileName : LPCSTR
    Fiddle::TYPE_VOIDP,  # lpszVolumePathName : LPSTR out
    -Fiddle::TYPE_INT,  # cchBufferLength : DWORD
  ],
  Fiddle::TYPE_INT)
#[link(name = "kernel32")]
extern "system" {
    fn GetVolumePathNameA(
        lpszFileName: *const u8,  // LPCSTR
        lpszVolumePathName: *mut u8,  // LPSTR out
        cchBufferLength: u32  // DWORD
    ) -> i32;
}
// crates: windows-sys provides ready-made bindings for this API.
$sig = @"
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("KERNEL32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern bool GetVolumePathNameA([MarshalAs(UnmanagedType.LPStr)] string lpszFileName, [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder lpszVolumePathName, uint cchBufferLength);
"@
$api = Add-Type -MemberDefinition $sig -Name 'KERNEL32_GetVolumePathNameA' -Namespace Win32 -PassThru
# $api::GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
#uselib "KERNEL32.dll"
#func global GetVolumePathNameA "GetVolumePathNameA" sptr, sptr, sptr
; GetVolumePathNameA lpszFileName, varptr(lpszVolumePathName), cchBufferLength   ; 戻り値は stat
; lpszFileName : LPCSTR -> "sptr"
; lpszVolumePathName : LPSTR out -> "sptr"
; cchBufferLength : DWORD -> "sptr"
; ※HSP3.7は #func のため戻り値はシステム変数 stat に格納されます。
出力引数:
#uselib "KERNEL32.dll"
#cfunc global GetVolumePathNameA "GetVolumePathNameA" str, var, int
; res = GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
; lpszFileName : LPCSTR -> "str"
; lpszVolumePathName : LPSTR out -> "var"
; cchBufferLength : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
出力引数:
; BOOL GetVolumePathNameA(LPCSTR lpszFileName, LPSTR lpszVolumePathName, DWORD cchBufferLength)
#uselib "KERNEL32.dll"
#cfunc global GetVolumePathNameA "GetVolumePathNameA" str, var, int
; res = GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
; lpszFileName : LPCSTR -> "str"
; lpszVolumePathName : LPSTR out -> "var"
; cchBufferLength : DWORD -> "int"
; ※出力/バッファ引数は var 方式(変数を直接渡す)。varptr 方式にも切替可。
import (
	"golang.org/x/sys/windows"
	"unsafe"
)

var (
	kernel32 = windows.NewLazySystemDLL("KERNEL32.dll")
	procGetVolumePathNameA = kernel32.NewProc("GetVolumePathNameA")
)

// lpszFileName (LPCSTR), lpszVolumePathName (LPSTR out), cchBufferLength (DWORD)
r1, _, err := procGetVolumePathNameA.Call(
	uintptr(unsafe.Pointer(windows.BytePtrFromString(lpszFileName))),
	uintptr(lpszVolumePathName),
	uintptr(cchBufferLength),
)
_ = err  // syscall.Errno (valid when the call sets last-error)
_ = r1   // BOOL
function GetVolumePathNameA(
  lpszFileName: PAnsiChar;   // LPCSTR
  lpszVolumePathName: PAnsiChar;   // LPSTR out
  cchBufferLength: DWORD   // DWORD
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'GetVolumePathNameA';
result := DllCall("KERNEL32\GetVolumePathNameA"
    , "AStr", lpszFileName   ; LPCSTR
    , "Ptr", lpszVolumePathName   ; LPSTR out
    , "UInt", cchBufferLength   ; DWORD
    , "Int")   ; return: BOOL
●GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength) = DLL("KERNEL32.dll", "bool GetVolumePathNameA(char*, char*, dword)")
# 呼び出し: GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
# lpszFileName : LPCSTR -> "char*"
# lpszVolumePathName : LPSTR out -> "char*"
# cchBufferLength : DWORD -> "dword"
# なでしこ1は32bit・ANSI(Shift_JIS)。文字列=char*(ANSI)、ポインタ/ハンドル=void*(4byte)。
const std = @import("std");

extern "kernel32" fn GetVolumePathNameA(
    lpszFileName: [*c]const u8, // LPCSTR
    lpszVolumePathName: [*c]u8, // LPSTR out
    cchBufferLength: u32 // DWORD
) callconv(std.os.windows.WINAPI) i32;
proc GetVolumePathNameA(
    lpszFileName: cstring,  # LPCSTR
    lpszVolumePathName: ptr char,  # LPSTR out
    cchBufferLength: uint32  # DWORD
): int32 {.importc: "GetVolumePathNameA", stdcall, dynlib: "KERNEL32.dll".}
pragma(lib, "kernel32");
extern(Windows)
int GetVolumePathNameA(
    const(char)* lpszFileName,   // LPCSTR
    char* lpszVolumePathName,   // LPSTR out
    uint cchBufferLength   // DWORD
);
ccall((:GetVolumePathNameA, "KERNEL32.dll"), stdcall, Int32,
      (Cstring, Ptr{UInt8}, UInt32),
      lpszFileName, lpszVolumePathName, cchBufferLength)
# lpszFileName : LPCSTR -> Cstring
# lpszVolumePathName : LPSTR out -> Ptr{UInt8}
# cchBufferLength : DWORD -> UInt32
# stdcall は 32bit のみ意味を持つ(x64 では無視)。
local ffi = require("ffi")
ffi.cdef[[
int32_t GetVolumePathNameA(
    const char* lpszFileName,
    char* lpszVolumePathName,
    uint32_t cchBufferLength);
]]
local kernel32 = ffi.load("kernel32")
-- kernel32.GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
-- lpszFileName : LPCSTR
-- lpszVolumePathName : LPSTR out
-- cchBufferLength : DWORD
-- 構造体/GUIDへのポインタは cdef が通るよう void* で表記(実型は各引数コメント参照)。値渡し構造体・enum は対応する typedef を cdef に追加すること。
const koffi = require('koffi');
const lib = koffi.load('KERNEL32.dll');
const GetVolumePathNameA = lib.func('__stdcall', 'GetVolumePathNameA', 'int32_t', ['str', 'char *', 'uint32_t']);
// GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
// lpszFileName : LPCSTR -> 'str'
// lpszVolumePathName : LPSTR out -> 'char *'
// cchBufferLength : DWORD -> 'uint32_t'
// 出力ポインタは koffi.out(...) で包む。構造体は koffi.struct で定義。
const lib = Deno.dlopen("KERNEL32.dll", {
  GetVolumePathNameA: { parameters: ["buffer", "buffer", "u32"], result: "i32" },
});
// lib.symbols.GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength)
// lpszFileName : LPCSTR -> "buffer"
// lpszVolumePathName : LPSTR out -> "buffer"
// cchBufferLength : DWORD -> "u32"
// 文字列は "buffer"。ANSI(-A) は new TextEncoder() で UTF-8/ANSI バイト列(末尾に \x00)を渡す。
// 値渡し構造体は { struct: [ ...field types... ] } を使用。
<?php
$ffi = FFI::cdef(<<<C
int32_t GetVolumePathNameA(
    const char* lpszFileName,
    char* lpszVolumePathName,
    uint32_t cchBufferLength);
C, "KERNEL32.dll");
// $ffi->GetVolumePathNameA(lpszFileName, lpszVolumePathName, cchBufferLength);
// lpszFileName : LPCSTR
// lpszVolumePathName : LPSTR out
// cchBufferLength : DWORD
// 構造体/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);
    boolean GetVolumePathNameA(
        String lpszFileName,   // LPCSTR
        byte[] lpszVolumePathName,   // LPSTR out
        int cchBufferLength   // DWORD
    );
}
@[Link("kernel32")]
lib LibKERNEL32
  fun GetVolumePathNameA = GetVolumePathNameA(
    lpszFileName : UInt8*,   # LPCSTR
    lpszVolumePathName : UInt8*,   # LPSTR out
    cchBufferLength : UInt32   # DWORD
  ) : Int32
end
# 構造体/GUID/enum は lib 内に対応する型定義が必要。
# 呼出規約: x64 は規約統一のため OK。x86(32bit)は WINAPI=stdcall だが Crystal の fun に stdcall 付与構文がなく非対応。
import 'dart:ffi';
import 'package:ffi/ffi.dart';

typedef GetVolumePathNameANative = Int32 Function(Pointer<Utf8>, Pointer<Utf8>, Uint32);
typedef GetVolumePathNameADart = int Function(Pointer<Utf8>, Pointer<Utf8>, int);
final GetVolumePathNameA = DynamicLibrary.open('KERNEL32.dll')
    .lookupFunction<GetVolumePathNameANative, GetVolumePathNameADart>('GetVolumePathNameA');
// lpszFileName : LPCSTR -> Pointer<Utf8>
// lpszVolumePathName : LPSTR out -> Pointer<Utf8>
// cchBufferLength : DWORD -> Uint32
// 文字列は package:ffi の "...".toNativeUtf16()/toNativeUtf8() で変換。
{$mode objfpc}{$H+}
function GetVolumePathNameA(
  lpszFileName: PAnsiChar;   // LPCSTR
  lpszVolumePathName: PAnsiChar;   // LPSTR out
  cchBufferLength: DWORD   // DWORD
): BOOL; stdcall;
  external 'KERNEL32.dll' name 'GetVolumePathNameA';
import Foreign
import Foreign.C.Types
import Foreign.C.String

foreign import stdcall safe "GetVolumePathNameA"
  c_GetVolumePathNameA :: CString -> CString -> Word32 -> IO CInt
-- lpszFileName : LPCSTR -> CString
-- lpszVolumePathName : LPSTR out -> CString
-- cchBufferLength : DWORD -> Word32
-- 要 GHC(Windows)。stdcall は x64 では ccall として扱われる。ブロックする API は safe 呼び出し推奨。
open Ctypes
open Foreign

let getvolumepathnamea =
  foreign "GetVolumePathNameA"
    (string @-> string @-> uint32_t @-> returning int32_t)
(* lpszFileName : LPCSTR -> string *)
(* lpszVolumePathName : LPSTR out -> string *)
(* cchBufferLength : DWORD -> uint32_t *)
(* foreign は cdecl 前提。x64 Windows では WINAPI と一致。構造体は ctypes structure を定義のこと。 *)
(cffi:define-foreign-library kernel32 (t "KERNEL32.dll"))
(cffi:use-foreign-library kernel32)

(cffi:defcfun ("GetVolumePathNameA" get-volume-path-name-a :convention :stdcall) :int32
  (lpsz-file-name :string)   ; LPCSTR
  (lpsz-volume-path-name :pointer)   ; LPSTR out
  (cch-buffer-length :uint32))   ; DWORD
; isize/usize(INT_PTR/SIZE_T)は x64 前提で :int64/:uint64。x86 では :int32/:uint32。
use Win32::API;
my $GetVolumePathNameA = Win32::API::More->new('KERNEL32',
    'BOOL GetVolumePathNameA(LPCSTR lpszFileName, LPSTR lpszVolumePathName, DWORD cchBufferLength)');
# my $ret = $GetVolumePathNameA->Call($lpszFileName, $lpszVolumePathName, $cchBufferLength);
# lpszFileName : LPCSTR -> LPCSTR
# lpszVolumePathName : LPSTR out -> LPSTR
# cchBufferLength : DWORD -> DWORD
# 値渡し構造体は pack() した文字列、または Win32::API::Struct を使用。

関連項目

文字セット違い
公式の関連項目