205 lines
6 KiB
C++
205 lines
6 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1991 - 1998.
|
||
|
//
|
||
|
// File: NtOpen.cxx
|
||
|
//
|
||
|
// Contents: Helper routines over Nt I/O API
|
||
|
//
|
||
|
// History: 09-Dec-97 Kyle Added header
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include <pch.cxx>
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <ntopen.hxx>
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CiNtOpenNoThrow
|
||
|
//
|
||
|
// Synopsis: Opens a file using NtOpenFile
|
||
|
//
|
||
|
// Arguments: [h] -- Returns the handle
|
||
|
// [pwcsPath] -- Path of the file to open
|
||
|
// [DesiredAccess] -- Access mask
|
||
|
// [ShareAccess] -- Sharing allowed
|
||
|
// [OpenOptions] -- NT open options
|
||
|
//
|
||
|
// Returns: The NTSTATUS result
|
||
|
//
|
||
|
// History: 09-Dec-97 KyleP Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
NTSTATUS CiNtOpenNoThrow(
|
||
|
HANDLE & h,
|
||
|
WCHAR const * pwcsPath,
|
||
|
ACCESS_MASK DesiredAccess,
|
||
|
ULONG ShareAccess,
|
||
|
ULONG OpenOptions )
|
||
|
{
|
||
|
h = INVALID_HANDLE_VALUE;
|
||
|
UNICODE_STRING uScope;
|
||
|
|
||
|
if ( !RtlDosPathNameToNtPathName_U( pwcsPath,
|
||
|
&uScope,
|
||
|
0,
|
||
|
0 ) )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ERROR, "Error converting %ws to Nt path\n", pwcsPath ));
|
||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Open scope.
|
||
|
//
|
||
|
|
||
|
IO_STATUS_BLOCK IoStatus;
|
||
|
OBJECT_ATTRIBUTES ObjectAttr;
|
||
|
|
||
|
InitializeObjectAttributes( &ObjectAttr, // Structure
|
||
|
&uScope, // Name
|
||
|
OBJ_CASE_INSENSITIVE, // Attributes
|
||
|
0, // Root
|
||
|
0 ); // Security
|
||
|
|
||
|
NTSTATUS Status = NtOpenFile( &h, // Handle
|
||
|
DesiredAccess, // Access
|
||
|
&ObjectAttr, // Object Attributes
|
||
|
&IoStatus, // I/O Status block
|
||
|
ShareAccess, // Shared access
|
||
|
OpenOptions ); // Flags
|
||
|
|
||
|
RtlFreeHeap( RtlProcessHeap(), 0, uScope.Buffer );
|
||
|
|
||
|
if ( NT_ERROR( Status ) )
|
||
|
{
|
||
|
vqDebugOut(( DEB_IERROR, "NtOpenFile( %ws ) returned 0x%lx\n",
|
||
|
pwcsPath, Status ));
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
return STATUS_SUCCESS;
|
||
|
} //CiNtOpenNoThrow
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CiNtOpenNoThrow
|
||
|
//
|
||
|
// Synopsis: Opens a file using NtOpenFile
|
||
|
//
|
||
|
// Arguments: [pwcsPath] -- Path of the file to open
|
||
|
// [DesiredAccess] -- Access mask
|
||
|
// [ShareAccess] -- Sharing allowed
|
||
|
// [OpenOptions] -- NT open options
|
||
|
//
|
||
|
// Returns: The Handle of the opened file, throws on failure
|
||
|
//
|
||
|
// History: 09-Dec-97 KyleP Created.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
HANDLE CiNtOpen( WCHAR const * pwcsPath,
|
||
|
ACCESS_MASK DesiredAccess,
|
||
|
ULONG ShareAccess,
|
||
|
ULONG OpenOptions )
|
||
|
{
|
||
|
HANDLE h;
|
||
|
|
||
|
NTSTATUS Status = CiNtOpenNoThrow( h,
|
||
|
pwcsPath,
|
||
|
DesiredAccess,
|
||
|
ShareAccess,
|
||
|
OpenOptions );
|
||
|
|
||
|
if ( STATUS_SUCCESS != Status )
|
||
|
QUIETTHROW( CException( Status ) );
|
||
|
|
||
|
return h;
|
||
|
} //CiNtOpen
|
||
|
|
||
|
#if 0 // no longer needed now that cnss does the right thing
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: CiNtFileSize, public
|
||
|
//
|
||
|
// Synopsis: Adds up size of all streams to report 'true' file size.
|
||
|
//
|
||
|
// Arguments: [h] -- Handle to file
|
||
|
//
|
||
|
// Returns: The total size of all streams or -1 if the volume does
|
||
|
// not support streams (like FAT).
|
||
|
//
|
||
|
// History: 09-Dec-97 KyleP Created.
|
||
|
// 08-May-98 KLam NtQueryInformationFile was incorrectly
|
||
|
// checking for STATUS_BUFFER_TOO_SMALL
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
LONGLONG CiNtFileSize( HANDLE h )
|
||
|
{
|
||
|
|
||
|
XGrowable<FILE_STREAM_INFORMATION, 16> aStreamInfo;
|
||
|
|
||
|
//
|
||
|
// Zero first entry, in case there are none (e.g. directories).
|
||
|
//
|
||
|
|
||
|
RtlZeroMemory( aStreamInfo.Get(), sizeof(FILE_STREAM_INFORMATION) );
|
||
|
|
||
|
NTSTATUS Status;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
IO_STATUS_BLOCK ioStatus;
|
||
|
|
||
|
Status = NtQueryInformationFile( h,
|
||
|
&ioStatus,
|
||
|
(void *)aStreamInfo.Get(),
|
||
|
aStreamInfo.Count() * sizeof(FILE_STREAM_INFORMATION),
|
||
|
FileStreamInformation );
|
||
|
|
||
|
//
|
||
|
// fat volumes don't support multiple streams, so fail gracefully
|
||
|
//
|
||
|
|
||
|
if ( STATUS_INVALID_PARAMETER == Status )
|
||
|
return -1;
|
||
|
|
||
|
if ( STATUS_BUFFER_OVERFLOW == Status )
|
||
|
aStreamInfo.SetSize( aStreamInfo.Count() * 2 );
|
||
|
else
|
||
|
break;
|
||
|
|
||
|
} while ( TRUE );
|
||
|
|
||
|
if ( !NT_SUCCESS(Status) )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ERROR, "Error 0x%x from NtQueryInformationFile(FileStreamInformation)\n", Status ));
|
||
|
THROW( CException( Status ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Iterate through the streams, adding up the sizes.
|
||
|
//
|
||
|
|
||
|
FILE_STREAM_INFORMATION * pStreamInfo = aStreamInfo.Get();
|
||
|
LONGLONG cbSize = pStreamInfo->StreamSize.QuadPart;
|
||
|
|
||
|
for ( ;
|
||
|
0 != pStreamInfo->NextEntryOffset;
|
||
|
pStreamInfo = (FILE_STREAM_INFORMATION *)(((BYTE *)pStreamInfo) + pStreamInfo->NextEntryOffset),
|
||
|
cbSize += pStreamInfo->StreamSize.QuadPart )
|
||
|
{
|
||
|
continue; // Null body
|
||
|
}
|
||
|
|
||
|
return cbSize;
|
||
|
}
|
||
|
|
||
|
#endif // 0
|