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.

242 lines
5.9 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: mapfile.cxx
  7. //
  8. // Contents: Mapped file class implementation
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 12-Feb-96 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "layouthd.cxx"
  18. #pragma hdrstop
  19. //#define TEST_MAPPING_LOWMEM
  20. CMappedFile::~CMappedFile(void)
  21. {
  22. #ifdef SUPPORT_FILE_MAPPING
  23. if (_pbBase != NULL)
  24. {
  25. UnmapViewOfFile(_pbBase);
  26. }
  27. if (_hMapping != INVALID_HANDLE_VALUE)
  28. {
  29. CloseHandle(_hMapping);
  30. }
  31. #endif
  32. if (_hFile != INVALID_HANDLE_VALUE)
  33. {
  34. CloseHandle(_hFile);
  35. }
  36. }
  37. //+---------------------------------------------------------------------------
  38. //
  39. // Member: CMappedFile::InitFromHandle, public
  40. //
  41. // Synopsis: Initialize object based on file handle
  42. //
  43. // Arguments: [h] -- File handle
  44. // [fReadOnly] -- TRUE if mapping is to be read-only
  45. // [fDuplicate] -- TRUE if handle is to be duplicated
  46. // [pvDesiredBaseAddress] -- Desired address for mapping
  47. //
  48. // Returns: Appropriate status code
  49. //
  50. // History: 13-Feb-96 PhilipLa Created
  51. //
  52. //----------------------------------------------------------------------------
  53. SCODE CMappedFile::InitFromHandle(HANDLE h,
  54. BOOL fReadOnly,
  55. BOOL fDuplicate,
  56. void *pvDesiredBaseAddress)
  57. {
  58. SCODE sc = S_OK;
  59. if (fDuplicate)
  60. {
  61. if (!DuplicateHandle(GetCurrentProcess(),
  62. h,
  63. GetCurrentProcess(),
  64. &_hFile,
  65. 0,
  66. TRUE,
  67. DUPLICATE_SAME_ACCESS))
  68. {
  69. layErr(Err, STG_SCODE(GetLastError()));
  70. }
  71. }
  72. else
  73. {
  74. _hFile = h;
  75. }
  76. #ifdef SUPPORT_FILE_MAPPING
  77. #ifndef UNICODE
  78. _hMapping = CreateFileMappingA
  79. #else
  80. _hMapping = CreateFileMapping
  81. #endif
  82. (_hFile,
  83. NULL, // No security
  84. (fReadOnly) ? PAGE_READONLY : PAGE_READWRITE,
  85. 0,
  86. 0, //File size determines map size
  87. NULL); // Unnamed
  88. #ifdef TEST_MAPPING_LOWMEM
  89. CloseHandle(_hMapping);
  90. _hMapping = NULL;
  91. #endif
  92. if (_hMapping != NULL)
  93. {
  94. //Mapping created OK, now map view
  95. _pbBase = MapViewOfFileEx(_hMapping,
  96. (fReadOnly) ? FILE_MAP_READ : FILE_MAP_WRITE,
  97. 0,
  98. 0,
  99. 0,
  100. pvDesiredBaseAddress);
  101. if (_pbBase == NULL)
  102. {
  103. CloseHandle(_hMapping);
  104. _hMapping = INVALID_HANDLE_VALUE;
  105. }
  106. }
  107. #endif //SUPPORT_FILE_MAPPING
  108. Err:
  109. return sc;
  110. }
  111. //+---------------------------------------------------------------------------
  112. //
  113. // Member: CMappedFile::Init, public
  114. //
  115. // Synopsis: Initialize based on a filename
  116. //
  117. // Arguments: [pwcsName] -- Filename for file
  118. // [dwSize] -- Desired size of file, 0 for no size change
  119. // [dwAccess] -- Access mode for file (see CreateFile)
  120. // [dwCreationDisposition] -- Creation for file (see CreateFile)
  121. // [pvDesiredBaseAddress] -- Desired base address for mapping
  122. //
  123. // Returns: Appropriate status code
  124. //
  125. // History: 13-Feb-96 PhilipLa Created
  126. //
  127. //----------------------------------------------------------------------------
  128. SCODE CMappedFile::Init(OLECHAR const *pwcsName,
  129. DWORD dwSize,
  130. DWORD dwAccess,
  131. DWORD dwCreationDisposition,
  132. void *pvDesiredBaseAddress)
  133. {
  134. SCODE sc;
  135. BOOL fReadOnly = ((dwAccess & GENERIC_WRITE) == 0);
  136. layAssert(!fReadOnly || (dwSize == 0));
  137. if (pwcsName == NULL)
  138. return STG_E_INVALIDNAME;
  139. #if (!defined(UNICODE) && !defined(_MAC))
  140. TCHAR atcPath[MAX_PATH + 1];
  141. UINT uCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
  142. if (!WideCharToMultiByte(
  143. uCodePage,
  144. 0,
  145. pwcsName,
  146. -1,
  147. atcPath,
  148. MAX_PATH + 1,
  149. NULL,
  150. NULL))
  151. {
  152. return STG_E_INVALIDNAME;
  153. }
  154. _hFile = CreateFileA(atcPath,
  155. dwAccess,
  156. 0, //No sharing
  157. NULL, //No security
  158. dwCreationDisposition,
  159. FILE_ATTRIBUTE_NORMAL,
  160. NULL); // No template file
  161. #else
  162. _hFile = CreateFile(pwcsName,
  163. dwAccess,
  164. 0, //No sharing
  165. NULL, //No security
  166. dwCreationDisposition,
  167. FILE_ATTRIBUTE_NORMAL,
  168. NULL); // No template file
  169. #endif
  170. if (_hFile == INVALID_HANDLE_VALUE)
  171. {
  172. layErr(Err, STG_SCODE(GetLastError()));
  173. }
  174. if (dwSize != 0)
  175. {
  176. DWORD dw = SetFilePointer(_hFile,
  177. dwSize,
  178. NULL,
  179. FILE_BEGIN);
  180. if (dw == 0xFFFFFFFF)
  181. {
  182. layErr(Err, STG_SCODE(GetLastError()));
  183. }
  184. if (!SetEndOfFile(_hFile))
  185. {
  186. layErr(Err, STG_SCODE(GetLastError()));
  187. }
  188. }
  189. else
  190. {
  191. DWORD dwFileSize;
  192. dwFileSize = GetFileSize(_hFile, NULL);
  193. if (dwFileSize == 0xFFFFFFFF)
  194. {
  195. layErr(Err, STG_SCODE(GetLastError()));
  196. }
  197. if ( dwFileSize == 0 )
  198. {
  199. return STG_S_FILEEMPTY;
  200. }
  201. }
  202. layChk(InitFromHandle(_hFile, fReadOnly, FALSE, pvDesiredBaseAddress));
  203. Err:
  204. return sc;
  205. }