
#include "shareCookie.h"
#define WINDEBUGER_NOPRINTING
#define _CRT_SECURE_NO_WARNINGS 1			//vc++のおせっかいな警告を消す
#define  _CRT_NON_CONFORMING_SWPRINTFS 1	//vc++のおせっかいな警告を消す
#include <shlobj.h>
#include <Wininet.h>
#include <Iepmapi.h>
#include <sqlite3\sqlite3.h>
#include <sqlite3\sqliteManager.h>

#include <qwerty\qwerty_common.h>
#include <qwerty\windebuger.h>


static WCHAR fireFoxCookiePath[_MAX_PATH];			//ファイアフォックスのクッキーのパス
static sqlite3 *firefoxCookie;						//ファイアフォックスのクッキーのDB
static sqlite3_stmt *firefoxCookieStmt;				//ファイアフォックスのクッキー取得用ステートメント
static CRITICAL_SECTION firefoxCs;					//ファイアフォックスのクッキー取得用クリティカルセクション


static WCHAR googleChromeCookiePath[_MAX_PATH];		//グーグルクロームのクッキーのパス
static sqlite3 *googleChromeCookie;					//グーグルクロームのクッキーのDB
static sqlite3_stmt *googleChromeCookieStmt;		//グーグルクロームのクッキー取得用ステートメント
static CRITICAL_SECTION googleChromeCs;				//グーグルクロームのクッキー取得用クリティカルセクション


static WCHAR safariCookiePath[_MAX_PATH];			//Safariのクッキーパス
static WCHAR operaCookiePath[_MAX_PATH];			//Operaのクッキーパス

typedef COOKIE_RESULT (*SelfParseCookieCallBack)(LPCSTR targetString,LPCSTR targetEndPointer,LPWSTR cookie,SIZE_T bufSize,LPCWSTR key,LPCWSTR domein);

///
///クロームとファイアフォックスの共通処理
///
static INLINE UINT checkDBAndStmt(sqlite3 **db,sqlite3_stmt **stmt,LPCWSTR path,LPCWSTR sql);
static INLINE VOID cookieStepExec(sqlite3_stmt *stmt,LPWSTR cooki,SIZE_T bufSize,COOKIE_RESULT *result);


///
///規定のブラウザタイプを取得
///
static BROWSERTYPE getDefaultBrowserType();

///
///自力で解析す場合の共通処理
///
static INLINE COOKIE_RESULT SelfParseCookie(LPCWSTR cookieFilePath,LPWSTR cookie,SIZE_T bufSize,LPCWSTR key,LPCWSTR domein,SelfParseCookieCallBack callBack);

///
///インターネットエクスプローラーのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieInternetExplorer(LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein,BOOL isIE);

///
///ファイアフォックスのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieFireFox(LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein);

///
///グーグルクロームのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieGoogleChrome(LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein);

///
///オペラのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieOpera(LPCSTR targetString,LPCSTR targetEndPointer,LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein);

///
///サファリのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieSafari(LPCSTR targetString,LPCSTR targetEndPointer,LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein);

#define FIREFOX_GET_COOKIE_SQL	"SELECT a.name, a.value FROM moz_cookies a WHERE a.name = ?1 AND a.baseDomain = ?2 "						//ファイアフォックスクッキー取得用SQL


#define GOOGLECHROME_GET_COOKIE_SQL	"SELECT a.name,a.value FROM cookies a WHERE a.name = ?1 AND (a.host_key = ?2 OR a.host_key = ?3)"	//グーグルクロームクッキー取得用SQL 頭に.付いてるのと付いてないのがあったのでとりえあえず両方拾うことにした。規則性がわかればもう少しスマートにいける


