Skip to content

Commit

Permalink
便携版 0.20
Browse files Browse the repository at this point in the history
  • Loading branch information
larryli committed Mar 12, 2023
1 parent 5c5082f commit 4e74b33
Show file tree
Hide file tree
Showing 3 changed files with 1,615 additions and 291 deletions.
6 changes: 3 additions & 3 deletions version.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
* default stuff used for local development runs of 'make'.
*/

#define TEXTVER "发布版 0.78-cn1"
#define SSHVER "-Release-0-78-CN1"
#define BINARY_VERSION 0,78,0,1
#define TEXTVER "发布版 0.78-cn1 (便携版 0.20)"
#define SSHVER "-Release-0-78-patch20-CN1"
#define BINARY_VERSION 0,78,20,1
308 changes: 292 additions & 16 deletions windows/pageant.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
* Pageant: the PuTTY Authentication Agent.
*/

/*
* JK: disk config 0.20 from 11. 12. 2022
*
* rewritten for storing information primary to disk
* reasonable error handling and reporting except for
* memory allocation errors (not enough memory)
*
* http://jakub.kotrla.net/putty/
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
Expand Down Expand Up @@ -74,6 +83,54 @@ static filereq *keypath = NULL;
#define PUTTY_DEFAULT "Default%20Settings"
static int initial_menuitems_count;


/* JK: buffers for path strings */
static char oldpath[2 * MAX_PATH] = "\0";
static char puttypath[2 * MAX_PATH] = "\0";

/* JK: my generic function for simplyfing error reporting */
DWORD errorShow(const char* pcErrText, const char* pcErrParam) {
HWND hwRParent;
DWORD errorCode;
char pcBuf[16];
char* pcMessage;

if (pcErrParam != NULL) {
pcMessage = snewn(strlen(pcErrParam) + strlen(pcErrText) + 31, char);
}
else {
pcMessage = snewn(strlen(pcErrText) + 31, char);
}

errorCode = GetLastError();
ltoa(errorCode, pcBuf, 10);

strcpy(pcMessage, "Error: ");
strcat(pcMessage, pcErrText);
strcat(pcMessage, "\n");

if (pcErrParam) {
strcat(pcMessage, pcErrParam);
strcat(pcMessage, "\n");
}
strcat(pcMessage, "Error code: ");
strcat(pcMessage, pcBuf);

/* JK: get parent-window and show */
hwRParent = GetActiveWindow();
if (hwRParent != NULL) { hwRParent = GetLastActivePopup(hwRParent); }

if (MessageBox(hwRParent, pcMessage, "Error", MB_OK | MB_APPLMODAL | MB_ICONEXCLAMATION) == 0) {
/* JK: this is really bad -> just ignore */
return 0;
}

sfree(pcMessage);
return errorCode;
};



/*
* Print a modal (Really Bad) message box and perform a fatal exit.
*/
Expand Down Expand Up @@ -893,43 +950,260 @@ static BOOL AddTrayIcon(HWND hwnd)
return res;
}

/* Update the saved-sessions menu. */
/*
* JK: rewritten to be able to load configuration from disk
* as rewritten putty saves it there - http://jakub.kotrla.net/putty/
*/
static void update_sessions(void)
{
int num_entries;
HKEY hkey;
TCHAR buf[MAX_PATH + 1];
TCHAR buf[MAX_PATH + 128];
MENUITEMINFO mii;
strbuf *sb;

HANDLE hFile;
char* fileCont = NULL;
DWORD fileSize;
DWORD bytesRead;
char* p = NULL;
char* p2 = NULL;
char* pcBuf = NULL;
strbuf* sb;

char sesspath[2 * MAX_PATH] = "\0";
char curdir[2 * MAX_PATH] = "\0";
char sessionsuffix[16] = "\0";
WIN32_FIND_DATA FindFileData;
int index_key, index_menu;

if (!putty_path)
return;
if (!putty_path) return;

if(ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, PUTTY_REGKEY, &hkey))
return;

