1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 19:42:48 -05:00

Merge out from trunk, to keep this branch viable. We are now up to

date as of r7913.

[originally from svn r7914]
[r7913 == d7eda6d99c]
This commit is contained in:
Simon Tatham
2008-03-10 18:48:36 +00:00
81 changed files with 2085 additions and 933 deletions

View File

@ -45,7 +45,7 @@ BEGIN
PUSHBUTTON "View &Licence", 101, 6, 52, 70, 14
CTEXT "Pageant", 102, 10, 6, 120, 8
CTEXT "", 100, 10, 16, 120, 16
CTEXT "\251 1997-2007 Simon Tatham. All rights reserved.",
CTEXT "\251 1997-2008 Simon Tatham. All rights reserved.",
103, 10, 34, 120, 16
END
@ -57,7 +57,7 @@ FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 98, 243, 44, 14
LTEXT "Copyright \251 1997-2007 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Copyright \251 1997-2008 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8

View File

@ -2,6 +2,7 @@
; $Id$
;
; -- Inno Setup installer script for PuTTY and its related tools.
; Last tested with Inno Setup 5.0.8.
;
; TODO for future releases:
;
@ -13,16 +14,16 @@
[Setup]
AppName=PuTTY
AppVerName=PuTTY version 0.59
VersionInfoTextVersion=Release 0.59
AppVersion=0.59
VersionInfoVersion=0.59.0.0
AppVerName=PuTTY version 0.60
VersionInfoTextVersion=Release 0.60
AppVersion=0.60
VersionInfoVersion=0.60.0.0
AppPublisher=Simon Tatham
AppPublisherURL=http://www.chiark.greenend.org.uk/~sgtatham/putty/
AppReadmeFile={app}\README.txt
DefaultDirName={pf}\PuTTY
DefaultGroupName=PuTTY
SetupIconFile=installer.ico
SetupIconFile=puttyins.ico
UninstallDisplayIcon={app}\putty.exe
ChangesAssociations=yes
;ChangesEnvironment=yes -- when PATH munging is sorted (probably)
@ -92,3 +93,14 @@ Root: HKCR; Subkey: "PuTTYPrivateKey\shell\edit\command"; ValueType: string; Val
; XXX: it would be nice if this task weren't run if a silent uninstall is
; requested, but "skipifsilent" is disallowed.
Filename: "{app}\putty.exe"; Parameters: "-cleanup-during-uninstall"; RunOnceId: "PuTTYCleanup"; StatusMsg: "Cleaning up saved sessions etc (optional)..."
[Messages]
; Since it's possible for the user to be asked to restart their computer,
; we should override the default messages to explain exactly why, so they
; can make an informed decision. (Especially as 95% of users won't need or
; want to restart; see rant above.)
FinishedRestartLabel=One or more [name] programs are still running. Setup will not replace these program files until you restart your computer. Would you like to restart now?
; This message is popped up in a message box on a /SILENT install.
FinishedRestartMessage=One or more [name] programs are still running.%nSetup will not replace these program files until you restart your computer.%n%nWould you like to restart now?
; ...and this comes up if you try to uninstall.
UninstalledAndNeedsRestart=One or more %1 programs are still running.%nThe program files will not be removed until your computer is restarted.%n%nWould you like to restart now?

View File

