#define		STRICT
#include	<windows.h>
#include	<tchar.h>
#include	"kctrl.h"
#include	"cetools.h"
#include	"log.h"

#define		is_kanji(x)		(((0xFF&(x))>=0x81 && (0xFF&(x))<=0x9F)||((0xFF&(x))>=0xE0 && (0xFF&(x))<=0xFC))
#define		is_digit(x)		((0xFF&(x))>='0'&&(0xFF&(x))<='9')
#define		MAX_LINE		(80)
#define		STEP_FILES		(16)
#define		STEP_FORUM		(32)
#define		STEP_MESSAGE	(128)
#define		FORUMID_MAIL	" MAIL"

enum {
	MODE_NONE = 0, MODE_MESSAGE
} ;

typedef struct {
	TCHAR	m_szFilename[ MAX_PATH ] ;
} FILES ;

typedef struct {
	CHAR	m_szForumID[20] ;	/* フォーラムID */
	DWORD	m_dwRoomNo ;		/* 会議室番号 */
	CHAR	m_szRoomName[70] ;	/* 会議室名 */
} NIFTYFORUM ;

typedef struct {
	DWORD	m_dwFileIdx ;		/* ファイルインデックス */
	DWORD	m_dwForumIdx ;		/* フォーラムインデックス */
	DWORD	m_dwMsgNo ;			/* 発言番号 */
	DWORD	m_dwRefNo ;			/* 返信番号 */
	DWORD	m_dwStartPos ;		/* ファイル内位置 */
	DWORD	m_dwMessageSize ;	/* 発言サイズ */
	CHAR	m_szUserID[ 9 ] ;	/* 発言者ID */
	LPSTR	m_szUserName ;		/* 発言者名 */
	LPSTR	m_szSubject ;		/* タイトル */
	BYTE	m_bIndent ;			/* インデントレベル */
} NIFTYMESSAGE ;

static	FILES			*g_Files = NULL ;
static	DWORD			g_dwNumFiles = 0 ;
static	DWORD			g_dwMaxFiles = 0 ;
static	NIFTYFORUM		*g_ForumInfo = NULL ;
static	DWORD			g_dwNumForumInfo = 0 ;
static	DWORD			g_dwMaxForumInfo = 0 ;
static	NIFTYMESSAGE	*g_MessageInfo = NULL ;
static	DWORD			g_dwNumMessageInfo = 0 ;
static	DWORD			g_dwMaxMessageInfo = 0 ;

static	DWORD			g_dwFileIdx = -1 ;
static	DWORD			g_dwCurMode = MODE_NONE ;
static	BOOL			g_bMessage = FALSE ;
static	BOOL			g_bPatioID = FALSE ;
static	BOOL			g_bInMail = FALSE ;
static	CHAR			g_szForumID[ MAX_LINE ] = "" ;
static	DWORD			g_dwRoomNo = 0 ;
static	CHAR			g_szRoomName[ MAX_LINE ] = "" ;
static	DWORD			g_dwMsgNo = 0 ;
static	DWORD			g_dwRefNo = 0 ;
static	DWORD			g_dwStartPos = 0 ;
static	CHAR			g_szUserID[ 9 ] = "" ;
static	CHAR			g_szUserName[ MAX_LINE ] = "" ;
static	CHAR			g_szSubject[ MAX_LINE ] = "" ;

LPDWORD			g_dwRefList = NULL ;
DWORD			g_dwNumRefList = 0 ;
LPDWORD			g_dwNormList = NULL ;
DWORD			g_dwNumNormList = 0 ;
BYTE			g_szReplyBase[ 512 ] = "SUB:%r\nRE:%m\n\n%q\n\n/POST\n" ;
BYTE			g_szNewBase[ 512 ] = "SUB:%r\nRE:NON\n\n%q\n\n/POST\n" ;
BYTE			g_szMailBase[ 512 ] = "TO:%i\nSUB:%r\n\n%q\n\n/POST\n" ;
TCHAR			g_szQuote[ 256 ] = TEXT(">>") ;
TCHAR			g_szPadDir[ MAX_PATH ] = TEXT("\\") ;
TCHAR			g_szMailPadFn[ MAX_PATH ] = TEXT("M_%S.TXT") ;
TCHAR			g_szForumPadFn[ MAX_PATH ] = TEXT("F_%F_%R_%S.TXT") ;

/*
 * ファイル名を格納する領域を確保する
 */
BOOL
NewFiles( LPTSTR *pFn, LPDWORD pIndex )
{
	FILES		*ptr ;
	DWORD		newsize ;

	if ( g_dwNumFiles >= g_dwMaxFiles ) {
		newsize = g_dwMaxFiles + STEP_FILES ;
		ptr = (FILES*) LocalAlloc( LPTR, sizeof (FILES) * newsize ) ;
		if ( !ptr ) {
			DWORD	ret = GetLastError() ;
			return FALSE ;
		}
		if ( g_dwMaxFiles ) {
			memcpy( ptr, g_Files, sizeof (FILES) * g_dwMaxFiles ) ;
			LocalFree( g_Files ) ;
		}
		g_Files = ptr ;
		g_dwMaxFiles = newsize ;
	}
	*pIndex = g_dwNumFiles ++ ;
	*pFn = g_Files[ *pIndex ].m_szFilename ;
	return TRUE ;
}

/*
 * ファイル名を追加する
 */
BOOL
AddFiles( LPCTSTR szPath, LPDWORD pIndex )
{
	DWORD	i ;
	LPTSTR	newPath ;

	for ( i = 0 ; i < g_dwNumFiles ; i ++ ) {
		if ( !_tcsicmp( g_Files[ i ].m_szFilename, szPath ) ) {
			*pIndex = i ;
			return TRUE ;
		}
	}
	if ( !NewFiles( &newPath, pIndex ) ) {
		return FALSE ;
	}
	_tcscpy( newPath, szPath ) ;
	return TRUE ;
}

/*
 * フォーラム情報を格納する領域を確保する
 */
