PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER
コールバックシグネチャ
DWORD PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER(
HCLUSTER hCluster,
HRESOURCE hResource,
LPWSTR pszDriveLetter,
DWORD* pcchDriveLetter
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| hCluster | HCLUSTER | クラスターのハンドルです。 |
| hResource | HRESOURCE | 依存関係を照会する対象のリソースのハンドルです。 |
| pszDriveLetter | LPWSTR | ドライブ文字を格納するバッファーです。 |
| pcchDriveLetter | DWORD* | 入力時には、pszDriveLetter バッファーのサイズを WCHAR 単位の数で指定します。出力時には、終端の NULL を含む結果データのサイズを WCHAR 単位の数で返します。 |
公式ドキュメント
リソース の Physical Disk 依存関係 に関連付けられたドライブ文字を取得します。PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER 型は、この関数へのポインターを定義します。
戻り値
処理が成功した場合、この関数は ERROR_SUCCESS (0) を返します。
処理が失敗した場合、この関数は システム エラー コード を返します。返される可能性のあるエラー コードは次のとおりです。
| 戻り値 | 説明 |
|---|---|
| 指定されたリソースの依存関係の一覧に Physical Disk 依存関係が見つかりませんでした。 | |
| ドライブ文字を返せませんでした。 | |
| 渡されたバッファーが小さすぎます。必要なサイズは pcchDriveLetter パラメーターに 格納されます。 |
解説(Remarks)
この関数を リソース DLL から呼び出さないでください。デッドロックの 原因になります。リソース拡張機能からこの関数を呼び出し、その結果をプライベート プロパティとして 書き出して、リソース DLL がそれを読み取るようにしてください。
hResource で識別されるリソースが複数の Physical Disk リソースに依存している場合、 ResUtilFindDependentDiskResourceDriveLetter は そのリソースについて最初に列挙された Physical Disk 依存関係のドライブ文字を返します。
例
次の例は、リソース名をコマンド ライン引数として受け取り、そのリソースの Physical Disk 依存関係に 関連付けられたドライブ文字を (存在する場合に) 表示します。この例では、フェールオーバー クラスターの ドキュメントで定義されている ClusDocEx.h ヘッダー ファイルを使用します。
//////////////////////////////////////////////////////////////////////
#include "ClusDocEx.h"
int main( int argc, char argv[] )
{
HCLUSTER hCluster = NULL;
HRESOURCE hRes = NULL;
DWORD dw;
DWORD cchResDrive = ClusDocEx_DEFAULT_CCH;
DWORD cchResName = ClusDocEx_DEFAULT_CCH;
WCHAR *pszResDrive = new WCHAR[cchResDrive];
WCHAR *pszResName = new WCHAR[cchResName];
dw = ClusDocEx_ConvertArg( argv[1], pszResName, cchResName );
if( dw == ERROR_SUCCESS )
{
hCluster = ClusDocEx_OpenLocalClusterWithName();
if( hCluster != NULL )
{
hRes = OpenClusterResource( hCluster, pszResName );
if( hRes != NULL )
{
dw = ResUtilFindDependentDiskResourceDriveLetter( hCluster,
hRes,
pszResDrive,
&cchResDrive );
if( dw == ERROR_MORE_DATA )
{
delete [] pszResDrive;
pszResDrive = new WCHAR[cchResDrive];
dw = ResUtilFindDependentDiskResourceDriveLetter( hCluster,
hRes,
pszResDrive,
&cchResDrive );
}
switch( dw )
{
case ERROR_SUCCESS:
wprintf( L"%ls depends on drive %ls.\n", pszResName, pszResDrive );
break;
case ERROR_NO_MORE_ITEMS:
case ERROR_RESOURCE_NOT_PRESENT:
wprintf( L"No Physical Disk dependency found for %ls.\n", pszResName );
break;
default:
ClusDocEx_DebugPrint( L"Could not obtain drive information", dw );
break;
}
CloseClusterResource( hRes );
}
else // if hRes == NULL
{
ClusDocEx_DebugPrint( L"Could not open a resource handle", GetLastError() );
}
CloseCluster( hCluster );
}
else // if hCluster == NULL
{
ClusDocEx_DebugPrint( L"Could not open a cluster handle", GetLastError() );
}
}
delete [] pszResName;
delete [] pszResDrive;
return 0;
}
hResource で識別されるリソースがマウント ポイント ディスクを参照している場合、その ディスク リソースにドライブ文字が関連付けられているとは限りません。マウント ポイント ディスクに 関連付けられたドライブ文字が無い場合、 ResUtilFindDependentDiskResourceDriveLetter が返す値は DiskXPartitionY という形式になります。これは有効なデータですが、CreateFile などの ファイル システム API に直接渡すことはできません。
次の例は、 ResUtilFindDependentDiskResourceDriveLetter の出力文字列を受け取り、Win32 形式に 変換します。この関数の出力文字列は CreateFile に渡せます。関数が失敗した場合、戻り値は NULL です。拡張エラー情報を取得するには GetLastError を 呼び出してください。関数が成功した場合、返されたバッファーは LocalFree を使用して呼び出し側が解放する必要があります。
#define UNICODE 1
#define _UNICODE 1
#pragma comment(lib, "ResUtils.lib")
#include <windows.h>
#include <stdlib.h>
#include <ResApi.h>
#include <strsafe.h>
#define IS_DRIVELETTER(x) ((iswalpha((x)[0])) && ((x)[1] == L':'))
#define IS_NTPATH(x) ((wcsstr((x), L"Disk") != NULL) && (wcsstr((x), L"Partition") != NULL))
#define GLOBALROOT_DISK_FORMAT L"\\\\\?\\GLOBALROOT\\Device\\Harddisk%u\\Partition%u"
LPWSTR ConvertNtDiskPathToW32DiskPath( LPCWSTR InputString )
{
LPWSTR outputString=NULL;
DWORD status=ERROR_INVALID_PARAMETER;
DWORD len;
DWORD diskNum, partNum;
if ((InputString == NULL) || (InputString[0] == 0))
{
goto Error_exit;
}
// Find out the required buffer size.
len = 0;
if (IS_DRIVELETTER(InputString))
{
len = wcslen(InputString) + 4;
}
else if (IS_NTPATH(InputString))
{
len = wcslen(GLOBALROOT_DISK_FORMAT) + 16;
}
else
{
//Malformed string.
goto Error_exit;
}
if ((outputString = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR))) == NULL)
{
status = GetLastError();
goto Error_exit;
}
if (IS_DRIVELETTER(InputString))
{
StringCchCopyW(outputString, len, InputString);
}
else
{
//Has to be NT path format.
swscanf_s(InputString, L"Disk%uPartition%u", &diskNum, &partNum);
StringCchPrintfW(outputString, len, GLOBALROOT_DISK_FORMAT, diskNum, partNum);
}
status = ERROR_SUCCESS;
Error_exit:
if (status != ERROR_SUCCESS)
{
if (outputString)
{
LocalFree(outputString);
}
SetLastError(status);
return NULL;
}
return outputString;
}
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)