@ -38,7 +38,7 @@ BEGIN
PUSHBUTTON "View &Licence", 101, 6, 52, 70, 14
CTEXT "PuTTYgen", 102, 10, 6, 120, 8
CTEXT "", 100, 10, 16, 120, 16
CTEXT "\251 1997-2007 Simon Tatham. All rights reserved.",
CTEXT "\251 1997-2008 Simon Tatham. All rights reserved.",
103, 10, 34, 120, 16
END
@ -50,7 +50,7 @@ FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 98, 243, 44, 14
LTEXT "Copyright \251 1997-2007 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Copyright \251 1997-2008 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -39,24 +39,37 @@
/* We keep this around even for snapshots, for monotonicity of version
* numbering. It needs to be kept up to date. NB _comma_-separated. */
#define BASE_VERSION 0,59
#define BASE_VERSION 0,60
#if defined SNAPSHOT
/* Make SVN_REV mandatory for snapshots, to avoid issuing binary
* version numbers that look like full releases. */
#if (!defined SVN_REV) || (SVN_REV == 0)
#ifndef SVN_REV
#error SVN_REV not defined/nonzero for snapshot build
#endif
#define VERSION_TEXT "Development snapshot " STR(SNAPSHOT) ":r" STR(SVN_REV)
#ifdef MODIFIED
#define BINARY_VERSION 0,0,0,0
#else
#define BINARY_VERSION BASE_VERSION,SVN_REV,0
#endif
#elif defined RELEASE
#define VERSION_TEXT "Release " STR(RELEASE)
#define BINARY_VERSION BASE_VERSION,0,0
#elif defined SVN_REV
#define VERSION_TEXT "Custom build r" STR(SVN_REV)
#ifdef MODIFIED
#define BINARY_VERSION 0,0,0,0
#else
#define BINARY_VERSION BASE_VERSION,SVN_REV,0
#endif
#else
/* We can't reliably get the same date and time as version.c, so
@ -102,7 +115,7 @@ BEGIN
VALUE "OriginalFilename", APPNAME
VALUE "FileVersion", VERSION_TEXT
VALUE "ProductVersion", VERSION_TEXT
VALUE "LegalCopyright", "Copyright \251 1997-2007 Simon Tatham."
VALUE "LegalCopyright", "Copyright \251 1997-2008 Simon Tatham."
#if (!defined SNAPSHOT) && (!defined RELEASE)
/* Only if VS_FF_PRIVATEBUILD. */
VALUE "PrivateBuild", VERSION_TEXT /* NBI */

View File

@ -26,7 +26,7 @@ BEGIN
PUSHBUTTON "Visit &Web Site", IDA_WEB, 84, 52, 70, 14
CTEXT "PuTTY", IDA_TEXT1, 10, 6, 194, 8
CTEXT "", IDA_VERSION, 10, 16, 194, 16
CTEXT "\251 1997-2007 Simon Tatham. All rights reserved.",
CTEXT "\251 1997-2008 Simon Tatham. All rights reserved.",
IDA_TEXT2, 10, 34, 194, 16
END
@ -58,7 +58,7 @@ FONT 8, "MS Shell Dlg"
BEGIN
DEFPUSHBUTTON "OK", IDOK, 98, 243, 44, 14
LTEXT "Copyright \251 1997-2007 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Copyright \251 1997-2008 Simon Tatham", 1000, 10, 10, 206, 8
LTEXT "Portions copyright Robert de Bath, Joris van Rantwijk, Delian", 1001, 10, 26, 206, 8
LTEXT "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas", 1002, 10, 34, 206, 8

View File

@ -2194,8 +2194,13 @@ int dlg_listbox_index(union control *ctrl, void *dlg)
struct dlgparam *dp = (struct dlgparam *)dlg;
struct winctrl *c = dlg_findbyctrl(dp, ctrl);
int msg, ret;
assert(c && c->ctrl->generic.type == CTRL_LISTBOX &&
!c->ctrl->listbox.multisel);
assert(c && c->ctrl->generic.type == CTRL_LISTBOX);
if (c->ctrl->listbox.multisel) {
assert(c->ctrl->listbox.height != 0); /* not combo box */
ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, LB_GETSELCOUNT, 0, 0);
if (ret == LB_ERR || ret > 1)
return -1;
}
msg = (c->ctrl->listbox.height != 0 ? LB_GETCURSEL : CB_GETCURSEL);
ret = SendDlgItemMessage(dp->hwnd, c->base_id+1, msg, 0, 0);
if (ret == LB_ERR)

View File

