static void show_last_error_crt(LPCWSTR preamble) { WCHAR buf[BUFSIZE]; int err = 0; _get_errno(&err); _wcserror_s(buf, BUFSIZE, err); show_detailed_error(preamble, buf, err); }
/********************************************************************* * _wcserror (MSVCRT.@) */ MSVCRT_wchar_t* CDECL _wcserror(int err) { thread_data_t *data = msvcrt_get_thread_data(); if (!data->wcserror_buffer) if (!(data->wcserror_buffer = MSVCRT_malloc(256 * sizeof(MSVCRT_wchar_t)))) return NULL; _wcserror_s(data->wcserror_buffer, 256, err); return data->wcserror_buffer; }
void print_error(int errnum) { const rsize_t ERR_MSG_MAX = 94; if (errnum) { wchar_t buff[ERR_MSG_MAX + 1]; _wcserror_s(buff, errnum); std::wcerr.imbue(std::locale("")); std::wcerr << buff << std::endl; } }
CUniString FormatResult(result_t r) { switch (RESULT_TYPE(r)) { case RESULT_TYPE_ERRNO: { CUniString str; #ifdef _MSC_VER _wcserror_s(str.GetBuffer(1024), 1024, RESULT_CODE(r)); #else CAnsiString strTemp; str=a2w(strerror_r(RESULT_CODE(r), strTemp.GetBuffer(1024), 1024)); #endif str=StringReplace(str, L"\r\n", L"", false); str=StringReplace(str, L"\n", L"", false); } case RESULT_TYPE_GENERIC: { switch (r) { case s_ok: return L"No error"; case e_notimpl: return L"Not implemented"; case e_fail: return L"Unspecified error"; case e_invalidarg: return L"Invalid argument"; case e_accessdenied: return L"Access denied"; case e_outofmemory: return L"Out of memory"; case e_fileformat: return L"File format is incorrect or corrupt"; case e_eof: return L"File format is incorrect or corrupt (unexpected eof)"; } } } return Format(L"Unknown error: 0x%.8x", r); }
/* Retrieves a descriptive string of the error number * This function uses the Visual Studio C runtime library functions * Returns the string_length if successful or -1 on error */ int libcerror_system_copy_string_from_error_number( libcstring_system_character_t *string, size_t string_size, uint32_t error_number ) { size_t string_length = 0; if( string == NULL ) { return( -1 ); } if( string_size > (size_t) INT_MAX ) { return( -1 ); } #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( _wcserror_s( string, string_size, (int) error_number ) != 0 ) #else if( strerror_s( string, string_size, (int) error_number ) != 0 ) #endif { return( -1 ); } string[ string_size - 1 ] = 0; string_length = libcstring_system_string_length( string ); return( (int) string_length ); }
/* Retrieves a descriptive string of the error number * Returns 1 if successful or -1 on error */ int libsmdev_error_string_copy_from_error_number( libcstring_system_character_t *string, size_t string_size, int error_number, liberror_error_t **error ) { static char *function = "libsmdev_error_string_copy_from_error_number"; #if ( defined( HAVE_STRERROR ) && !defined( HAVE_STRERROR_R ) && !defined( WINAPI ) ) || ( defined( WINAPI ) && defined( USE_CRT_FUNCTIONS ) && !defined( _MSC_VER ) ) #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) const wchar_t *static_error_string = NULL; #else const char *static_error_string = NULL; #endif size_t static_error_string_length = 0; #endif if( string == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid string.", function ); return( -1 ); } if( string_size > (size_t) SSIZE_MAX ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_ARGUMENTS, LIBERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid string size value exceeds maximum.", function ); return( -1 ); } /* Use the WINAPI error string function */ #if defined( WINAPI ) && !defined( USE_CRT_FUNCTIONS ) #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD) error_number, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), string, string_size, NULL ) == 0 ) #else if( FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM, NULL, (DWORD) error_number, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), string, string_size, NULL ) == 0 ) #endif { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set string.", function ); return( -1 ); } /* Use MSVSC++ specific CRT error string functions */ #elif defined( USE_CRT_FUNCTIONS ) && defined( _MSC_VER ) #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) if( _wcserror_s( string, string_size, error_number ) != 0 ) #else if( strerror_s( string, string_size, error_number ) != 0 ) #endif { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set string.", function ); return( -1 ); } /* Use POSIX specific error string functions */ #elif defined( HAVE_STRERROR_R ) /* Sanity check */ #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) #error Missing wide character strerror_r function #endif #if defined( STRERROR_R_CHAR_P ) if( strerror_r( error_number, string, string_size ) == NULL ) #else if( strerror_r( error_number, string, string_size ) != 0 ) #endif { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set string.", function ); return( -1 ); } /* Use the static error string function */ #elif defined( HAVE_STRERROR ) || defined( WINAPI ) /* Sanity check */ #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) && !defined( WINAPI ) #error Missing wide character strerror function #endif #if defined( LIBCSTRING_HAVE_WIDE_SYSTEM_CHARACTER ) static_error_string = _wcserror( error_number ); #else static_error_string = strerror( error_number ); #endif if( static_error_string == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to create static error string.", function ); return( -1 ); } static_error_string_length = libcstring_system_string_length( static_error_string ); if( libcstring_system_string_copy( string, static_error_string, static_error_string_length ) == NULL ) { liberror_error_set( error, LIBERROR_ERROR_DOMAIN_RUNTIME, LIBERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set string.", function ); return( -1 ); } string[ static_error_string_length ] = 0; #else #error Missing strerror function #endif return( 1 ); }
//----------------------------------------------------------------------------- static void process_dir_watcher_results( watch_entry *watch_entry_p, DWORD buffer_size){ //----------------------------------------------------------------------------- HANDLE hChangeLog; PFILE_NOTIFY_INFORMATION buffer_p; DWORD buffer_index; BOOL more; SSIZE_T path_len; int compare_result; BOOL exclude; struct exclude_entry * exclude_entry_p; DWORD error_code; errno_t copy_result; LPWSTR fmt, slash_pos; hChangeLog = INVALID_HANDLE_VALUE; more = TRUE; buffer_index = 0; // If buffer size is 0, indicates that too many changes occurred to fit in the buffer // Write out the top level dir to trigger the monitor to do a full pass of it if (buffer_size == 0){ more = FALSE; copy_result = wcsncpy_s(full_file_name, ARRAYSIZE(full_file_name), watch_entry_p->dir_path, watch_entry_p->dir_path_len); if (copy_result != 0){ report_error(L"wcsncpy_s failed", copy_result); ExitProcess(28); } write_path_to_temp_file(full_file_name, ARRAYSIZE(full_file_name), &hChangeLog); } while (more) { buffer_p = (PFILE_NOTIFY_INFORMATION) &watch_entry_p->changes_buffer[buffer_index]; // Cannot use just sizeof(FILE_NOTIFY_INFORMATION) as it includes 2 bytes of struct padding, // causing this check to fail for single-character filenames size_t entry_size = offsetof(FILE_NOTIFY_INFORMATION, FileName) + buffer_p->FileNameLength; if ((buffer_index + entry_size) > buffer_size) { _wfopen_s(&error_file, error_path, L"w"); fwprintf( error_file, L"process_dir_watcher_results buffer overrun %d %d\n", buffer_index, buffer_size ); fclose(error_file); ExitProcess(18); } copy_result = wcsncpy_s(relative_file_name, ARRAYSIZE(relative_file_name), buffer_p->FileName, buffer_p->FileNameLength/sizeof(wchar_t)); if (copy_result != 0){ report_error(L"wcsncpy_s failed", copy_result); ExitProcess(25); } // 2010-09-05 dougfort -- if the dir_path ends in a slash // (probably something like c:\) then we don't want to // interpolate another slash if (watch_entry_p->dir_path[watch_entry_p->dir_path_len-1] == L'\\') fmt = L"%s%s"; else fmt = L"%s\\%s"; path_len = _snwprintf_s(full_file_name, ARRAYSIZE(full_file_name), _TRUNCATE, fmt, watch_entry_p->dir_path, relative_file_name); if (path_len == -1){ report_error(L"_snwprintf_s failed, path too long", (DWORD)(watch_entry_p->dir_path_len + wcslen(relative_file_name))); ExitProcess(26); } // We want the directory where the event took place, // for consistency with OSX. // Needs to be done before calling GetLongPathName since in the case of // a rename or delete the actual file itself is already gone if (full_file_name[path_len-1] != L'\\') { slash_pos = wcsrchr(full_file_name, L'\\'); if (slash_pos) *slash_pos = L'\0'; } // Need to translate short names before checking excludes // According to MSDN docs, you can reuse the same buffer for output path_len = GetLongPathNameW( full_file_name, full_file_name, ARRAYSIZE(full_file_name) ); // Note that most of errors that occurred here were due to a buffer overflow // which has since been fixed. In case of error, pass orig filename unchanged and // let code that picks up output deal with removed folders, etc if (path_len == 0) { error_code = GetLastError(); report_error(L"GetLongPathNameW", error_code); path_len=wcslen(full_file_name); } else if (path_len > ARRAYSIZE(full_file_name)){ // Shouldn't happen since buffer is maximum possible path length report_error(L"GetLongPathNameW result would overflow buffer", (DWORD)path_len); ExitProcess(27); } // Can check for excludes last since we only ever exclude folders exclude = FALSE; for ( exclude_entry_p=exclude_entry_list_p; exclude_entry_p != NULL; exclude_entry_p = exclude_entry_p->next_p ) { compare_result = _wcsnicmp( full_file_name, exclude_entry_p->dir_path, exclude_entry_p->dir_path_len ); if (0 == compare_result) { exclude = TRUE; break; } } if (exclude) { if (0 == buffer_p->NextEntryOffset) { more = FALSE; } else { buffer_index += buffer_p->NextEntryOffset; } continue; } write_path_to_temp_file(full_file_name, ARRAYSIZE(full_file_name), &hChangeLog); if (0 == buffer_p->NextEntryOffset) { more = FALSE; } else { buffer_index += buffer_p->NextEntryOffset; } } // while (more) if (hChangeLog != INVALID_HANDLE_VALUE) { CloseHandle(hChangeLog); notification_sequence++; wsprintf( notification_file_path, // LPTSTR pszDest, L"%s\\%08d.txt", // LPCTSTR pszFormat notification_path, notification_sequence ); if (_wrename(temp_file_path, notification_file_path) != 0) { _wfopen_s(&error_file, error_path, L"w"); _wcserror_s( error_buffer, sizeof error_buffer/sizeof(wchar_t), errno ); fwprintf( error_file, L"_wrename(%s, %s) failed: (%d) %s\n", temp_file_path, notification_file_path, errno, error_buffer ); fclose(error_file); ExitProcess(24); } } } // static void process_dir_watcher_results(
//----------------------------------------------------------------------------- static void load_paths_to_exclude(LPCTSTR path) { //----------------------------------------------------------------------------- FILE * stream_p; wchar_t *get_result; size_t line_len; struct exclude_entry **link_p; struct exclude_entry * next_p; if (_wfopen_s(&stream_p, path, L"r, ccs=UTF-8")) { _wfopen_s(&error_file, error_path, L"w"); _wcserror_s(error_buffer, sizeof error_buffer/sizeof(wchar_t), errno); fwprintf( error_file, L"_wfopen(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } link_p = &exclude_entry_list_p; while (1) { // create an exclude entry next_p = (struct exclude_entry *) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct exclude_entry) ); if (next_p == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(203); } // read in the path to watch from config.txt get_result = \ fgetws(full_file_name, ARRAYSIZE(full_file_name), stream_p); if (NULL == get_result) { if (0 == ferror(stream_p)) { HeapFree(GetProcessHeap(), 0, next_p); break; } _wfopen_s(&error_file, error_path, L"w"); _wcserror_s( error_buffer, sizeof error_buffer/sizeof(wchar_t) , errno ); fwprintf( error_file, L"fgetws(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } // clean out the newline, if there is one line_len = wcslen(full_file_name); if (line_len && full_file_name[line_len-1] == L'\n'){ full_file_name[line_len-1] = L'\0'; line_len--; } if (full_file_name[0] == L'\0') continue; next_p->dir_path_len = line_len; next_p->dir_path = (wchar_t *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (line_len + 1) * sizeof(wchar_t)); if (next_p->dir_path == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(204); } wcsncpy_s(next_p->dir_path, line_len+1, full_file_name, line_len); // add this entry to the list *link_p = next_p; // point to the new entry's next pointer link_p = &(*link_p)->next_p; } // while(1) fclose(stream_p); } // load_paths_to_exclude
//----------------------------------------------------------------------------- static void load_paths_to_watch(LPCTSTR path, HANDLE completion_port_h) { //----------------------------------------------------------------------------- FILE * stream_p; wchar_t *get_result; HANDLE create_result; size_t line_len; struct watch_entry **link_p; struct watch_entry * next_p; if (_wfopen_s(&stream_p, path, L"r, ccs=UTF-8")) { _wfopen_s(&error_file, error_path, L"w"); _wcserror_s(error_buffer, ARRAYSIZE(error_buffer), errno); fwprintf( error_file, L"_wfopen(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } link_p = &watch_entry_list_p; while (1) { // create a watch entry next_p = (struct watch_entry *) HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct watch_entry) ); if (next_p == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(200); } // read in the path to watch from config.txt get_result = \ fgetws(full_file_name, ARRAYSIZE(full_file_name), stream_p); if (NULL == get_result) { if (0 == ferror(stream_p)) { HeapFree(GetProcessHeap(), 0, next_p); break; } _wfopen_s(&error_file, error_path, L"w"); _wcserror_s( error_buffer, sizeof error_buffer/sizeof(wchar_t) , errno ); fwprintf( error_file, L"fgetws(%s) failed: (%d) %s\n", path, errno, error_buffer ); fclose(error_file); ExitProcess(2); } // clean out the newline, if there is one line_len = wcslen(full_file_name); if (line_len && full_file_name[line_len-1] == L'\n'){ full_file_name[line_len-1] = L'\0'; line_len--; } if (full_file_name[0] == L'\0') continue; next_p->dir_path_len = line_len; next_p->dir_path = (wchar_t *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (line_len + 1) * sizeof(wchar_t)); if (next_p->dir_path == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(201); } wcsncpy_s(next_p->dir_path, line_len+1, full_file_name, line_len); next_p->changes_buffer = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, CHANGES_BUFFER_SIZE); if (next_p->changes_buffer == NULL){ report_error(L"HeapAlloc failed to allocate memory", GetLastError()); ExitProcess(202); } // 2020-09-05 dougfort -- we don't clean out trailing slash here // because if they are backing up something like c:\\, we need // the trailing slash. This will come back to bite us when we are // checking for excludes // open a file handle to watch the directory in overlapped mode next_p->hDirectory = CreateFile( next_p->dir_path, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL ); // 2009-03-11 dougfort -- if we can't create this file, // assume it is a top-level directory // which no longer exists; so ignore it and move on. if (INVALID_HANDLE_VALUE == next_p->hDirectory) { report_error(L"CreateFile", GetLastError()); continue; } // add this file handle to the IO Complete port create_result = CreateIoCompletionPort( next_p->hDirectory, // FileHandle, completion_port_h, // ExistingCompletionPort, 0, // CompletionKey, 0 // NumberOfConcurrentThreads ); if (NULL == create_result) { report_error(L"CreateIOCompletionPort (add)", GetLastError()); ExitProcess(102); } if (create_result != completion_port_h) { ExitProcess(103); } start_watch(next_p); // add this entry to the list *link_p = next_p; // point to the new entry's next pointer link_p = &(*link_p)->next_p; } // while(1) fclose(stream_p); } // load_paths_to_watch