VOID InitializeShareCookie(LPCWSTR appDataPath,LPCWSTR localAppDataPath){

	//FireFoxの設定
	{

		WCHAR fireFoxProfilesPath[_MAX_PATH];
		WCHAR fireFoxCookieTmp[_MAX_PATH];
		LPWSTR fireFoxCookieFileName = L"cookies.sqlite";
		

	
		LPWSTR index;
		

		wcscpy(fireFoxProfilesPath,appDataPath);
		wcscat(fireFoxProfilesPath,L"Mozilla\\Firefox\\profiles.ini");

		GetPrivateProfileStringW(L"Profile0",L"Path",L"",fireFoxCookieTmp,sizeof(fireFoxCookieTmp) / sizeof(fireFoxCookieTmp[0]),fireFoxProfilesPath);

		for(index = wcsstr(fireFoxCookieTmp,L"/");index != NULL ;index = wcsstr(fireFoxCookieTmp,L"/")){

			index[0] = L'\\';


		}

		switch(GetPrivateProfileIntW(L"Profile0",L"IsRelative",2,fireFoxProfilesPath)){

		case 0:

			wcscpy(fireFoxCookiePath,fireFoxCookieTmp);
			break;

		case 1:
			wcscpy(fireFoxCookiePath,appDataPath);
			wcscat(fireFoxCookiePath,L"Mozilla\\Firefox\\");
			wcscat(fireFoxCookiePath,fireFoxCookieTmp);
			wcscat(fireFoxCookiePath,L"\\");
			wcscat(fireFoxCookiePath,fireFoxCookieFileName);

			break;

		default:
			//ZeroMemory(fireFoxCookiePath,sizeof(fireFoxCookiePath) / sizeof(fireFoxCookiePath[0]));

			break;




		}
		/*
		if(SqliteManager_open(&firefoxCookie,fireFoxCookiePath,SQLITE_OPEN_READONLY,0) == SQLITE_OK){

			rc = SqliteManager_prepare( firefoxCookie, WTEXT(FIREFOX_GET_COOKIE_SQL), -1, &firefoxCookieStmt,(void**)NULL);
			dumpln(TEXT("firefoxのクッキーファイルを開いた"));
		}
		*/
		checkDBAndStmt(&firefoxCookie,&firefoxCookieStmt,fireFoxCookiePath,WTEXT(FIREFOX_GET_COOKIE_SQL));

		InitializeCriticalSection(&firefoxCs);
	}
	
	//GoogleChromeの設定
	{

		wcscpy(googleChromeCookiePath,localAppDataPath);
		wcscat(googleChromeCookiePath,L"Google\\Chrome\\User Data\\Default\\Cookies");


		
		/*
		if(SqliteManager_open(&googleChromeCookie,googleChromeCookiePath,SQLITE_OPEN_READONLY,0) == SQLITE_OK){


			rc = SqliteManager_prepare( googleChromeCookie, WTEXT(GOOGLECHROME_GET_COOKIE_SQL), -1, &googleChromeCookieStmt,(void**)NULL);
			dumpln(TEXT("chromeのクッキーファイルを開いた"));
		}
		*/
		checkDBAndStmt(&googleChromeCookie,&googleChromeCookieStmt,googleChromeCookiePath,WTEXT(GOOGLECHROME_GET_COOKIE_SQL));

		InitializeCriticalSection(&googleChromeCs);







	}


	//サファリの設定
	
	wcscpy(safariCookiePath,appDataPath);
	wcscat(safariCookiePath,L"Apple Computer\\Safari\\Cookies\\Cookies.binarycookies");

	//Operaの設定
	//
	wcscpy(operaCookiePath,appDataPath);
	wcscat(operaCookiePath,L"Opera\\Opera\\cookies4.dat");

	return;
}

VOID FinalizeShareCookie(){


	DeleteCriticalSection(&firefoxCs);
	DeleteCriticalSection(&googleChromeCs);
	sqlite3_finalize(firefoxCookieStmt);
	sqlite3_finalize(googleChromeCookieStmt);
	SqliteManager_close(&firefoxCookie);
	SqliteManager_close(&googleChromeCookie);



	return;
}



