開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 コンソール アプリケーション
プロジェクト名 thumbs
アプリケーションの種類 コンソール アプリケーション
追加のオプション 空のプロジェクト

エクスプローラーでThumbs.dbを表示するには「保護されたオペレーティング システム ファイルを表示しない(推奨)」のチェックを外す。
格納されているのは縦横最大96ピクセルのjpgファイル。

参考

thumbs.cpp
#include <stdio.h>
#include <Windows.h>
 
int nIndent = 0;
 
void ReadStorage(LPSTORAGE pStg);
void WriteStream(LPSTORAGE pStg, STATSTG& statstg);
 
//==============================================================================
int wmain(int argc, LPTSTR argv[])
{
	if (argc != 2) {
		fwprintf(stderr, L"usage: thumbs filepath\n");
		return 1;
	}
 
	HRESULT hr = CoInitialize(NULL);
 
	LPSTORAGE pStgRoot = NULL;
	hr = StgOpenStorage(argv[1], NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pStgRoot);
	if (FAILED(hr)) {
		fwprintf(stderr, L"error\n");
		return 1;
	}
	ReadStorage(pStgRoot);
	pStgRoot->Release();
 
	CoUninitialize();
	return 0;
}
 
void ReadStorage(LPSTORAGE pStg)
{
	nIndent++;
	LPMALLOC pMalloc = NULL;	// statstgを解放するため
	HRESULT hr = CoGetMalloc(MEMCTX_TASK, &pMalloc);
 
	LPENUMSTATSTG pEnum = NULL;
	hr = pStg->EnumElements(0, NULL, 0, &pEnum);
	if (FAILED(hr)) return;
 
	STATSTG statstg;
	while (pEnum->Next(1, &statstg, NULL) == S_OK) {
		switch (statstg.type) {
		case STGTY_STORAGE:
			LPSTORAGE pSubStg;
			pSubStg = NULL;
			hr = pStg->OpenStorage(statstg.pwcsName,
				NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, NULL, 0, &pSubStg);
			wprintf(L"%d Storage = %s\n", nIndent, statstg.pwcsName);
			ReadStorage(pSubStg);
			pSubStg->Release();
			break;
		case STGTY_STREAM:
			wprintf(L"%d Stream = %s %llu\n", nIndent, statstg.pwcsName, statstg.cbSize.QuadPart);
			WriteStream(pStg, statstg);
			break;
		}
		pMalloc->Free(statstg.pwcsName);	// メモリリークを避ける
	}
 
	pMalloc->Release();
	pEnum->Release();
	nIndent--;
}
 
void WriteStream(LPSTORAGE pStg, STATSTG& statstg)
{
	LPSTREAM pStream = NULL;
	HRESULT hr = pStg->OpenStream(statstg.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream);
	if (FAILED(hr)) return;
 
	TCHAR szFileName[MAX_PATH];
	wcscpy_s(szFileName, statstg.pwcsName);
	BOOL bJpg;
	if (wcscmp(statstg.pwcsName, L"Catalog")) {
		wcscat_s(szFileName, L".jpg");
		bJpg = TRUE;
	} else {
		wcscat_s(szFileName, L".bin");
		bJpg = FALSE;
	}
 
	FILE *pFile = NULL;
	errno_t er = _wfopen_s(&pFile, szFileName, L"wb");	// 上書き注意
	if (er) goto Exit;
 
	BYTE buffer[8192];
	ULONG nLength;
	hr = pStream->Read(buffer, _countof(buffer), &nLength);
	DWORD dwHeaderSize = bJpg ? *(LPDWORD)buffer : 0;
	fwrite(buffer + dwHeaderSize, 1, nLength - dwHeaderSize, pFile);
Exit:
	if (pFile) fclose(pFile);
	pStream->Release();
}
 

出力
C:\>thumbs "C:\backup\picture\一般\Thumbs.db"
1 Stream = 1 3012
1 Stream = 2 3192
1 Stream = 3 2680
1 Stream = 4 3728
1 Stream = 5 1278
1 Stream = 6 2723
1 Stream = 7 3164
1 Stream = 8 4257
1 Stream = 9 2704
1 Stream = 01 3519
1 Stream = Catalog 3106
最終更新:2013年04月13日 09:07