IBM iのオブジェクトを直接読取るなんて考えたことは
あるだろうか?
一体そんなことができるのだろうか?
最近になってオブジェクトの読取りに成功したので
その方法を紹介する。
オブジェクトをダンプ・リストではなく直接読むことが
できるとかなり深い解析に役に立つ。
先に「ボインタでプログラムを呼び出す」でプログラム・オブジェクトの
システム・ポインタを取得する方法を紹介したので
今回はいよいよそのオブジェクトの読取りである。
[オブジェクトを読取るTESTMIOBJ ]
ソースはこちらから
0001.00 #include0002.00 #include 0003.00 #include 0004.00 #include /* triml */ 0005.00 #include 0006.00 #include 0007.00 #include 0008.00 #include 0009.00 #include 0010.00 #include 0011.00 #include 0012.00 #include 0013.00 #include 0014.00 #include 0015.00 0016.00 #define TRUE 0 0017.00 #define FALSE -1 0018.00 typedef struct { 0019.00 int BYTESPRO; 0020.00 int BYTESAVL; 0021.00 char MSGID[7]; 0022.00 char RESRVD; 0023.00 char EXCPDATA[100]; 0024.00 } ERRSTRUCTURE; /* Define the error return structure */ 0025.00 ERRSTRUCTURE errcode;/* Error Code Structure for RCVMSG */ 0026.00 typedef struct { 0027.00 char OBJ[10]; 0028.00 char OBJLIB[10]; 0029.00 char OBJTYPE[10]; 0030.00 } OBJECT; 0031.00 OBJECT m_object; 0032.00 char m_OBJTYP[2]; 0033.00 0034.00 void main(void){ 0035.00 char OBJ[11], OBJLIB[11]; 0036.00 _SYSPTR ptr_object; 0037.00 _SPCPTR objptr; 0038.00 _MPTR_Template_T opt; 0039.00 unsigned char* buff; 0040.00 int i; 0041.00 _SPC_Template_T spc_template; 0042.00 0043.00 printf("*** TESTMIOBJ: OBJ 検索 MI テスト ***n"); 0044.00 getchar(); 0045.00 errcode.BYTESPRO = 160; 0046.00 errcode.BYTESAVL = 0; 0047.00 memcpy(m_object.OBJ, "QGSPDSPQ ", 10); 0048.00 memcpy(m_object.OBJLIB, "QSYS ", 10); 0049.00 memcpy(m_object.OBJTYPE, "*PNLGRP " , 10); 0050.00 printf("[%d] OBJ=[%s]n", __LINE__, m_object.OBJ); 0051.00 getchar(); 0052.00 QLICVTTP("*SYMTOHEX ", "*PNLGRP ", m_OBJTYP, &errcode); 0053.00 if(errcode.BYTESAVL != 0){/*APIERR*/ 0054.00 printf("[%d] APIERR MSGID=[%s]n", __LINE__, errcode.MSGID); 0055.00 getchar(); 0056.00 exit(-1); 0057.00 }/*APIERR*/ 0058.00 printf("[%d] m_OBJTYP = 0x%02x%02xn", __LINE__, m_OBJTYP[0], m_OBJTYP[1]); 0059.00 getchar(); 0060.00 0061.00 memcpy(OBJ, m_object.OBJ, 10); 0062.00 OBJ[10] = 0x00; 0063.00 memcpy(OBJLIB, m_object.OBJLIB, 10); 0064.00 OBJLIB[10] = 0x00; 0065.00 ptr_object = rslvsp(WLI_PNLGRP, OBJ, OBJLIB, _AUTH_RETRIEVE); /* オブジェクトの開始 */ 0066.00 if(ptr_object == NULL){/* 失敗 */ 0067.00 printf("[%d] failed in RSLVSP.n", __LINE__); 0068.00 getchar(); 0069.00 exit(-1); 0070.00 }/* 失敗 */ 0071.00 printf("[%d] 名前解決が成功した。 n", __LINE__); 0072.00 getchar(); 0073.00 0074.00 spc_template.TmpSize = sizeof(spc_template); 0075.00 mats(&spc_template, ptr_object); /* スペース属性 */ 0076.00 objptr = setsppfp(ptr_object); /* スペース */ 0077.00 if(objptr == NULL){/* 失敗 */ 0078.00 printf("[%d] setsppfp オブジェクト・ポインタ取得に失敗 n", __LINE__); 0079.00 getchar(); 0080.00 exit(-1); 0081.00 }/* 失敗 */ 0082.00 printf("[%d] objptr オブジェクト・ポインタの取得に成功しました。 n",__LINE__); 0083.00 getchar(); 0084.00 printf("[%d] object size = %dn", __LINE__, spc_template.Size); 0085.00 getchar(); 0086.00 for(i = 0; i 0 && i % 16 == 15) printf("n"); 0090.00 }/*for-loop*/ 0091.00 printf("n"); 0092.00 getchar(); 0093.00 }
[コンパイル]
CRTBNDC OBJLIB/TESTMIOBJ SRCFILE(SRCLIB/QCSRC) AUT(*ALL)
[解説]
海外のサイトでもオブジェクトの読取りを試みている例が少しはあってプログラム(*PGM)の
読取りに成功している例もあるがここで紹介するのはパネル・グループ(*PNLGRP)のオブジェクトを
読取る例である。
しかも読者でテストできるように QSYS/QGSPDSPQ *PNLGRP というパネル・グルーブ・オブジェクトを
読取るようにした。
これは WRKOUTQコマンドのインターフェースを構成しているパネル・グループ(*PNLGRP)である。
簡単に説明すると
0065.00 ptr_object = rslvsp(WLI_PNLGRP, OBJ, OBJLIB, _AUTH_RETRIEVE); /* オブジェクトの開始 */
によってオブジェクトのシステム・ポインタ ptr_object を取得している。
次にこのオブジェクトの長さを調べるために
0074.00 spc_template.TmpSize = sizeof(spc_template); 0075.00 mats(&spc_template, ptr_object); /* スペース属性 */
によって属性を取得して spc_template.Size というバイト数としての長さを取得している。
さらに
0076.00 objptr = setsppfp(ptr_object); /* スペース */
によってオブジェクトのポインタに変換して後は
0086.00 for(i = 0; i0 && i % 16 == 15) printf("n"); 0090.00 }/*for-loop*/
によってオブジェクトそのものの内容を読み取って出力している。
結果は
*** TESTMIOBJ: OBJ 検索 MI テスト *** > [50] OBJ=[QGSPDSPQ QSYS *PNLGRP ] [58] m_OBJTYP = 0x1915 [71] 名前解決が成功した。 [82] objptr オブジェクト・ポインタの取得に成功しました [84] object size = 110592 > 00 00 01 00 00 00 18 f0 00 01 2e 10 00 01 52 10 00 01 aa 30 00 00 00 00 00 00 00 00 ff ff ff fd 00 00 0a d0 00 00 00 0b 03 40 40 40 0e 47 cb 44 88 0f 4b 4b 4b 40 40 40 40 0e 49 f4 44 bc 44 ae 0f 0e 43 a2 43 af 43 d7 0f 40 40 40 40 40 40 40 : :
という感じである。
ところでオブジェクトの読取りには次の2つの注意がある。
(1) システム保護レベル(QSECURITY) が 40以上の場合は *SYSTEM オブジェクトは読取れない。
DSPOBJD OBJ(QSYS/QGSPDSPQ) OBJTYPE(*PNLGRP) を実行すると
オブジェクト記述の表示-明細 ライブラリー 1 の 1 オブジェクト . . . . : QGSPDSPQ 属性 . . . . . . . . : ライブラリー . . . : QSYS 所有者 . . . . . . . : QSYS ライブラリー ASP 装置 . : *SYSBAS ライブラリー ASP グループ : *SYSBAS タイプ . . . . . . . : *PNLGRP 1 次グループ . . . . : *NONE ユーザー定義の情報 : 属性 . . . . . . . . . . . . . . . . : テキスト . . . . . . . . . . . . . . : 作成情報 : 作成日/時刻 . . . . . . . . . . . . : 08/04/01 00:21:17 作成ユーザー . . . . . . . . . . . . : *IBM 作成システム . . . . . . . . . . . . : 00000000 オブジェクト定義域 . . . . . . . . . : *SYSTEM 続く ... 続行するには,実行キーを押してください。 F3= 終了 F12= 取り消し
[解説]
注目して欲しいのはオブジェクト定義域が *SYSTEM と表示されていることである。
これは IBM が提供しているQSYSのオブジェクトであるからだけではない。
ユーザーがコンパイルした *PGM の場合は
オブジェクト定義域 : *USER
であるが
ユーザーが作成した *CMD や *PNLGRP はすべて
オブジェクト定義域 : *SYSTEM
となってしまう。(この理由は現在調査中である)
次に
システム保護レベル(QSECURITY) が 40以上の場合はオブジェクト定義域が *SYSTEM のオブジェクトは
保護違反となって読取ることができない。
従って例えばユーザーが作成したパネル・グループやコマンドのオブジェクトを読取ることが
できるのは QSECURITYが 30以下の場合だけである。
(2) 古いリリースで作成されたオブジェクトは読取れない。
弊社にあった V2R2M0のオブジェクトは読取りエラーになった。
かなり古いオブジェトクは読取れないようである。
– 以上の2点を注意すればオブジェクトを読取ることができる。
オブジェクトの読取りはIBM iのオブジェクト解析を進化させうまく行けば劇的な改革が可能となる。
オブジェクト解析はまだ始まったばかりであるが大きな一歩となったと信じたい。