windows - 获取特定驱动器的 GUID

标签 windows delphi winapi

我想找出特定驱动器盘符的 Drive-GUID。 我有以下代码:

Function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: LPCTSTR; lpszVolumeName: LPTSTR; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPointW';

procedure TForm1.Button1Click(Sender: TObject);
var
  Buffer: array[0..50] of AnsiChar;
begin
  if GetVolumeNameForVolumeMountPoint('C:\', Buffer, SizeOf(Buffer)) then
  begin
    showmessage(buffer); // Expected: "\\?\Volume{deadbeef-895e-4a1d-9d64-9b82fa068d76}\"
  end
  else RaiseLastOSError; // Actual: ERROR_INVALID_NAME (123).
end;

我收到错误 ERROR_INVALID_NAME (123),但我不知道为什么。我做错了什么?

最佳答案

您正在调用该函数的 Unicode 版本,但传递的是 ANSI 文本。因此,您传递的第一个参数编码错误,因此出现错误消息。

这个程序演示了它应该如何完成:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function GetVolumeNameForVolumeMountPointA(lpszVolumeMountPoint: PAnsiChar;
  lpszVolumeName: PAnsiChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';

procedure Main;
var
  Buffer: array [0 .. 49] of AnsiChar;
begin
  Win32Check(GetVolumeNameForVolumeMountPointA('C:\', Buffer, Length(Buffer)));
  Writeln(Buffer);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

因为很明显您使用的是 Delphi 的 pre-Unicode 版本(否则您的程序将无法编译),我在上面给了您 ANSI 代码。如果您曾经升级到 Unicode 版本的 Delphi,那么您应该这样写:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

function GetVolumeNameForVolumeMountPointW(lpszVolumeMountPoint: PWideChar;
  lpszVolumeName: PWideChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';

procedure Main;
var
  Buffer: array [0 .. 49] of WideChar;
begin
  Win32Check(GetVolumeNameForVolumeMountPointW('C:\', Buffer, Length(Buffer)));
  Writeln(Buffer);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

或者如果您想要在所有版本的 Delphi 中工作的代码,您可以这样做:

{$APPTYPE CONSOLE}

uses
  SysUtils, Windows;

const
  Win32ImportSuffix = {$IFDEF Unicode}'W'{$ELSE}'A'{$ENDIF};

function GetVolumeNameForVolumeMountPointA(lpszVolumeMountPoint: PAnsiChar;
  lpszVolumeName: PAnsiChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';
function GetVolumeNameForVolumeMountPointW(lpszVolumeMountPoint: PWideChar;
  lpszVolumeName: PWideChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll';
function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: PChar;
  lpszVolumeName: PChar; cchBufferLength: DWORD): BOOL; stdcall;
  external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPoint' + Win32ImportSuffix;

procedure Main;
var
  Buffer: array [0 .. 49] of Char;
begin
  Win32Check(GetVolumeNameForVolumeMountPoint('C:\', Buffer, Length(Buffer)));
  Writeln(Buffer);
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

关于windows - 获取特定驱动器的 GUID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38121438/

相关文章:

c - Win32中如何设置线程栈的地址?

c++ - 在 COM 对象上调用 Release 似乎永远不会返回

c# - 检测文件是否被操作系统阻止

delphi - 如何检测在 A TTabControl 中单击了不同的选项卡?

windows - Win32 ASM 程序不向命令行打印任何内容

winapi - 如何在 CertCreate 自签名证书函数中指定 key 大小

windows - 在 token 分隔符批处理文件中使用百分号

c++ - 如何在 C++ 中构建与运行时版本无关的 DLL?

delphi - 通过 COM 访问静态属性

delphi - 删除临时目录