BOOL
NewForumInfo( NIFTYFORUM **pNf, LPDWORD pIndex )
{
	NIFTYFORUM		*ptr ;
	DWORD			newsize ;

	if ( g_dwNumForumInfo >= g_dwMaxForumInfo ) {
		newsize = g_dwMaxForumInfo + STEP_FORUM ;
		ptr = (NIFTYFORUM*) LocalAlloc( LPTR, sizeof (NIFTYFORUM) * newsize ) ;
		if ( !ptr ) {
			DWORD	ret = GetLastError() ;
			return FALSE ;
		}
		if ( g_dwMaxForumInfo ) {
			memcpy( ptr, g_ForumInfo, sizeof (NIFTYFORUM) * g_dwMaxForumInfo ) ;
			LocalFree( g_ForumInfo ) ;
		}
		g_ForumInfo = ptr ;
		g_dwMaxForumInfo = newsize ;
	}
	*pIndex = g_dwNumForumInfo ++ ;
	(*pNf) = &g_ForumInfo[ *pIndex ] ;
	memset( (*pNf), 0, sizeof (NIFTYFORUM) ) ;
	return TRUE ;
}

/*
 * フォーラム情報を追加する
 */
BOOL
AddForumInfo( LPCSTR szForumID, DWORD dwRoomNo, LPCSTR szRoomName, LPDWORD pIndex )
{
	DWORD		i ;
	NIFTYFORUM	*pNf = g_ForumInfo ;

	for ( i = 0 ; i < g_dwNumForumInfo ; i ++, pNf ++ ) {
		if ( !strcmp( szForumID, pNf->m_szForumID ) && dwRoomNo == pNf->m_dwRoomNo ) {
			*pIndex = i ;
			if ( !*pNf->m_szRoomName ) {
				strcpy( pNf->m_szRoomName, szRoomName ) ;
			}
			return TRUE ;
		}
	}
	if ( !NewForumInfo( &pNf, pIndex ) ) {
		return FALSE ;
	}
	strcpy( pNf->m_szForumID, szForumID ) ;
	pNf->m_dwRoomNo = dwRoomNo ;
	strcpy( pNf->m_szRoomName, szRoomName ) ;
	return TRUE ;
}

/*
 * メッセージ情報を格納する領域を確保する
 */
BOOL
NewMessageInfo( NIFTYMESSAGE **pNm )
{
	NIFTYMESSAGE	*ptr ;
	DWORD			newsize ;

	if ( g_dwNumMessageInfo >= g_dwMaxMessageInfo ) {
		newsize = g_dwMaxMessageInfo + STEP_MESSAGE ;
		ptr = (NIFTYMESSAGE*) LocalAlloc( LPTR, sizeof (NIFTYMESSAGE) * newsize ) ;
		if ( !ptr ) {
			DWORD	ret = GetLastError() ;
			return FALSE ;
		}
		if ( g_dwMaxMessageInfo ) {
			memcpy( ptr, g_MessageInfo, sizeof (NIFTYMESSAGE) * g_dwMaxMessageInfo ) ;
			LocalFree( g_MessageInfo ) ;
		}
		g_MessageInfo = ptr ;
		g_dwMaxMessageInfo = newsize ;
	}
	*pNm = &g_MessageInfo[ g_dwNumMessageInfo ++ ] ;
	memset( *pNm, 0, sizeof (NIFTYMESSAGE) ) ;
	return TRUE ;
}

/*
 * 新しいメッセージを登録する
 */
BOOL
AddMessageInfo( DWORD dwForumIdx )
{
	DWORD			len ;
	NIFTYMESSAGE	*pNm ;

	if ( !NewMessageInfo( &pNm ) ) {
		return FALSE ;
	}
	pNm->m_dwFileIdx = g_dwFileIdx ;
	pNm->m_dwForumIdx = dwForumIdx ;
	pNm->m_dwMsgNo = g_dwMsgNo ;
	pNm->m_dwRefNo = g_dwRefNo ;
	pNm->m_dwStartPos = g_dwStartPos ;
	pNm->m_dwMessageSize = 0 ;
	strcpy( pNm->m_szUserID, g_szUserID ) ;
	len = strlen( g_szUserName ) + 1 ;
	pNm->m_szUserName = (LPSTR) LocalAlloc( LPTR, len ) ;
	len = strlen( g_szSubject ) + 1 ;
	pNm->m_szSubject = (LPSTR) LocalAlloc( LPTR, len ) ;
	if ( !pNm->m_szUserName || !pNm->m_szSubject ) {
		if ( pNm->m_szUserName ) {
			LocalFree( pNm->m_szUserName ) ;
		}
		if ( pNm->m_szSubject ) {
			LocalFree( pNm->m_szSubject ) ;
		}
		return FALSE ;
	}
	strcpy( pNm->m_szUserName, g_szUserName ) ;
	strcpy( pNm->m_szSubject, g_szSubject ) ;
	pNm->m_bIndent = 0 ;
	return TRUE ;
}

/*
 * 直前のメッセージのサイズを設定する
 */
void
SetLastMessageSize( DWORD dwPos )
{
	NIFTYMESSAGE	*pNm ;

	if ( !g_dwNumMessageInfo ) {
		return ;
	}
	pNm = &g_MessageInfo[ g_dwNumMessageInfo - 1 ] ;
	pNm->m_dwMessageSize = dwPos - pNm->m_dwStartPos ;
}

LPSTR
FindNotDigit( LPCSTR str )
{
	CHAR	c ;

	while ( c = *str ) {
		if ( c < '0' || c > '9' ) {
			break ;
		}
		str ++ ;
	}
	return (LPSTR) str ;
}

/*
 * 文字列の右側の空白を除去する
 */
void
RTrim( LPSTR ptr )
{
	CHAR	c, c2, *szLastPos = NULL ;

	while ( c = *ptr ++ ) {
		if ( c == ' ' ) {
			if ( !szLastPos ) {
				szLastPos = ptr - 1 ;
			}
		} else if ( is_kanji( c ) ) {
			c2 = *ptr ++ ;
			if ( ((0xFF & c) == 0x81) && ((0xFF & c2) == 0x40) ) {
				if ( !szLastPos ) {
					szLastPos = ptr - 2 ;
				}
			} else {
				szLastPos = 0 ;
			}
		} else {
			szLastPos = 0 ;
		}
	}
	if ( szLastPos ) {
		*szLastPos = 0 ;
	}
}

/*
 * メール先頭行かどうか調べる
 */
