#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))#define FILENAME TEXT("FILEREV.DAT")inline void chMB(PCSTR s) { char szTMP[128]; GetModuleFileNameA(NULL, szTMP, chDIMOF(szTMP)); MessageBoxA(GetActiveWindow(), s, szTMP, MB_OK);}///////////////////////////////////////////////////////////////////////////////BOOL FileReverse(PCTSTR pszPathname, PBOOL pfIsTextUnicode) { *pfIsTextUnicode = FALSE; // Assume text is Unicode // Open the file for reading and writing. HANDLE hFile = CreateFile(pszPathname, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { chMB("File could not be opened."); return(FALSE); } // Get the size of the file (I assume the whole file can be mapped). DWORD dwFileSize = GetFileSize(hFile, NULL); // Create the file-mapping object. The file-mapping object is 1 character // bigger than the file size so that a zero character can be placed at the // end of the file to terminate the string (file). Because I don't yet know // if the file contains ANSI or Unicode characters, I assume worst case // and add the size of a WCHAR instead of CHAR. HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize + sizeof(WCHAR), NULL); if (hFileMap == NULL) { chMB("File map could not be opened."); CloseHandle(hFile); return(FALSE); } // Get the address where the first byte of the file is mapped into memory. PVOID pvFile = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0); if (pvFile == NULL) { chMB("Could not map view of file."); CloseHandle(hFileMap); CloseHandle(hFile); return(FALSE); } // Does the buffer contain ANSI or Unicode? int iUnicodeTestFlags = -1; // Try all tests *pfIsTextUnicode = IsTextUnicode(pvFile, dwFileSize, &iUnicodeTestFlags); if (!*pfIsTextUnicode) { // For all the file manipulations below, we explicitly use ANSI // functions because we are processing an ANSI file. // Put a zero character at the very end of the file. PSTR pchANSI = (PSTR) pvFile; pchANSI[dwFileSize / sizeof(CHAR)] = 0; // Reverse the contents of the file. _strrev(pchANSI); // Convert all "\n\r" combinations back to "\r\n" to // preserve the normal end-of-line sequence. pchANSI = strchr(pchANSI, '\n'); // Find first '\n'. while (pchANSI != NULL) { // We have found an occurrence.... *pchANSI++ = '\r'; // Change '\n' to '\r'. *pchANSI++ = '\n'; // Change '\r' to '\n'. pchANSI = strchr(pchANSI, '\n'); // Find the next occurrence. } } else { // For all the file manipulations below, we explicitly use Unicode // functions because we are processing a Unicode file. // Put a zero character at the very end of the file. PWSTR pchUnicode = (PWSTR) pvFile; pchUnicode[dwFileSize / sizeof(WCHAR)] = 0; if ((iUnicodeTestFlags & IS_TEXT_UNICODE_SIGNATURE) != 0) { // If the first character is the Unicode BOM (byte-order-mark), // 0xFEFF, keep this character at the beginning of the file. pchUnicode++; } // Reverse the contents of the file. _wcsrev(pchUnicode); // Convert all "\n\r" combinations back to "\r\n" to // preserve the normal end-of-line sequence. pchUnicode = wcschr(pchUnicode, L'\n'); // Find first '\n'. while (pchUnicode != NULL) { // We have found an occurrence.... *pchUnicode++ = L'\r'; // Change '\n' to '\r'. *pchUnicode++ = L'\n'; // Change '\r' to '\n'. pchUnicode = wcschr(pchUnicode, L'\n'); // Find the next occurrence. } } // Clean up everything before exiting. UnmapViewOfFile(pvFile); CloseHandle(hFileMap); // Remove trailing zero character added earlier. SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN); SetEndOfFile(hFile); CloseHandle(hFile); return(TRUE);}void CFileReverseDlg::OnReverse() { TCHAR szPathname[MAX_PATH]; GetDlgItemText( IDC_FILENAME, szPathname, chDIMOF(szPathname)); // Make copy of input file so that we don't destroy it if (!CopyFile(szPathname, FILENAME, FALSE)) { chMB("New file could not be created."); return; } BOOL fIsTextUnicode; if (FileReverse(FILENAME, &fIsTextUnicode)) { SetDlgItemText( IDC_TEXTTYPE, fIsTextUnicode ? TEXT("Unicode") : TEXT("ANSI")); // Spawn Notepad to see the fruits of our labors. STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; TCHAR sz[] = TEXT("Notepad ") FILENAME; if (CreateProcess(NULL, sz, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); } }}