BOOL FileReverse(PCTSTR pszPathname, PBOOL pfIsTextUnicode)

来源:互联网 发布:手机淘宝5.9.2旧版本 编辑:程序博客网 时间:2024/06/09 23:41
#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);            }         }}