COOKIE_RESULT GetCookie(BROWSERTYPE browserType,LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein){

	//ブラウザタイプにより実行する関数を決定する

	switch(browserType){

		//IEの場合
	case BT_INTERNET_EXPLORER:


		return GetCookieInternetExplorer(cookie,bufSize,key,domein,TRUE);

		//ファイアフォックスの場合
	case BT_FIRE_FOX:

		return  GetCookieFireFox(cookie,bufSize,key,domein);

		//グーグルクロームの場合
	case BT_GOOGLE_CHROME:


		return  GetCookieGoogleChrome(cookie,bufSize,key,domein);

		//オペラの場合
	case BT_OPERA:

		return SelfParseCookie(operaCookiePath,cookie,bufSize,key,domein,GetCookieOpera);
		

		//サファリの場合
	case BT_SAFARI:
		return SelfParseCookie(safariCookiePath,cookie,bufSize,key,domein,GetCookieSafari);
		

		//IEコンポーネントの場合
	case BT_IE_COMPONENT:

		return GetCookieInternetExplorer(cookie,bufSize,key,domein,FALSE);

		//規定のブラウザ

	case BT_DEFAULT:

		return GetCookie(getDefaultBrowserType(),cookie,bufSize,key,domein);

		//ブラウザタイプが設定されていない場合
	case BT_NOSETTING:

		return  COOKIE_ERR_BROWSERTYPE_NOSETTING;




		//未定義のブラウザタイプが指定された場合
	default:

		return  COOKIE_ERR_UNDEFINED_BROWSERTYPE;

	}





}

///
///インターネットエクスプローラーのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieInternetExplorer(LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein,BOOL isIE){

#define GET_IE_COOKIE_URL_MAXLENGTH			LENGTH_512		//urlバッファ長
	
	HKEY hKey = (HKEY)NULL;									//レジストリキー
	COOKIE_RESULT result = COOKIE_ERR_OK;						//結果コード
	DWORD data;												//レジストリ値格納変数
	DWORD size = sizeof(data);								//dataのサイズ
	HRESULT cookieResult;									//クッキー取得結果コード
	BOOL  isProtectedMode = FALSE;							//保護モードフラグ
	WCHAR url[GET_IE_COOKIE_URL_MAXLENGTH];					//urlバッファ

	//IEかIEコンポーネントかを判定
	if(isIE){

		//レジストリキーを読み取り専用でオープン
		if(RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\3"),0,KEY_READ,&hKey) != ERROR_SUCCESS){
			return COOKIE_ERR_INTERNETOPTION_NOTOPEN;
		}





		//保護モードの状態を取得
		switch(RegQueryValueEx(hKey,TEXT("2500"),(LPDWORD)NULL,(LPDWORD)NULL,(LPBYTE)&data,&size)){


			//保護モード取得に成功
		case ERROR_SUCCESS:

			//取得した値が0だった場合、保護モードフラグをTRUEにする
			isProtectedMode = data == 0;
			

			break;

		
			//保護モード取得に失敗した場合でもレジストリ値が見つからないエラーであれば、XP以前のOSと判定され、保護モードはFALSEのままにする
		case ERROR_FILE_NOT_FOUND:



			break;

			//上記エラー以外のエラーが発生した場合、クッキー取得を失敗とする
		default:
		
			result = COOKIE_ERR_PROTECTIONMODE_READFAILD;
			goto end;

		}//switch(RegQueryValueEx(hKey,TEXT("2500"),(LPDWORD)NULL,(LPDWORD)NULL,(LPBYTE)&data,&size))
	}//if(isIE)



	
	

	//渡されたurlの長さがGET_IE_COOKIE_URL_MAXLENGTHよりも長かった場合、URL文字列が長すぎるエラーコードをresultにいれる
	if(wcslen(domein) >= GET_IE_COOKIE_URL_MAXLENGTH){
		result = COOKIE_ERR_DETAIL_URL_TOOBIG;


	} else {
		//ドメインからurlを設定
		wcscpy(url,L"http://");
		wcscat(url,domein);

		//保護モードフラグがTRUEならIEGetProtectedModeCookieでクッキーの値を取得
		if(isProtectedMode == TRUE){
			cookieResult = IEGetProtectedModeCookie(url,key,cookie,&bufSize,0);
			

		//保護モードフラグがFALSEならInternetGetCookieExでクッキーの値を取得
		}else{
			if(InternetGetCookieEx(url,key,cookie,&bufSize,0,NULL) == TRUE){

				cookieResult = S_OK;
			}else {
				cookieResult = GetLastError();
			}
				
			
		}
			
		
			

		//結果コード判定
		if(cookieResult == ERROR_SUCCESS){


			//取得したクッキーのサイズが0より大きければ、resultsに正常終了の値を設定
			if(bufSize > 0){

				result = COOKIE_ERR_OK;

			//取得したクッキーのサイズが0の場合、notFoundErrorを設定
			} else {
				result = COOKIE_ERR_DETAIL_NOTFOUND;

			}//if(bufSize > 0)

		//結果コードが正常終了ではない場合resultsにエラーの詳細を設定
		} else {
	

			switch(cookieResult){
				//バッファ長が足りない場合のエラーwinerror.hに設定されていなかったのでそのままの値で飛ぶようにしてあるどこかに定義されているかもしれないので見つけたら定義マクロに置き換える
			case 0x8007007a:

				result = COOKIEERR_DETAIL_RESULT_TOOBIG;

				break;

				//未定義のエラーが発生した場合


			case INTERNET_COOKIE_HTTPONLY:
			default:

				wincheck(cookieResult);

				result = COOKIE_ERR_UNKNOWN;

				break;

			}//switch(cookieResult)
		}//if(cookieResult == ERROR_SUCCESS)
	}//if(wcslen(domeins[index]) >= GET_IE_COOKIE_URL_MAXLENGTH)




