windows-nt/Source/XPSP1/NT/termsrv/admtools/qobject/qobject.c
2020-09-26 16:20:57 +08:00

381 lines
9.6 KiB
C

//Copyright (c) 1998 - 1999 Microsoft Corporation
/*****************************************************************************
*
* QOBJECT.C for Windows NT
*
* Description:
*
* Query NT Objects.
*
****************************************************************************/
/* include files */
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <winstaw.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <utilsub.h>
#include <printfoa.h>
#include "qobject.h"
/*
* Local variables
*/
WCHAR objectW[MAX_FILE_LEN+1];
USHORT dev_flag = FALSE;
USHORT help_flag = FALSE;
/*
* Command line parsing strucutre
*/
TOKMAP ptm[] =
{
{L" ", TMFLAG_OPTIONAL, TMFORM_STRING, MAX_FILE_LEN, objectW},
{L"/Device", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &dev_flag},
{L"/?", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &help_flag},
{0, 0, 0, 0, 0}
};
/*
* Local function prototypes
*/
VOID Usage(BOOL);
BOOL AreWeRunningTerminalServices(void);
/*
* External Procedure prototypes
*/
void display_devices( void );
/*******************************************************************************
*
* print
* Display a message to stdout with variable arguments. Message
* format string comes from the application resources.
*
* ENTRY:
* nResourceID (input)
* Resource ID of the format string to use in the message.
* ... (input)
* Optional additional arguments to be used with format string.
*
* EXIT:
*
******************************************************************************/
void
Print( int nResourceID, ... )
{
char sz1[256], sz2[512];
va_list args;
va_start( args, nResourceID );
if ( LoadStringA( NULL, nResourceID, sz1, 256 ) ) {
vsprintf( sz2, sz1, args );
printf( sz2 );
}
va_end(args);
}
/*******************************************************************************
*
* QueryLink
*
******************************************************************************/
void
QueryLink( HANDLE DirectoryHandle, PCWSTR pName, PWSTR pLinkName, ULONG Length )
{
UNICODE_STRING UnicodeString;
OBJECT_ATTRIBUTES Attributes;
ULONG ReturnedLength;
HANDLE LinkHandle;
NTSTATUS Status;
pLinkName[ 0 ] = UNICODE_NULL;
pLinkName[ 1 ] = UNICODE_NULL;
RtlInitUnicodeString( &UnicodeString, pName );
InitializeObjectAttributes( &Attributes,
&UnicodeString,
OBJ_CASE_INSENSITIVE,
DirectoryHandle,
NULL
);
Status = NtOpenSymbolicLinkObject( &LinkHandle,
SYMBOLIC_LINK_QUERY,
&Attributes
);
if (NT_SUCCESS( Status )) {
UnicodeString.Buffer = pLinkName;
UnicodeString.Length = 0;
UnicodeString.MaximumLength = (USHORT)(Length * sizeof( WCHAR ));
ReturnedLength = 0;
Status = NtQuerySymbolicLinkObject( LinkHandle,
&UnicodeString,
&ReturnedLength
);
NtClose( LinkHandle );
if (NT_SUCCESS( Status )) {
pLinkName[ (ReturnedLength >> 1) + 0 ] = UNICODE_NULL;
pLinkName[ (ReturnedLength >> 1) + 1 ] = UNICODE_NULL;
}
else {
pLinkName[ 0 ] = UNICODE_NULL;
pLinkName[ 1 ] = UNICODE_NULL;
}
}
}
/*******************************************************************************
*
* QueryObject
*
******************************************************************************/
void
QueryObject( PCWSTR lpDeviceName )
{
NTSTATUS Status;
UNICODE_STRING UnicodeString;
OBJECT_ATTRIBUTES Attributes;
HANDLE DirectoryHandle;
POBJECT_DIRECTORY_INFORMATION DirInfo;
BOOLEAN RestartScan;
UCHAR DirInfoBuffer[ 512 ];
WCHAR NameBuffer[ 256 ];
WCHAR LinkBuffer[ 256 ];
ULONG Context = 0;
ULONG ReturnedLength;
WCHAR * pInfo;
RtlInitUnicodeString( &UnicodeString, lpDeviceName );
InitializeObjectAttributes( &Attributes,
&UnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
Status = NtOpenDirectoryObject( &DirectoryHandle,
DIRECTORY_QUERY,
&Attributes
);
// printf( "NtOpenDirectoryObject: %x\n", Status );
if (!NT_SUCCESS( Status ))
return;
RestartScan = TRUE;
DirInfo = (POBJECT_DIRECTORY_INFORMATION)&DirInfoBuffer;
while (TRUE) {
Status = NtQueryDirectoryObject( DirectoryHandle,
(PVOID)DirInfo,
sizeof( DirInfoBuffer ),
TRUE,
RestartScan,
&Context,
&ReturnedLength
);
// printf( "NtQueryDirectoryObject: %x\n", Status );
if (!NT_SUCCESS( Status )) {
if (Status == STATUS_NO_MORE_ENTRIES)
Status = STATUS_SUCCESS;
break;
}
swprintf( NameBuffer, L"%s%s%s", lpDeviceName,
(PCWSTR) (!wcscmp(lpDeviceName,L"\\") ? L"" : L"\\"),
DirInfo->Name.Buffer );
if ( !wcscmp( DirInfo->TypeName.Buffer, L"SymbolicLink" ) ) {
QueryLink( DirectoryHandle, DirInfo->Name.Buffer, LinkBuffer, 255 );
wprintf( L"%-50s ", NameBuffer );
pInfo = LinkBuffer;
while ( *pInfo ) {
wprintf( L"%s ", pInfo );
pInfo += (wcslen( pInfo ) + 1);
}
wprintf( L"\n" );
} else {
wprintf( L"%-50s %s\n", NameBuffer, DirInfo->TypeName.Buffer );
QueryObject( NameBuffer );
}
RestartScan = FALSE;
}
NtClose( DirectoryHandle );
}
/*******************************************************************************
*
* Usage
*
******************************************************************************/
VOID
Usage( BOOL bError )
{
if ( bError ) {
ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
ErrorPrintf(IDS_HELP_USAGE1);
ErrorPrintf(IDS_HELP_USAGE2);
ErrorPrintf(IDS_HELP_USAGE3);
ErrorPrintf(IDS_HELP_USAGE4);
ErrorPrintf(IDS_HELP_USAGE5);
} else {
Print(IDS_HELP_USAGE1);
Print(IDS_HELP_USAGE2);
Print(IDS_HELP_USAGE3);
Print(IDS_HELP_USAGE4);
Print(IDS_HELP_USAGE5);
}
}
/*******************************************************************************
*
* main
*
******************************************************************************/
int __cdecl
main( int argc, char *argv[] )
{
INT i;
ULONG rc;
WCHAR **argvW;
//Check if we are running under Terminal Server
if(!AreWeRunningTerminalServices())
{
ErrorPrintf(IDS_ERROR_NOT_TS);
return(FAILURE);
}
/*
* No popups
*/
SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX );
/*
* Massage the new command line to look like an argv[] type
* because ParseCommandLine() depends on this format
*/
argvW = (WCHAR **)malloc( sizeof(WCHAR *) * (argc+1) );
if(argvW == NULL) {
ErrorPrintf(IDS_ERROR_MALLOC);
return STATUS_NO_MEMORY;
}
for( i=0; i < argc; i++ ) {
// Convert to Ansi
OEM2ANSIA(argv[i], (USHORT)strlen(argv[i]));
argvW[i] = (WCHAR *)malloc( (strlen(argv[i]) + 1) * sizeof(WCHAR) );
wsprintf( argvW[i], L"%S", argv[i] );
}
argvW[argc] = NULL;
/*
* parse the cmd line without parsing the program name (argc-1, argv+1)
*/
rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
/*
* Check for error from ParseCommandLine
*/
if ( help_flag || (rc && rc != PARSE_FLAG_NO_PARMS) ) {
if ( !help_flag ) {
Usage(TRUE);
return rc;
} else {
Usage(FALSE);
return ERROR_SUCCESS;
}
}
/*
* Dos devices only
*/
if ( dev_flag ) {
display_devices();
}
else {
if ( ptm[0].tmFlag & TMFLAG_PRESENT ) {
QueryObject( objectW );
} else {
QueryObject( L"\\" );
}
}
return( 0 );
}
/*******************************************************************************
*
* AreWeRunningTerminalServices
*
* Check if we are running terminal server
*
* ENTRY:
*
* EXIT: BOOL: True if we are running Terminal Services False if we
* are not running Terminal Services
*
*
******************************************************************************/
BOOL AreWeRunningTerminalServices(void)
{
OSVERSIONINFOEX osVersionInfo;
DWORDLONG dwlConditionMask = 0;
ZeroMemory(&osVersionInfo, sizeof(OSVERSIONINFOEX));
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osVersionInfo.wSuiteMask = VER_SUITE_TERMINAL;
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME, VER_AND );
return VerifyVersionInfo(
&osVersionInfo,
VER_SUITENAME,
dwlConditionMask
);
}