mirror of https://github.com/lianthony/NT4.0
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.
372 lines
9.9 KiB
372 lines
9.9 KiB
/*++
|
|
|
|
Copyright (c) 1991-1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
QueryEA.c
|
|
|
|
Abstract:
|
|
|
|
Test NT EA handling.
|
|
|
|
Author:
|
|
|
|
MadanA 16-Mar-1991
|
|
|
|
Revision History:
|
|
|
|
12-Dec-1991 MadanA
|
|
Created.
|
|
06-Jan-1993 JohnRo
|
|
Massive surgery; work with _stdcall; added this block of comments.
|
|
22-Feb-1993 JohnRo
|
|
Fix infinite loop on two or more EAs.
|
|
Dump entire array in the EA buffer, and compute EA size too.
|
|
07-May-1993 JohnRo
|
|
RAID 3258: file not updated due to ERROR_INVALID_USER_BUFFER.
|
|
Corrected DumpEaBuffer's computation of size.
|
|
|
|
--*/
|
|
|
|
|
|
// These must be included first:
|
|
|
|
#include <nt.h> // NT definitions
|
|
#include <ntrtl.h> // NT runtime library definitions
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <lmcons.h> // Needed by NetDebug.h, etc.
|
|
|
|
// These may be included in any order:
|
|
|
|
#include <assert.h> // assert().
|
|
#include <netdebug.h> // NetpAssert(), FORMAT_ equates.
|
|
#include <repldefs.h> // ReplGetEaSize(), ReplGlobalTrace, REPL_DEBUG_ALL.
|
|
#include <stdio.h> // printf().
|
|
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS, _CRTAPI1.
|
|
#include <string.h> // _stricmp().
|
|
#include <tstring.h> // NetpAlloc{type}From{type}, etc.
|
|
|
|
|
|
#define BUFFER_SIZE 1024
|
|
|
|
|
|
#define MY_ACCESS_DESIRED ( FILE_READ_DATA | FILE_READ_EA \
|
|
| FILE_TRAVERSE \
|
|
| SYNCHRONIZE | FILE_READ_ATTRIBUTES )
|
|
|
|
DBGSTATIC VOID
|
|
Usage(
|
|
VOID
|
|
)
|
|
{
|
|
(VOID) printf("Usage: QueryEA [-v] filename\n");
|
|
}
|
|
|
|
|
|
DBGSTATIC VOID
|
|
DumpEaBuffer(
|
|
IN PBYTE EaBuffer
|
|
)
|
|
{
|
|
PFILE_FULL_EA_INFORMATION Ea;
|
|
DWORD DosEaSize = 0;
|
|
|
|
Ea = (PFILE_FULL_EA_INFORMATION) EaBuffer;
|
|
NetpAssert( Ea != NULL );
|
|
|
|
while( Ea != NULL ) {
|
|
|
|
(VOID) printf( "EA name length = " FORMAT_ULONG ".\n", Ea->EaNameLength );
|
|
(VOID) printf( "EA value length = " FORMAT_ULONG ".\n", Ea->EaValueLength );
|
|
DosEaSize += EA_MIN_SIZE; // fixed overhead for DOS FEA structure.
|
|
|
|
DosEaSize += Ea->EaNameLength + 1;
|
|
DosEaSize += Ea->EaValueLength;
|
|
|
|
if( Ea->NextEntryOffset == 0 ) {
|
|
|
|
// no more EA
|
|
|
|
Ea = NULL;
|
|
|
|
} else {
|
|
|
|
// to next EA structure
|
|
|
|
Ea = (PVOID) (((PBYTE) (PVOID) Ea) + Ea->NextEntryOffset);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
DosEaSize += EA_MIN_SIZE; // Overhead for offset of 0 (marks end of list).
|
|
|
|
|
|
(VOID) printf( "Final EA size is " FORMAT_DWORD ".\n", DosEaSize );
|
|
|
|
} // DumpEaBuffer
|
|
|
|
DBGSTATIC DWORD
|
|
EaSizeAccordingToNt(
|
|
IN LPCWSTR UnicodeFileName
|
|
)
|
|
{
|
|
|
|
FILE_EA_INFORMATION EaInfo;
|
|
DWORD EaSize = EA_MIN_SIZE; // initial value to return on err
|
|
HANDLE FileHandle = INVALID_HANDLE_VALUE;
|
|
UNICODE_STRING FileName;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
NTSTATUS NtStatus;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
assert( UnicodeFileName != NULL );
|
|
assert( (*UnicodeFileName) != L'\0' );
|
|
|
|
if( !RtlDosPathNameToNtPathName_U(
|
|
UnicodeFileName,
|
|
&FileName,
|
|
NULL,
|
|
NULL
|
|
) ) {
|
|
|
|
(VOID) printf("EaSizeAccordingToNt: Could not convert DOS path to NT path\n");
|
|
goto Cleanup;
|
|
}
|
|
// BUGBUG: memory leak.
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&FileName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL );
|
|
|
|
NtStatus = NtOpenFile(
|
|
&FileHandle,
|
|
MY_ACCESS_DESIRED,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
FILE_SHARE_READ,
|
|
FILE_SYNCHRONOUS_IO_NONALERT ); // open options
|
|
|
|
if (! NT_SUCCESS(NtStatus)) {
|
|
(VOID) printf(
|
|
"EaSizeAccordingToNt: NtOpenFile " FORMAT_LPWSTR " failed: "
|
|
FORMAT_NTSTATUS "\n",
|
|
UnicodeFileName, NtStatus);
|
|
goto Cleanup;
|
|
} else {
|
|
(VOID) printf("EaSizeAccordingToNt: Succeeded in opening dir.\n");
|
|
}
|
|
|
|
NtStatus = NtQueryInformationFile(
|
|
FileHandle,
|
|
&IoStatusBlock,
|
|
&EaInfo,
|
|
sizeof(FILE_EA_INFORMATION),
|
|
FileEaInformation ); // information class
|
|
|
|
if ( !NT_SUCCESS( NtStatus ) ) {
|
|
|
|
(VOID) printf(
|
|
"EaSizeAccordingToNt: NtQueryInformationFile for "
|
|
FORMAT_LPWSTR " FAILED, NtStatus="
|
|
FORMAT_NTSTATUS ", iosb.info=" FORMAT_ULONG "\n",
|
|
UnicodeFileName, NtStatus, IoStatusBlock.Information );
|
|
goto Cleanup;
|
|
}
|
|
|
|
EaSize = EaInfo.EaSize;
|
|
|
|
Cleanup:
|
|
|
|
(VOID) printf(
|
|
"EaSizeAccordingToNt: returning EA size " FORMAT_DWORD
|
|
" for " FORMAT_LPWSTR ", final status " FORMAT_NTSTATUS "\n",
|
|
EaSize, UnicodeFileName, NtStatus);
|
|
|
|
if (FileHandle != INVALID_HANDLE_VALUE) {
|
|
(void) NtClose(FileHandle);
|
|
}
|
|
|
|
return (EaSize);
|
|
|
|
} // EaSizeAccordingToNt
|
|
|
|
|
|
int _CRTAPI1
|
|
main(
|
|
IN int argc,
|
|
IN char * argv[]
|
|
)
|
|
{
|
|
|
|
NTSTATUS ntstatus;
|
|
|
|
HANDLE FileHandle;
|
|
LPSTR FileNameA = NULL;
|
|
UNICODE_STRING FileName;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
BYTE RawEaBuffer[BUFFER_SIZE];
|
|
LPWSTR UnicodeFileName;
|
|
|
|
|
|
//
|
|
// Parse command-line arguments.
|
|
//
|
|
|
|
if ( (argc < 2) || (argc > 3) ) {
|
|
Usage();
|
|
return (EXIT_FAILURE);
|
|
} else if (argc == 3) {
|
|
if ( (_stricmp(argv[1], "-v")==0) || (_stricmp(argv[1], "/v")==0) ) {
|
|
ReplGlobalTrace = REPL_DEBUG_ALL;
|
|
FileNameA = argv[2];
|
|
} else {
|
|
Usage();
|
|
return (EXIT_FAILURE);
|
|
}
|
|
} else {
|
|
FileNameA = argv[1];
|
|
}
|
|
assert( FileNameA != NULL );
|
|
|
|
//
|
|
// Do some output and call various new routines to get EA size.
|
|
//
|
|
|
|
(VOID) printf("FileName = " FORMAT_LPSTR " \n", FileNameA );
|
|
|
|
UnicodeFileName = NetpAllocWStrFromStr( FileNameA );
|
|
NetpAssert( UnicodeFileName != NULL );
|
|
|
|
(VOID) printf(
|
|
"EA size according to NT API: " FORMAT_DWORD ".\n\n",
|
|
EaSizeAccordingToNt( UnicodeFileName ) );
|
|
|
|
(VOID) printf(
|
|
"EA size according to repl routine: " FORMAT_DWORD ".\n\n",
|
|
ReplGetEaSize( UnicodeFileName ) );
|
|
|
|
//
|
|
// OK, now compute the same thing the old way.
|
|
//
|
|
|
|
if( !RtlDosPathNameToNtPathName_U(
|
|
UnicodeFileName,
|
|
&FileName,
|
|
NULL,
|
|
NULL
|
|
) ) {
|
|
|
|
(VOID) printf("Could not convert DOS path to NT path\n");
|
|
return (EXIT_FAILURE);
|
|
}
|
|
// BUGBUG: memory leak.
|
|
|
|
InitializeObjectAttributes(
|
|
&ObjectAttributes,
|
|
&FileName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL );
|
|
|
|
ntstatus = NtOpenFile(
|
|
&FileHandle,
|
|
MY_ACCESS_DESIRED,
|
|
&ObjectAttributes,
|
|
&IoStatusBlock,
|
|
FILE_SHARE_READ,
|
|
FILE_SYNCHRONOUS_IO_NONALERT ); // open options
|
|
|
|
if (! NT_SUCCESS(ntstatus)) {
|
|
(VOID) printf(
|
|
"NtOpenFile " FORMAT_LPSTR " failed: " FORMAT_NTSTATUS "\n",
|
|
FileNameA, ntstatus);
|
|
return (EXIT_FAILURE);
|
|
} else {
|
|
(VOID) printf("Succeeded in opening dir.\n");
|
|
}
|
|
|
|
|
|
|
|
if ( NT_SUCCESS( ntstatus = NtQueryEaFile(FileHandle,
|
|
&IoStatusBlock,
|
|
RawEaBuffer,
|
|
BUFFER_SIZE,
|
|
FALSE,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
TRUE
|
|
) ) ) {
|
|
|
|
(VOID) printf(
|
|
"NtQueryEaFile for " FORMAT_LPSTR " succeeded, ntstatus="
|
|
FORMAT_NTSTATUS ", iosb.info=" FORMAT_ULONG "\n",
|
|
FileNameA, ntstatus, IoStatusBlock.Information );
|
|
NetpAssert( IoStatusBlock.Information != 0 );
|
|
|
|
// NetpDbgHexDump( RawEaBuffer, BUFFER_SIZE );
|
|
|
|
DumpEaBuffer( (LPVOID) RawEaBuffer );
|
|
|
|
while( NT_SUCCESS( ntstatus = NtQueryEaFile(FileHandle,
|
|
&IoStatusBlock,
|
|
RawEaBuffer,
|
|
BUFFER_SIZE,
|
|
FALSE,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
FALSE
|
|
) ) ) {
|
|
|
|
|
|
(VOID) printf(
|
|
"NtQueryEaFile for " FORMAT_LPSTR " succeeded "
|
|
FORMAT_NTSTATUS "\n",
|
|
FileNameA, ntstatus);
|
|
|
|
// NetpDbgHexDump( RawEaBuffer, BUFFER_SIZE );
|
|
|
|
// Check for redir's way of indicating no more EAs.
|
|
if (IoStatusBlock.Information == 0) {
|
|
break;
|
|
}
|
|
|
|
DumpEaBuffer( (LPVOID) RawEaBuffer );
|
|
|
|
}
|
|
|
|
if( ( ntstatus != STATUS_NO_EAS_ON_FILE )
|
|
&& ( ntstatus != STATUS_NO_MORE_EAS )
|
|
&& ( ntstatus != STATUS_SUCCESS ) ) {
|
|
|
|
(VOID) printf(
|
|
"NtQueryEaFile for " FORMAT_LPSTR " FAILED, NT status="
|
|
FORMAT_NTSTATUS "\n", FileNameA, ntstatus );
|
|
}
|
|
|
|
}
|
|
|
|
if (ntstatus == STATUS_NO_EAS_ON_FILE) {
|
|
(VOID) printf(
|
|
"No EAs for file, so EA size would be " FORMAT_DWORD ".\n",
|
|
EA_MIN_SIZE );
|
|
}
|
|
|
|
(VOID) printf(
|
|
"NtQueryEaFile for " FORMAT_LPSTR " final status " FORMAT_NTSTATUS
|
|
"\n", FileNameA, ntstatus);
|
|
|
|
(void) NtClose(FileHandle);
|
|
return (EXIT_SUCCESS);
|
|
|
|
} // main
|