[PR]

水無瀬の部屋 > Programming > sample > exe2ico > install.cpp
最終更新日: 2007/03/29

   1: //*********************************************************
   2: // プロジェクト: exe2ico
   3: //   ファイル名: install.cpp
   4: //*********************************************************
   5: #include "install.h"
   6: #include "cmdline.h"
   7: #include <relation/relation.h>
   8: 
   9: 
  10: //---------------------------------------------------------
  11: // テスト関数 の 宣言
  12: //---------------------------------------------------------
  13: DECLARE_TESTPROC( test_install );
  14: 
  15: 
  16: //---------------------------------------------------------
  17: // マクロ定数 の 定義
  18: //---------------------------------------------------------
  19: // 登録
  20: #define APP_VERB           "exe2ico"  // 動詞 
  21: #define EXT_EXE            ".exe"    // 拡張子
  22: #define EXT_DLL            ".dll"    // 拡張子
  23: #define MENUTITLE_DEFAULT  "リソースを抜き出す" // メニュー名
  24: #define FLAG_DEFAULT       ( 0 )
  25: 
  26: 
  27: //---------------------------------------------------------
  28: // ファイルスコープ変数 の 定義
  29: //---------------------------------------------------------
  30: static const struct
  31: 	{
  32: 		      id_t   id;
  33: 		      DWORD  flag;
  34: 		const char  *ext;
  35: 	}
  36: g_pair[] = 
  37: 	{
  38: #define MAKE_TBL( name ) { ID_ ## name, FLAG_ ## name, EXT_ ## name }
  39: 		MAKE_TBL( EXE ),
  40: 		MAKE_TBL( DLL ),
  41: #undef MAKE_TBL
  42: 	};
  43: COMPILE_ASSERT( numof(g_pair) == numof( ((install_t *)null)->reg ) );
  44: 
  45: 
  46: //*********************************************************
  47: // IsValidInstallInfo
  48: //*********************************************************
  49: bool
  50: IsValidInstallInfo
  51: 	(
  52: 		const install_t *info
  53: 	)
  54: {
  55: 	CALLONCE_TESTPROC( test_install ); // [テスト]
  56: 
  57: 	// パラメタの仮定
  58: 	VALID_TEST( IsValidReadPtr( info, sizeof( *info ) ) );
  59: 	VALID_TEST( info->flags == (info->flags & ((1 << numof( info->reg )) - 1))  );
  60: 	
  61: 	{for( int i = 0; i < numof( info->reg ); ++i )
  62: 	{
  63: 		const size_t index = ID_INDEX( g_pair[ i ].id );
  64: 		ASSERT( IS_VALID_INDEX( index ) );
  65: 
  66: 		const relation_t *reg = &info->reg[ index ];
  67: 
  68: //		VALID_TEST( IsValidRegistryPathString( reg->regpath ) );
  69: 		VALID_TEST( IsValidCommandLineString( reg->cmdline ) );
  70: 		VALID_TEST( IsValidStringPtr( reg->menu ) );
  71: 
  72: 		VALID_TEST( strlen( reg->regpath ) < numof(reg->regpath) );
  73: 		VALID_TEST( strlen( reg->cmdline ) < numof(reg->cmdline) );
  74: 		VALID_TEST( strlen( reg->menu ) < numof(reg->menu) );
  75: 	}}
  76: 
  77: 	return true;
  78: }//IsValidInstallInfo
  79: 
  80: //*********************************************************
  81: // LoadInstallInfo
  82: //*********************************************************
  83: bool
  84: LoadInstallInfo
  85: 	(
  86: 		install_t *info
  87: 	)	
  88: {
  89: 	CALLONCE_TESTPROC( test_install ); // [テスト]
  90: 
  91: 	// パラメタの仮定
  92: 	ASSERT( IsValidPtr( info, sizeof( *info ) ) );
  93: 	DESTROY_BUFFER( info, sizeof( *info ) ); // [破壊]
  94: 
  95: 	//
  96: 	info->flags = 0;
  97: 	{for( int i = 0; i < numof( g_pair ); ++i )
  98: 	{
  99: 		const size_t index = ID_INDEX( g_pair[ i ].id );
 100: 		ASSERT( IS_VALID_INDEX( index ) );
 101: 
 102: 		relation_t *reg = &info->reg[ index ];
 103: 
 104: 		//
 105: 		reg->regpath[ 0 ] = '\0';
 106: 
 107: 		//
 108: 		if ( RegGetClassRelation( g_pair[ i ].ext, APP_VERB, reg->menu, numof( reg->menu ), reg->cmdline, numof( reg->cmdline ) ) )
 109: 		{
 110: 			info->flags |= g_pair[ i ].flag;
 111: 		}
 112: 		else
 113: 		{
 114: 			strcopy( reg->menu, numof( reg->menu ), MENUTITLE_DEFAULT );
 115: 			VERIFY( make_cmdline( reg->cmdline, numof( reg->cmdline ), FLAG_DEFAULT ) );
 116: 		}
 117: 
 118: //		ASSERT( IsValidRegistryPathString( reg->regpath ) );
 119: 		ASSERT( IsValidCommandLineString( reg->cmdline ) );
 120: 		ASSERT( IsValidStringPtr( reg->menu ) );
 121: 	}}
 122: 
 123: 	ASSERT( IsValidInstallInfo( info ) );
 124: 	return true;
 125: }//LoadInstallInfo
 126: 
 127: //*********************************************************
 128: // SaveInstallInfo
 129: //*********************************************************
 130: bool
 131: SaveInstallInfo
 132: 	(
 133: 		const install_t *info,
 134: 		      DWORD      mask  // 値を反映させる項目を示すフラグ
 135: 	)
 136: {
 137: 	CALLONCE_TESTPROC( test_install ); // [テスト]
 138: 
 139: 	// パラメタの仮定
 140: 	ASSERT( IsValidInstallInfo( info ) );
 141: 
 142: 	//
 143: 	{for( int i = 0; i < numof( g_pair ); ++i )
 144: 	{
 145: 		const size_t index = ID_INDEX( g_pair[ i ].id );
 146: 		ASSERT( IS_VALID_INDEX( index ) );
 147: 
 148: 		const relation_t *reg = &info->reg[ index ];
 149: //		ASSERT( IsValidRegistryPathString( reg->regpath ) );
 150: 		ASSERT( IsValidCommandLineString( reg->cmdline ) );
 151: 		ASSERT( IsValidStringPtr( reg->menu ) );
 152: 
 153: 		if ( g_pair[ i ].flag == (mask & g_pair[ i ].flag) )
 154: 		{
 155: 			if ( g_pair[ i ].flag == (info->flags & g_pair[ i ].flag) )
 156: 			{
 157: 				VERIFY( RegSetClassRelation( g_pair[ i ].ext, APP_VERB, reg->menu, reg->cmdline ) );
 158: 			}
 159: 			else
 160: 			{
 161: 				VERIFY( RegResetClassRelation( g_pair[ i ].ext, APP_VERB ) );
 162: 			}
 163: 		}
 164: 	}}
 165: 
 166: 	return true;
 167: }//SaveInstallInfo
 168: 
 169: //*********************************************************
 170: // GetModifiedFlags
 171: //*********************************************************
 172: DWORD
 173: GetModifiedFlags
 174: 	(
 175: 		const install_t *a,
 176: 		const install_t *b
 177: 	)
 178: {
 179: 	CALLONCE_TESTPROC( test_install ); // [テスト]
 180: 
 181: 	// パラメタの仮定
 182: 	ASSERT( IsValidInstallInfo( a ) );
 183: 	ASSERT( IsValidInstallInfo( b ) );
 184: 
 185: 	// 関連づけが変更されているか?
 186: 	DWORD modified = a->flags ^ b->flags;
 187: 
 188: 	//
 189: 	{for( int i = 0; i < numof( a->reg ); ++i )
 190: 	{
 191: 		// 設定の詳細が変更されているか?
 192: 		// ・設定 -> 設定 …… 詳細の比較が必要
 193: 		// ・設定 -> 削除 …… 不要 ( 削除 が確定済み )
 194: 		// ・削除 -> 設定 …… 不要 ( 設定 が確定済み )
 195: 		// ・削除 -> 削除 …… 不要 ( 無視 が確定済み ) 
 196: 		if ( g_pair[ i ].flag == (g_pair[ i ].flag & (a->flags & b->flags)) )
 197: 		{
 198: 			const size_t index = ID_INDEX( g_pair[ i ].id );
 199: 			ASSERT( IS_VALID_INDEX( index ) );
 200: 
 201: 			if ( ! streql( a->reg[ index ].cmdline, b->reg[ index ].cmdline ) )
 202: 			{
 203: 				modified |= g_pair[ i ].flag;
 204: 			}
 205: 
 206: 			if ( ! streql( a->reg[ index ].menu, b->reg[ index ].menu ) )
 207: 			{
 208: 				modified |= g_pair[ i ].flag;
 209: 			}
 210: 		}
 211: 	}}
 212: 
 213: 	return modified;
 214: }//GetModifiedFlags
 215: 
 216: 
 217: 
 218: //******************************************************************************************************************
 219: // TEST
 220: //******************************************************************************************************************
 221: 
 222: 
 223: #ifdef _DEBUG // デバッグ時のみ
 224: 
 225: 
 226: //*********************************************************
 227: // test_install
 228: //*********************************************************
 229: DEFINE_TESTPROC( test_install )
 230: {
 231: 	//---------------------------------------------------------
 232: 	// 定数 の テスト
 233: 	//---------------------------------------------------------
 234: 
 235: 	//
 236: 	{for( int i = 0; i < numof( g_pair ); ++i )
 237: 	{
 238: 		ASSERT( IS_VALID_ID( g_pair[ i ].id ) );
 239: 		ASSERT( IS_VALID_INDEX( ID_INDEX( g_pair[ i ].id ) ) );
 240: 	}}
 241: 
 242: 	//
 243: 	{for( int i = 0; i < numof( g_pair ) - 1; ++i )
 244: 	{
 245: 		{for( int j = i+1; j < numof( g_pair ); ++j )
 246: 		{
 247: 			ASSERT( i != j );
 248: 			ASSERT( g_pair[ i ].id != g_pair[ j ].id );
 249: 			ASSERT( 0 == (g_pair[ i ].flag & g_pair[ j ].flag) );
 250: 			ASSERT( ! streqli( g_pair[ i ].ext, g_pair[ j ].ext ) );
 251: 		}}
 252: 	}}
 253: 
 254: 
 255: 	//---------------------------------------------------------
 256: 	// ファイルスコープ関数 の テスト
 257: 	//---------------------------------------------------------
 258: 
 259: 	//---------------------------------------------------------
 260: 	// 公開関数 の テスト
 261: 	//---------------------------------------------------------
 262: 
 263: 	{
 264: 		install_t a;
 265: 		install_t b;
 266: 		LoadInstallInfo( &a );
 267: 		LoadInstallInfo( &b );
 268: 		ASSERT( 0 == GetModifiedFlags( &a, &b ) );
 269: 	}
 270: 
 271: 	{
 272: 		const struct 
 273: 			{
 274: 				DWORD flag_a;
 275: 				DWORD flag_b;
 276: 				DWORD result;
 277: 				DWORD ico; // .lnk の詳細を変更した
 278: 				DWORD cur; // .pif の詳細を変更した
 279: 			}
 280: 		testcase[] =
 281: 			{
 282: #define FLAG_BOTH  (FLAG_DLL | FLAG_EXE)
 283: #define MAKE_TESTCASE( flag_a, flag_b, result, lnk, pif ) { flag_a, flag_b, result, lnk, pif }
 284: 		MAKE_TESTCASE( 0,         0,         0,         0,         0 ),
 285: 		MAKE_TESTCASE( 0,         FLAG_DLL,  FLAG_DLL,  FLAG_DLL,  FLAG_DLL ),
 286: 		MAKE_TESTCASE( 0,         FLAG_EXE,  FLAG_EXE,  FLAG_EXE,  FLAG_EXE ),
 287: 		MAKE_TESTCASE( 0,         FLAG_BOTH, FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
 288: 		MAKE_TESTCASE( FLAG_DLL,  0,         FLAG_DLL,  FLAG_DLL,  FLAG_DLL ),
 289: 		MAKE_TESTCASE( FLAG_DLL,  FLAG_DLL,  0,         FLAG_DLL,  0 ),
 290: 		MAKE_TESTCASE( FLAG_DLL,  FLAG_EXE,  FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
 291: 		MAKE_TESTCASE( FLAG_DLL,  FLAG_BOTH, FLAG_EXE,  FLAG_BOTH, FLAG_EXE ),
 292: 		MAKE_TESTCASE( FLAG_EXE,  0,         FLAG_EXE,  FLAG_EXE,  FLAG_EXE ),
 293: 		MAKE_TESTCASE( FLAG_EXE,  FLAG_DLL,  FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
 294: 		MAKE_TESTCASE( FLAG_EXE,  FLAG_EXE,  0,         0,         FLAG_EXE ),
 295: 		MAKE_TESTCASE( FLAG_EXE,  FLAG_BOTH, FLAG_DLL,  FLAG_DLL,  FLAG_BOTH ),
 296: 		MAKE_TESTCASE( FLAG_BOTH, 0,         FLAG_BOTH, FLAG_BOTH, FLAG_BOTH ),
 297: 		MAKE_TESTCASE( FLAG_BOTH, FLAG_DLL,  FLAG_EXE,  FLAG_BOTH, FLAG_EXE  ),
 298: 		MAKE_TESTCASE( FLAG_BOTH, FLAG_EXE,  FLAG_DLL,  FLAG_DLL,  FLAG_BOTH ),
 299: 		MAKE_TESTCASE( FLAG_BOTH, FLAG_BOTH, 0,         FLAG_DLL,  FLAG_EXE  ),
 300: #undef MAKE_TESTCASE
 301: #undef FLAG_BOTH
 302: 			};
 303: 		{for( int i = 0; i < numof( testcase ); ++i )
 304: 		{
 305: 			install_t a;
 306: 			install_t b;
 307: 			a.flags = testcase[ i ].flag_a;
 308: 			b.flags = testcase[ i ].flag_b;
 309: 						
 310: 			{for( int j = 0; j < numof( a.reg ); ++j )
 311: 			{
 312: 				a.reg [ j ].regpath[ 0 ] = '\0';
 313: 				b.reg [ j ].regpath[ 0 ] = '\0';
 314: 			}}
 315: 
 316: 
 317: 			{
 318: 				{for( int j = 0; j < numof( g_pair ); ++j )
 319: 				{
 320: 					const size_t idx = ID_INDEX( g_pair[ j ].id );
 321: 					ASSERT( IS_VALID_INDEX( idx ) );
 322: 
 323: 					strcopy( a.reg[ idx ].cmdline, numof(a.reg[ idx ].cmdline), "not modified" );
 324: 					strcopy( b.reg[ idx ].cmdline, numof(b.reg[ idx ].cmdline), "not modified" );
 325: 					strcopy( a.reg[ idx ].menu, numof(a.reg[ idx ].menu), "not modified" );
 326: 					strcopy( b.reg[ idx ].menu, numof(b.reg[ idx ].menu), "not modified" );
 327: 				}}
 328: 
 329: 				const DWORD modified = GetModifiedFlags( &a, &b );
 330: 				ASSERT( modified == testcase[ i ].result );
 331: 			}
 332: 
 333: 			// .ico の詳細を変更した
 334: 			{
 335: 				const size_t index = ID_INDEX( ID_DLL );
 336: 
 337: 				{for( int k = 0; k < 2; ++k )
 338: 				{
 339: 					{for( int j = 0; j < numof( g_pair ); ++j )
 340: 					{
 341: 						const size_t idx = ID_INDEX( g_pair[ j ].id );
 342: 						ASSERT( IS_VALID_INDEX( idx ) );
 343: 
 344: 						strcopy( a.reg[ idx ].cmdline, numof(a.reg[ idx ].cmdline), "not modified" );
 345: 						strcopy( b.reg[ idx ].cmdline, numof(b.reg[ idx ].cmdline), "not modified" );
 346: 						strcopy( a.reg[ idx ].menu, numof(a.reg[ idx ].menu), "not modified" );
 347: 						strcopy( b.reg[ idx ].menu, numof(b.reg[ idx ].menu), "not modified" );
 348: 					}}
 349: 					ASSERT( testcase[ i ].result == GetModifiedFlags( &a, &b ) );
 350: 
 351: 					if ( 0 == (k & 1) )
 352: 						strcopy( a.reg[ index ].cmdline, numof(a.reg[ index ].cmdline), "modified" );
 353: 					else
 354: 						strcopy( a.reg[ index ].menu, numof(a.reg[ index ].menu), "modified" );
 355: 
 356: 					const DWORD modified = GetModifiedFlags( &a, &b );
 357: 					ASSERT( modified == testcase[ i ].ico );
 358: 				}}
 359: 			}
 360: 			
 361: 			// .cur の詳細を変更した
 362: 			{
 363: 				const size_t index = ID_INDEX( ID_EXE );
 364: 
 365: 				{for( int k = 0; k < 2; ++k )
 366: 				{
 367: 					{for( int j = 0; j < numof( g_pair ); ++j )
 368: 					{
 369: 						const size_t idx = ID_INDEX( g_pair[ j ].id );
 370: 						ASSERT( IS_VALID_INDEX( idx ) );
 371: 
 372: 						strcopy( a.reg[ idx ].cmdline, numof(a.reg[ idx ].cmdline), "not modified" );
 373: 						strcopy( b.reg[ idx ].cmdline, numof(b.reg[ idx ].cmdline), "not modified" );
 374: 						strcopy( a.reg[ idx ].menu, numof(a.reg[ idx ].menu), "not modified" );
 375: 						strcopy( b.reg[ idx ].menu, numof(b.reg[ idx ].menu), "not modified" );
 376: 					}}
 377: 					ASSERT( testcase[ i ].result == GetModifiedFlags( &a, &b ) );
 378: 
 379: 					if ( 0 == (k & 1) )
 380: 						strcopy( a.reg[ index ].cmdline, numof(a.reg[ index ].cmdline), "modified" );
 381: 					else
 382: 						strcopy( a.reg[ index ].menu, numof(a.reg[ index ].menu), "modified" );
 383: 
 384: 					const DWORD modified = GetModifiedFlags( &a, &b );
 385: 					ASSERT( modified == testcase[ i ].cur );
 386: 				}}
 387: 			}
 388: 		}}
 389: 	}
 390: 
 391: }//test_install
 392: 
 393: 
 394: #endif // #ifdef _DEBUG
 395: 
 396: 
 397: //** end **

参照:


Google
ご意見・ご感想をお聞かせ下さい。匿名で送信できます。

 * 返信が必要な場合には postmaster@katsura-kotonoha.sakura.ne.jp へ直接メールしてください。

水無瀬の部屋 > sample > exe2ico > install.cpp

このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/exe2ico/install_cpp.shtml
同人ダウンロード販売
同人ダウンロード販売|DL.Getchu.com