元派遣プログラマの自称技術系ブログです。雑記とか自作のオープンソースプロジェクトの話とか。
Javaとか組込とかできます。お仕事ください。

C#でPCに接続したPSPを見つける方法

いわゆる技術情報。
PSPControllerに使ってます。
PsperController-0.1.0 - nyatla@Hatena::Diary



WMIを使って特定のモデル名に一致したドライブを検索→論理デバイスから、ドライブレターを取る方法です。
PSP等のUSBドライブになれる機材の接続状況を調べたり、書き込んだりするときに大変役に立ちます。

ソースコード

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Windows.Forms;

namespace PSPController
{
    //http://msdn.microsoft.com/en-us/library/aa394173%28v=VS.85%29.aspx
    public class PspDriveInterface
    {
        const string PSP_MODEL_NAME = "SONY \"PSP\" MS USB Device";
        public enum RESULT
        {
            ERROR_NO_DEVICE,
            ERROR_MANY_DEVICE,
            ERROR_NO_PARTITION,
            ERROR_NO_DRIVE,
            OK
        }
        public string getErrorMessage(RESULT r)
        {
            switch (r)
            {
            case RESULT.ERROR_NO_DEVICE:
                return "PSPが接続されていません。";
            case RESULT.ERROR_MANY_DEVICE:
                return "複数台のPSPが接続されています。";
            case RESULT.ERROR_NO_PARTITION:
                return "PSPのファイルシステムが見つかりません。";
            case RESULT.ERROR_NO_DRIVE:
                return "PSPのドライブが見つかりません。";
            case RESULT.OK:
                return "成功。";
            }
            return "不明なエラー";
        }
        /*  ディスクのモデル名から、ドライブ文字列を返す。
         */
        private static RESULT getLogicalDriveIdByModelName(string model_name, ref string o_drive,ref string o_disk_pnpid)
        {
            using (ManagementObjectSearcher se = new ManagementObjectSearcher())
            {
                se.Scope.Path.Path = "\\root\\cimv2";
                se.Query.QueryString = "SELECT * FROM Win32_DiskDrive WHERE Model='" + model_name + "'";
                string devid = null;
                using (ManagementObjectCollection co = se.Get())
                {
                    if (co.Count > 1)
                    {
                        return RESULT.ERROR_MANY_DEVICE;
                    }
                    foreach (ManagementObject item in co)
                    {
                        devid = item["DeviceID"].ToString();
                        o_disk_pnpid=item["PNPDeviceID"].ToString();

                        item.Dispose();
                        break;
                    }
                    if (devid == null)
                    {
                        return RESULT.ERROR_NO_DEVICE;
                    }
                }
                //パーティションを得る(1個目)
                se.Query.QueryString = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + devid + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition";
                string pid = null;
                using (ManagementObjectCollection co = se.Get())
                {
                    foreach (ManagementObject item in co)
                    {
                        pid = item["DeviceID"].ToString();
                        item.Dispose();
                        break;
                    }
                    if (pid == null)
                    {
                        return RESULT.ERROR_NO_PARTITION;
                    }
                }
                //パーティション→論理ドライブ変換
                se.Query.QueryString = "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" + pid + "'} WHERE AssocClass = Win32_LogicalDiskToPartition";
                string drive = null;
                using (ManagementObjectCollection co = se.Get())
                {
                    foreach (ManagementObject item in co)
                    {
                        item.Dispose();
                        drive = item["DeviceID"].ToString();
                        break;
                    }
                    if (drive == null)
                    {
                        return RESULT.ERROR_NO_DRIVE;
                    }
                }
                o_drive = drive;
                return RESULT.OK;
            }
        }
        public PspDriveInterface()
        {
            this._is_connected = false;
        }
        private bool _is_connected;
        private string _drive;
        private string _pnp_device_id;
        public bool connectPspDrive(out RESULT o_error)
        {
            string s = "";
            string did = "";
            o_error = getLogicalDriveIdByModelName(PSP_MODEL_NAME, ref s,ref did);
            if (o_error != RESULT.OK)
            {
                return false;
            }
            this._drive = s;
            this._pnp_device_id = did;
            this._is_connected = true;
            return true;
        }
        public bool isConnected()
        {
            return this._is_connected;
        }
        public string getPnPId()
        {
            return this._pnp_device_id;
        }
        public string getCommonFilePath()
        {
            return this._drive + "\\PSP\\COMMON";
        }
        public string getBrowserBookmarkFileName()
        {
            return this._drive + "\\PSP\\SYSTEM\\BROWSER\\bookmarks.html";
        }
    }
}