From: Iain Patterson Date: Wed, 15 Jan 2014 21:27:32 +0000 (+0000) Subject: Adjust buffer sizes. X-Git-Tag: v2.22~49 X-Git-Url: http://git.iain.cx/?p=nssm.git;a=commitdiff_plain;h=2994e17c24d8a3d32937a92733ba1ee0f26dc33d Adjust buffer sizes. Unicode applications can under certain circumstances access paths longer than MAX_PATH characters. Service names are limited to 256 characters. Adjust our buffers to suit. --- diff --git a/gui.cpp b/gui.cpp index 64382f4..3f34943 100644 --- a/gui.cpp +++ b/gui.cpp @@ -746,14 +746,17 @@ void browse(HWND window, TCHAR *current, unsigned long flags, ...) { va_end(arg); /* Remainder of the buffer is already zeroed */ } - ofn.lpstrFile = new TCHAR[MAX_PATH]; + ofn.lpstrFile = new TCHAR[PATH_LENGTH]; if (flags & OFN_NOVALIDATE) { /* Directory hack. */ - _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES)); + _sntprintf_s(ofn.lpstrFile, _countof(ofn.lpstrFile), _TRUNCATE, _T(":%s:"), message_string(NSSM_GUI_BROWSE_FILTER_DIRECTORIES)); + ofn.nMaxFile = DIR_LENGTH; } - else _sntprintf_s(ofn.lpstrFile, MAX_PATH, _TRUNCATE, _T("%s"), current); + else { + _sntprintf_s(ofn.lpstrFile, _countof(ofn.lpstrFile), _TRUNCATE, _T("%s"), current); + ofn.nMaxFile = PATH_LENGTH; + } ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE); - ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | flags; if (GetOpenFileName(&ofn)) { @@ -774,7 +777,7 @@ INT_PTR CALLBACK tab_dlg(HWND tab, UINT message, WPARAM w, LPARAM l) { /* Button was pressed or control was controlled. */ case WM_COMMAND: HWND dlg; - TCHAR buffer[MAX_PATH]; + TCHAR buffer[PATH_LENGTH]; unsigned char enabled; switch (LOWORD(w)) { diff --git a/io.cpp b/io.cpp index 2578800..3f80810 100644 --- a/io.cpp +++ b/io.cpp @@ -71,7 +71,7 @@ int get_createfile_parameters(HKEY key, TCHAR *prefix, TCHAR *path, unsigned lon log_event(EVENTLOG_ERROR_TYPE, NSSM_EVENT_OUT_OF_MEMORY, prefix, _T("get_createfile_parameters()"), 0); return 1; } - switch (expand_parameter(key, value, path, MAX_PATH, true, false)) { + switch (expand_parameter(key, value, path, PATH_LENGTH, true, false)) { case 0: if (! path[0]) return 0; break; /* OK. */ default: return 2; /* Error. */ } @@ -165,10 +165,10 @@ static void rotated_filename(TCHAR *path, TCHAR *rotated, unsigned long rotated_ GetSystemTime(st); } - TCHAR buffer[MAX_PATH]; + TCHAR buffer[PATH_LENGTH]; memmove(buffer, path, sizeof(buffer)); TCHAR *ext = PathFindExtension(buffer); - TCHAR extension[MAX_PATH]; + TCHAR extension[PATH_LENGTH]; _sntprintf_s(extension, _countof(extension), _TRUNCATE, _T("-%04u%02u%02uT%02u%02u%02u.%03u%s"), st->wYear, st->wMonth, st->wDay, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds, ext); *ext = _T('\0'); _sntprintf_s(rotated, rotated_len, _TRUNCATE, _T("%s%s"), buffer, extension); @@ -227,7 +227,7 @@ void rotate_file(TCHAR *service_name, TCHAR *path, unsigned long seconds, unsign /* Get new filename. */ FileTimeToSystemTime(&info.ftLastWriteTime, &st); - TCHAR rotated[MAX_PATH]; + TCHAR rotated[PATH_LENGTH]; rotated_filename(path, rotated, _countof(rotated), &st); /* Rotate. */ @@ -507,7 +507,7 @@ unsigned long WINAPI log_and_rotate(void *arg) { /* Rotate. */ *logger->rotate_online = NSSM_ROTATE_ONLINE; - TCHAR rotated[MAX_PATH]; + TCHAR rotated[PATH_LENGTH]; rotated_filename(logger->path, rotated, _countof(rotated), 0); /* diff --git a/nssm.h b/nssm.h index 8e82d59..1ad2b94 100644 --- a/nssm.h +++ b/nssm.h @@ -1,6 +1,37 @@ #ifndef NSSM_H #define NSSM_H +/* + MSDN says, basically, that the maximum length of a path is 260 characters, + which is represented by the constant MAX_PATH. Except when it isn't. + + The maximum length of a directory path is MAX_PATH - 12 because it must be + possible to create a file in 8.3 format under any valid directory. + + Unicode versions of filesystem API functions accept paths up to 32767 + characters if the first four (wide) characters are L"\\?\" and each component + of the path, separated by L"\", does not exceed the value of + lpMaximumComponentLength returned by GetVolumeInformation(), which is + probably 255. But might not be. + + Relative paths are always limited to MAX_PATH because the L"\\?\" prefix + is not valid for a relative path. + + Note that we don't care about the last two paragraphs because we're only + concerned with allocating buffers big enough to store valid paths. If the + user tries to store invalid paths they will fit in the buffers but the + application will fail. The reason for the failure will end up in the + event log and the user will realise the mistake. + + So that's that cleared up, then. +*/ +#ifdef UNICODE +#define PATH_LENGTH 32767 +#else +#define PATH_LENGTH MAX_PATH +#endif +#define DIR_LENGTH PATH_LENGTH - 12 + #define _WIN32_WINNT 0x0500 #include #include diff --git a/process.cpp b/process.cpp index 69aea03..19b893a 100644 --- a/process.cpp +++ b/process.cpp @@ -314,7 +314,7 @@ void kill_process_tree(nssm_service_t *service, unsigned long pid, unsigned long -1 on error. */ int test_environment(TCHAR *env) { - TCHAR path[MAX_PATH]; + TCHAR path[PATH_LENGTH]; GetModuleFileName(0, path, _countof(path)); STARTUPINFO si; ZeroMemory(&si, sizeof(si)); diff --git a/registry.cpp b/registry.cpp index 0cb552f..158158d 100644 --- a/registry.cpp +++ b/registry.cpp @@ -17,7 +17,7 @@ int create_messages() { } /* Get path of this program */ - TCHAR path[MAX_PATH]; + TCHAR path[PATH_LENGTH]; GetModuleFileName(0, path, _countof(path)); /* Try to register the module but don't worry so much on failure */ @@ -609,7 +609,7 @@ int get_parameters(nssm_service_t *service, STARTUPINFO *si) { if (get_number(key, NSSM_REG_ROTATE_BYTES_HIGH, &service->rotate_bytes_high, false) != 1) service->rotate_bytes_high = 0; /* Change to startup directory in case stdout/stderr are relative paths. */ - TCHAR cwd[MAX_PATH]; + TCHAR cwd[PATH_LENGTH]; GetCurrentDirectory(_countof(cwd), cwd); SetCurrentDirectory(service->dir); diff --git a/service.h b/service.h index 0d37757..6da55f3 100644 --- a/service.h +++ b/service.h @@ -6,16 +6,16 @@ /* MSDN says the commandline in CreateProcess() is limited to 32768 characters and the application name to MAX_PATH. + A service name and service display name are limited to 256 characters. A registry key is limited to 255 characters. A registry value is limited to 16383 characters. Therefore we limit the service name to accommodate the path under HKLM. */ -#define EXE_LENGTH MAX_PATH +#define EXE_LENGTH PATH_LENGTH #define CMD_LENGTH 32768 #define KEY_LENGTH 255 #define VALUE_LENGTH 16383 -#define SERVICE_NAME_LENGTH KEY_LENGTH - 55 -#define SERVICE_DISPLAYNAME_LENGTH 256 +#define SERVICE_NAME_LENGTH 256 #define ACTION_LEN 16 @@ -35,7 +35,7 @@ typedef struct { bool native; TCHAR name[SERVICE_NAME_LENGTH]; - TCHAR displayname[SERVICE_DISPLAYNAME_LENGTH]; + TCHAR displayname[SERVICE_NAME_LENGTH]; TCHAR description[VALUE_LENGTH]; unsigned long startup; TCHAR *username; @@ -43,28 +43,28 @@ typedef struct { TCHAR *password; size_t passwordlen; unsigned long type; - TCHAR image[MAX_PATH]; + TCHAR image[PATH_LENGTH]; TCHAR exe[EXE_LENGTH]; TCHAR flags[VALUE_LENGTH]; - TCHAR dir[MAX_PATH]; + TCHAR dir[DIR_LENGTH]; TCHAR *env; __int64 affinity; unsigned long envlen; TCHAR *env_extra; unsigned long env_extralen; unsigned long priority; - TCHAR stdin_path[MAX_PATH]; + TCHAR stdin_path[PATH_LENGTH]; unsigned long stdin_sharing; unsigned long stdin_disposition; unsigned long stdin_flags; - TCHAR stdout_path[MAX_PATH]; + TCHAR stdout_path[PATH_LENGTH]; unsigned long stdout_sharing; unsigned long stdout_disposition; unsigned long stdout_flags; HANDLE stdout_pipe; HANDLE stdout_thread; unsigned long stdout_tid; - TCHAR stderr_path[MAX_PATH]; + TCHAR stderr_path[PATH_LENGTH]; unsigned long stderr_sharing; unsigned long stderr_disposition; unsigned long stderr_flags;