Win32 API 日本語リファレンス
ホーム › Networking.Clustering › PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER

PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER

コールバック

シグネチャ

DWORD PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER(
    HCLUSTER hCluster,
    HRESOURCE hResource,
    LPWSTR pszDriveLetter,
    DWORD* pcchDriveLetter
);

パラメーター

フィールド型説明
hClusterHCLUSTERクラスターのハンドルです。
hResourceHRESOURCE依存関係を照会する対象のリソースのハンドルです。
pszDriveLetterLPWSTRドライブ文字を格納するバッファーです。
pcchDriveLetterDWORD*入力時には、pszDriveLetter バッファーのサイズを WCHAR 単位の数で指定します。出力時には、終端の NULL を含む結果データのサイズを WCHAR 単位の数で返します。

公式ドキュメント

リソース の Physical Disk 依存関係 に関連付けられたドライブ文字を取得します。PRESUTIL_FIND_DEPENDENT_DISK_RESOURCE_DRIVE_LETTER 型は、この関数へのポインターを定義します。

戻り値

処理が成功した場合、この関数は ERROR_SUCCESS (0) を返します。

処理が失敗した場合、この関数は システム エラー コード を返します。返される可能性のあるエラー コードは次のとおりです。

戻り値 説明
ERROR_NO_MORE_ITEMS
指定されたリソースの依存関係の一覧に Physical Disk 依存関係が見つかりませんでした。
ERROR_RESOURCE_NOT_PRESENT
ドライブ文字を返せませんでした。
ERROR_MORE_DATA
渡されたバッファーが小さすぎます。必要なサイズは 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 の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)