static	BOOL
CheckMailLine( LPCSTR szLine, LPSTR szName, LPSTR szID )
{
	CHAR	c ;
	LPCSTR	ptr ;
	DWORD	len = strlen( szLine ) ;

	if ( len <= 18 ) {
		return FALSE ;
	}
	c = *szLine++ ;
	if ( !(c == ' ' || is_digit(c)) ) {
		return FALSE ;
	}
	c = *szLine++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *szLine++ ;
	if ( !(c == ' ') ) {
		return FALSE ;
	}
	c = *szLine++ ;
	if ( !(c == ' ' || c == '#') ) {
		return FALSE ;
	}
	len -= 4 ;
	/* 99/02/10 14:10 */
	ptr = &szLine[ len - 14 ] ;
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !(c == '/') ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !(c == '/') ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !(c == ' ') ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !(c == ':') ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	c = *ptr++ ;
	if ( !is_digit(c) ) {
		return FALSE ;
	}
	if ( szName ) {
		strncpy( szName, szLine, 17 ) ;
		szName[17] = 0 ;
	}
	if ( szID ) {
		strncpy( szID, &szLine[18], 8 ) ;
		szID[8] = 0 ;
	}
	return TRUE ;
}

/*
 * フォーラムＩＤをセットする
 */
BOOL
SetForumID( LPCSTR szForumID )
{
	CHAR	szTmp[ MAX_LINE ], *ptr ;

	strcpy( szTmp, szForumID ) ;
	ptr = strchr( szTmp, '/' ) ;
	if ( ptr ) {
		*ptr = 0 ;
	}
	RTrim( szTmp ) ;
	if ( !*szTmp ) {
		return FALSE ;
	}
	strcpy( g_szForumID, szTmp ) ;
	g_dwRoomNo = 0 ;
	*g_szRoomName = 0 ;
	g_bMessage = FALSE ;
	g_dwCurMode = MODE_NONE ;
	return TRUE ;
}

/*
 * 行内容を調べ登録する
 */
static	BOOL
CheckLogLine( DWORD dwPos, LPCSTR szLine )
{
	DWORD	len = strlen( szLine ) ;
	DWORD	dwForumIdx, dwMsgNo, dwTmp ;
	CHAR	szNum[ 10 ], szTmp[ MAX_LINE + 1 ], *ptr ;

	if ( g_dwCurMode == MODE_MESSAGE ) {
		SetLastMessageSize( dwPos ) ;
	}
	/* ID (改行のみ：自分のパティオ) */
	if ( !strnicmp( szLine, "ID (改行のみ：自分のパティオ)", 29 ) ) {
		g_bPatioID = TRUE ;
		return TRUE ;
	} else if ( g_bPatioID ) {
		g_bPatioID = FALSE ;
		if ( !strnicmp( szLine, "：", 2 ) ) {
			SetForumID( &szLine[ 2 ] ) ;
		}
		return TRUE ;
	}
	/* メールかどうか調べる */
	if ( CheckMailLine( szLine, g_szUserName, g_szUserID ) ) {
		g_bInMail = TRUE ;
		g_dwStartPos = dwPos ;
		g_dwMsgNo = 0 ;
		g_dwRefNo = 0 ;
		g_dwCurMode = MODE_NONE ;
		return TRUE ;
	} else if ( g_bInMail ) {
		g_bInMail = FALSE ;
		if ( !strnicmp( szLine, "    題名：", 10 ) ) {
			strcpy( g_szSubject, &szLine[10] ) ;
			RTrim( g_szSubject ) ;
			if ( !AddForumInfo( FORUMID_MAIL, 0, "メール", &dwForumIdx ) ) {
				return FALSE ;
			}
			if ( !AddMessageInfo( dwForumIdx ) ) {
				return FALSE ;
			}
			g_dwCurMode = MODE_MESSAGE ;
			return TRUE ;
		}
	}
	/* MAIL> */
	if ( !strnicmp( szLine, "MAIL>", 5 ) ) {
		g_dwCurMode = MODE_NONE ;
		return TRUE ;
	}
	/* action: */
	if ( !strnicmp( szLine, "action:", 7 ) ) {
		g_dwCurMode = MODE_NONE ;
		return TRUE ;
	}
	/* PATIO(N)> */
	if ( !strnicmp( szLine, "PATIO(", 6 ) && !strnicmp( &szLine[7], ")>", 2 ) ) {
		/* PATIO(N)>MOV パティオ名 */
		if ( !strnicmp( &szLine[ 9 ], "MOV ", 4 ) ) {
			SetForumID( &szLine[ 13 ] ) ;
			return TRUE ;
		}
		/* PATIO(N)>MOVE パティオ名 */
		if ( !strnicmp( &szLine[ 9 ], "MOVE ", 5 ) ) {
			SetForumID( &szLine[ 14 ] ) ;
			return TRUE ;
		}
		g_dwCurMode = MODE_NONE ;
		return TRUE ;
	}
	/* ＞MOV パティオ名 */
	if ( !strnicmp( szLine, "＞MOV ", 6 ) ) {
		SetForumID( &szLine[ 6 ] ) ;
		return TRUE ;
	}
	/* ＞MOVE パティオ名 */
	if ( !strnicmp( szLine, "＞MOVE ", 7 ) ) {
		SetForumID( &szLine[ 7 ] ) ;
		return TRUE ;
	}
	/* CCS(N)> */
	if ( !strnicmp( szLine, "CCS(", 4 ) && !strnicmp( &szLine[5], ")>", 2 ) ) {
		g_dwCurMode = MODE_NONE ;
		return TRUE ;
	}
	/* ＞MAIL */
	if ( !strnicmp( szLine, "＞MAIL", 6 ) ) {
		SetForumID( "MAIL" ) ;
		return TRUE ;
	}
	/* ＞GO フォーラム名 */
	if ( !strnicmp( szLine, "＞GO ", 5 ) ) {
		SetForumID( &szLine[ 5 ] ) ;
		return TRUE ;
	}
	/* −会議室??  会議室名称  発言数 :?? 未読 :??− */
	if ( !strnicmp( szLine, "−会議室", 8 ) ) {
		if ( !strcmp( &szLine[ strlen( szLine ) - 2 ], "−" ) ) {
			memcpy( szNum, &szLine[ 8 ], 2 ) ;
			szNum[ 2 ] = 0 ;
			g_dwRoomNo = atol( szNum ) ;
			strcpy( g_szRoomName, &szLine[ 12 ] ) ;
			ptr = strstr( g_szRoomName, "  発言数 :" ) ;
			if ( ptr ) {
				*ptr = 0 ;
			}
			RTrim( g_szRoomName ) ;
//			printf( "[%d:%s]\n", g_dwRoomNo, g_szRoomName ) ;
			g_dwCurMode = MODE_NONE ;
		}
		g_bMessage = FALSE ;
		return TRUE ;
	}
	/* - MES( 1):[TRAIN]データ作成部会 99/02/11 - */
	if ( !strnicmp( szLine, "- MES(", 6 ) ) {
		strcpy( szTmp, &szLine[ 6 ] ) ;
		len -= 6 ;
		if ( len >= 11 && !strcmp( &szTmp[ len - 2 ], " -" ) ) {
			szTmp[ 2 ] = 0 ;
			g_dwRoomNo = atol( szTmp ) ;
			szTmp[ len - 11 ] = 0 ;
			strcpy( g_szRoomName, &szTmp[ 4 ] ) ;
			RTrim( g_szRoomName ) ;
			g_dwCurMode = MODE_NONE ;
		}
		g_bMessage = FALSE ;
		return TRUE ;
	}
	/* - ﾌｫｰﾗﾑ  MES(??):会議室名称 YY/MM/DD - */
	if ( !strnicmp( szLine, "- ", 2 ) ) {
		strcpy( szTmp, &szLine[ 2 ] ) ;
		len -= 2 ;
		if ( len >= 11 && !strcmp( &szTmp[ len - 2 ], " -" ) ) {
			szTmp[ len - 11 ] = 0 ;
			ptr = strstr( szTmp, "  MES(" ) ;
			if ( ptr ) {
				*ptr = 0 ;
				strcpy( g_szForumID, szTmp ) ;
				RTrim( g_szForumID ) ;
				ptr += 6 ;
				ptr[ 2 ] = 0 ;
				g_dwRoomNo = atol( ptr ) ;
				strcpy( g_szRoomName, &ptr[ 4 ] ) ;
				RTrim( g_szRoomName ) ;
//				printf( "[%d:%s]\n", g_dwRoomNo, g_szRoomName ) ;
				g_dwCurMode = MODE_NONE ;
			}
		}
		g_bMessage = FALSE ;
		return TRUE ;
	}
	/* 99999/99999 ユーザーID  ユーザー名  発言タイトル */
	strcpy( szTmp, szLine ) ;
	ptr = FindNotDigit( szTmp ) ;
	if ( *ptr == '/' ) {
		*ptr++ = 0 ;
		dwMsgNo = atol( szTmp ) ;
		ptr = FindNotDigit( ptr ) ;
		if ( *ptr++ == ' ' ) {
			g_dwMsgNo = dwMsgNo ;
			memcpy( g_szUserID, ptr, 8 ) ;
			g_szUserID[ 8 ] = 0 ;
			memcpy( g_szUserName, &ptr[10], 17 ) ;
			g_szUserName[ 17 ] = 0 ;
			RTrim( g_szUserName ) ;
			strcpy( g_szSubject, &ptr[27] ) ;
			RTrim( g_szSubject ) ;
			g_dwStartPos = dwPos ;
			g_dwCurMode = MODE_NONE ;
			g_bMessage = TRUE ;
		}
		return TRUE ;
	}
	/* (??)   YY/MM/DD HH:MI  99999へのコメント  コメント数：1 */
	if ( g_bMessage ) {
		g_bMessage = FALSE ;
		if ( szLine[0] == '(' && !strnicmp( &szLine[3], ")   ", 4 ) ) {
			memcpy( szTmp, &szLine[1], 2 ) ;
			szTmp[ 2 ] = 0 ;
			dwTmp = atol( szTmp ) ;
			if ( g_dwRoomNo != dwTmp ) {
				g_dwRoomNo = dwTmp ;
				*g_szRoomName = 0 ;
			}
			if ( len >= 23 ) {
				strcpy( szTmp, &szLine[23] ) ;
				ptr = strstr( szTmp, "へのコメント" ) ;
				if ( ptr ) {
					*ptr = 0 ;
				}
				g_dwRefNo = atol( szTmp ) ;
			} else {
				g_dwRefNo = 0 ;
			}
			if ( !AddForumInfo( g_szForumID, g_dwRoomNo, g_szRoomName, &dwForumIdx ) ) {
				return FALSE ;
			}
			if ( !AddMessageInfo( dwForumIdx ) ) {
				return FALSE ;
			}
			g_dwCurMode = MODE_MESSAGE ;
		}
		return TRUE ;
	}
	return TRUE ;
}