end:
	//開いたレジストリを閉じる
	RegCloseKey(hKey);

	return result;
}

///
///ファイアフォックスのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieFireFox(LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein){

	COOKIE_RESULT result = COOKIE_ERR_OK;						//結果コード
	LPCWSTR pName = (LPCWSTR)NULL;						//名前の値を確保する一時的なポインタ
	LPCWSTR pValue = (LPCWSTR)NULL;						//valueの値を確保する一時的なポインタ
	
	

	

	//db,ステートメントが開かれているかチェック
	switch(checkDBAndStmt(&firefoxCookie,&firefoxCookieStmt,fireFoxCookiePath, WTEXT(FIREFOX_GET_COOKIE_SQL))){

	case 0:
		break;

	case 1:
		result = COOKIE_ERR_DBOPEN_FAILED;
		goto end;

	case 2:
		result = COOKIE_ERR_CREATESTMT_FAILED;
		goto end;


	}

	EnterCriticalSection(&firefoxCs);

	

	switch(sqlite3_bind_text16(firefoxCookieStmt,1,key,-1,SQLITE_STATIC)){

	case SQLITE_OK:


		switch(sqlite3_bind_text16(firefoxCookieStmt,2,domein,-1,SQLITE_STATIC)){

		case SQLITE_OK:

			cookieStepExec(firefoxCookieStmt,cookie,bufSize, &result);

			


			break;

		case SQLITE_TOOBIG:

			result = COOKIE_ERR_DETAIL_URL_TOOBIG;


			break;

		default:

			result = COOKIE_ERR_UNKNOWN;


			break;

		}//switch(sqlite3_bind_text16(firefoxCookieStmt,2,domeins[index],sizeof(WCHAR) * (wcslen(key[index]) + 1),SQLITE_STATIC))




		break;//SQLITE_OK

	case SQLITE_TOOBIG:

		result = COOKIE_ERR_DETAIL_KEY_TOOBIG;

		break;

	default:

		result = COOKIE_ERR_UNKNOWN;


		break;

	}//switch(sqlite3_bind_text16(firefoxCookieStmt,1,key[index],sizeof(WCHAR) * (wcslen(key[index]) + 1),SQLITE_STATIC))

	//パラメタのリセット(バインド解除)
	sqlite3_reset(firefoxCookieStmt);


	
	LeaveCriticalSection(&firefoxCs);

end:


	return result;
}






