シングルトンパターン

最近シングルトンパターンをよく使うので,スケルトンクラスを保守します.

#ifndef _DATAMANAGER_
#define _DATAMANAGER_

class DataManager {
private:
	//インスタンスポインタ
	static DataManager *m_pDataManager;

public:
	//コンストラクタ
	DataManager(void);
	//デストラクタ
	~DataManager(void);
	//インスタンス生成
	static DataManager* GetInstance(void);
	//インスタンス消滅
	void DeleteInstance(void);
};

#endif
#include "DataManager.h"
#include <windows.h>

DataManager* DataManager::m_pDataManager = 0;

DataManager::DataManager(void)
{
}

DataManager::~DataManager(void)
{
}

DataManager* DataManager::GetInstance(void)
{
	if (m_pDataManager == NULL) m_pDataManager = new DataManager();
	return m_pDataManager;
}

void DataManager::DeleteInstance(void)
{
	if (m_pDataManager != NULL) delete m_pDataManager;
	m_pDataManager = NULL;
}

ダウンローダクラス完成

無事にプロクシも突破するダウンローダが完成しました.

#ifndef _DOWNLOADER_
#define _DOWNLOADER_

#include <windows.h>
#include <wininet.h>

class Downloader {
private:
	//インターネットハンドル
	HINTERNET hInternet;
	//コネクションハンドル
    HINTERNET hConnect;
	//リクエストハンドル
    HINTERNET hRequest;
	//ホスト名
	TCHAR host[20];
	//プロキシ名
	TCHAR proxy[40];
	//プロキシユーザ名
	TCHAR user[20];
	//プロキシパスワード
	TCHAR passwd[20];
	//ユーザ名+パスワードのbase64変換
	TCHAR base64[30];
	
public:
	//ダウンロードしたファイルサイズ
	long fSize;

public:
	//デフォルトコンストラクタ
	Downloader();
	//ホスト名指定コンストラクタ
	Downloader(TCHAR *_host);
	//デストラクタ
	~Downloader();
	//直接続
	bool DirectOpen(void);
	//プロキシ経由接続
	bool ProxyOpen(TCHAR *config);
	//ファイルダウンロード
	int Download(char *data, TCHAR *url);
};

#endif
#include "Downloader.h"
#include <stdio.h>
#include <tchar.h>