/*
 * LOGファイルを読み込む
 */
BOOL
ReadLogFile( LPCTSTR fn )
{
	DWORD	dwTopPos, dwCurPos, dwCount ;
	CHAR	szLine[ MAX_LINE + 1 ], c, *pszLine ;

	g_dwCurMode = MODE_NONE ;
	g_bMessage = FALSE ;
	*g_szForumID = 0 ;
	g_dwRoomNo = 0 ;
	*g_szRoomName = 0 ;
	g_dwMsgNo = 0 ;
	g_dwRefNo = 0 ;
	g_dwStartPos = 0 ;
	if ( !AddFiles( fn, &g_dwFileIdx ) ) {
		return FALSE ;
	}
	if ( !Fopen( fn, TEXT("rb") ) ) {
		return FALSE ;
	}
	dwTopPos = dwCurPos = 0 ;
	pszLine = szLine ;
	dwCount = 0 ;
	while ( 1 ) {
		c = Fgetc() ;
		if ( c == -1 ) {
			*pszLine = 0 ;
			if ( !CheckLogLine( dwTopPos, szLine ) ) {
				Fclose() ;
				return FALSE ;
			}
			break ;
		} else if ( c == 0x0A ) {
			*pszLine = 0 ;
			if ( !CheckLogLine( dwTopPos, szLine ) ) {
				Fclose() ;
				return FALSE ;
			}
			dwTopPos = ++ dwCurPos ;
			pszLine = szLine ;
			dwCount = 0 ;
		} else {
			if ( c != 0x0D && dwCount < MAX_LINE ) {
				*pszLine++ = c ;
				dwCount ++ ;
			}
			dwCurPos ++ ;
		}
	}
	Fclose() ;
	return TRUE ;
}