///
///グーグルクロームのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieGoogleChrome(LPWSTR cookie,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein){



	COOKIE_RESULT result = COOKIE_ERR_OK;					//結果コード
	LPCWSTR pName = (LPCWSTR)NULL;						//名前の値を確保する一時的なポインタ
	LPCWSTR pValue = (LPCWSTR)NULL;						//valueの値を確保する一時的なポインタ
	WCHAR host_key2Buf[LENGTH_DOMEIN] = {L"."};						//ドメインその２領域
	LPWSTR pHostKey = &host_key2Buf[1];
	


	

	//db,ステートメントが開かれているかチェック
	switch(checkDBAndStmt(&googleChromeCookie,&googleChromeCookieStmt,googleChromeCookiePath, WTEXT(GOOGLECHROME_GET_COOKIE_SQL))){

	case 0:
		break;

	case 1:
		result = COOKIE_ERR_DBOPEN_FAILED;
		goto end;

	case 2:
		result = COOKIE_ERR_CREATESTMT_FAILED;
		goto end;


	}

	EnterCriticalSection(&googleChromeCs);




	//ステートメントにパラメタを設定1
	switch(sqlite3_bind_text16(googleChromeCookieStmt,1,key,-1,SQLITE_STATIC)){

	case SQLITE_OK:

		//ステートメントにパラメタを設定2
		switch(sqlite3_bind_text16(googleChromeCookieStmt,2,domein,-1,SQLITE_STATIC)){

		case SQLITE_OK:

			if(wcslen(domein) > LENGTH_DOMEIN -2){

				result = COOKIE_ERR_DETAIL_URL_TOOBIG;
				

				break;

			}

			wcscpy(pHostKey,domein);						//このあたりはもう少し効率化できる？

			//ステートメントにパラメタを設定3
			switch(sqlite3_bind_text16(googleChromeCookieStmt,3,host_key2Buf,-1,SQLITE_STATIC)){

			case SQLITE_OK:

		
				//クッキー取得SQL実行
				cookieStepExec(googleChromeCookieStmt,cookie,bufSize,&result);

				


				break;


				case SQLITE_TOOBIG:

					result = COOKIE_ERR_DETAIL_URL_TOOBIG;


					break;

				default:
				
					result = COOKIE_ERR_UNKNOWN;


				break;

			}//switch(sqlite3_bind_text16(googleChromeCookieStmt,3,domeins[index],-1,SQLITE_STATIC))



			break;

		case SQLITE_TOOBIG:

			result = COOKIE_ERR_DETAIL_URL_TOOBIG;


			break;

		default:
				
			result = COOKIE_ERR_UNKNOWN;


			break;

		}//switch(sqlite3_bind_text16(googleChromeCookieStmt,2,domeins[index],sizeof(WCHAR) * (wcslen(key[index]) + 1),SQLITE_STATIC))




		break;//SQLITE_OK

	case SQLITE_TOOBIG:

		result = COOKIE_ERR_DETAIL_KEY_TOOBIG;


		break;

	default:

		result = COOKIE_ERR_UNKNOWN;


	}//switch(sqlite3_bind_text16(googleChromeCookieStmt,1,key[index],sizeof(WCHAR) * (wcslen(key[index]) + 1),SQLITE_STATIC))

	//パラメタのリセット(バインド解除)
	sqlite3_reset(googleChromeCookieStmt);


	
	LeaveCriticalSection(&googleChromeCs);

end:



	return result;
}

///
///オペラのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieOpera(LPCSTR targetString,LPCSTR targetEndPointer,LPWSTR cookies,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein){

	COOKIE_RESULT result = COOKIE_ERR_UNKNOWN;
	CHAR mb_key[_MAX_PATH];
	CHAR mb_domein[_MAX_PATH];
	LPCSTR cookiePointer;
	LPCSTR keyPointer;

	if(ARRAY_LENGTH(mb_key) < GetLenToMB(CP_THREAD_ACP,key)){
		
		goto keybuffbigerr;

	} else if(ARRAY_LENGTH(mb_domein) < GetLenToMB(CP_THREAD_ACP,domein) ){

		goto domeinbuffbigerr;

	}


	WideToMB(CP_THREAD_ACP,key,mb_key,ARRAY_LENGTH(mb_key));
	WideToMB(CP_THREAD_ACP,domein,mb_domein,ARRAY_LENGTH(mb_domein));
	strstr(mb_domein,".jp")[0] = '\0';

	for(;targetString < targetEndPointer;targetString += strlen(targetString) + 1){

		
		if(strncmp(targetString + 1,mb_domein,strlen(mb_domein)) == 0){
			
			
			
			
			
			for(keyPointer = (targetString + strlen(targetString) + 1);keyPointer < targetEndPointer;keyPointer = (keyPointer + strlen(keyPointer) + 1)){
				if(strstr(keyPointer,mb_key) !=NULL){
					CHAR cookie_mbBuff[_MAX_PATH];
					UINT_PTR length;
					cookiePointer = keyPointer+ strlen(keyPointer) + 1;
					length = strlen(cookiePointer) -2;
					strncpy(cookie_mbBuff,cookiePointer+1,length);
					cookie_mbBuff[length] = '\0';
					if(((INT_PTR)bufSize) < GetLenToWide(CP_THREAD_ACP,cookie_mbBuff) + wcslen(key) + 1){

						goto cookiebuffbigerr;
					}
					wcscpy(cookies,key);
					cookies += wcslen(cookies);
					cookies[0] = L'=';
					cookies++;

					MBToWide(CP_THREAD_ACP,cookie_mbBuff,cookies,bufSize);
					result = COOKIE_ERR_OK;
					goto end;
				}
			}
			
		}

	}

end:


	return result;


keybuffbigerr:
	result = COOKIE_ERR_DETAIL_URL_TOOBIG;
	goto end;

domeinbuffbigerr:
	result = COOKIE_ERR_DETAIL_DOMEIN_TOOBIG;
	goto end;

cookiebuffbigerr:
	result = COOKIEERR_DETAIL_RESULT_TOOBIG;
	goto end;
}

///
///サファリのクッキーを取得
///
static INLINE COOKIE_RESULT GetCookieSafari(LPCSTR targetString,LPCSTR targetEndPointer,LPWSTR cookies,SIZE_T bufSize, LPCWSTR key,LPCWSTR domein){
	COOKIE_RESULT result = COOKIE_ERR_UNKNOWN;
	CHAR mb_key[_MAX_PATH] = "A";
	CHAR mb_domein[_MAX_PATH] = ".";
	LPCSTR cookiePointer;
	LPCSTR domeinPointer;
	SIZE_T mb_keyLen;

	if(ARRAY_LENGTH(mb_key)-1 < GetLenToMB(CP_THREAD_ACP,key)){
		
		goto keybuffbigerr;

	} else if(ARRAY_LENGTH(mb_domein) - 1 < GetLenToMB(CP_THREAD_ACP,domein) ){

		goto domeinbuffbigerr;

	}

	WideToMB(CP_THREAD_ACP,key,mb_key + 1,ARRAY_LENGTH(mb_key) - 1);
	WideToMB(CP_THREAD_ACP,domein,mb_domein + 1,ARRAY_LENGTH(mb_domein) - 1);
	mb_keyLen = strlen(mb_key);
	
	for(;targetString < targetEndPointer;targetString += strlen(targetString) + 1){

		if(strstr(targetString,mb_key) != NULL){

			cookiePointer = targetString + strlen(targetString) + 1;
			domeinPointer = cookiePointer + strlen(cookiePointer) + 1;

			if(strcmp(mb_domein,domeinPointer) == 0){

				if(((INT_PTR)bufSize) < GetLenToWide(CP_THREAD_ACP,cookiePointer) + wcslen(key) + 1){

					goto cookiebuffbigerr;
				}
				wcscpy(cookies,key);
				cookies += wcslen(cookies);
				cookies[0] = L'=';
				cookies++;

				MBToWide(CP_THREAD_ACP,cookiePointer,cookies,bufSize);
				result = COOKIE_ERR_OK;
				break;
			}
		}

	}

end:


	return result;


keybuffbigerr:
	result = COOKIE_ERR_DETAIL_URL_TOOBIG;
	goto end;

domeinbuffbigerr:
	result = COOKIE_ERR_DETAIL_DOMEIN_TOOBIG;
	goto end;

cookiebuffbigerr:
	result = COOKIEERR_DETAIL_RESULT_TOOBIG;
	goto end;
}

///
///クロームとファイアフォックスの共通処理
///

