Palm Programmer's Laboratory
【C/C++】 「データ保護」の処理方法
[開発情報]
概要
Palm OS のデータベースに格納されるレコードには、プライベート属性が設定できます。標準のPIMアプリなどでは、デバイスのセキュリティ設定(表示・マスク・非表示のいずれか)によって プライベート設定された情報の表示方法を変えています。しかし、このセキュリティ設定はPIMデータだけのためのものではありません。このドキュメントでは、Palm OS API を使用してこのような制御を実現する方法を解説します。
説明
システムプリファレンスの取得
データ保護はデバイス単位で設定されるもので、アプリ単位ではありません。デバイスの現在の設定を取得するには、Palm OS API の PrefGetPreference を使用します。
privateRecordViewEnum level = (privateRecordViewEnum)PrefGetPreference( prefShowPrivateRecords );
privateDataShowEnum は以下の3種類の値をとる列挙値です。
typedef enum privateRecordViewEnum { showPrivateRecords = 0x00, /* 表示 */ maskPrivateRecords, /* マスク */ hidePrivateRecords /* 非表示 */ } privateRecordViewEnum;
データベースのオープン
通常、データベースをオープンする場合は以下のようにします。DmOpenDatabase API の最後のパラメータがオープンモードです。
DmOpenRef dbRef = DmOpenDatabase( cardNo, dbID, dmModeReadWrite );
しかし、このオープンモードではプライベートデータにはアクセスできません。プライベートデータにアクセスするには、dmModeShowPrivate も併せて指定する必要があります。先の privateDataShowEnum を使って以下のように書くことができます。
UInt16 openmode = dmModeReadWrite; if( level != hidePrivateRecords ) openmode |= dmModeShowPrivate; DmOpenRef dbRef = DmOpenDatabase( cardNo, dbID, openmode );
設定が「非表示」になっている場合はプライベートデータにアクセスする必要はありませんから、dmModeShowPrivate は指定する必要がありません。しかし、それ以外の場合はひとまず全てのレコードを取得する必要がありますから、もともとのオープンモードと dmModeShowPrivate の論理和を渡しているわけです。
テーブルにおけるマスク表示
さて、ここまでで設定が「非表示」以外の場合にプライベートレコードにアクセスできるようになりました。これをたとえばテーブルコントロールに表示する場合、設定が「マスク」であればマスク表示をしなければなりません。これは、Palm OS API の TblSetRowMasked 関数と TblSetColumnMasked 関数を使用します。
void TblSetColumnMasked( TableType* tableP, Int16 column, Boolean masked ); void TblSetRowMasked( TableType *tableP, Int16 row, Boolean masked );
TblSetColumnMasked 関数は指定された列をマスクし、TblSetRowMasked 関数は指定された行をマスクします。しかし、この2つの関数は単独では何の効果ももたらしません。この2つの関数でマスク指定された行と列が交わるセルだけがマスクされます。
TblSetColumnMasked 関数は、テーブルの初期化時に1度だけ呼出せばいいものですが、TblSetRowMasked 関数は行を再描画するたびに呼び出す必要があります。
セキュリティ設定の変更
標準PIMアプリでは、メニューから「データ保護」を選択することで設定画面を表示できます。これは、以下に示す SecSelectViewStatus という Palm OS API を実行するだけで実現できます。
privateRecordViewEnum SecSelectViewStatus( void );
この API 関数を呼び出すと、プライベートデータの表示設定を変更する画面が表示され、変更内容によってはパスワード認証が実行されます。設定を完了して画面が閉じられると、最終的に設定された内容が privateRecordViewEnum 列挙値で返却されます。
画面からではなく、プログラムから明示的に設定を変更する場合、以下に示す SecVerifyPW という Palm OS API を使用します。
Boolean SecVerifyPW( privateRecordViewEnum newSecLevel );
この関数を呼び出して新しい値を設定すると、セキュリティレベルが落ちる(非表示→マスク、あるいはマスク→表示のような)場合、自動的にパスワード認証が行われます。パスワード認証に成功すると、指定された値にセキュリティ設定が変更され、true が返されます。それ以外の場合(パスワード認証でキャンセルした場合など)には false が返されます。
上記2つの API でセキュリティレベルが「マスク」あるいは「非表示」に設定された場合、マスクされる、あるいは表示されないレコードがありうるという情報をユーザーに通知するための画面が表示されます。
マスクレコードのオープン
テーブル上でマスクされた行をタップするなどしてデータを表示する場合、パスワードによる認証が必要になります。しかし、Palm OS API には単独でパスワード認証を行う関数がありません。前述の SecVerifyPW を使って設定を「表示」に変更すればパスワード認証画面を表示させることができますが、認証後に設定を元に戻すために再度 SecVerifyPW を呼び出して maskPrivateRecords を設定すると、セキュリティに関する前述の通知画面が表示されてしまいます。これを避けるためには、設定を「マスク」に戻すのに SecVerifyPW を使用せず、PrefSetPreference を使用して直接設定を変更します。
/* 設定を「表示」に変更することでパスワード認証を実行 */ if( SecVerifyPW( showPrivateRecords ) == true ) { /* パスワード認証成功。設定を「マスク」に戻す必要あり */ PrefSetPreference( prefShowPrivateRecords, maskPrivateRecords ); } else { /* パスワード認証キャンセル。*/ }
参考情報
各 API 関数の詳細については Palm OS API Rreference を参照してください。また、SDK に付属する(と思われる)標準PIMアプリのサンプルソースコードも参考になります。