SDカードのライトプロテクトスイッチをONにしてマウントされたディスク、ボリュームはそのボリューム全体が読み込み専用(READONLY)になります。この情報は、WindowsではWin32 APIのGetVolumeInformation
APIを使用して取得することができます。
GetVolumeInformationA - Windows App Development
具体的には、APIを実行し、成功すると出力用のパラメータに指定したlpFileSystemFlags
のDWORD
値にFILE_READ_ONLY_VOLUME
フラグが立ちます。ライトプロテクトスイッチのON/OFFによって結果的にそのドライブが書き込み禁止(読み込み専用)になったかどうかを判定するのは、この方法を利用するのも簡便です。
以下はC言語での簡単なサンプルプログラムです。SDカードを挿入し、そのドライブを「D:\」や「J:\」などとコマンドライン引数に指定して実行すると、当該フラグのON/OFFを判定して端末へ出力します。
C
1#include <stdio.h>
2#include <Windows.h>
3
4int main(int argc, char *argv[])
5{
6 CHAR rootPathName[256] = "J:\\";
7 CHAR volumeNameBuffer[256];
8 DWORD volumeSerialNumber;
9 DWORD maximumComponentLength;
10 DWORD fileSystemFlags;
11 CHAR fileSystemNameBuffer[256];
12 if (argc > 1) {
13 lstrcpyA(rootPathName, argv[1]);
14 }
15
16 printf("rootPathName=%s\n", rootPathName);
17 BOOL succeeded = GetVolumeInformationA(rootPathName,
18 volumeNameBuffer, _countof(volumeNameBuffer),
19 &volumeSerialNumber, &maximumComponentLength,
20 &fileSystemFlags,
21 fileSystemNameBuffer, _countof(fileSystemNameBuffer));
22 if (succeeded) {
23 printf("fileSystemFlags=0x%X\n", fileSystemFlags);
24 if ((fileSystemFlags & FILE_READ_ONLY_VOLUME) != 0) {
25 printf("Volume is readonly.\n");
26 }
27 }
28 else {
29 printf("Failed. GetLastError=%X\n\n", GetLastError());
30 }
31
32 return 0;
33}
VisualStudio 2022で作成し、Windows 10上で確認しています。
例えば SDカードのライトプロテクトスイッチをONにしてJ:ドライブとして使う場合、以下の様な出力を得ます。
PowerShell
1PS C:\projects\ConApp1\x64\Debug> .\ConApp1.exe J:\
2rootPathName=J:\
3fileSystemFlags=0xA0206
4Volume is readonly.
5PS C:\projects\ConApp1\x64\Debug>
ライトプロテクトスイッチをOFFにした場合FILE_READ_ONLY_VOLUME
フラグが立たないので、以下のような出力になります。
PowerShell
1PS C:\projects\ConApp1\x64\Debug> .\ConApp1.exe J:\
2rootPathName=J:\
3fileSystemFlags=0x20206
4PS C:\projects\ConApp1\x64\Debug>
質問者さんはプログラミング言語としてC#をお使いと言うことなので、上記のコードは当然のことながらそのままでは使えません。.NETで同等の機能が使えるクラス、メソッドがあれば良いのですが、System.IO.DriveInfoなどでは情報が少なくて残念ながら利用できないようです。GetVolumeInformation
APIをC#で使うのであれば、P/Invoke(Platform Invoke)を利用して間接的に使うような形になるかと思います。本回答では詳述を避けますが、「C# GetVolumeInformation」などとキーワード指定して検索してみてください。最悪、C言語(あるいはC++)の別のプロジェクトで別の実行ファイルを作成し、その実行、出力結果をもって判定に利用することもできると思います。
あともうひとつ、WMIのWin32_Volume
クラスを使うことでボリュームの情報を得ることができます。当該クラスのAccess
プロパティが利用できると思いますが、私の方では動作確認をしていませんので、C#での利用の詳述を含めて、別途あたってください。
Win32_Volume - Microsoft