@ -219,12 +219,7 @@ static void start_backend(void)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
back = backend_from_proto(cfg.protocol);
if (back == NULL) {
char *str = dupprintf("%s Internal Error", appname);
MessageBox(NULL, "Unsupported protocol number found",
@ -361,17 +356,18 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
{
char *p;
int got_host = 0;
/* By default, we bring up the config dialog, rather than launching
* a session. This gets set to TRUE if something happens to change
* that (e.g., a hostname is specified on the command-line). */
int allow_launch = FALSE;
default_protocol = be_default_protocol;
/* Find the appropriate default port. */
{
int i;
Backend *b = backend_from_proto(default_protocol);
default_port = 0; /* illegal */
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == default_protocol) {
default_port = backends[i].backend->default_port;
break;
}
if (b)
default_port = b->default_port;
}
cfg.logtype = LGTYP_NONE;
@ -397,6 +393,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
if (!cfg_launchable(&cfg) && !do_config()) {
cleanup_exit(0);
}
allow_launch = TRUE; /* allow it to be launched directly */
} else if (*p == '&') {
/*
* An initial & means we've been given a command line
@ -415,6 +412,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
} else if (!do_config()) {
cleanup_exit(0);
}
allow_launch = TRUE;
} else {
/*
* Otherwise, break up the command line and deal with
@ -539,7 +537,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
cmdline_run_saved(&cfg);
if (!cfg_launchable(&cfg) && !do_config()) {
if (loaded_session || got_host)
allow_launch = TRUE;
if ((!allow_launch || !cfg_launchable(&cfg)) && !do_config()) {
cleanup_exit(0);
}
@ -596,15 +597,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
}
}
/* Check for invalid Port number (i.e. zero) */
if (cfg.port == 0) {
char *str = dupprintf("%s Internal Error", appname);
MessageBox(NULL, "Invalid Port Number",
str, MB_OK | MB_ICONEXCLAMATION);
sfree(str);
cleanup_exit(1);
}
if (!prev) {
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
@ -816,9 +808,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
sfree(handles);
if (must_close_session)
close_session();
}
sfree(handles);
} else
sfree(handles);
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT)
@ -3564,8 +3555,9 @@ int char_width(Context ctx, int uc) {
/*
* Translate a WM_(SYS)?KEY(UP|DOWN) message into a string of ASCII
* codes. Returns number of bytes used or zero to drop the message
* or -1 to forward the message to windows.
* codes. Returns number of bytes used, zero to drop the message,
* -1 to forward the message to Windows, or another negative number
* to indicate a NUL-terminated "special" string.
*/
static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
unsigned char *output)
@ -3985,9 +3977,9 @@ static int TranslateKey(UINT message, WPARAM wParam, LPARAM lParam,
return p - output;
}
if (wParam == VK_CANCEL && shift_state == 2) { /* Ctrl-Break */
*p++ = 3;
*p++ = 0;
return -2;
if (back)
back->special(backhandle, TS_BRK);
return 0;
}
if (wParam == VK_PAUSE) { /* Break/Pause */
*p++ = 26;

View File

@ -96,7 +96,7 @@ struct handle_input {
*/
char buffer[4096]; /* the data read from the handle */
DWORD len; /* how much data that was */
int readret; /* lets us know about read errors */
int readerr; /* lets us know about read errors */
/*
* Callback function called by this module when data arrives on
@ -113,7 +113,7 @@ static DWORD WINAPI handle_input_threadfunc(void *param)
struct handle_input *ctx = (struct handle_input *) param;
OVERLAPPED ovl, *povl;
HANDLE oev;
int readlen;
int readret, readlen;
if (ctx->flags & HANDLE_FLAG_OVERLAPPED) {
povl = &ovl;
@ -132,17 +132,34 @@ static DWORD WINAPI handle_input_threadfunc(void *param)
memset(povl, 0, sizeof(OVERLAPPED));
povl->hEvent = oev;
}
ctx->readret = ReadFile(ctx->h, ctx->buffer, readlen,
&ctx->len, povl);
if (povl && !ctx->readret && GetLastError() == ERROR_IO_PENDING) {
readret = ReadFile(ctx->h, ctx->buffer,readlen, &ctx->len, povl);
if (!readret)
ctx->readerr = GetLastError();
else
ctx->readerr = 0;
if (povl && !readret && ctx->readerr == ERROR_IO_PENDING) {
WaitForSingleObject(povl->hEvent, INFINITE);
ctx->readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
readret = GetOverlappedResult(ctx->h, povl, &ctx->len, FALSE);
if (!readret)
ctx->readerr = GetLastError();
else
ctx->readerr = 0;
}
if (!ctx->readret)
if (!readret) {
/*
* Windows apparently sends ERROR_BROKEN_PIPE when a
* pipe we're reading from is closed normally from the
* writing end. This is ludicrous; if that situation
* isn't a natural EOF, _nothing_ is. So if we get that
* particular error, we pretend it's EOF.
*/
if (ctx->readerr == ERROR_BROKEN_PIPE)
ctx->readerr = 0;
ctx->len = 0;
}
if (ctx->readret && ctx->len == 0 &&
if (readret && ctx->len == 0 &&
(ctx->flags & HANDLE_FLAG_IGNOREEOF))
continue;
@ -227,7 +244,7 @@ struct handle_output {
* and read by the main thread after receiving that signal.
*/
DWORD lenwritten; /* how much data we actually wrote */
int writeret; /* return value from WriteFile */
int writeerr; /* return value from WriteFile */
/*
* Data only ever read or written by the main thread.
@ -245,6 +262,7 @@ static DWORD WINAPI handle_output_threadfunc(void *param)
{
struct handle_output *ctx = (struct handle_output *) param;
OVERLAPPED ovl, *povl;
int writeret;
if (ctx->flags & HANDLE_FLAG_OVERLAPPED)
povl = &ovl;
@ -259,14 +277,23 @@ static DWORD WINAPI handle_output_threadfunc(void *param)
}
if (povl)
memset(povl, 0, sizeof(OVERLAPPED));
ctx->writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
&ctx->lenwritten, povl);
if (povl && !ctx->writeret && GetLastError() == ERROR_IO_PENDING)
ctx->writeret = GetOverlappedResult(ctx->h, povl,
&ctx->lenwritten, TRUE);
writeret = WriteFile(ctx->h, ctx->buffer, ctx->len,
&ctx->lenwritten, povl);
if (!writeret)
ctx->writeerr = GetLastError();
else
ctx->writeerr = 0;
if (povl && !writeret && GetLastError() == ERROR_IO_PENDING) {
writeret = GetOverlappedResult(ctx->h, povl,
&ctx->lenwritten, TRUE);
if (!writeret)
ctx->writeerr = GetLastError();
else
ctx->writeerr = 0;
}
SetEvent(ctx->ev_to_main);
if (!ctx->writeret)
if (!writeret)
break;
}
@ -512,7 +539,7 @@ void handle_got_event(HANDLE event)
/*
* EOF, or (nearly equivalently) read error.
*/
h->u.i.gotdata(h, NULL, (h->u.i.readret ? 0 : -1));
h->u.i.gotdata(h, NULL, -h->u.i.readerr);
h->u.i.defunct = TRUE;
} else {
backlog = h->u.i.gotdata(h, h->u.i.buffer, h->u.i.len);
@ -526,13 +553,13 @@ void handle_got_event(HANDLE event)
* write. Call the callback to indicate that the output
* buffer size has decreased, or to indicate an error.
*/
if (!h->u.o.writeret) {
if (h->u.o.writeerr) {
/*
* Write error. Send a negative value to the callback,
* and mark the thread as defunct (because the output
* thread is terminating by now).
*/
h->u.o.sentdata(h, -1);
h->u.o.sentdata(h, -h->u.o.writeerr);
h->u.o.defunct = TRUE;
} else {
bufchain_consume(&h->u.o.queued_data, h->u.o.lenwritten);

View File

@ -21,7 +21,6 @@ static int help_has_contents;
#ifndef NO_HTMLHELP
typedef HWND (CALLBACK *htmlhelp_t)(HWND, LPCSTR, UINT, DWORD);
static char *chm_path;
static DWORD html_help_cookie;
static htmlhelp_t htmlhelp;
#endif /* NO_HTMLHELP */
@ -63,9 +62,7 @@ void init_help(void)
if (!htmlhelp)
FreeLibrary(dllHH);
}
if (htmlhelp)
htmlhelp(NULL, NULL, HH_INITIALIZE, (DWORD)&html_help_cookie);
else
if (!htmlhelp)
chm_path = NULL;
}
#endif /* NO_HTMLHELP */
@ -73,10 +70,9 @@ void init_help(void)
void shutdown_help(void)
{
#ifndef NO_HTMLHELP
if (chm_path)
htmlhelp(NULL, NULL, HH_UNINITIALIZE, html_help_cookie);
#endif /* NO_HTMLHELP */
/* Nothing to do currently.
* (If we were running HTML Help single-threaded, this is where we'd
* call HH_UNINITIALIZE.) */
}
int has_help(void)

View File

@ -42,6 +42,7 @@
#define WINHELP_CTX_terminal_autowrap "terminal.autowrap:config-autowrap"
#define WINHELP_CTX_terminal_decom "terminal.decom:config-decom"
#define WINHELP_CTX_terminal_lfhascr "terminal.lfhascr:config-crlf"
#define WINHELP_CTX_terminal_crhaslf "terminal.crhaslf:config-lfcr"
#define WINHELP_CTX_terminal_bce "terminal.bce:config-erase"
#define WINHELP_CTX_terminal_blink "terminal.blink:config-blink"
#define WINHELP_CTX_terminal_answerback "terminal.answerback:config-answerback"
@ -130,6 +131,7 @@
#define WINHELP_CTX_ssh_bugs_rsapad2 "ssh.bugs.rsapad2:config-ssh-bug-sig"
#define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2:config-ssh-bug-pksessid2"
#define WINHELP_CTX_ssh_bugs_rekey2 "ssh.bugs.rekey2:config-ssh-bug-rekey"
#define WINHELP_CTX_ssh_bugs_maxpkt2 "ssh.bugs.maxpkt2:config-ssh-bug-maxpkt2"
#define WINHELP_CTX_serial_line "serial.line:config-serial-line"
#define WINHELP_CTX_serial_speed "serial.speed:config-serial-speed"
#define WINHELP_CTX_serial_databits "serial.databits:config-serial-databits"

View File

@ -96,6 +96,10 @@ static int cmpfortree(void *av, void *bv)
return -1;
if (as > bs)
return +1;
if (a < b)
return -1;
if (a > b)
return +1;
return 0;
}
@ -788,6 +792,14 @@ static DWORD try_connect(Actual_Socket sock)
family = AF_INET;
}
/*
* Remove the socket from the tree before we overwrite its
* internal socket id, because that forms part of the tree's
* sorting criterion. We'll add it back before exiting this
* function, whether we changed anything or not.
*/
del234(sktree, sock);
s = p_socket(family, SOCK_STREAM, 0);
sock->s = s;
@ -932,11 +944,15 @@ static DWORD try_connect(Actual_Socket sock)
sock->writable = 1;
}
add234(sktree, sock);
err = 0;
ret:
/*
* No matter what happened, put the socket back in the tree.
*/
add234(sktree, sock);
if (err)
plug_log(sock->plug, 1, sock->addr, sock->port, sock->error, err);
return err;