for(num_entries = GetMenuItemCount(session_menu);
/* clear old menu */
for (num_entries = GetMenuItemCount(session_menu);
num_entries > initial_menuitems_count;
num_entries--)
RemoveMenu(session_menu, 0, MF_BYPOSITION);

/* init for new menu */
index_key = 0;
index_menu = 0;


/* JK: save path/curdir */
GetCurrentDirectory((MAX_PATH * 2), oldpath);


/* JK: try curdir for putty.conf first */
hFile = CreateFile("putty.conf", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile != INVALID_HANDLE_VALUE)
{
/* JK: there is a putty.conf in curdir - use it and use curdir as puttypath */
GetCurrentDirectory((MAX_PATH * 2), puttypath);
GetCurrentDirectory((MAX_PATH * 2), curdir);
CloseHandle(hFile);
}
else {
/* JK: get where putty.exe is */
if (GetModuleFileName(NULL, puttypath, (MAX_PATH * 2)) != 0)
{
p = strrchr(puttypath, '\\');
if (p)
{
*p = '\0';
}
SetCurrentDirectory(puttypath);
}
else GetCurrentDirectory((MAX_PATH * 2), puttypath);
}

/* JK: set default values - if there is a config file, it will be overwitten */
strcpy(sesspath, puttypath);
strcat(sesspath, "\\sessions");

hFile = CreateFile("putty.conf", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

/* JK: now we can pre-clean-up */
SetCurrentDirectory(oldpath);

/* JK: read from putty.conf if is there */
if (hFile != INVALID_HANDLE_VALUE) {
fileSize = GetFileSize(hFile, NULL);
fileCont = snewn(fileSize + 16, char);

if (!ReadFile(hFile, fileCont, fileSize, &bytesRead, NULL)) {
errorShow("无法读取配置文件,回滚到默认设置", NULL);

/* JK: default values are already there - just clean-up */
}
else
{
/* JK: parse conf file to path variables */
*(fileCont + fileSize + 1) = '\0';
*(fileCont + fileSize) = '\n';
p = fileCont;
while (p) {
if (*p == ';') { /* JK: comment -> skip line */
p = strchr(p, '\n');
++p;
continue;
}
p2 = strchr(p, '=');
if (!p2) break;
*p2 = '\0';
++p2;

if (!strcmp(p, "sessions")) {
p = strchr(p2, '\n');
*p = '\0';

/* This is actually call to joinPath, done inline and optimized just for pageant */
pcBuf = snewn(MAX_PATH + 1, char);

/* at first ExpandEnvironmentStrings */
if (0 == ExpandEnvironmentStrings(p2, pcBuf, MAX_PATH)) {
/* JK: failure -> revert back - but it ussualy won't work, so report error to user! */
errorShow("Unable to ExpandEnvironmentStrings for session path", p2);
strncpy(pcBuf, p2, strlen(p2));
}

if ((*pcBuf == '/') || (*pcBuf == '\\')) {
/* JK: everything ok */
strcpy(sesspath, curdir);
strcat(sesspath, pcBuf);
}
else {
if (*(pcBuf + 1) == ':') {
/* JK: absolute path */
strcpy(sesspath, pcBuf);
}
else {
/* JK: some weird relative path - add '\' */
strcpy(sesspath, curdir);
strcat(sesspath, "\\");
strcat(sesspath, pcBuf);
}
}
sfree(pcBuf);

p2 = sesspath + strlen(sesspath) - 1;
while ((*p2 == ' ') || (*p2 == '\n') || (*p2 == '\r') || (*p2 == '\t')) --p2;
*(p2 + 1) = '\0';
}
else if (!strcmp(p, "sessionsuffix")) {
p = strchr(p2, '\n');
*p = '\0';
strcpy(sessionsuffix, p2);
p2 = sessionsuffix + strlen(sessionsuffix) - 1;
while ((*p2 == ' ') || (*p2 == '\n') || (*p2 == '\r') || (*p2 == '\t')) --p2;
*(p2 + 1) = '\0';
}
else {
p = strchr(p2, '\n');
}
/* JK: else if - pageant don't care about other stuff */
++p;
}
}

CloseHandle(hFile);
sfree(fileCont);
}
/* else - INVALID_HANDLE {
* JK: unable to read conf file - probably doesn't exists
* we won't create one, user wants putty light, just fall back to defaults
* and defaults are already there
}*/

/* JK: we have path to sessions */

if (SetCurrentDirectory(sesspath)) {

/* JK: we're able to load from files */
hFile = FindFirstFile("*", &FindFileData);

/* JK: skip directories ("." and ".." too) */
while ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
if (!FindNextFile(hFile, &FindFileData)) {
break;
}
}

sb = strbuf_new();

/* JK: add first file */
if (hFile != INVALID_HANDLE_VALUE) {
unescape_registry_key(FindFileData.cFileName, sb);

/* JK: cut off session.suffix */
p = sb->s + strlen(sb->s) - strlen(sessionsuffix);
if (strncmp(p, sessionsuffix, strlen(sessionsuffix)) == 0) {
*p = '\0';

if (strcmp(sb->s, PUTTY_DEFAULT) != 0) {
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.wID = (index_menu * 16) + IDM_SESSIONS_BASE;
mii.dwTypeData = sb->s;
InsertMenuItem(session_menu, index_menu, TRUE, &mii);
index_menu++;
}
}
}

/* JK: enum files */
while (FindNextFile(hFile, &FindFileData)) {
/* JK: add files as menu item one-by-one */

sb->len = 0;
unescape_registry_key(FindFileData.cFileName, sb);

/* JK: cut off sessionsuffix */
p = sb->s + strlen(sb->s) - strlen(sessionsuffix);
if (strncmp(p, sessionsuffix, strlen(sessionsuffix)) == 0) {
*p = '\0';

if (strcmp(sb->s, PUTTY_DEFAULT) != 0) {
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.wID = (index_menu * 16) + IDM_SESSIONS_BASE;
mii.dwTypeData = sb->s;
InsertMenuItem(session_menu, index_menu, TRUE, &mii);
index_menu++;
}
}
}

FindClose(hFile);
strbuf_free(sb);
SetCurrentDirectory(curdir);
}

/* JK: load keys from registry */
if (ERROR_SUCCESS != RegOpenKey(HKEY_CURRENT_USER, PUTTY_REGKEY, &hkey)) {
return;
}

sb = strbuf_new();
while(ERROR_SUCCESS == RegEnumKey(hkey, index_key, buf, MAX_PATH)) {
if(strcmp(buf, PUTTY_DEFAULT) != 0) {
strbuf_clear(sb);
unescape_registry_key(buf, sb);
while (ERROR_SUCCESS == RegEnumKey(hkey, index_key, buf, MAX_PATH)) {
strbuf_clear(sb);
unescape_registry_key(buf, sb);

if (strcmp(buf, PUTTY_DEFAULT) != 0) {
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
mii.wID = (index_menu * 16) + IDM_SESSIONS_BASE;
/* JK: add [registry] mark */
put_fmt(sb, " [注册表]]");
mii.dwTypeData = sb->s;
InsertMenuItem(session_menu, index_menu, true, &mii);
index_menu++;
Expand All @@ -940,7 +1214,7 @@ static void update_sessions(void)

RegCloseKey(hkey);

if(index_menu == 0) {
if (index_menu == 0) {
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE | MIIM_STATE;
mii.fType = MFT_STRING;
Expand Down Expand Up @@ -1309,8 +1583,9 @@ static LRESULT CALLBACK TrayWndProc(HWND hwnd, UINT message,
if (restrict_putty_acl)
strcat(cmdline, "&R");

/* JK: execute putty.exe with working directory same as is for pageant.exe */
if((INT_PTR)ShellExecute(hwnd, NULL, putty_path, cmdline,
_T(""), SW_SHOW) <= 32) {
putty_path, SW_SHOW) <= 32) {
MessageBox(NULL, "无法执行 PuTTY!",
"错误", MB_OK | MB_ICONERROR);
}
Expand Down Expand Up @@ -1384,8 +1659,9 @@ static LRESULT CALLBACK TrayWndProc(HWND hwnd, UINT message,
strcat(param, "&R");
strcat(param, "@");
strcat(param, mii.dwTypeData);
/* JK: execute putty.exe with working directory same as is for pageant.exe */
if((INT_PTR)ShellExecute(hwnd, NULL, putty_path, param,
_T(""), SW_SHOW) <= 32) {
puttypath, SW_SHOW) <= 32) {
MessageBox(NULL, "无法执行 PuTTY!", "错误",
MB_OK | MB_ICONERROR);
}
Expand Down
Loading

0 comments on commit 4e74b33

Please sign in to comment.