void
FreeLogInfo()
{
	DWORD	i ;

	/* フォーラム情報を解放する */
	if ( g_ForumInfo ) {
		LocalFree( g_ForumInfo ) ;
		g_ForumInfo = 0 ;
	}
	g_dwNumForumInfo = 0 ;
	g_dwMaxForumInfo = 0 ;
	/* ファイル情報を解放する */
	g_dwNumFiles = 0 ;
	/* メッセージ情報を解放する */
	if ( g_MessageInfo ) {
		for ( i = 0 ; i < g_dwNumMessageInfo ; i ++ ) {
			NIFTYMESSAGE	*pNm = &g_MessageInfo[ i ] ;
			LocalFree( pNm->m_szUserName ) ;
			LocalFree( pNm->m_szSubject ) ;
		}
		LocalFree( g_MessageInfo ) ;
		g_MessageInfo = 0 ;
	}
	g_dwNumMessageInfo = 0 ;
	g_dwMaxMessageInfo = 0 ;
}

/*
 * 参照順リストを確保する
 */
static	BOOL
AllocRefList()
{
	DWORD	num ;

	FreeRefList() ;
	num = g_dwNumMessageInfo + g_dwNumForumInfo ;
	g_dwRefList = (LPDWORD) LocalAlloc( LPTR, sizeof (DWORD) * num ) ;
	if ( !g_dwRefList ) {
		return FALSE ;
	}
	memset( g_dwRefList, 0, sizeof (DWORD) * num ) ;
	return TRUE ;
}

/*
 * 参照リストの指定された位置に値を挿入する
 */
static	void
InsertRefList( DWORD dwRefIdx, DWORD dwMsgIdx )
{
	DWORD	i ;

	for ( i = g_dwNumRefList ; i > dwRefIdx ; i -- ) {
		g_dwRefList[ i ] = g_dwRefList[ i - 1 ] ;
	}
	g_dwRefList[ dwRefIdx ] = dwMsgIdx ;
	g_dwNumRefList ++ ;
}

/*
 * 参照順リストにメッセージを昇順で追加する
 */
static	void
AddRefList( DWORD dwMsgIdx )
{
	DWORD			i ;
	NIFTYMESSAGE	*pNewNm = &g_MessageInfo[ dwMsgIdx ] ;
	DWORD			dwNewForumIdx = pNewNm->m_dwForumIdx ;
	NIFTYFORUM		*pNewNf = &g_ForumInfo[ dwNewForumIdx ] ;
	LPCSTR			szNewForumID = pNewNf->m_szForumID ;
	DWORD			dwNewRoomNo = pNewNf->m_dwRoomNo ;
	DWORD			dwNewMsgNo = pNewNm->m_dwMsgNo ;

	pNewNm->m_bIndent = 0 ;
	for ( i = 0 ; i < g_dwNumRefList ; i ++ ) {
		DWORD			idx = g_dwRefList[ i ] ;
		NIFTYMESSAGE	*pNm = &g_MessageInfo[ idx ] ;
		DWORD			dwForumIdx = pNm->m_dwForumIdx ;
		NIFTYFORUM		*pNf = &g_ForumInfo[ dwForumIdx ] ;
		int				rc1 = stricmp( pNf->m_szForumID, szNewForumID ) ;
		int				rc2 = pNf->m_dwRoomNo - dwNewRoomNo ;
		int				rc3 = pNm->m_dwMsgNo - dwNewMsgNo ;

		if ( rc1 > 0 || (rc1 == 0 && rc2 > 0) || (rc1 == 0 && rc2 == 0 && rc3 > 0) ) {
			InsertRefList( i, dwMsgIdx ) ;
			return ;
		}
	}
	/* 最後まで到達した場合はリストに追加して終了 */
	g_dwRefList[ g_dwNumRefList ++ ] = dwMsgIdx ;
}

/*
 * 参照リストを参照順にする
 */
static	void
ChangeRefList( DWORD dwCurRefIdx )
{
	DWORD			i, j ;
	DWORD			dwCurMsgIdx = g_dwRefList[ dwCurRefIdx ] ;
	NIFTYMESSAGE	*pCurNm = &g_MessageInfo[ dwCurMsgIdx ] ;
	DWORD			dwCurForumIdx = pCurNm->m_dwForumIdx ;
	DWORD			dwCurMsgNo = pCurNm->m_dwMsgNo ;
	DWORD			dwCurRefNo = pCurNm->m_dwRefNo ;

	if ( pCurNm->m_bIndent ) {
		/* 既に割り振られている場合は何もしない */
		return ;
	} else if ( !dwCurRefNo ) {
		/* 参照先がない場合は何もしない */
		return ;
	}
	for ( i = 0 ; i < dwCurRefIdx ; i ++ ) {
		DWORD			dwMsgIdx = g_dwRefList[ i ] ;
		NIFTYMESSAGE	*pNm = &g_MessageInfo[ dwMsgIdx ] ;
		DWORD			dwMsgNo = pNm->m_dwMsgNo ;
		DWORD			dwRefNo = pNm->m_dwRefNo ;

		if ( dwCurForumIdx != pNm->m_dwForumIdx ) {
			/* 別のフォーラム・会議室になった場合 */
			continue ;
		} else if ( dwCurRefNo == dwMsgNo ) {
			/* 参照先のメッセージが見つかった場合 */
			pCurNm->m_bIndent = pNm->m_bIndent + 1 ;
			break ;
		}
	}
	/* 参照先のメッセージが見つからなかった場合 */
	if ( i == dwCurRefIdx ) {
		return ;
	}
	/* 等しいか、より下位のインデントレベルのメッセージをスキップする */
	for ( i ++ ; i < dwCurRefIdx ; i ++ ) {
		DWORD			dwMsgIdx = g_dwRefList[ i ] ;
		NIFTYMESSAGE	*pNm = &g_MessageInfo[ dwMsgIdx ] ;

		if ( pCurNm->m_bIndent > pNm->m_bIndent ) {
			break ;
		}
	}
	for ( j = dwCurRefIdx ; j > i ; j -- ) {
		g_dwRefList[ j ] = g_dwRefList[ j - 1 ] ;
	}
	g_dwRefList[ i ] = dwCurMsgIdx ;
}

BOOL
MakeRefList()
{
	DWORD		i, dwLastForumIdx = -1 ;

	/* 参照リストを確保する */
	if ( !AllocRefList() ) {
		return FALSE ;
	}
	/* 全てのメッセージを参照リストに昇順で格納する */
	for ( i = 0 ; i < g_dwNumMessageInfo ; i ++ ) {
		AddRefList( i ) ;
	}
	/* 参照リストの全てのメッセージを参照順にする */
	for ( i = 0 ; i < g_dwNumRefList ; i ++ ) {
		ChangeRefList( i ) ;
	}
	/* 参照リストにフォーラム・会議室データを挿入する */
	for ( i = 0 ; i < g_dwNumRefList ; i ++ ) {
		DWORD			dwMsgIdx = g_dwRefList[ i ] ;
		NIFTYMESSAGE	*pNm = &g_MessageInfo[ dwMsgIdx ] ;

		if ( pNm->m_dwForumIdx != dwLastForumIdx ) {
			dwLastForumIdx = pNm->m_dwForumIdx ;
			InsertRefList( i, - 1 - dwLastForumIdx ) ;
		}
	}
	return TRUE ;
}

