?? secretchatdlg.cpp
字號:
//把注冊表好友公鑰文件名改成現在的連線好友
AfxGetApp()->WriteProfileString(
"SecretKeySetup",
"FriendPublicKey",
secretKeyEditDlg.CharToCString(secretKey.userName, 32) + ".pk");
//提示成功
MessageBox(
"已經獲得公鑰 " + AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"),
"密聊",
MB_ICONINFORMATION);
MyUpdateData(); //更新設置
return TRUE;
}
BOOL CSecretChatDlg::ValidatePrivateKey() //驗證私鑰的設置情況
{
//連接之情必須要有一個私鑰并且要有一個被選中
WIN32_FIND_DATA wfd;
HANDLE hSearch;
//判斷是否至少有一個私鑰文件
hSearch = ::FindFirstFile(
m_appName + "\\user\\*.sk" ,
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //沒有私鑰存在,就要提示生成新的密鑰
MessageBox(
"沒有任何用戶私鑰文件,請先創建新的密鑰",
"密聊",
MB_ICONINFORMATION);
CSecretKeyEdit secretKeyEditDlg;
secretKeyEditDlg.m_select = SELECT_CREATE;
secretKeyEditDlg.DoModal();
return FALSE; //沒有生成密鑰將永遠不能進行連接
}
hSearch = ::FindFirstFile(
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey"),
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //沒有選擇私鑰,提示要選擇
MessageBox(
"通訊前必須選擇用戶私鑰文件",
"密聊",
MB_ICONINFORMATION);
m_setupDlg.m_index = 1;
m_setupDlg.DoModal(); //選擇私鑰和公鑰
return FALSE; //沒有選中將永遠不能進行連接
}
//還有判斷它是合格的私鑰文件
CSecretKeyEdit secretKeyEditDlg;
if(secretKeyEditDlg.validateSecretKey(
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey")) != SECRETKEY_PRIVATE)
{
MessageBox(
AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey") + " 不是合格的私鑰文件",
"密聊",
MB_ICONINFORMATION);
m_setupDlg.m_index = 1;
m_setupDlg.DoModal();
return FALSE; //不合格將永遠不能進行連接
}
if(!InstallPrivateKey()) //安裝私鑰文件
{
MessageBox(
"無法安裝用戶私鑰文件",
"密聊",
MB_ICONINFORMATION);
return FALSE;
}
return TRUE;
}
BOOL CSecretChatDlg::ValidatePublicKey() //驗證公鑰的設置情況
{
WIN32_FIND_DATA wfd;
HANDLE hSearch;
//連接成功后,就要判斷有沒好友公鑰
//判斷是否至少有一個公鑰文件
hSearch = ::FindFirstFile(
m_appName + "\\friend\\*.pk" ,
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //沒有公鑰存在,就要提示請求獲取新的公鑰
if(MessageBox(
"沒有任何好友公鑰文件,是否請求獲取對方的公鑰?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDYES)
{ //獲取對方的公鑰
AskPublicKey();
}
return FALSE;
}
//查看公鑰是否被選中
hSearch = ::FindFirstFile(
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey"),
&wfd);
if(hSearch == INVALID_HANDLE_VALUE)
{ //沒有選擇公鑰,提示要選擇和獲取新的公鑰
if(MessageBox(
"請選擇好友公鑰文件或請求獲取對方的公鑰,\r\n是否請求獲取對方的公鑰?",
"密聊",
MB_YESNO | MB_ICONQUESTION) == IDYES)
{ //獲取對方的公鑰
AskPublicKey();
}
else
{
m_setupDlg.m_index = 2;
m_setupDlg.DoModal();
}
return FALSE;
}
//還有判斷它是合格的公鑰文件
CSecretKeyEdit secretKeyEditDlg;
if(secretKeyEditDlg.validateSecretKey(
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey")) != SECRETKEY_PUBLIC)
{
MessageBox(
AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey") + " 不是合格的公鑰文件",
"密聊",
MB_ICONINFORMATION);
m_setupDlg.m_index = 2;
m_setupDlg.DoModal();
return FALSE; //不合格將永遠不能進行連接
}
if(!InstallPublicKey()) //安裝公鑰文件
{
MessageBox(
"無法安裝好友公鑰文件",
"密聊",
MB_ICONINFORMATION);
return FALSE;
}
return TRUE;
}
LRESULT CSecretChatDlg::RunHide(WPARAM wParam,LPARAM lParam) //運行時隱藏窗口
{
if(wParam == 0)
{
ShowWindow(SW_HIDE); //隱藏窗口
MoveWindow(m_rect);
return 0;
}
if(wParam == 1)//詢問打開接收到的文件
{
if(MessageBox(
"是否打開 " + m_receive_file_name + " 文件?",
"密聊",
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2) == IDYES)
{
::ShellExecute(
NULL,
"open",
m_receive_file_name,
"",
"",
SW_SHOW);
}
return 0;
}
if(wParam == 2)
{
int arithmometer(0);
while(!(ValidatePrivateKey() && ValidatePublicKey()))
{//必須要把私鑰和公鑰安裝好了,才能開始接收消息
if(arithmometer++ == 5)
break;
};
if(arithmometer != 5)
{ //向對方發送"你好!我們可以進行安全通話了。"
}
}
return 0;
}
void CSecretChatDlg::TrayIcon() //設置狀態區圖標
{
if(AfxGetApp()->GetProfileInt("General", "Tray", 1))
{
//必須先刪除圖標才能用這種方法更改任務欄狀態區圖標
MyTaskBarDeleteIcon(
101,
m_hWnd);
if(m_online)
{
MyTaskBarAddIcon(
m_hWnd,
101,
m_hOnline,
"文件密使 - 密聊(已連接)");//在任務欄狀態區添加圖標
}
else
{
MyTaskBarAddIcon(
m_hWnd,
101,
m_hOffline,
"文件密使 - 密聊(未連接)");//在任務欄狀態區添加圖標
}
}
else
{
MyTaskBarDeleteIcon(
101,
m_hWnd); //從任務欄狀態區刪除圖標
}
}
void CSecretChatDlg::TextToMessagePackage(MessagePackage &package, CString strm) //將明文strm轉化成消息包
{
MessageDollop *pDollop;
__DWORD128 b1, b2;
int quotient, remainder, i, j;
CSecretKeyEdit secretKeyEditDlg; //只為了轉換時間格式
char chm[DATA_LENGTH]; //明文
// package.n/*明文長度*/ = strm.GetLength();
secretKeyEditDlg.CStringToChar(chm, strm, package.n);
quotient = (package.n * 2) / sizeof(MessageDollop);
remainder = (package.n * 2) % sizeof(MessageDollop);
if(remainder != 0)
{
quotient++;
//多余的補零
for(i = package.n;i < (package.n + (int)sizeof(MessageDollop) / 2 - remainder);i++)
{
chm[i] = 0;
}
}
pDollop = new MessageDollop[quotient]; //消息塊是消息包的元素
//分配每條消息塊和總消息包的ID
b2.Nil();
for(i = 0;i < quotient;i++)
{
b1.RandCount(); //沒有生成隨機的數嗎?
b2 = b2 + b1;
b1.Store(pDollop[i].messageDollop_ID/*每個消息塊的ID*/);
}
/* for(int s = 0;s < 32;s++)
{
if(b2 == m_send_message_package_ID[s])
{ //這里表示b1.RandCount()沒有生成隨機數
//TRACE("這里出錯了");
AfxMessageBox("出現了相同的隨機數了");
}
}*/
//把它添加到發送消息ID數組中,可以等下查詢
m_send_message_package_ID_add(b2/*這里b2變成了消息包的ID了*/);
//獲得當前的時間
CTime time = CTime::GetCurrentTime();
m_send_time = time.Format("%Y-%m-%d %H:%M:%S");
//寫入數字標識
b1.DigitalID();//這里b1變成了數字標識了
for(i = 0;i < quotient;i++)
{
//把消息塊合并成消息包
//必須為0,否則會無法進行加解密
pDollop[i].nil[0] = 0;
//消息包ID
b2.Store(pDollop[i].messagePackage_ID);
//數字標識
b1.Store(pDollop[i].digital_ID);
//發送時間
secretKeyEditDlg.CStringToChar(
pDollop[i].time,
m_send_time,
20);
//獲得正文內容
::MoveMemory(
pDollop[i].text,
chm + i * sizeof(MessageDollop) / 2,
sizeof(MessageDollop) / 2);//除2是因為只要得到正文信息
//設置隨機數
srand((unsigned)::GetTickCount()); //播撒隨機數的種子,rand()才能生成隨機數
for(j = 0;j < 16;j++)
{
pDollop[i].randCount[j] = (char)(0x41+rand()%0xAF);
//pDollop[j應該是i的這樣會產生無法回復的錯誤].randCount[j] = (char)rand();
}
//把信息存儲到消息包中
::MoveMemory(
package.data + i * sizeof(MessageDollop),//目標
(char *)&pDollop[i], //源內容
sizeof(MessageDollop));
}
//設置消息包的頭信息
package.head = HEAD_TEXT;
delete[] pDollop;
}
void CSecretChatDlg::MessagePackageToText(MessagePackage &package)//將消息包轉化成明文
{
MessageDollop *pDollop;
__DWORD128 b1, b2;
BOOL bMessagePackageID = TRUE; //只要有一個數字標識不合就永遠不能給m_receive_digital_ID合
int quotient, remainder, i;
CSecretKeyEdit secretKeyEditDlg; //只為了轉換時間格式
quotient = (package.n * 2) / sizeof(MessageDollop);
remainder = (package.n * 2) % sizeof(MessageDollop);
quotient = remainder?++quotient:quotient;//quotient代表有幾個消息塊
pDollop = new MessageDollop[quotient]; //消息塊是消息包的元素
m_receive_message_dollop_ID.Nil();
for(i = 0;i < quotient;i++)
{
//把消息包分成若干塊
::MoveMemory(
(char *)&pDollop[i], //目標
package.data + i * sizeof(MessageDollop),//源內容
sizeof(MessageDollop));
//獲得正文內容
::MoveMemory(
m_receive_text + i * sizeof(MessageDollop) / 2,
pDollop[i].text,
sizeof(MessageDollop) / 2);//除2是因為只要得到正文信息
//獲得數字標識
if(bMessagePackageID)
{
b1.Load(pDollop[i].digital_ID); //對方簽名的數字標識
b2.DigitalID();
if(!(b1 == b2))//只要有一個消息塊不合,就不能使得m_messagePackageID合格
{
bMessagePackageID = FALSE;
}
m_receive_digital_ID = b1;
}
//獲得消息包的ID
b1.Load(pDollop[i].messageDollop_ID/*每個消息塊的ID*/);
m_receive_message_dollop_ID = m_receive_message_dollop_ID + b1;
}
//獲得整個消息包的ID
m_receive_message_package_ID.Load(pDollop[0].messagePackage_ID/*消息包的ID*/);
//獲得消息發送的時間
m_receive_time = secretKeyEditDlg.CharToCString(pDollop[0].time, 20);
//獲取正文的長度
m_receive_text_length = package.n;
delete[] pDollop;
}
CString CSecretChatDlg::GetUserName() //獲得通信的用戶名
{
CString fileName =
m_appName
+ "\\user\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "UserPrivateKey");
CFile file;
SecretKey secretKey;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return "";
if(file.GetLength() != sizeof(SecretKey))
return "";
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
if(secretKey.ID != SECRETKEY_ID)
return "";
if(secretKey.privateOrPublic != SECRETKEY_PRIVATE)
return "";
return secretKey.userName;
}
CString CSecretChatDlg::GetFriendName() //獲得通信的好友名
{
CString fileName =
m_appName
+ "\\friend\\"
+ AfxGetApp()->GetProfileString("SecretKeySetup", "FriendPublicKey");
CFile file;
SecretKey secretKey;
if(!file.Open(
fileName,
CFile::modeReadWrite | CFile::typeBinary))
return "";
if(file.GetLength() != sizeof(SecretKey))
return "";
file.SeekToBegin();
file.Read(&secretKey, sizeof(SecretKey));
file.Close();
if(secretKey.ID != SECRETKEY_ID)
return "";
if(secretKey.privateOrPublic != SECRETKEY_PUBLIC)
return "";
return secretKey.userName;
}
void CSecretChatDlg::send_or_receive_tip(BOOL sendOrReceive)//發送和收到消息提示信息和處理
{
CString nowMessage; //現在獲得的信息
CFileFind find; //查找文件用
CFile file;
CString fileName; //消息記錄文件名
if(sendOrReceive)
{ //發送
nowMessage =
"("
+
m_send_time
+ ")\t"
+ GetUserName()
+ "\r\n"
+ m_message
+ "\r\n";
m_messageNote += nowMessage;
m_statusMessages.SetWindowText("發送消息");
m_messageNoteEdit.SetWindowText(m_messageNote);
//將消息記錄框滾動到最尾
m_messageNoteEdit.LineScroll(m_messageNoteEdit.GetLineCount());
m_messageEdit.SetWindowText("");
//焦點再回到消息輸入框
m_messageEdit.SetFocus();
PlayWaveSound(IDR_MESSAGESEND);
}
else
{
CSecretKeyEdit secretKeyEditDlg; //只為了轉換密文格式
nowMessage =
"("
+ m_receive_time
+ ")\t"
+ GetFriendName()
+ "\r\n"
+ secretKeyEditDlg.CharToCString(m_receive_text, m_receive_text_length)
+ "\r\n";
m_mes
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -