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.

204 lines
6.0 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1998.
  5. //
  6. // File: NtOpen.cxx
  7. //
  8. // Contents: Helper routines over Nt I/O API
  9. //
  10. // History: 09-Dec-97 Kyle Added header
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #pragma hdrstop
  15. #include <ntopen.hxx>
  16. //+---------------------------------------------------------------------------
  17. //
  18. // Function: CiNtOpenNoThrow
  19. //
  20. // Synopsis: Opens a file using NtOpenFile
  21. //
  22. // Arguments: [h] -- Returns the handle
  23. // [pwcsPath] -- Path of the file to open
  24. // [DesiredAccess] -- Access mask
  25. // [ShareAccess] -- Sharing allowed
  26. // [OpenOptions] -- NT open options
  27. //
  28. // Returns: The NTSTATUS result
  29. //
  30. // History: 09-Dec-97 KyleP Created.
  31. //
  32. //----------------------------------------------------------------------------
  33. NTSTATUS CiNtOpenNoThrow(
  34. HANDLE & h,
  35. WCHAR const * pwcsPath,
  36. ACCESS_MASK DesiredAccess,
  37. ULONG ShareAccess,
  38. ULONG OpenOptions )
  39. {
  40. h = INVALID_HANDLE_VALUE;
  41. UNICODE_STRING uScope;
  42. if ( !RtlDosPathNameToNtPathName_U( pwcsPath,
  43. &uScope,
  44. 0,
  45. 0 ) )
  46. {
  47. ciDebugOut(( DEB_ERROR, "Error converting %ws to Nt path\n", pwcsPath ));
  48. return STATUS_INSUFFICIENT_RESOURCES;
  49. }
  50. //
  51. // Open scope.
  52. //
  53. IO_STATUS_BLOCK IoStatus;
  54. OBJECT_ATTRIBUTES ObjectAttr;
  55. InitializeObjectAttributes( &ObjectAttr, // Structure
  56. &uScope, // Name
  57. OBJ_CASE_INSENSITIVE, // Attributes
  58. 0, // Root
  59. 0 ); // Security
  60. NTSTATUS Status = NtOpenFile( &h, // Handle
  61. DesiredAccess, // Access
  62. &ObjectAttr, // Object Attributes
  63. &IoStatus, // I/O Status block
  64. ShareAccess, // Shared access
  65. OpenOptions ); // Flags
  66. RtlFreeHeap( RtlProcessHeap(), 0, uScope.Buffer );
  67. if ( NT_ERROR( Status ) )
  68. {
  69. vqDebugOut(( DEB_IERROR, "NtOpenFile( %ws ) returned 0x%lx\n",
  70. pwcsPath, Status ));
  71. return Status;
  72. }
  73. return STATUS_SUCCESS;
  74. } //CiNtOpenNoThrow
  75. //+---------------------------------------------------------------------------
  76. //
  77. // Function: CiNtOpenNoThrow
  78. //
  79. // Synopsis: Opens a file using NtOpenFile
  80. //
  81. // Arguments: [pwcsPath] -- Path of the file to open
  82. // [DesiredAccess] -- Access mask
  83. // [ShareAccess] -- Sharing allowed
  84. // [OpenOptions] -- NT open options
  85. //
  86. // Returns: The Handle of the opened file, throws on failure
  87. //
  88. // History: 09-Dec-97 KyleP Created.
  89. //
  90. //----------------------------------------------------------------------------
  91. HANDLE CiNtOpen( WCHAR const * pwcsPath,
  92. ACCESS_MASK DesiredAccess,
  93. ULONG ShareAccess,
  94. ULONG OpenOptions )
  95. {
  96. HANDLE h;
  97. NTSTATUS Status = CiNtOpenNoThrow( h,
  98. pwcsPath,
  99. DesiredAccess,
  100. ShareAccess,
  101. OpenOptions );
  102. if ( STATUS_SUCCESS != Status )
  103. QUIETTHROW( CException( Status ) );
  104. return h;
  105. } //CiNtOpen
  106. #if 0 // no longer needed now that cnss does the right thing
  107. //+---------------------------------------------------------------------------
  108. //
  109. // Function: CiNtFileSize, public
  110. //
  111. // Synopsis: Adds up size of all streams to report 'true' file size.
  112. //
  113. // Arguments: [h] -- Handle to file
  114. //
  115. // Returns: The total size of all streams or -1 if the volume does
  116. // not support streams (like FAT).
  117. //
  118. // History: 09-Dec-97 KyleP Created.
  119. // 08-May-98 KLam NtQueryInformationFile was incorrectly
  120. // checking for STATUS_BUFFER_TOO_SMALL
  121. //
  122. //----------------------------------------------------------------------------
  123. LONGLONG CiNtFileSize( HANDLE h )
  124. {
  125. XGrowable<FILE_STREAM_INFORMATION, 16> aStreamInfo;
  126. //
  127. // Zero first entry, in case there are none (e.g. directories).
  128. //
  129. RtlZeroMemory( aStreamInfo.Get(), sizeof(FILE_STREAM_INFORMATION) );
  130. NTSTATUS Status;
  131. do
  132. {
  133. IO_STATUS_BLOCK ioStatus;
  134. Status = NtQueryInformationFile( h,
  135. &ioStatus,
  136. (void *)aStreamInfo.Get(),
  137. aStreamInfo.Count() * sizeof(FILE_STREAM_INFORMATION),
  138. FileStreamInformation );
  139. //
  140. // fat volumes don't support multiple streams, so fail gracefully
  141. //
  142. if ( STATUS_INVALID_PARAMETER == Status )
  143. return -1;
  144. if ( STATUS_BUFFER_OVERFLOW == Status )
  145. aStreamInfo.SetSize( aStreamInfo.Count() * 2 );
  146. else
  147. break;
  148. } while ( TRUE );
  149. if ( !NT_SUCCESS(Status) )
  150. {
  151. ciDebugOut(( DEB_ERROR, "Error 0x%x from NtQueryInformationFile(FileStreamInformation)\n", Status ));
  152. THROW( CException( Status ) );
  153. }
  154. //
  155. // Iterate through the streams, adding up the sizes.
  156. //
  157. FILE_STREAM_INFORMATION * pStreamInfo = aStreamInfo.Get();
  158. LONGLONG cbSize = pStreamInfo->StreamSize.QuadPart;
  159. for ( ;
  160. 0 != pStreamInfo->NextEntryOffset;
  161. pStreamInfo = (FILE_STREAM_INFORMATION *)(((BYTE *)pStreamInfo) + pStreamInfo->NextEntryOffset),
  162. cbSize += pStreamInfo->StreamSize.QuadPart )
  163. {
  164. continue; // Null body
  165. }
  166. return cbSize;
  167. }
  168. #endif // 0