/*
 * 参照順リストを解放する
 */
void
FreeRefList()
{
	if ( g_dwRefList ) {
		LocalFree( g_dwRefList ) ;
		g_dwRefList = 0 ;
	}
	g_dwNumRefList = 0 ;
}

/*
 * ログ順リストを確保する
 */
static	BOOL
AllocNormList()
{
	DWORD	i, num, dwLastForumIdx = -1 ;

	FreeNormList() ;
	num = g_dwNumMessageInfo ;
	/* 全てのメッセージを参照リストに昇順で格納する */
	for ( i = 0 ; i < g_dwNumMessageInfo ; i ++ ) {
		NIFTYMESSAGE	*pNm = &g_MessageInfo[ i ] ;

		if ( pNm->m_dwForumIdx != dwLastForumIdx ) {
			num ++ ;
		}
		dwLastForumIdx = pNm->m_dwForumIdx ;
	}
	g_dwNormList = (LPDWORD) LocalAlloc( LPTR, sizeof (DWORD) * num ) ;
	if ( !g_dwNormList ) {
		return FALSE ;
	}
	memset( g_dwNormList, 0, sizeof (DWORD) * num ) ;
	return TRUE ;
}

BOOL
MakeNormList()
{
	DWORD		i, dwLastForumIdx = -1 ;

	/* 参照リストを確保する */
	if ( !AllocNormList() ) {
		return FALSE ;
	}
	/* 全てのメッセージを参照リストに昇順で格納する */
	for ( i = 0 ; i < g_dwNumMessageInfo ; i ++ ) {
		NIFTYMESSAGE	*pNm = &g_MessageInfo[ i ] ;

		if ( pNm->m_dwForumIdx != dwLastForumIdx ) {
			dwLastForumIdx = pNm->m_dwForumIdx ;
			g_dwNormList[ g_dwNumNormList ++ ] = - 1 - dwLastForumIdx ;
		}
		g_dwNormList[ g_dwNumNormList ++ ] = i ;
	}
	return TRUE ;
}

/*
 * 参照順リストを解放する
 */
void
FreeNormList()
{
	if ( g_dwNormList ) {
		LocalFree( g_dwNormList ) ;
		g_dwNormList = 0 ;
	}
	g_dwNumNormList = 0 ;
}

LPCSTR
GetLogTitle( DWORD index, BOOL bRef, DWORD dwMaxCol )
{
	DWORD			num ;
	LPSTR			ptr ;
	NIFTYFORUM		*pNf ;
	NIFTYMESSAGE	*pNm ;
	static	CHAR	sjis[ 256 ] ;

	if ( index >= g_dwNumMessageInfo ) {
		index = - 1 - index ;
		if ( index >= g_dwNumForumInfo ) {
			return NULL ;
		}
		pNf = &g_ForumInfo[ index ] ;
		if ( pNf->m_dwRoomNo ) {
			Sprintf( sjis, "%s %d番会議室", pNf->m_szForumID, pNf->m_dwRoomNo ) ;
		} else {
			Sprintf( sjis, "%s", pNf->m_szRoomName ) ;
		}
		num = strlen( sjis ) ;
		if ( dwMaxCol > num ) {
			ptr = &sjis[ num ] ;
			num = dwMaxCol - num ;
			do {
				*ptr++ = '=' ;
			} while ( -- num ) ;
			*ptr = 0 ;
		}
		return sjis ;
	} else {
		ptr = sjis ;
		pNm = &g_MessageInfo[ index ] ;
		num = (bRef ? pNm->m_bIndent : 0) + 1 ;
		do {
			*ptr++ = ' ' ;
		} while ( -- num ) ;
		strcpy( ptr, pNm->m_szSubject ) ;
		return sjis ;
	}
}

LPCTSTR
GetLogFile( DWORD index, LPDWORD pPos, LPDWORD pSize )
{
	NIFTYMESSAGE	*pNm ;

	if ( index >= g_dwNumMessageInfo ) {
		return NULL ;
	}
	pNm = &g_MessageInfo[ index ] ;
	index = pNm->m_dwFileIdx ;
	*pPos = pNm->m_dwStartPos ;
	*pSize = pNm->m_dwMessageSize ;
	return g_Files[ index ].m_szFilename ;
}

/*
 * フォーラム・会議室の情報を取得する
 */
BOOL
GetForumInfo( DWORD index, LPCSTR *forum, LPDWORD roomNo, LPCSTR *roomName )
{
	NIFTYFORUM		*pNf ;
	NIFTYMESSAGE	*pNm ;

	if ( index >= g_dwNumMessageInfo ) {
		index = - 1 - index ;
		if ( index >= g_dwNumForumInfo ) {
			return FALSE ;
		}
	} else {
		pNm = &g_MessageInfo[ index ] ;
		index = pNm->m_dwForumIdx ;
	}
	pNf = &g_ForumInfo[ index ] ;
	*forum = pNf->m_szForumID ;
	*roomNo = pNf->m_dwRoomNo ;
	*roomName = pNf->m_szRoomName ;
	return TRUE ;
}

/*
 * 指定された発言がメールかどうか調べる
 */
BOOL
IsMailForum( DWORD index )
{
	NIFTYFORUM		*pNf ;
	NIFTYMESSAGE	*pNm ;

	if ( index >= g_dwNumMessageInfo ) {
		index = - 1 - index ;
		if ( index >= g_dwNumForumInfo ) {
			return FALSE ;
		}
	} else {
		pNm = &g_MessageInfo[ index ] ;
		index = pNm->m_dwForumIdx ;
	}
	pNf = &g_ForumInfo[ index ] ;
	return !strcmp( pNf->m_szForumID, FORUMID_MAIL ) ;
}

/*
 * 返事用の記号に応じた文字列を挿入する
 */