View File

@ -228,7 +228,13 @@ int stdin_gotdata(struct handle *h, void *data, int len)
/*
* Special case: report read error.
*/
fprintf(stderr, "Unable to read from standard input\n");
char buf[4096];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -len, 0,
buf, lenof(buf), NULL);
buf[lenof(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Unable to read from standard input: %s\n", buf);
cleanup_exit(0);
}
noise_ultralight(len);
@ -249,8 +255,14 @@ void stdouterr_sent(struct handle *h, int new_backlog)
/*
* Special case: report write error.
*/
fprintf(stderr, "Unable to write to standard %s\n",
(h == stdout_handle ? "output" : "error"));
char buf[4096];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, -new_backlog, 0,
buf, lenof(buf), NULL);
buf[lenof(buf)-1] = '\0';
if (buf[strlen(buf)-1] == '\n')
buf[strlen(buf)-1] = '\0';
fprintf(stderr, "Unable to write to standard %s: %s\n",
(h == stdout_handle ? "output" : "error"), buf);
cleanup_exit(0);
}
if (connopen && back->connected(backhandle)) {
@ -295,13 +307,10 @@ int main(int argc, char **argv)
char *p = getenv("PLINK_PROTOCOL");
int i;
if (p) {
for (i = 0; backends[i].backend != NULL; i++) {
if (!strcmp(backends[i].name, p)) {
default_protocol = cfg.protocol = backends[i].protocol;
default_port = cfg.port =
backends[i].backend->default_port;
break;
}
const Backend *b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
default_port = cfg.port = b->default_port;
}
}
}
@ -368,19 +377,14 @@ int main(int argc, char **argv)
*/
r = strchr(p, ',');
if (r) {
int i, j;
for (i = 0; backends[i].backend != NULL; i++) {
j = strlen(backends[i].name);
if (j == r - p &&
!memcmp(backends[i].name, p, j)) {
default_protocol = cfg.protocol =
backends[i].protocol;
portnumber =
backends[i].backend->default_port;
p = r + 1;
break;
}
const Backend *b;
*r = '\0';
b = backend_from_name(p);
if (b) {
default_protocol = cfg.protocol = b->protocol;
portnumber = b->default_port;
}
p = r + 1;
}
/*
@ -523,19 +527,11 @@ int main(int argc, char **argv)
* Select protocol. This is farmed out into a table in a
* separate file to enable an ssh-free variant.
*/
{
int i;
back = NULL;
for (i = 0; backends[i].backend != NULL; i++)
if (backends[i].protocol == cfg.protocol) {
back = backends[i].backend;
break;
}
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
back = backend_from_proto(cfg.protocol);
if (back == NULL) {
fprintf(stderr,
"Internal fault: Unsupported protocol found\n");
return 1;
}
/*

View File

@ -21,7 +21,7 @@ struct printer_job_tag {
static char *printer_add_enum(int param, DWORD level, char *buffer,
int offset, int *nprinters_ptr)
{
DWORD needed, nprinters;
DWORD needed = 0, nprinters = 0;
buffer = sresize(buffer, offset+512, char);

View File

@ -221,8 +221,39 @@ static const char *serial_init(void *frontend_handle, void **backend_handle,
logevent(serial->frontend, msg);
}
serport = CreateFile(cfg->serline, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
{
/*
* Munge the string supplied by the user into a Windows filename.
*
* Windows supports opening a few "legacy" devices (including
* COM1-9) by specifying their names verbatim as a filename to
* open. (Thus, no files can ever have these names. See
* <http://msdn2.microsoft.com/en-us/library/aa365247.aspx>
* ("Naming a File") for the complete list of reserved names.)
*
* However, this doesn't let you get at devices COM10 and above.
* For that, you need to specify a filename like "\\.\COM10".
* This is also necessary for special serial and serial-like
* devices such as \\.\WCEUSBSH001. It also works for the "legacy"
* names, so you can do \\.\COM1 (verified as far back as Win95).
* See <http://msdn2.microsoft.com/en-us/library/aa363858.aspx>
* (CreateFile() docs).
*
* So, we believe that prepending "\\.\" should always be the
* Right Thing. However, just in case someone finds something to
* talk to that doesn't exist under there, if the serial line
* contains a backslash, we use it verbatim. (This also lets
* existing configurations using \\.\ continue working.)
*/
char *serfilename =
dupprintf("%s%s",
strchr(cfg->serline, '\\') ? "" : "\\\\.\\",
cfg->serline);
serport = CreateFile(serfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
sfree(serfilename);
}
if (serport == INVALID_HANDLE_VALUE)
return "Unable to open serial port";
@ -423,5 +454,7 @@ Backend serial_backend = {
serial_provide_logctx,
serial_unthrottle,
serial_cfg_info,
1
"serial",
PROT_SERIAL,
0
};