static INLINE UINT checkDBAndStmt(sqlite3 **db,sqlite3_stmt **stmt,LPCWSTR path,LPCWSTR sql){


	//DBポインタがNULLの場合もう一度DBをオープンするそれでもNULLの場合、エラーを返す
	if(*db == NULL){
		SqliteManager_open(db,path,SQLITE_OPEN_READONLY,0);
		if(*db == NULL){
			return 1;

		}
	}

	//ステートメントがNULLの場合もう一度ステートメントの作成を行う、失敗した場合エラーを返す
	if(*stmt == NULL){
		SqliteManager_prepare( *db,sql, -1, stmt,(void**)NULL);
		if(*stmt == NULL){
			return 2;


		}
	}

	return 0;

}

static INLINE VOID cookieStepExec(sqlite3_stmt *stmt,LPWSTR cookie,SIZE_T bufSize,COOKIE_RESULT *result){

	LPCWSTR pName;
	LPCWSTR pValue;
	INT_PTR rc;


	//dumpln_mb(CP_UTF8,"sql%s",sqlite3_sql(stmt));

	do{
		//sqlが成功した場合、取得したvalueを結果に収める
		rc =  sqlite3_step( stmt );

	}while(SQLITE_BUSY == rc || SQLITE_LOCKED == rc);


	switch(rc){

	case SQLITE_ROW:


		pName = (LPCWSTR)sqlite3_column_text16( stmt, 0 );
		pValue   = (LPCWSTR)sqlite3_column_text16( stmt, 1 );

		//取得した文字列がバッファのサイズより大きかった場合、バッファサイズが小さいエラーを格納する
		if(wcslen(pValue) + wcslen(pName) + 2 >= bufSize){

			*result = COOKIEERR_DETAIL_RESULT_TOOBIG;


		} else  {


			wcscpy(cookie,pName);
			wcscat(cookie,L"=");
			wcscat(cookie,pValue);


			

			

		}
			


		break;


	case SQLITE_DONE:
		*result = COOKIE_ERR_DETAIL_NOTFOUND;

		break;

	default:
		*result = COOKIE_ERR_UNKNOWN;

		break;

	}

	return;


}


static COOKIE_RESULT SelfParseCookie(LPCWSTR cookieFilePath,LPWSTR cookie,SIZE_T bufSize,LPCWSTR key,LPCWSTR domein,SelfParseCookieCallBack callBack){

	COOKIE_RESULT result = COOKIE_ERR_UNKNOWN;

	HANDLE hCookieFile = CreateFile(cookieFilePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL);
	if(hCookieFile == INVALID_HANDLE_VALUE ){

		goto fileopenerr;
	}
	{
		DWORD readSize;
		DWORD highSize;
		DWORD lowSize = GetFileSize(hCookieFile,&highSize);
		SIZE_T bufferSize = MAKELONG(lowSize,highSize);
		LPSTR buffer = (LPSTR)malloc(bufferSize);
		
		ReadFile(hCookieFile,buffer,bufferSize,&readSize,NULL);
		
	

		
		result = callBack(buffer,buffer + (bufferSize / sizeof(CHAR)),cookie,bufSize,key,domein);
		free(buffer);
	}

end:
	
	CloseHandle(hCookieFile);
	
	return result;

fileopenerr:
	result = COOKIE_ERR_OPEN_FAILED;
	goto end;
}


BROWSERTYPE getDefaultBrowserType(){

	BROWSERTYPE rslt = BT_NOSETTING;
	WCHAR currentUserSID[_MAX_PATH];
	DWORD cName  = ARRAY_LENGTH(currentUserSID);
	FILETIME fileTime;
	HKEY hKey;
	//レジストリキーを読み取り専用でオープン
	if(RegOpenKeyEx(HKEY_CURRENT_USER,L"Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\https\\UserChoice",0,KEY_READ,&hKey) != ERROR_SUCCESS){
		return COOKIE_ERR_INTERNETOPTION_NOTOPEN;
	}



	

	RegQueryValueEx(hKey,TEXT("Progid"),(LPDWORD)NULL,(LPDWORD)NULL,(LPBYTE)&currentUserSID,&cName);
	//HKEY_CURRENT_USER\Software\Microsoft\Protected Storage System Provider\


	RegCloseKey(hKey);
	return rslt;
}