static	void
InsertItem( LPBYTE *pDst, LPDWORD pCount, DWORD index, LPBYTE szBody, int c )
{
	NIFTYMESSAGE	*pNm ;
	NIFTYFORUM		*pNf ;
	DWORD			i, len ;
	CHAR			buf[ 256 ], *szBuf ;

	szBuf = 0 ;
	switch ( c ) {
	case 'r':
		/* 返答用のサブジェクト */
		if ( *pDst ) {
			strcpy( (LPSTR) *pDst, "RE:" ) ;
			(*pDst) += 3 ;
		}
		(*pCount) += 3 ;
		//
	case 's':
		/* サブジェクト */
		if ( index >= g_dwNumMessageInfo ) {
			break ;
		}
		pNm = &g_MessageInfo[ index ] ;
		if ( pNm->m_szSubject ) {
			len = strlen( pNm->m_szSubject ) ;
			if ( *pDst ) {
				strcpy( (LPSTR) *pDst, pNm->m_szSubject ) ;
				(*pDst) += len ;
			}
			(*pCount) += len ;
		}
		break ;
	case 'm':
		/* メッセージ番号 */
		if ( index >= g_dwNumMessageInfo ) {
			break ;
		}
		pNm = &g_MessageInfo[ index ] ;
		Sprintf( buf, "%d", pNm->m_dwMsgNo ) ;
		szBuf = buf ;
		break ;
	case 'b':
		/* 本文 */
		for ( i = 0 ; i < 3 ; i ++ ) {
			while ( c = *szBody++ ) {
				if ( c == '\n' ) {
					break ;
				}
			}
			if ( !c ) {
				return ;
			}
		}
		while ( c = *szBody++ ) {
			if ( c == '\n' ) {
				if ( *pDst ) {
					*(*pDst)++ = '\r' ;
					*(*pDst)++ = c ;
				}
				(*pCount) += 2 ;
			} else if ( c != '\r' ) {
				if ( *pDst ) {
					*(*pDst)++ = c ;
				}
				(*pCount) ++ ;
			}
		}
		break ;
	case 'q':
		/* 引用記号つきの本文 */
		for ( i = 0 ; i < 3 ; i ++ ) {
			while ( c = *szBody++ ) {
				if ( c == '\n' ) {
					break ;
				}
			}
			if ( !c ) {
				return ;
			}
		}
		unicode2sjis( g_szQuote, buf, sizeof buf ) ;
		len = strlen( (LPSTR) buf ) ;
		if ( *pDst ) {
			strcpy( *pDst, buf ) ;
			(*pDst) += len ;
		}
		(*pCount) += len ;
		while ( c = *szBody++ ) {
			if ( c == '\n' ) {
				if ( *pDst ) {
					*(*pDst)++ = '\r' ;
					*(*pDst)++ = c ;
					strcpy( *pDst, buf ) ;
					(*pDst) += len ;
				}
				(*pCount) += 2 + len ;
			} else if ( c != '\r' ) {
				if ( *pDst ) {
					*(*pDst)++ = c ;
				}
				(*pCount) ++ ;
			}
		}
		break ;
	case 'n':
		/* 発言者の名前 */
		if ( index >= g_dwNumMessageInfo ) {
			break ;
		}
		pNm = &g_MessageInfo[ index ] ;
		szBuf = pNm->m_szUserName ;
		break ;
	case 'i':
		/* 発言者のID */
		if ( index >= g_dwNumMessageInfo ) {
			break ;
		}
		pNm = &g_MessageInfo[ index ] ;
		szBuf = pNm->m_szUserID ;
		break ;
	case 'F':
	case 'R':
		/* フォーラム名/会議室番号 */
		if ( index >= g_dwNumMessageInfo ) {
			break ;
		}
		pNm = &g_MessageInfo[ index ] ;
		if ( index < g_dwNumMessageInfo ) {
			/* メッセージの場合 */
			pNm = &g_MessageInfo[ index ] ;
			index = pNm->m_dwForumIdx ;
		} else {
			/* フォーラムの場合 */
			index = - 1 - index ;
		}
		if ( index >= g_dwNumForumInfo ) {
			break ;
		}
		pNf = &g_ForumInfo[ index ] ;
		if ( c == 'F' ) {
			szBuf = pNf->m_szForumID ;
		} else {
			Sprintf( buf, "%d", pNf->m_dwRoomNo ) ;
			szBuf = buf ;
		}
		break ;
	case 'S':
		/* 通し番号 */
		szBuf = "%S" ;
		break ;
	}
	if ( szBuf ) {
		len = strlen( szBuf ) ;
		if ( *pDst ) {
			strcpy( *pDst, szBuf ) ;
			(*pDst) += len ;
		}
		(*pCount) += len ;
	}
}

/*
 * ベースの文字列からメッセージを作成する
 */
static	DWORD
MakeMessage( LPBYTE dst, DWORD index, LPBYTE szBody, LPBYTE src )
{
	BYTE	c ;
	DWORD	count ;

	count = 0 ;
	while ( c = *src++ ) {
		if ( c == '%' ) {
			c = *src++ ;
			InsertItem( &dst, &count, index, szBody, c ) ;
		} else if ( c == '\r' ) {
		} else if ( c == '\n' ) {
			if ( dst ) {
				*dst++ = '\r' ;
				*dst++ = '\n' ;
			}
			count += 2 ;
		} else if ( is_kanji( c ) ) {
			if ( dst ) {
				*dst++ = c ;
				*dst++ = *src++ ;
			}
			count += 2 ;
		} else {
			if ( dst ) {
				*dst++ = c ;
			}
			count ++ ;
		}
	}
	if ( dst ) {
		*dst = 0 ;
	}
	count ++ ;
	return count ;
}

/*
 * 指定された発言に対する返答を作成する
 */
DWORD
MakeReplyMessage( LPBYTE dst, DWORD index, LPBYTE szBody )
{
	if ( index >= g_dwNumMessageInfo ) {
		return MakeNewMessage( dst, index, szBody ) ;
	}
	return MakeMessage( dst, index, szBody, g_szReplyBase ) ;
}

/*
 * 新しい発言を作成する
 */
DWORD
MakeNewMessage( LPBYTE dst, DWORD index, LPBYTE szBody )
{
	if ( index >= g_dwNumMessageInfo ) {
		szBody = "" ;
	}
	return MakeMessage( dst, index, szBody, g_szNewBase ) ;
}

/*
 * メール用の新しい発言を作成する
 */
DWORD
MakeMailMessage( LPBYTE dst, DWORD index, LPBYTE szBody )
{
	if ( index >= g_dwNumMessageInfo ) {
		szBody = "" ;
	}
	return MakeMessage( dst, index, szBody, g_szMailBase ) ;
}

