Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
3.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. SimpleFp.cpp
  5. Abstract:
  6. simple file pointer, to replace msvcrt.dll
  7. Author:
  8. Xiaoyu Wu(xiaoyuw) July 2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include "simplefp.h"
  13. #include "fusiontrace.h"
  14. #include "csxspreservelasterror.h"
  15. #include "util.h"
  16. CSimpleFileStream::CSimpleFileStream(PCSTR pFileName)
  17. {
  18. BOOL fSuccess = FALSE;
  19. FN_TRACE_WIN32(fSuccess);
  20. if (!pFileName)
  21. {
  22. // duplicate it so we can close it like normal
  23. HANDLE hFile = GetStdHandle(STD_ERROR_HANDLE);
  24. IFW32FALSE_ORIGINATE_AND_EXIT(::DuplicateHandle(::GetCurrentProcess(), hFile, ::GetCurrentProcess(), &m_hFile, 0, FALSE, DUPLICATE_SAME_ACCESS));
  25. }
  26. else
  27. {
  28. IFCOMFAILED_EXIT(this->fopen(pFileName));
  29. }
  30. fSuccess = FALSE;
  31. Exit:
  32. ;
  33. }
  34. CSimpleFileStream::~CSimpleFileStream()
  35. {
  36. if ( m_hFile != INVALID_HANDLE_VALUE) // if it is GetStdHandle, Could I close the handle?
  37. {
  38. CSxsPreserveLastError ple;
  39. this->fclose();
  40. ple.Restore();
  41. }
  42. }
  43. HRESULT
  44. CSimpleFileStream::fopen(
  45. PCSTR pFileName
  46. )
  47. {
  48. HRESULT hr = NOERROR;
  49. FN_TRACE_HR(hr);
  50. if ( m_hFile != INVALID_HANDLE_VALUE)
  51. {
  52. IFCOMFAILED_EXIT(this->fclose());
  53. }
  54. IFW32INVALIDHANDLE_ORIGINATE_AND_EXIT(
  55. m_hFile = ::CreateFileA(
  56. pFileName,
  57. GENERIC_WRITE,
  58. 0,
  59. NULL,
  60. CREATE_ALWAYS,
  61. 0,
  62. NULL));
  63. FN_EPILOG
  64. }
  65. HRESULT
  66. CSimpleFileStream::fclose()
  67. {
  68. HRESULT hr = NOERROR;
  69. FN_TRACE_HR(hr);
  70. if (m_hFile == INVALID_HANDLE_VALUE)
  71. {
  72. IFCOMFAILED_EXIT(E_UNEXPECTED);
  73. }
  74. IFW32FALSE_ORIGINATE_AND_EXIT(::CloseHandle(m_hFile));
  75. hr = NOERROR;
  76. Exit:
  77. m_hFile = INVALID_HANDLE_VALUE; // avoid the destructor to call it repeatly
  78. return hr;
  79. }
  80. HRESULT
  81. CSimpleFileStream::fprintf(
  82. const char *format,
  83. ...
  84. )
  85. {
  86. HRESULT hr = NOERROR;
  87. FN_TRACE_HR(hr);
  88. va_list ap;
  89. char rgchBuffer[2048];
  90. int cchIn = 0;
  91. DWORD cchWritten = 0;
  92. ASSERT(m_hFile != INVALID_HANDLE_VALUE);
  93. if ( m_hFile == INVALID_HANDLE_VALUE)
  94. IFCOMFAILED_EXIT(E_UNEXPECTED);
  95. va_start(ap, format);
  96. cchIn = _vsnprintf(rgchBuffer, NUMBER_OF(rgchBuffer) - 1, format, ap);
  97. rgchBuffer[NUMBER_OF(rgchBuffer) - 1] = 0;
  98. va_end(ap);
  99. if (cchIn < 0)
  100. IFCOMFAILED_EXIT(E_UNEXPECTED);
  101. IFW32FALSE_ORIGINATE_AND_EXIT(::WriteFile(m_hFile, rgchBuffer, cchIn, &cchWritten, NULL));
  102. hr = NOERROR;
  103. Exit:
  104. return hr;
  105. }
  106. HRESULT CSimpleFileStream::fwrite(const VOID* pData, SIZE_T itemsize, SIZE_T itemcount)
  107. {
  108. HRESULT hr = NOERROR;
  109. FN_TRACE_HR(hr);
  110. SIZE_T count = 0;
  111. DWORD ByteWritten = 0;
  112. ASSERT(m_hFile != INVALID_HANDLE_VALUE);
  113. if ( m_hFile == INVALID_HANDLE_VALUE)
  114. IFCOMFAILED_EXIT(E_UNEXPECTED);
  115. count = itemsize * itemcount;
  116. while (count > ULONG_MAX)
  117. {
  118. IFW32FALSE_ORIGINATE_AND_EXIT(::WriteFile(m_hFile, pData, ULONG_MAX, &ByteWritten, NULL));
  119. count -= ULONG_MAX;
  120. }
  121. if (count != 0)
  122. {
  123. IFW32FALSE_ORIGINATE_AND_EXIT(::WriteFile(m_hFile, pData, static_cast<DWORD>(count), &ByteWritten, NULL));
  124. }
  125. hr = NOERROR;
  126. Exit:
  127. return hr;
  128. }