#pragma comment(lib, "wininet.lib")
#pragma warning(disable:4996)
//-----------------------------------------------------------
//コンストラクタ(未使用)
//-----------------------------------------------------------
Downloader::Downloader()
{
}
//-----------------------------------------------------------
//コンストラクタ
//@param : host 接続先ホスト名
//@note host:L"www.google.co.jp"
//-----------------------------------------------------------
Downloader::Downloader(TCHAR *_host)
{
	_tcsncpy_s(host, _host, 20);
}
//-----------------------------------------------------------
//デストラクタ
//-----------------------------------------------------------
Downloader::~Downloader()
{
	InternetCloseHandle(hRequest);
	InternetCloseHandle(hConnect);
	InternetCloseHandle(hInternet);
}
//-----------------------------------------------------------
//直接続
//@note : 事前にコンストラクタでhostを設定
//-----------------------------------------------------------
bool Downloader::DirectOpen()
{
	//インターネットのハンドルの作成
	hInternet = InternetOpen(L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
	if (hInternet == NULL) {
		fprintf(stderr, "Cannot connect to Internet\n");
		return false;
	}
	
	//HTTPサーバへ接続
	hConnect = InternetConnect(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 10000);
	if (hConnect == NULL) {
		fprintf(stderr, "Cannot connect to Server\n");
		InternetCloseHandle(hInternet);
		return false;
	}

	return true;
}
//-----------------------------------------------------------
//プロキシ経由接続
//@param _config : プロキシのコンフィグファイル
//@note : _configの書式は_fgettsの順番に1行に1つ記述
//-----------------------------------------------------------
bool Downloader::ProxyOpen(TCHAR *_config)
{
	FILE *fp;
	//PROXYとUSER:PASSの読み込み
	fp = _tfopen(_config, L"r");
	if (fp == NULL) return false;
	//proxy.doshisha.ac.jp:8080
	_fgetts(proxy, 40, fp);
	//bth0103
	_fgetts(user, 20, fp);
	//パスワード
	_fgetts(passwd, 20, fp);
	//base64
	_fgetts(base64, 30, fp);
	fclose(fp);

	//インターネットのハンドルの作成
	hInternet = InternetOpen(L"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)", CERN_PROXY_INTERNET_ACCESS, proxy, NULL, 0);
	if (hInternet == NULL) {
		fprintf(stderr, "Cannot connect to Internet\n");
		return false;
	}

	//HTTPサーバへ接続
	hConnect = InternetConnect(hInternet, host, INTERNET_DEFAULT_HTTP_PORT, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
	if (hConnect == NULL) {
		fprintf(stderr, "Cannot connect to Server\n");
		InternetCloseHandle(hInternet);
		return false;
	}

	BOOL bResult;
	//プロキシユーザ設定
	bResult = InternetSetOption(hConnect, INTERNET_OPTION_PROXY_USERNAME, user, lstrlen(user));
	if (bResult == FALSE) {
		fprintf(stderr, "Cannot set Option\n");
		InternetCloseHandle(hInternet);
		return false;
	}
	bResult = InternetSetOption(hConnect, INTERNET_OPTION_PROXY_PASSWORD, passwd, lstrlen(passwd));
	if (bResult == FALSE) {
		fprintf(stderr, "Cannot set Option\n");
		InternetCloseHandle(hInternet);
		return false;
	}
	
	return true;
}
//-----------------------------------------------------------
//ダウンロード
//@param data : 受信データのバッファへのポインタ
//@param url : 接続先URL
//@note url : L"/images/srpr/nav_logo27.png" (ホスト名は含まない)
//-----------------------------------------------------------
int Downloader::Download(char *data, TCHAR *url)
{
	fSize = 0;
	char szBuf[1025];
	unsigned long dwSize = 1024;//, dwCode;
	if (hConnect == NULL) return 0;

	//HTTPリクエストの作成
	hRequest = HttpOpenRequest(hConnect, L"GET", url, HTTP_VERSION, L"", NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, 0);
	if (hRequest == NULL) {
		fprintf(stderr, "Request Create Failed\n");
		InternetCloseHandle(hInternet);
		InternetCloseHandle(hConnect);
		return false;
	}

	TCHAR buf[60] = L"Proxy-Authorization: Basic ";
	_tcscat_s(buf, base64);

	//プロキシのリクエストヘッダを付加する
	if (HttpAddRequestHeaders(hRequest, buf, -1, HTTP_ADDREQ_FLAG_ADD) == FALSE) {
		fprintf(stderr, "Request Create Failed\n");
		InternetCloseHandle(hInternet);
		InternetCloseHandle(hConnect);
		return false;
	}

	//HTTPリクエストを送信する
	if (HttpSendRequest(hRequest, NULL, 0, NULL, 0) == FALSE) {
		fprintf(stderr, "Request Send Failed\n");
		InternetCloseHandle(hInternet);
		InternetCloseHandle(hConnect);
		InternetCloseHandle(hRequest);
		return false;
	}

	////HTTPの情報を取得する
	//dwSize = sizeof(DWORD);
	//if (HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwCode, &dwSize, NULL) == FALSE) {
	//	fprintf(stderr, "Get Infomation Failed\n");
	//	InternetCloseHandle(hInternet);
	//	InternetCloseHandle(hConnect);
	//	InternetCloseHandle(hRequest);
	//	return false;
	//}
	////結果処理
	//if (dwCode == HTTP_STATUS_DENIED || dwCode == HTTP_STATUS_PROXY_AUTH_REQ) {
	//	fprintf(stderr, "Status Bad\n");
	//	InternetCloseHandle(hInternet);
	//	InternetCloseHandle(hConnect);
	//	InternetCloseHandle(hRequest);
	//	return false;
	//}

	//データ受信
	while (1) {
		dwSize = 1024;
		if (InternetReadFile(hRequest, szBuf, dwSize, &dwSize) == FALSE) break;
		if (dwSize <= 0) break;
		szBuf[dwSize] = '\0';
		memcpy(data+fSize, szBuf, dwSize);
		fSize += dwSize;
    }

	InternetCloseHandle(hRequest);
	return fSize;
}

Velocity と Speedの違い

他人のソースコードを見ていて,速さだったら変数名はVelocityじゃなくてSpeedを使えばいいのにとふと思いました.
しかし,実際の意味を考えてみるとこれではダメなようです.
Velocity = 速度,Speed = 速さですが,これには違いがあります.
実は,(速さ) = |(速度)|,なのです.
従って速度計算をするプログラムは,SpeedではなくVelocityを用いています.

HP2133 の Windows Vistaを ddコマンドで再インストール(裏)

こんばんは.
管理人です.
個人的にかれこれ2年ほど戦ってきた話題です.


今回行うのは,HP2133のリストアです.
とりあえず概要から説明しましょうか.


1.前提条件 (回想)
HP2133にLinuxとか入れたくなった.
とりあえず,USBブートでLinuxを起動し,外付けHDDにRECOVERY(D:\)を9GB程ddコマンドで吸い出した.
ライセンスキーも回収した.
その後C,Dドライブ両方とも削除し,綺麗さっぱりLinuxになった.(≧∇≦)ノ


そして色々なOS(XP,Vista,7,OpenSUSE,Ubuntu,Fedora,...)を試して遊んだことだし,そろそろVistaに戻そうか….
あれ? BIOSからリカバリできなぃっすよ!!   ガビーンΣ( ̄Д ̄;)


2.方法(裏)
ddコマンドでRECOVERY(D:\)のイメージデータを所有しているので,こいつで頑張りましょう.
メーカちっくな認証をします.


ここで余談ですが,メーカ製Windows Vistaアクティベーション手法をご存じでしょうか?
このアクティベーションはSLPという名前です.
詳しいことはおいといて,認証には以下のものがあればOKなのです.
1:SLPに対応したBIOS (メーカ固有)
2:SLPに対応したプロダクトキー
3:SLP用のライセンスファイル (メーカ固有)


要は…ライセンスファイルを入手すれば,認証後となり,リストア(裏)が可能です.
HP2133のソフト・ドライバは消えますが,別に要らないでしょうw
Vistaの正規ライセンスが回収できればそれでいいのです.


3.手順(裏)
ちょっと読みにくいかと思いますが,以下手順です.
作業はすべてWindowsからします.


3.1.ライセンスファイルのサルベージ
7zipをインストール後起動します.
7zFM.exeはGUIからイメージを展開することができます.
RECOVERY(D:)ドライブの「util」ディレクトリにある,「HPFactory.WIM」というファイルを探します.
さらにその内部を展開し,「HPFactory.WIM\vista.all\appl.zip\vistaut\」と探索します.
そこで,「oem-cert.xrm-ms」というファイルを見つけたら,コピーしてどこかに保存します.


3.2.Vistaのインストール
Vistaをインストールします.
実はバージョンはなんでもいいですが,私は高性能のHP2133なのでBussinessです.
CD-ROMが使えない人はUSBからインストールしましょう.


3.3.ライセンスの復元
Vistaインストール後,正規のHP2133のプロダクトキーに戻します.
cscript c:\windows\system32\slmgr.vbs -dlv
上のコマンドで[説明]の処にVista,OEM_SLP channelとあればOKです.
回収したoem-cert.xrm-msをHP2133のデスクトップとかにコピーします.
cscript c:\windows\system32\slmgr.vbs -ilc c:\Users\[ユーザ名]\Desktop\oem-cert.xrm-ms
を実行します.
ライセンスファイルc:\Users\[ユーザ名]\Desktop\oem-cert.xrm-msは正常にインストールされました.
と出ればOKです.
cscript c:\windows\system32\slmgr.vbs -dlv
もう一度これして,「ライセンス認証されています.」を確認します.

後はメーカのサポートページでドライバを突っ込めば問題ないでしょう.

そうかこれはクラスのプロトタイプ宣言だったのか

前々から「アレ,こうすればあのクラスが使えるな〜?」程度には知っておりましたが….
循環参照のコードを書いたときによく使ったもので.

しかし,循環参照とシングルトンパターンのコンボはなかなか気に入っておりますよ.

IPアドレスを変更するプログラム

/*
** IPアドレスを変更するプログラム in C++言語 Ver0.01α
** Written by Straus Ashley
** 2010 / 10 / 23
** ☆ゴリ押しだが、シンプルなIP変更方法だぉ☆
**
** 根本的な機能はWindowsのコマンドプロンプトの機能。
** 「netsh」というコマンドを利用している。
** 「netsh interface ip」というコマンドでipの設定をする。
** 効果としては、手動でIPアドレスを設定したのと同じ効果を得る。
**
** XPの場合
** netsh interface ip set address 対象アダプタ static IPアドレス サブネット・マスク デフォルト・ゲートウエイ none
** netsh interface ip set dns 対象アダプタ static IPアドレス PrimaryかSecondary
** という引数であり、管理者であれば実行に制限は特にないため(管理者権限は要る UACはない)、
** #include <stdlib.h>でインクルードし、system関数を使いコマンドを実行する。
**
** 例) 無線LANのIPアドレス等を次のように設定したい場合
** IPAddress : 192.168.1.21
** Subnet Mask : 255.255.255.0
** Default Gateway : 192.168.1.1
** 
** system("netsh interface ip set address \"ワイヤレス ネットワーク接続\" static 192.168.1.21 255.255.255.0 192.168.1.1 none");
**
** 例) 有線LANのIPアドレス等を次のように設定したい場合
** IPAddress : 192.168.1.21
** Subnet Mask : 255.255.255.0
** Default Gateway : 192.168.1.1
** 
** system("netsh interface ip set address \"ローカル エリア接続\" static 192.168.1.21 255.255.255.0 192.168.1.1 none");
**
** 例) 無線LANのDNSのアドレスを次のように設定したい場合
** Primary : 192.168.1.1
** secondary : NULL
**
** system("netsh interface ip set dns \"ワイヤレス ネットワーク接続\" static 192.168.1.1 primary");
**
** Vistaの場合
** コマンドが少し違うようだ
** IPを設定する場合noneを消す必要がある。
** VistaはUACにより管理者権限を要求されるため、一般ユーザはsystem関数でコマンドを実行しても権限が無いと言われる。
** しかしsystem関数では権限昇格を入力できないため、スルーされる。
** ビルドしたプログラムを右クリックして、「管理者として実行」とすればよいが、ビルドの度にするのは面倒であると思われる。
** 従ってrunasを指定したWin32APIを用いて、その場で管理者権限を昇格できるようにする。
** 一時的に権限昇格するため、まだセキュリティ上よい(?)。
** ShellExecuteExの実行を決める構造体に上述の設定を施し、実行する。
** 余談であるが、コンソールが追加で表示されるのを防ぐために、info.nShow = SW_HIDE;を指定したが、SW_SHOWで表示可能。
** 実行後UACでパスワードを入力し、管理者として実行することができる。
**
** 最後に。。。
** 1.本プログラムではエラーチェックをしていません。
** 2.好きに改造してOK。
** 3.壊れても知りません。
** 4.IP変更するプログラム創るのに、調べ始めてから3時間もかかったアル。
** 5.後は・・・任せた orz
*/
#include <stdlib.h>
#include <windows.h>

int main(void)
{
	//Vista用
	SHELLEXECUTEINFO info;
	ZeroMemory(&info, sizeof(info));
	info.cbSize = sizeof(info);
	info.fMask = SEE_MASK_FLAG_NO_UI;
	info.lpVerb = L"runas";
	info.lpFile = L"netsh";
	info.lpParameters = L"interface ip set address \"ワイヤレス ネットワーク接続\" static 192.168.1.24 255.255.255.0 192.168.1.1";
	info.nShow = SW_HIDE;
	ShellExecuteEx(&info);

	//XP用
	//設定するコマンド
	//IP
	//system("netsh interface ip set address \"ワイヤレス ネットワーク接続\" static 192.168.1.21 255.255.255.0 192.168.1.1 none");
	//DNS
	//system("netsh interface ip set dns \"ワイヤレス ネットワーク接続\" static 192.168.1.1 primary");

	//元に戻すコマンド
	//IP
	//system("netsh interface ip set address \"ワイヤレス ネットワーク接続\" dhcp");
	//DNS
	//system("netsh interface ip set dns \"ワイヤレス ネットワーク接続\" dhcp");
	return 0;
}

IJGのlibjpegを使うメモ

既に出つくされていると思うが、IJGのlibjpegというライブラリを作る方法をメモ。
このライブラリはソースコードのみで提供されているので、各自ビルドする必要がある。


IJGよりzipをDLする。
解凍する。


makefile.vc→makefile
jconfig.vc→jconfig.h
に変更。


cvars32.bat
nmake all clean
と実行。


jpeglib.h
jconfig.h
jerror.h
jmorecfg.h
libjpeg.lib
を回収する。