static	HWND	g_hwndFindWin = 0 ;

/*
 * FindWinのコールバック関数
 */
BOOL CALLBACK
FindWin_EnumWindowsProc( HWND hWnd, LPARAM lParam )
{
	TCHAR	buf[ MAX_PATH ] ;
	LPCTSTR	szWinName = (LPCTSTR) lParam ;

	if ( GetWindowText( hWnd, buf, MAX_PATH ) ) {
		if ( !_tcsicmp( buf, szWinName ) ) {
			g_hwndFindWin = hWnd ;
			return FALSE ;
		}
	}
	return TRUE ;
}

/*
 * 指定されたウィンドウタイトルを持つウィンドウを探す
 */
HWND
FindWin( LPCTSTR szWinName )
{
	g_hwndFindWin = NULL ;
	EnumWindows( FindWin_EnumWindowsProc, (LPARAM) szWinName ) ;
	return g_hwndFindWin ;
}

/*
 * 指定されたディレクトリを作成する
 */
BOOL
CreateDirectoryRecursiveSub( LPCTSTR szPath )
{
	DWORD	dwAttr ;

	dwAttr = GetFileAttributes( szPath ) ;
	if ( dwAttr == 0xFFFFFFFF ) {
		if ( !CreateDirectory( szPath, NULL ) ) {
			return FALSE ;
		}
	} else if ( !(dwAttr & FILE_ATTRIBUTE_DIRECTORY) ) {
		return FALSE ;
	}
	return TRUE ;
}

/*
 * 指定されたディレクトリを再帰的に作成する
 */
BOOL
CreateDirectoryRecursive( LPCTSTR szDir )
{
	TCHAR		c ;
	TCHAR		szPath[ MAX_PATH ], *szPtr ;

	_tcscpy( szPath, szDir ) ;
	szPtr = szPath ;
	while ( c = *szPtr ) {
		if ( (c == '\\') && (szPtr != szPath) ) {
			*szPtr = 0 ;
			if ( !CreateDirectoryRecursiveSub( szPath ) ) {
				return FALSE ;
			}
			*szPtr = TEXT('\\') ;
		}
		szPtr ++ ;
	}
	return CreateDirectoryRecursiveSub( szPath ) ;
}

/*
 * EmTerm用のPADファイル名を作成する
 */
BOOL
MakeForumFn_EmTerm( LPTSTR szPath, DWORD index, BOOL bForceMail )
{
	DWORD			i, dwOrgIndex ;
	NIFTYMESSAGE	*pNm ;
	NIFTYFORUM		*pNf ;
	BOOL			bMail ;
	CHAR			sjis[ MAX_PATH ], sjis2[ MAX_PATH ] ;
	TCHAR			szPadDir[ MAX_PATH ], szPadFn[ MAX_PATH ] ;
	TCHAR			unicode[ MAX_PATH ], unicode2[ MAX_PATH ], *ptr ;

	dwOrgIndex = index ;
	if ( index < g_dwNumMessageInfo ) {
		/* メッセージの場合 */
		pNm = &g_MessageInfo[ index ] ;
		index = pNm->m_dwForumIdx ;
	} else {
		/* フォーラムの場合 */
		index = - 1 - index ;
	}
	if ( index >= g_dwNumForumInfo ) {
		return FALSE ;
	}
	pNf = &g_ForumInfo[ index ] ;
	bMail = bForceMail || !strcmp( pNf->m_szForumID, FORUMID_MAIL ) ;
	/* 格納フォルダ名を生成する */
	unicode2sjis( g_szPadDir, sjis, sizeof sjis ) ;
	MakeMessage( sjis2, dwOrgIndex, "", sjis ) ;
	sjis2unicode( sjis2, szPadDir, sizeof szPadDir ) ;
	if ( !CreateDirectoryRecursive( szPadDir ) ) {
		return FALSE ;
	}
	/* 格納ファイル名を作成する */
	unicode2sjis( (bMail ? g_szMailPadFn : g_szForumPadFn), sjis, sizeof sjis ) ;
	MakeMessage( sjis2, dwOrgIndex, "", sjis ) ;
	sjis2unicode( sjis2, szPadFn, sizeof szPadFn ) ;
	for ( i = 1 ; i < 9999 ; i ++ ) {
		_tcscpy( szPath, szPadDir ) ;
		_tcscpy( unicode2, szPadFn ) ;
		ptr = _tcsstr( unicode2, TEXT("%S") ) ;
		if ( ptr ) {
			/* %Sをシリアル番号に変換する */
			*ptr = 0 ;
			wsprintf( unicode, TEXT("%s%d%s"), unicode2, i, ptr + 2 ) ;
			catdir( szPath, unicode, NULL ) ;
			if ( GetFileAttributes( szPath ) != 0xFFFFFFFF ) {
				/* 既にファイルが存在していた場合はやりなおし */
				continue ;
			}
			if ( FindWin( unicode ) != NULL ) {
				/* 同じ名前のウィンドウがある場合もやりなおし */
				continue ;
			}
		} else {
			/* %Sが含まれていない場合 */
			catdir( szPath, szPadFn, NULL ) ;
		}
		return TRUE ;
	}
	*szPath = 0 ;
	return FALSE ;
}

/*
 * メモリ内の文字列を検索する
 */
BOOL
FindStringForwardMem( LPBYTE szBuffer, DWORD dwSize, DWORD dwStartPos, LPCTSTR szFindStr, BOOL bIgnoreCase, LPDWORD pFoundPos )
{
	DWORD	dwLen ;
	CHAR	sjis[ 128 ] ;

	/* 検索文字列をSJISに変換する */
	unicode2sjis( szFindStr, sjis, sizeof sjis ) ;
	dwLen = strlen( sjis ) ;
	while ( dwStartPos < dwSize ) {
		if ( bIgnoreCase ) {
			if ( !strnicmp( &szBuffer[ dwStartPos ], sjis, dwLen ) ) {
				if ( pFoundPos ) {
					*pFoundPos = dwStartPos ;
				}
				return TRUE ;
			}
		} else {
			if ( !strncmp( &szBuffer[ dwStartPos ], sjis, dwLen ) ) {
				if ( pFoundPos ) {
					*pFoundPos = dwStartPos ;
				}
				return TRUE ;
			}
		}
		dwStartPos ++ ;
	}
	return FALSE ;
}
