質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

2回答

1698閲覧

SDカードの書き込み禁止SWの状態取得方法が知りたい

OlivePopeye.net

総合スコア26

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2022/11/16 07:35

毎度活用させていただいております。
早速ですが、以下についてご教授をお願いしたいです。

実現したいこと

PCに接続したSDカードの書き込み禁止SWの状態を取得をしたいです。
現状、ファイル書き込みを実施して失敗するかでしか判断方法が思い浮かばず。。。
対象SDカードドライブが書き込み禁止状態なのかを知る方法があれば教えてほしいです。

開発環境

OS:Windows10
使用言語:C#

ネット検索では、それっぽい内容を見つけることが出来ず困っています。
申し訳ありませんが、協力をよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2022/11/16 11:01

> 現状、ファイル書き込みを実施して失敗するかでしか判断方法が思い浮かばず。。。 それではダメな理由がありますか? それは何ですか?
dodox86

2022/11/16 11:24

SDカードの書き込み禁止SWの状態、と言うよりは、そのON/OFFの結果としてSDカードを挿したときのドライブ(ボリューム)が書き込み禁止になっているかどうかが知りたいのですよね。SDカードのSWの状態とは、より正確にはSDカード側のハードウェア、ピンの状態になります。そのON/OFFとソフトウェアであるOSの連携で、書き込み禁止になります。
OlivePopeye.net

2022/11/16 11:36

質問コメントありがとうございます! ・・・説明不足で申し訳ありません。。 > epistemeさん   判断したいのは、SDカードの書き込み禁止SWが正しく機能しているのかを判断したいのです。   例えば、SDカードの故障によって書き込みができなくなったのか、書き込み禁止SWがON状態に   なっているのから書き込みができなくなったのかを切り分けられるか?となると、   単純な「書き込めない」と言う確認では不十分だと考えています。 > dodox86さん   はい。おっしゃる通り、「ドライブが書き込み禁止状態となっているかを判断したい」と   いうことを確認するすべがないか?を知りたいのです。   また、SDカードの書き込み禁止SWは、SDカード自体に作用はしていないのですね。   実際には、SDカードスロット側のメカニカルSWを、SDカードの書き込み禁止SW部分の   状態によってON/OFFされることによって、PC側が判断されるといったイメージです。   (SDカードが書き込み禁止SWがON状態になっていても、例えばテープを貼ったりすると    書き込めるようになったりします)
guest

回答2

0

ベストアンサー

SDカードのライトプロテクトスイッチをONにしてマウントされたディスク、ボリュームはそのボリューム全体が読み込み専用(READONLY)になります。この情報は、WindowsではWin32 APIのGetVolumeInformation APIを使用して取得することができます。

GetVolumeInformationA - Windows App Development

具体的には、APIを実行し、成功すると出力用のパラメータに指定したlpFileSystemFlagsDWORD値に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

投稿2022/11/17 02:25

dodox86

総合スコア9369

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2022/11/17 03:33

質問のコメント欄でいただいた返信でもちょっと判断つかなかった(「純粋に、ライトプロテクトスイッチのON/OFFの状態を取得したい」のか、「結果的にドライブが書き込み禁止になっているか否かが分かれば良い」)のもあって回答しました。SDカードやPC側のコントローラーチップと直接通信することは難易度は置いておいて技術的には可能かと思いますが、Windowsがデバイスドライバーで既に使用中で抱えているリソースでもあるはずなので、その辺りの考慮も必要になります。
OlivePopeye.net

2022/11/17 04:32

dodox86さん、回答ありがとうございます。 上記の「GetVolumeInformationA」を試して、判別可能なのか検討したいと思います。 >Windowsがデバイスドライバーで既に使用中で抱えているリソースでもあるはずなので、その辺りの考慮も必要になります。 直接デバイスへのアクセスは、おっしゃるとおりDriver側でリソースを握られていると思うので、出来ない気もしますね。 ★本質的にやりたいことは「書き込み禁止SWのON/OFF状態を確認」ですね。  質問のコメントでうまく伝えられず申し訳ないです。。
OlivePopeye.net

2022/12/29 04:04

長く間が空いてしまいました。 アドバイス頂いた方法でできそうでしたので、まずはこちらで評価をしていこうと思います。 協力ありがとうございました!
guest

0

回答の前提

C#はほんの少し触ったことがあるだけなので、実際にC#で出来るかまでは分かりませんので、
言語を問わず「もし自分がやるのであればこうするだろう」というアプローチを回答します。

回答

全部自力でやるなら、
SDカードとの通信プロトコルとコマンドを調べて
https://so-zou.jp/robot/tech/microcomputer/pic/example/sd-card/
windows SPI SDカードあたりをキーワードにして調べていく感じになるかと思います。
SDカードの規格と向き合う必要があるので割と大変ですが、まずは規格をざっと理解するというのは有用です。
pic sdカード 制御とかで検索すると、C言語でのSDカード制御の例がいくつも見つかるので、理解の助けになります。

その辺りの理解は置いておいて、とにかく実装したいということであれば、
diskpartattributes diskすればreadonlyかどうかが分かるので、
この辺りを参考にして、
https://learn.microsoft.com/ja-jp/windows-server/administration/windows-commands/diskpart-scripts-and-examples
ファイル経由なりリダイレクトなりして状態を取得して判断出来るようにしたものをプログラムから呼び出す
というのが手っ取り早いでしょう。

投稿2022/11/16 15:38

tanat

総合スコア18778

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YT0014

2022/11/16 23:57

この回答の主旨に賛同します。 APIやライブラリなどがあったとしても、内部処理まで調査して、書込みによるチェックでないことを確認する必要があるので、ドライバなどを介さない処理を作る方が確実だと思います。
OlivePopeye.net

2022/11/17 04:22

tanatさん、YT0014さん、回答ありがとうございます! SDカードの通信プロトコルは、、、、理解が難しそうですね。 ただ、パッと見た感じでは、書き込み禁止に関する部分がなさそうにみえました。。。 (SDカードを書き込み禁止状態に設定はあったので取得もあればよいですが、、、うまく理解は出来てない) ※WP信号ラインについてはSDカード端子上になく、SDカード内部も書き込み禁止SW部分と電気的にもつながってないですね。(SDカードスロット側にSWがついているので) http://blog1.bakw.sub.jp/?eid=664718 SDカードリーダー側でなにかないが探してみます。 diskpartで判断できるのかは確認してみます。 ただ、管理者権限が必要となる場合は、こちらで対応するアプリ都合で参考に出来ないかもしれません。。。。
tanat

2022/11/17 05:56

コマンドでそれっぽいのは CMD30 Yes [31:0] write protect data address R1 SEND_WRITE_ PROT If the card has write protection features, this command asks the card to send the status of the write protection bits. あたりですかね?
OlivePopeye.net

2022/11/17 09:58

tanatさん 確認ありがとうございます。 そうですね。「 this command asks the card to send the status」 というのが、状態取得要求と言う意味と捉えるのかが、うまく読み切れなくて迷ってました。 検討方法はよくわかってないですが、上記Linkみて考えてみます。 (といっても、PICのように直接SDカードではなく、実際にはSDカードリーダーデバイス経由になると思うので、どう実現できるのか検討つきませんけど。。。。)
dodox86

2022/11/21 02:41

@質問者 OlivePopeye.net さん > PICのように直接SDカードではなく、実際にはSDカードリーダーデバイス経由になると思うので、どう実現できるのか検討つきませんけど。。。。 正攻法でいくとWindowsのデバイスドライバーの実装技術が必要になるかと思います。 [SD Card Driver Stack] https://learn.microsoft.com/en-us/windows-hardware/drivers/sd/sd-card-driver-stack もし、SD Card Driver経由のアクセスがデバイスファイルで可能な場合、アプリからCreateFile、WriteFile, ReadFile, DeviceIoControlなどのWindows API経由でコマンドを送受できる場合があります。(私自身は試したことは無いので実際にできるかは存じません)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問